Google मैप्स API v3: क्या मैं फ़िटबाउंड्स के बाद सेटज़ूम कर सकता हूं?


201

मेरे पास उन बिंदुओं का एक समूह है जो मैं एक एम्बेडेड Google मानचित्र (एपीआई v3) पर साजिश करना चाहता हूं। जब तक ज़ूम स्तर बहुत कम न हो (यानी, बहुत अधिक ज़ूम आउट किया जाता है) तक सभी बिंदुओं को समायोजित करने के लिए सीमाएँ चाहूंगा। मेरा दृष्टिकोण इस तरह रहा है:

var bounds = new google.maps.LatLngBounds();

// extend bounds with each point

gmap.fitBounds(bounds); 
gmap.setZoom( Math.max(6, gmap.getZoom()) );

यह काम नहीं करता है। अंतिम पंक्ति "gmap.setZoom ()" फिटबाउंड के बाद सीधे कॉल करने पर मानचित्र के ज़ूम स्तर को नहीं बदलती है।

क्या नक्शे में इसे लागू किए बिना सीमा का ज़ूम स्तर प्राप्त करने का एक तरीका है? इसे हल करने के लिए अन्य विचार?


1
देखें stackoverflow.com/questions/4523023/use-setzoom-after-using-fitbounds-with-google-maps-api-v3
Mawg का कहना है कि मोनिका

जवाबों:


337

संपादित करें : नीचे मैट डायमंड की टिप्पणी देखें।

समझ गया! इसे इस्तेमाल करे:

map.fitBounds(bounds);
var listener = google.maps.event.addListener(map, "idle", function() { 
  if (map.getZoom() > 16) map.setZoom(16); 
  google.maps.event.removeListener(listener); 
});

अपनी आवश्यकताओं के लिए संशोधित करें।


76
महान समाधान, पूरी तरह से मुझे बहुत परेशानी से बचा लिया। बस यह जोड़ना चाहता था कि आप addListenerOnce विधि का उपयोग करके इसे और सरल बना सकते हैं ... इस तरह, आपको श्रोता को सहेजना नहीं है और इसे मैन्युअल रूप से निकालना है, क्योंकि यह विधि आपके लिए ध्यान रखेगी।
मैट डायमंड

9
इसमें नक्शा "स्किप" देखने का व्यवहार है। इसके बजाय "zoom_change" इवेंट के लिए सुनो, और fitBounds () को कॉल करने से पहले इसे सेट करें। मेरा जवाब नीचे देखें
बेंजामिन सुस्मैन

