सभी मार्करों को दिखाने के लिए एंड्रॉइड मैप v2 ज़ूम


286

मेरे 10 मार्कर हैं GoogleMap। मैं अधिक से अधिक ज़ूम करना चाहता हूं और सभी मार्करों को ध्यान में रखना चाहता हूं? पहले के संस्करण में इससे प्राप्त किया जा सकता है, zoomToSpan()लेकिन v2 में मुझे नहीं पता कि इसे कैसे करना है। इसके अलावा, मैं उस दायरे की त्रिज्या को जानता हूं जिसे दिखाई देने की आवश्यकता है।

जवाबों:


810

आपको CameraUpdateसभी प्रोग्रामेटिक मैप आंदोलनों को करने के लिए कक्षा का उपयोग करना चाहिए (शायद)।

ऐसा करने के लिए, पहले सभी मार्करों की सीमा की गणना करें:

LatLngBounds.Builder builder = new LatLngBounds.Builder();
for (Marker marker : markers) {
    builder.include(marker.getPosition());
}
LatLngBounds bounds = builder.build();

फिर कारखाने का उपयोग करके एक आंदोलन विवरण वस्तु प्राप्त करें CameraUpdateFactory:

int padding = 0; // offset from edges of the map in pixels
CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, padding);

अंत में मानचित्र को स्थानांतरित करें:

googleMap.moveCamera(cu);

या यदि आप एक एनीमेशन चाहते हैं:

googleMap.animateCamera(cu);

बस इतना ही :)

स्पष्टता १

लगभग सभी आंदोलन विधियों Mapमें लेआउट प्रक्रिया को पारित करने के लिए ऑब्जेक्ट की आवश्यकता होती है। आप addOnGlobalLayoutListenerनिर्माण का उपयोग करने के लिए इसके लिए प्रतीक्षा कर सकते हैं । विवरण इस उत्तर और शेष उत्तर के लिए टिप्पणियों में पाया जा सकता है। आप यहां उपयोग करके मानचित्र सीमा निर्धारित करने के लिएaddOnGlobalLayoutListener एक पूर्ण कोड भी पा सकते हैं

स्पष्टता २

एक टिप्पणी नोट करती है कि केवल एक मार्कर के लिए इस पद्धति का उपयोग करने से मैप ज़ूम में "विचित्र" ज़ूम स्तर पर सेट होता है (जिसे मैं मानती हूं कि दिए गए स्थान के लिए अधिकतम ज़ूम स्तर उपलब्ध है)। मुझे लगता है कि यह अपेक्षित है क्योंकि:

  1. LatLngBounds boundsउदाहरण होगा northeastसंपत्ति के बराबर southwestहै, जिसका अर्थ है कि पृथ्वी इस के अंतर्गत आने वाले क्षेत्र के भाग boundsबिल्कुल शून्य है। (यह तर्कसंगत है क्योंकि एकल मार्कर का कोई क्षेत्र नहीं है।)
  2. आपके पास जाने के boundsलिए CameraUpdateFactory.newLatLngBoundsअनिवार्य रूप से ऐसे ज़ूम स्तर की गणना का अनुरोध करें जो bounds(शून्य क्षेत्र वाला) पूरे मानचित्र दृश्य को कवर करेगा।
  3. आप वास्तव में इस गणना को कागज के एक टुकड़े पर कर सकते हैं। सैद्धांतिक ज़ूम स्तर जो उत्तर है + + inf (सकारात्मक अनंत) है। व्यवहार में Mapवस्तु इस मूल्य का समर्थन नहीं करती है, इसलिए इसे दिए गए स्थान के लिए अनुमति दी गई अधिक उचित अधिकतम स्तर पर दबाना है।

इसे लगाने का एक और तरीका: Mapऑब्जेक्ट कैसे जान सकता है कि किसी एकल स्थान के लिए ज़ूम स्तर क्या होना चाहिए ? शायद इष्टतम मूल्य 20 होना चाहिए (यदि यह एक विशिष्ट पते का प्रतिनिधित्व करता है)। या शायद 11 (यदि यह एक शहर का प्रतिनिधित्व करता है)। या हो सकता है 6 (यदि यह एक देश का प्रतिनिधित्व करता है)। एपीआई स्मार्ट नहीं है और निर्णय आप पर निर्भर है।

तो, आपको बस यह जांचना चाहिए कि markersक्या केवल एक स्थान है और यदि ऐसा है, तो निम्न में से एक का उपयोग करें:

  • CameraUpdate cu = CameraUpdateFactory.newLatLng(marker.getPosition()) - मार्कर स्थिति पर जाएं, वर्तमान ज़ूम स्तर बरकरार रखें।
  • CameraUpdate cu = CameraUpdateFactory.newLatLngZoom(marker.getPosition(), 12F) - मार्कर स्थिति पर जाएं, ज़ूम स्तर को मनमाने ढंग से चुने गए मान 12 पर सेट करें।

21
यह ध्यान दिया जाना चाहिए कि चाल onCreate कॉल से नहीं हो सकती है, दृश्य बनाया जाना चाहिए। मुझे उचित नमूना प्राप्त करने के लिए addOnGlobalLayoutListener का उपयोग करने की आवश्यकता थी।
बारूच

6
@ बर खैर, यह आंशिक रूप से सच है। सटीक होने के लिए: मैप ऑब्जेक्ट बनाने के बाद कुछ मूवमेंट मेथड सही काम नहीं करेंगे। इसका कारण यह है कि मैप ऑब्जेक्ट को अभी तक मापा नहीं गया है अर्थात यह लेआउट प्रक्रिया से नहीं गुजरा है। एक विशिष्ट फिक्स का उपयोग करना addOnGlobalLayoutListener()या post()एक उपयुक्त के साथ करना है Runnable। यही कारण है कि मार्कर स्क्रीन निर्देशांक प्राप्त नहीं किया जा सकता है onCreate- देखें stackoverflow.com/q/14429877/1820695 हालांकि लेआउट होने से पहले ही आप कुछ विधियों का उपयोग कर सकते हैं - जैसे। 4 परिमों केCameraUpdateFactory.newLatLngBounds() साथ ।
.r

1
यार, आप मेरा दिन बचाते हैं ... वास्तव में इसे अपने दम पर करने की कोशिश कर रहे थे, मैन्युअल रूप से सीमा की गणना करते हैं, और ज़ूम करते समय मार्कर इसमें है ... बहुत बदसूरत काम कर रहा था, लेकिन आपकी सरल विधि के साथ, यह एक आकर्षण की तरह काम करता है। धन्यवाद
Bibu

9
googleMap .setOnMapLoadedCallback (नया GoogleMap .nMapLoadedCallback () {@Override सार्वजनिक शून्य onMapLoaded () {googleMap.moveCamera (cu);}}); यह माप पर त्रुटि से बच जाएगा।
रमज़ जूल

1
यह अन्यथा काम करता है लेकिन जब मानचित्र पर एक एकल मार्कर होता है तो यह कुछ विचित्र स्तर तक पहुंच जाता है कि मानचित्र धुंधला हो जाता है। इसे कैसे ठीक करें?
उत्सव गुप्ता

124

Google मानचित्र V2

निम्नलिखित समाधान एंड्रॉइड मार्शमैलो 6 (एपीआई 23, एपीआई 24, एपीआई 25, एपीआई 26, एपीआई 27, एपीआई 28) के लिए काम करता है। यह ज़मीरिन में भी काम करता है।

LatLngBounds.Builder builder = new LatLngBounds.Builder();

//the include method will calculate the min and max bound.
builder.include(marker1.getPosition());
builder.include(marker2.getPosition());
builder.include(marker3.getPosition());
builder.include(marker4.getPosition());

LatLngBounds bounds = builder.build();

int width = getResources().getDisplayMetrics().widthPixels;
int height = getResources().getDisplayMetrics().heightPixels;
int padding = (int) (width * 0.10); // offset from edges of the map 10% of screen

CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, width, height, padding);

mMap.animateCamera(cu);

7
बेहतर दिखने वाले पैडिंग के लिए, चौड़ाई के बजाय ऊंचाई का उपयोग करें और इसके 10% के बजाय 20% लें।
noob

2
स्वीकृत उत्तर कभी-कभी अजीब ज़ूमिंग का कारण बनता है। यह एक आकर्षण की तरह काम करता है। यह एक बेहतर जवाब है।
हुसेन बुएलबुल

1
यह उत्तर स्वीकार किए गए की तुलना में बेहतर काम करता है, स्वीकार किए जाते हैं कुछ मातम व्यवहार का कारण बनता है।
हैथम

13

इसलिए

मुझे उचित नमूना प्राप्त करने के लिए addOnGlobalLayoutListener का उपयोग करने की आवश्यकता थी

उदाहरण के लिए, आपका Google मानचित्र RelativeLayout के अंदर है:

RelativeLayout mapLayout = (RelativeLayout)findViewById(R.id.map_layout);
mapLayout.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            //and write code, which you can see in answer above
        }
    });