धन्यवाद! google.maps.event.addListenerOnce (मानचित्र, "निष्क्रिय", फ़ंक्शन () {} ->
सुगरसीआरएम के

श्रोता मेरे लिए ट्रिगर नहीं होता है। मैंने डॉक्यूमेंट में यह कोशिश की। पहले से और window.load। कोई विचार? मैप ऑब्जेक्ट ठीक है और एडल्टर की कोशिश की गई है: `var map = $ (" # js-main-map-कैनवस "); var श्रोता = google.maps.event.addListenerOnce (मानचित्र, "निष्क्रिय", फ़ंक्शन () {चेतावनी ('हैलो');}); `
हेनरिक एर्लडसन

हेनरिक, $ कोशिश करें ("# js-main-map-कैनवास") [0] या $ ("# js-main-map-कैनवास")। get (0);
राफेल

68

मैंने अपने एक ऐप में इसी तरह की समस्या को हल किया। समस्या के आपके वर्णन से मैं थोड़ा उलझन में था, लेकिन मुझे लगता है कि आपके पास वही लक्ष्य है जो मेरे पास था ...

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

जब कई बिंदु थे, तब समाधान का उपयोग किया गया था और केवल एक बिंदु होने पर सेटकेंटर + सेटज़ूम था।

if (pointCount > 1) {
  map.fitBounds(mapBounds);
}
else if (pointCount == 1) {
  map.setCenter(mapBounds.getCenter());
  map.setZoom(14);
}

5
आपके उत्तर ने Google मैप्स V3 के साथ मेरी समस्या को हल कर दिया है। धन्यवाद!
FR6

1
मुझे वही समस्या थी, और आपके समाधान ने काम किया! धन्यवाद!
manubkk

मैं अपने आप से उसी दृष्टिकोण की कोशिश कर रहा था, लेकिन यह काम नहीं किया क्योंकि मैं ज़ूम सेट करने से पहले सेटकेंटर () का आह्वान नहीं कर रहा था ... मैं अभी भी सोच रहा हूं कि इस कदम की आवश्यकता क्यों है, लेकिन वैसे भी अब यह काम करता है ... धन्यवाद a बहुत जिम!
डेवोनकोड

मानचित्र केंद्र ने मेरे पास मौजूद समस्या को हल किया! नाइस वन +1
पिओटर कुला

1
आपके अच्छे उत्तर के लिए धन्यवाद +1
भारत चोदवाड़िया

44

मैं उत्तर पाने के लिए इस पेज पर कई बार आया हूं, और जबकि सभी मौजूदा उत्तर सुपर सहायक थे, उन्होंने मेरी समस्या का समाधान नहीं किया।

google.maps.event.addListenerOnce(googleMap, 'zoom_changed', function() {
    var oldZoom = googleMap.getZoom();
    googleMap.setZoom(oldZoom - 1); //Or whatever
});

मूल रूप से मैंने पाया कि 'zoom_changed' ईवेंट ने मैप के UI को "स्किपिंग" से रोका था जो तब हुआ जब मैंने 'आइडल' इवेंट का इंतज़ार किया।

आशा है कि यह किसी की मदद करता है!


4
बहुत बढ़िया, मेरे पास 'स्किपिंग / ऑटो-जूमिंग' व्यवहार भी था। बस अन्य पाठकों के लिए एक नोट के रूप में: "addListenerOnce" का उपयोग करने के बेंजामिन "addListener" के बजाय ऊपर करता है, या पर क्यों आपके ब्राउज़र सभी दुर्घटनाओं समय ;-) अपने सिर को तोड़ने के लिए सुनिश्चित हो
गीर्ट जनवरी

6
यह भी ध्यान दें कि fitBounds()यदि कॉल कर रहे हैं तो श्रोता को कॉल करने से पहले जोड़ा जाना चाहिएzoom_changed
gapple

1
इसके लिए धन्यवाद, ऐसा लगता है जैसे v4 के पास एक फिटबाउंड (सीमा, minZoomLevel) होना चाहिए :)
रिचर्ड

3
बेंजामिन, मुझे लगता है कि इसका उपयोग करना बेहतर है bounds_changed, क्योंकि ज़ूम स्तर को बनाए रखने के zoom_changedमामले में ट्रिगर नहीं करना पड़ता fitBoundsहै। मेरा प्रयास jsfiddle.net/rHeMp/10 इसकी पुष्टि नहीं करता है, लेकिन किसी को अपरिभाषित व्यवहार पर भरोसा नहीं करना चाहिए।
TMS

10

मैंने इसे पहले से अधिकतम रूप से सेट करके निर्धारित किया है, फिर बाद में इसे हटा रहा हूं। उदाहरण के लिए:

map.setOptions({ maxZoom: 15 });
map.fitBounds(bounds);
map.setOptions({ maxZoom: null });

बहुत अधिक ज़ूमिंग को रोकने के लिए अब तक का सबसे अच्छा समाधान। सरल और सहज। नक्शे की कोई ड्राइंग और पुन: ड्राइंग नहीं।
user2605793

यह वास्तव में अब तक का सबसे अच्छा चलना है।
डाउनहिल्स्की

2
मैंने पाया कि अगर आप फिटबाउंड्स को कॉल करने के तुरंत बाद मैक्सजूम को रीसेट करते हैं तो यह काम नहीं करता है, क्योंकि ज़ूम असिंक्रोनस रूप से होता है (इसलिए अधिकतम ज़ूम वापस उसी समय तक शून्य हो जाता है)। "निष्क्रिय" होने तक प्रतीक्षा करने के लिए इसे रीसेट करना होगा, हालांकि मुझे लगता है कि यह ठीक हो जाएगा।
user987356

4

अगर मैं गलत नहीं हूं, तो मैं मान रहा हूं कि आप चाहते हैं कि आपके सभी बिंदु उच्चतम संभव ज़ूम स्तर के साथ मानचित्र पर दिखाई दें। मैंने मानचित्र के ज़ूम स्तर को 16 से प्रारंभ करके इसे पूरा किया (यह सुनिश्चित नहीं है कि यह V3 पर उच्चतम संभव ज़ूम स्तर है)।

var map = new google.maps.Map(document.getElementById('map_canvas'), {
  zoom: 16,
  center: marker_point,
  mapTypeId: google.maps.MapTypeId.ROADMAP
});

फिर उसके बाद मैंने सीमा सामान किया:

var bounds = new google.maps.LatLngBounds();

// You can have a loop here of all you marker points
// Begin loop
bounds.extend(marker_point);
// End loop

map.fitBounds(bounds);

परिणाम: सफलता!


3

मैं उपयोग करता हूं:

gmap.setZoom(24); //this looks a high enough zoom value
gmap.fitBounds(bounds); //now the fitBounds should make the zoom value only less

यह आपके कोड के अनुसार 24 के छोटे और आवश्यक ज़ूम स्तर का उपयोग करेगा, हालांकि यह शायद वैसे भी ज़ूम को बदलता है और इस बात की परवाह नहीं करता है कि आपने कितना ज़ूम आउट किया है।


मुझे यह कहने से नफरत है, लेकिन यह जवाब जितना अजीब लग रहा था, यह एकमात्र ऐसी चीज है जो अब तक काम करती है और मैं 3 दिनों के अंतराल पर 4-5 घंटे खोज रहा हूं। हालांकि अभी भी एक बेहतर समाधान के लिए खोज की जाएगी।
एल्वोव

3

कृपया इसे आज़माएँ:

map.fitBounds(bounds);

// CHANGE ZOOM LEVEL AFTER FITBOUNDS
zoomChangeBoundsListener = google.maps.event.addListenerOnce(map, 'bounds_changed', function(event) {
  if (this.getZoom()){
    this.setZoom(15);
  }
});
setTimeout(function(){
  google.maps.event.removeListener(zoomChangeBoundsListener)
}, 2000);

2

मेरे पास एक ही मुद्दा था और मैं निम्नलिखित कोड का उपयोग करके इसे हल करने में सक्षम था। इस श्रोता ( google.maps.addListenerOnce()) घटना को केवल एक बार निकाल दिया जाएगा, जिसके ठीक बाद map.fitBounds()निष्पादित किया जाएगा। तो, कोई जरूरत नहीं है

  1. ध्यान रखें और मैन्युअल रूप से श्रोता को हटा दें, या
  2. नक्शा होने तक प्रतीक्षा करें idle

यह शुरू में उचित ज़ूम स्तर सेट करता है और उपयोगकर्ता को प्रारंभिक ज़ूम स्तर से ज़ूम इन और आउट करने की अनुमति देता है क्योंकि ईवेंट श्रोता समाप्त हो गया है। उदाहरण के लिए, यदि केवल google.maps.addListener()कॉल किया गया था, तो उपयोगकर्ता कभी भी ज़ूम-इन पिछले बताए गए स्तर (मामले में, 4) को ज़ूम-इन नहीं कर पाएगा। जब से हमने लागू किया है google.maps.addListenerOnce(), उपयोगकर्ता किसी भी स्तर पर ज़ूम कर सकेगा / चुनेगी।

map.fitBounds(bounds);

var zoom_level_for_one_marker = 4;

google.maps.event.addListenerOnce(map, 'bounds_changed', function(event){
   if (this.getZoom() >= zoom_level_for_one_marker){  
       this.setZoom(zoom_level_for_one_marker) 
   }
});

2

एक ही समस्या थी, नक्शे पर कई मार्करों को फिट करने की आवश्यकता थी। इससे मेरा मामला हल हो गया:

  1. डिक्लेयर कर दिया
  2. कोडरॉइड द्वारा प्रदान की गई योजना का उपयोग करें (प्रत्येक मार्कर सेट के लिए bounds.extend(objLatLng))
  3. पूरा होने के बाद फिटबॉन्ड्स को पूरा करें:

    google.maps.event.addListenerOnce(map, 'idle', function() { 
        map.fitBounds( bounds );
    });