1
उदमी ट्यूटोरियल, महान काम आदमी से यहां आए, उन्होंने समस्या को हल करने के लिए आपके उत्तर का उपयोग किया।
शांतनु शेडी

13

मैं onGlobalLayoutlistener का उपयोग नहीं कर सका, इसलिए यहां "Map size can't be 0. Most likely, layout has not yet occured for the map view. Either wait until layout has occurred or use newLatLngBounds(LatLngBounds, int, int, int) which allows you to specify the map's dimensions."त्रुटि को रोकने के लिए एक और उपाय है :

mMap.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback() { 
@Override 
public void onMapLoaded() { 
    mMap.moveCamera(CameraUpdateFactory.newLatLngBounds(builder.build(), 15));
 } 
});

यह एक मेरे लिए OnGlobalLayoutListener से अधिक समय जिस तरह से लेता है, तो यह अभी भी पता चला मानचित्र डिफ़ॉल्ट क्षेत्र / पहले ज़ूम मेरी जरूरतों के लिए कैमरा ले जाने से पहले
जब तक

कुछ पैडिंग कैसे दें क्योंकि मेरे 2 मार्करों को मानचित्र सीमा के साथ स्पर्श किया गया है।
प्रतीक बुटानी

9

मेरे लिए काम करना ठीक है।

इस कोड से, मैं मानचित्र स्क्रीन पर विशेष ज़ूम के साथ कई मार्कर प्रदर्शित कर रहा हूं।

// घोषित चर

private LatLngBounds bounds;
private LatLngBounds.Builder builder;

// ड्रा करने योग्य आइकन के साथ कई मार्कर बिंदुओं को जोड़ने की विधि

private void drawMarker(LatLng point, String text) {

        MarkerOptions markerOptions = new MarkerOptions();
        markerOptions.position(point).title(text).icon(BitmapDescriptorFactory.fromResource(R.drawable.icon));
        mMap.addMarker(markerOptions);
        builder.include(markerOptions.getPosition());

    }

// मानचित्र पर दिखाई देने वाले कई मार्कर जोड़ने के लिए

@Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;
        builder = new LatLngBounds.Builder();
    for (int i = 0; i < locationList.size(); i++) {

        drawMarker(new LatLng(Double.parseDouble(locationList.get(i).getLatitude()), Double.parseDouble(locationList.get(i).getLongitude())), locationList.get(i).getNo());

     }
     bounds = builder.build();
     CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, 0);
     mMap.animateCamera(cu);

4

नोट - यह मूल प्रश्न का हल नहीं है। यह ऊपर चर्चा की गई उपप्रकारों में से एक का समाधान है ।

@ शेडोंग क्लैरिफिकेशन 2 का समाधान -

इसकी वास्तव में समस्या है जब सीमा में केवल एक मार्कर है और इसके कारण ज़ूम स्तर बहुत उच्च स्तर ( 21 स्तर ) पर सेट है। और Google इस बिंदु पर अधिकतम ज़ूम स्तर सेट करने का कोई तरीका प्रदान नहीं करता है। यह तब भी हो सकता है जब 1 से अधिक मार्कर होते हैं लेकिन वे सभी एक दूसरे के बहुत करीब होते हैं। फिर वही समस्या भी आएगी।

समाधान - मान लीजिए कि आप चाहते हैं कि आपका मानचित्र कभी भी 16 ज़ूम स्तर से आगे न बढ़े। फिर करने के बाद -

CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, padding);
mMap.moveCamera(cu);

जांचें कि क्या आपका जूम स्तर 16 के स्तर को पार कर गया है (या आप जो भी चाहते हैं) -

float currentZoom = mMap.getCameraPosition().zoom;

और यदि यह स्तर 16 से अधिक है, जो केवल तभी होगा जब बहुत कम मार्कर हों या सभी मार्कर एक-दूसरे के बहुत करीब हों, तो केवल ज़ूम स्तर को 16 पर सेट करके अपने मानचित्र को उस विशेष स्थिति में ज़ूम आउट करें।

mMap.moveCamera(CameraUpdateFactory.zoomTo(16));

इस तरह से आपको कभी भी "विचित्र" ज़ूम के स्तर की समस्या नहीं होगी, यह @andr द्वारा बहुत अच्छी तरह से समझाया गया है।