2

मुझे एक समाधान मिला है जो कॉल fitBoundsकरने से पहले चेक करता है ताकि आप ज़ूम इन न करें और अचानक ज़ूम आउट करें

var bounds = new google.maps.LatLngBounds();

// extend bounds with each point

var minLatSpan = 0.001;
if (bounds.toSpan().lat() > minLatSpan) {
    gmap.fitBounds(bounds); 
} else {
    gmap.setCenter(bounds.getCenter());
    gmap.setZoom(16);
}

जहाँ आप चाहते हैं, उसे पाने के लिए आपको minLatSpan वैरिएबल के साथ चारों ओर खेलना होगा। यह ज़ूम-स्तर और मैप कैनवास के आयामों के आधार पर अलग-अलग होगा।

आप अक्षांश के बजाय देशांतर का उपयोग भी कर सकते हैं


मेरे लिए काम करता है, लेकिन मैं minLatSpan का उपयोग नहीं कर रहा हूं - मुझे केवल ज़ूम करने की आवश्यकता है जब 1 मार्कर मानचित्र में हो। इसलिए मैं केवल जाँच कर रहा हूं कि क्या अधिक हैं तो 1 मार्कर।
मिसेर

2

मैंने कई गलत या बहुत जटिल समाधान देखे, इसलिए एक काम, सुरुचिपूर्ण समाधान पोस्ट करने का फैसला किया ।

कारण setZoom()यह काम नहीं करता है जैसा कि आप उम्मीद करते हैं कि fitBounds()यह अतुल्यकालिक है, इसलिए यह कोई गारंटी नहीं देता है कि यह तुरंत ज़ूम को अपडेट करेगा, लेकिन आपका कॉल setZoom()उस पर निर्भर करता है।

आप जो विचार कर सकते हैं उसे minZoomकॉल करने से पहले मैप का विकल्प सेट करना fitBounds()और उसके पूरा होने के बाद उसे साफ़ करना (ताकि उपयोगकर्ता अभी भी मैन्युअल रूप से ज़ूम इन कर सकें अगर वे चाहते हैं):

var bounds = new google.maps.LatLngBounds();
// ... (extend bounds with all points you want to fit)

// Ensure the map does not get too zoomed out when fitting the bounds.
gmap.setOptions({minZoom: 6});
// Clear the minZoom only after the map fits the bounds (note that
// fitBounds() is asynchronous). The 'idle' event fires when the map
// becomes idle after panning or zooming.
google.maps.event.addListenerOnce(gmap, 'idle', function() {
  gmap.setOptions({minZoom: null});
});

gmap.fitBounds(bounds);

इसके अलावा, यदि आप अधिकतम ज़ूम को भी सीमित करना चाहते हैं, तो आप maxZoomसंपत्ति के साथ एक ही चाल को लागू कर सकते हैं।

MapOptions डॉक्स देखें ।


1

मैं इसका उपयोग यह सुनिश्चित करने के लिए करता हूं कि ज़ूम स्तर एक निर्धारित स्तर से अधिक न हो ताकि मुझे पता चले कि उपग्रह चित्र उपलब्ध होंगे।

zoom_changedघटना में एक श्रोता जोड़ें । यह UI पर ज़ूम नियंत्रण को नियंत्रित करने का अतिरिक्त लाभ है।

केवल निष्पादित करें setZoomयदि आपको आवश्यकता है, तो एक ifबयान के लिए Math.maxया उसके लिए बेहतर हैMath.min

   google.maps.event.addListener(map, 'zoom_changed', function() { 
      if ( map.getZoom() > 19 ) { 
        map.setZoom(19); 
      } 
    });
    bounds = new google.maps.LatLngBounds( ... your bounds ... )
    map.fitBounds(bounds);

बहुत दूर तक ज़ूम करने से रोकने के लिए:

   google.maps.event.addListener(map, 'zoom_changed', function() { 
      if ( map.getZoom() < 6 ) { 
        map.setZoom(6); 
      } 
    });
    bounds = new google.maps.LatLngBounds( ... your bounds ... )
    map.fitBounds(bounds);

1

इस फ़ंक्शन में, आपको ज्यामितीय प्रकार को संग्रहीत करने के लिए मेटाडेटा को गतिशील रूप से जोड़ना होगा क्योंकि फ़ंक्शन किसी भी ज्यामिति को स्वीकार करता है।

"fitGeometries" एक JSON फ़ंक्शन है जो मानचित्र ऑब्जेक्ट को बढ़ाता है।

"ज्यामितीय" एक सामान्य जावास्क्रिप्ट सरणी है जो MVCArray () नहीं है।

geometry.metadata = { type: "point" };
var geometries = [geometry];

fitGeometries: function (geometries) {
    // go and determine the latLngBounds...
    var bounds = new google.maps.LatLngBounds();
    for (var i = 0; i < geometries.length; i++) {
        var geometry = geometries[i];
        switch (geometry.metadata.type)
        {
            case "point":
                var point = geometry.getPosition();
                bounds.extend(point);
                break;
            case "polyline":
            case "polygon": // Will only get first path
                var path = geometry.getPath();
                for (var j = 0; j < path.getLength(); j++) {
                    var point = path.getAt(j);
                    bounds.extend(point);
                }
                break;
        }
    }
    this.getMap().fitBounds(bounds);
},

वैकल्पिक रूप से, मैंने यह जाने बिना सभी काम किए कि लाटलजबाउंड्स ऑब्जेक्ट पर एक विस्तार () विधि है। यह बहुत आसान होगा।
CrazyEnigma

1

एपीआई v3 के साथ मेरे लिए यह काम है लेकिन तय ज़ूम के साथ:

var bounds = new google.maps.LatLngBounds();
// extend bounds with each point

gmap.setCenter(bounds.getCenter()); 
gmap.setZoom( 6 );

1

मेरी तरह, यदि आप श्रोताओं के साथ खेलने के लिए तैयार नहीं हैं, तो यह एक सरल उपाय है जो मैं लेकर आया हूं: मानचित्र पर एक विधि जोड़ें जो आपकी आवश्यकताओं के अनुसार कड़ाई से काम करता है जैसे:

    map.fitLmtdBounds = function(bounds, min, max){
        if(bounds.isEmpty()) return;
        if(typeof min == "undefined") min = 5;
        if(typeof max == "undefined") max = 15;

        var tMin = this.minZoom, tMax = this.maxZoom;
        this.setOptions({minZoom:min, maxZoom:max});
        this.fitBounds(bounds);
        this.setOptions({minZoom:tMin, maxZoom:tMax});
    }

तब आप निर्धारित ज़ूम रेंज के तहत सीमा निर्धारित करने के map.fitLmtdBounds(bounds)बजाय कॉल कर सकते हैं map.fitBounds(bounds)... या ज़ूम रेंज map.fitLmtdBounds(bounds,3,5)को ओवरराइड कर सकते हैं।


0

कृपया यह प्रयास करें।

// Find out what the map's zoom level is
zoom = map.getZoom();
if (zoom == 1) {
  // If the zoom level is that low, means it's looking around the
world.
  // Swap the sw and ne coords
  viewportBounds = new
google.maps.LatLngBounds(results[0].geometry.location, initialLatLng);
  map.fitBounds(viewportBounds);
}

अगर यह आपके लिए मददगार होगा।

शुभकामनाएं


0

सीमाओं की गणना के बाद आप ऊपरी बाएं और नीचे दाएं कोने के बीच की दूरी की जांच कर सकते हैं; तब आप दूरी का परीक्षण करके ज़ूम स्तर को समझ सकते हैं (यदि दूरी बहुत दूर है ज़ूम स्तर कम होगा) तो आप सेटबाउंड विधि या सेटज़ूम का उपयोग करके घरघराहट का चयन कर सकते हैं।


0

मुझे यह सुझाव देना पसंद नहीं है, लेकिन अगर आपको कोशिश करनी चाहिए - पहले कॉल करें

gmap.fitBounds(bounds);

फिर एक नया थ्रेड / AsyncTask बनाएं, क्या यह 20-50ms या तो सोता है और फिर कॉल करें

gmap.setZoom( Math.max(6, gmap.getZoom()) );

UI थ्रेड से (एक हैंडलर या onPostExecuteAsyncTask के लिए विधि का उपयोग करें )।