अच्छा समाधान है, लेकिन अगर आप onMapReady () के अंदर "cu" ऑब्जेक्ट डालते हैं, तो इस मामले में एक दुर्व्यवहार होता है: स्थान प्राप्त -> ज़ूम बड़ा है इसलिए इसे 16 बनाएं -> फिर उपयोगकर्ता zooms में -> स्थान फिर से और कैमरा है 16 के स्तर पर वापस डाल दिया । यह एक समस्या हो सकती है जब स्थान लगभग वास्तविक समय पर प्राप्त होता है क्योंकि यह 16 के स्तर पर लौटता रहेगा।
मैहर नबील

"और Google इस बिंदु पर अधिकतम ज़ूम स्तर निर्धारित करने का कोई तरीका प्रदान नहीं करता है।" - यह सच नहीं है: Developers.google.com/android/reference/com/google/android/gms/…
user1209216

3

यह मदद करेगा .. गूगल एपिस डेमो से

private List<Marker> markerList = new ArrayList<>();
Marker marker = mGoogleMap.addMarker(new MarkerOptions().position(geoLatLng)
                .title(title));
markerList.add(marker);
    // Pan to see all markers in view.
    // Cannot zoom to bounds until the map has a size.
    final View mapView = getSupportFragmentManager().findFragmentById(R.id.map).getView();
    if (mapView!=null) {
        if (mapView.getViewTreeObserver().isAlive()) {
            mapView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @SuppressWarnings("deprecation") // We use the new method when supported
                @SuppressLint("NewApi") // We check which build version we are using.
                @Override
                public void onGlobalLayout() {
                    //Calculate the markers to get their position
                    LatLngBounds.Builder b = new LatLngBounds.Builder();
                    for (Marker m : markerList) {
                        b.include(m.getPosition());
                    }
                    // also include current location to include in the view
                    b.include(new LatLng(mLocation.getLatitude(),mLocation.getLongitude()));

                    LatLngBounds bounds = b.build();
                    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
                        mapView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                    } else {
                        mapView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                    }
                    mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 50));
                }
            });
        }
    }

स्पष्ट जानकारी के लिए इस url को देखें। https://github.com/googlemaps/android-samples/blob/master/ApiDemos/app/src/main/java/com/example/mapdemo/MarkerDemoActivity.java


1

मुझे इस तरह की समस्या थी, निम्नलिखित कोड के उपयोग से समस्या हल हो गई:

CameraUpdateFactory.newLatLngBounds(bounds, 200, 200, 5) आम तौर पर मेरे मामले में स्थान अंतर दो पड़ोसी शहरों से अधिक नहीं हैं।

ज़ूम करने के लिए सभी मार्करों को फिट करें मानचित्र गूगल मैप्स v2


1

Google मानचित्र के साथ सभी मार्कर दिखाएं

इन तरीकों में सभी मार्करों को संग्रहीत करते हैं और स्वचालित रूप से सभी मार्करों को Google मानचित्र में दिखाने के लिए ज़ूम इन करते हैं।

// Declare the Markers List.
List<MarkerOptions> markerList;
private BitmapDescriptor vnrPoint,banPoint;


public void storeAllMarkers()
{
      markerList=new ArrayList<>();
      markerList.removeAll(markerList);


      // latitude and longitude of Virudhunagar

      double latitude1=9.587209;
      double longitude1=77.951431;
   vnrPoint=BitmapDescriptorFactory.fromResource(R.drawable.location_icon_1);
      LatLng vnr = new LatLng(latitude1, longitude1);
      MarkerOptions vnrMarker = new MarkerOptions();
      vnrMarker.position(vnr);
      vnrMarker.icon(vnrPoint);
      markerList.add(vnrMarker);

      // latitude and longitude of Bengaluru

      double latitude2=12.972442;
      double longitude2=77.580643;

    banPoint=BitmapDescriptorFactory.fromResource(R.drawable.location_icon_2);

      LatLng ban = new LatLng(latitude2, longitude2);
      MarkerOptions bengalureMarker = new MarkerOptions();
      bengalureMarker.position(ban);
      bengalureMarker.icon(banPoint);
      markerList.add(bengalureMarker);

      // You can add any numbers of MarkerOptions like this.

     showAllMarkers();

 }


public void showAllMarkers()
{
    LatLngBounds.Builder builder = new LatLngBounds.Builder();

    for (MarkerOptions m : markerList) {
        builder.include(m.getPosition());
    }

    LatLngBounds bounds = builder.build();

    int width = getResources().getDisplayMetrics().widthPixels;
    int height = getResources().getDisplayMetrics().heightPixels;
    int padding = (int) (width * 0.30); 

    // Zoom and animate the google map to show all markers

    CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, width, height, padding);
    googleMap.animateCamera(cu);
}

0

केंद्र समन्वय और CameraPosition में उपयोग करने के लिए "getCenterCoordinate" विधि का उपयोग करें।

private void setUpMap() {
    mMap.setMyLocationEnabled(true);
    mMap.getUiSettings().setScrollGesturesEnabled(true);
    mMap.getUiSettings().setTiltGesturesEnabled(true);
    mMap.getUiSettings().setRotateGesturesEnabled(true);

    clientMarker = mMap.addMarker(new MarkerOptions()
            .position(new LatLng(Double.valueOf(-12.1024174), Double.valueOf(-77.0262274)))
            .icon(BitmapDescriptorFactory.fromResource(R.mipmap.ic_taxi))
    );
    clientMarker = mMap.addMarker(new MarkerOptions()
            .position(new LatLng(Double.valueOf(-12.1024637), Double.valueOf(-77.0242617)))
            .icon(BitmapDescriptorFactory.fromResource(R.mipmap.ic_location))
    );

    camPos = new CameraPosition.Builder()
            .target(getCenterCoordinate())
            .zoom(17)
            .build();
    camUpd3 = CameraUpdateFactory.newCameraPosition(camPos);
    mMap.animateCamera(camUpd3);
}


public LatLng getCenterCoordinate(){
    LatLngBounds.Builder builder = new LatLngBounds.Builder();
    builder.include(new LatLng(Double.valueOf(-12.1024174), Double.valueOf(-77.0262274)));
    builder.include(new LatLng(Double.valueOf(-12.1024637), Double.valueOf(-77.0242617)));
    LatLngBounds bounds = builder.build();
    return bounds.getCenter();
}

0

मेरे पास एक ही तरीका है कि यह वही काम करे जो पूरी तरह से काम करे। इसलिए स्क्रीन पर सभी मार्करों को दिखाने के लिए विचार के लिए हमें एक केंद्र अक्षांश लंबा और ज़ूम स्तर चाहिए। यहां वह फ़ंक्शन है जो आपको दोनों देगा और इनपुट के रूप में सभी मार्कर के लैटलिंग ऑब्जेक्ट की आवश्यकता होगी।

 public Pair<LatLng, Integer> getCenterWithZoomLevel(LatLng... l) {
    float max = 0;

    if (l == null || l.length == 0) {
        return null;
    }
    LatLngBounds.Builder b = new LatLngBounds.Builder();
    for (int count = 0; count < l.length; count++) {
        if (l[count] == null) {
            continue;
        }
        b.include(l[count]);
    }

    LatLng center = b.build().getCenter();

    float distance = 0;
    for (int count = 0; count < l.length; count++) {
        if (l[count] == null) {
            continue;
        }
        distance = distance(center, l[count]);
        if (distance > max) {
            max = distance;
        }
    }

    double scale = max / 1000;
    int zoom = ((int) (16 - Math.log(scale) / Math.log(2)));
    return new Pair<LatLng, Integer>(center, zoom);
}

यह फ़ंक्शन Pair ऑब्जेक्ट देता है जिसे आप पसंद कर सकते हैं

जोड़ी जोड़ी = getCenterWithZoomLevel (l1, l2, l3 ..); mGoogleMap.moveCamera (CameraUpdateFactory.newLatLngZoom (pair.first, pair.second));

आप स्क्रीन मार्करों से अपने मार्करों को दूर रखने के लिए पैडिंग का उपयोग करने के बजाय, ज़ूम -1 को समायोजित कर सकते हैं।


-3
   //For adding a marker in Google map
        MarkerOptions mp = new MarkerOptions();
        mp.position(new LatLng(Double.parseDouble(latitude), Double.parseDouble(longitude)));
        mp.snippet(strAddress);
        map.addMarker(mp);

        try {

            b = new LatLngBounds.Builder();

            if (MapDetailsList.list != null && MapDetailsList.list.size() > 0) {

                for (int i = 0; i < MapDetailsList.list.size(); i++) {

                    b.include(new LatLng(Double.parseDouble(MapDetailsList.list.get(i).getLatitude()),
                            Double.parseDouble(MapDetailsList.list.get(i).getLongitude())));

                }
                LatLngBounds bounds = b.build();

                DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
                int width = displayMetrics.widthPixels;
                int height = displayMetrics.heightPixels;

                // Change the padding as per needed
                CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, width-200, height-200, 5);
                // map.setCenter(bounds.getCenter());

                map.animateCamera(cu);

            }

        } catch (Exception e) {

        }

http://i64.tinypic.com/2qjybh4.png

http://i63.tinypic.com/flzwus.png

http://i63.tinypic.com/112g5fm.png

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.