मुझे नहीं पता कि यह काम करता है, सिर्फ एक सुझाव। इसके अलावा आपको किसी भी तरह से अपने बिंदुओं से जूम स्तर की गणना करनी होगी, जांचें कि क्या यह बहुत कम है, इसे ठीक करें और फिर कॉल करेंgmap.setZoom(correctedZoom)


0

यदि 'bounds_changed' सही ढंग से फायरिंग नहीं कर रहा है (कभी-कभी Google निर्देशांक को पूरी तरह से स्वीकार नहीं करता है), तो इसके बजाय 'center_changed' का उपयोग करने पर विचार करें।

'Center_changed' ईवेंट हर बार फ़िटबाउंड्स () कहा जाता है, हालांकि यह तुरंत चलता है और जरूरी नहीं कि नक्शा चले जाने के बाद।

सामान्य मामलों में, 'निष्क्रिय' अभी भी सबसे अच्छा ईवेंट श्रोता है, लेकिन इससे कुछ लोगों को अपने फ़ायबाउंड्स () कॉल के साथ अजीब मुद्दों में भाग लेने में मदद मिल सकती है।

Google मानचित्र फ़िटबाउंड कॉलबैक देखें


0

एक और समाधान के साथ झंकार करने के लिए - मैंने पाया कि "bounds_changed घटना के लिए सुनो और फिर नया ज़ूम सेट करें" दृष्टिकोण मेरे लिए मज़बूती से काम नहीं करता था। मुझे लगता है कि fitBoundsनक्शे को पूरी तरह से शुरू करने से पहले मैं कभी-कभी फोन कर रहा था , और प्रारंभिककरण एक सीमा-परिवर्तन की घटना पैदा कर रहा था जो कि fitBoundsसीमा और ज़ूम स्तर को बदलने से पहले श्रोता का उपयोग करेगा । मैंने इस कोड के साथ काम किया, जो अब तक काम करता है:

// If there's only one marker, or if the markers are all super close together,
// `fitBounds` can zoom in too far. We want to limit the maximum zoom it can
// use.
//
// `fitBounds` is asynchronous, so we need to wait until the bounds have
// changed before we know what the new zoom is, using an event handler.
//
// Sometimes this handler gets triggered by a different event, before
// `fitBounds` takes effect; that particularly seems to happen if the map
// hasn't been fully initialized yet. So we don't immediately remove the
// listener; instead, we wait until the 'idle' event, and remove it then.
//
// But 'idle' might happen before 'bounds_changed', so we can't set up the
// removal handler immediately. Set it up in the first event handler.

var removeListener = null;
var listener = google.maps.event.addListener(map, 'bounds_changed', () => {
  console.log(map.getZoom());
  if (map.getZoom() > 15) {
    map.setZoom(15);
  }

  if (!removeListener) {
    removeListener = google.maps.event.addListenerOnce(map, 'idle', () => {
      console.log('remove');
      google.maps.event.removeListener(listener);
    });
  }
});

0

मेरे लिए सबसे आसान समाधान यह था:

map.fitBounds(bounds);

function set_zoom() {
    if(map.getZoom()) {map.setZoom(map.getZoom() - 1);}
    else {setTimeout(set_zoom, 5);}
}
setTimeout(set_zoom, 5);

-1
google.maps.event.addListener(marker, 'dblclick', function () {
    var oldZoom = map.getZoom(); 
    map.setCenter(this.getPosition());
    map.setZoom(parseInt(oldZoom) + 1);
});

-3

मैंने किया है:

map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));

और यह V3 API पर काम करता है।


map.setCenter केवल एक विशेषता को स्वीकार करता है, latlng, और मैप का कोई कार्य नहीं है जैसे getBoundsZoomLevel
विक्टर

मुझे लगा कि इस पोस्ट को देखने के बाद getBoundsZoomLevel की तरह एक फ़ंक्शन है, और मुझे एहसास होने के बाद मैं निराश हूं कि वहाँ नहीं है।
पालकी

मुझे लगता है कि getBoundsZoomLevel () Google मैप्स V2 API में उपलब्ध था और V3 API में नहीं
कुश
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.