ตั้งกึ่งกลาง / ซูมแผนที่เพื่อให้ครอบคลุมเครื่องหมายที่มองเห็นได้ทั้งหมด


352

ฉันกำลังตั้งเครื่องหมายหลายตัวบนแผนที่ของฉันและฉันสามารถตั้งค่าระดับการซูมและศูนย์กลางแบบคงที่ แต่สิ่งที่ฉันต้องการคือเพื่อครอบคลุมเครื่องหมายและการซูมทั้งหมดให้มากที่สุดเท่าที่จะเป็นไปได้

วิธีการที่ใช้ได้มีดังต่อไปนี้

setZoom(zoom:number)

และ

setCenter(latlng:LatLng)

ไม่setCenterรองรับหลายตำแหน่งหรืออินพุตอาร์เรย์ของตำแหน่งที่ตั้งและsetZoomไม่มีฟังก์ชันการทำงานประเภทนี้

ป้อนคำอธิบายรูปภาพที่นี่



คุณจำเป็นต้องเพิ่มlatlngไปยังboundsวัตถุทุกครั้งที่คุณเพิ่มเครื่องหมายและการตั้งค่าแผนที่ของคุณเพื่อให้พอดีกับขอบเขตสุดท้าย ดูคำตอบได้ที่นี่: stackoverflow.com/questions/1556921/…
Suvi Vignarajah

คำตอบ:


678

คุณต้องใช้fitBounds()วิธีการ

var markers = [];//some array
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < markers.length; i++) {
 bounds.extend(markers[i]);
}

map.fitBounds(bounds);

เอกสารจากdevelopers.google.com/maps/documentation/javascript :

fitBounds(bounds[, padding])

พารามิเตอร์:

`bounds`:  [`LatLngBounds`][1]|[`LatLngBoundsLiteral`][1]
`padding` (optional):  number|[`Padding`][1]

ค่าส่งคืน: ไม่มี

ตั้งค่าวิวพอร์ตให้มีขอบเขตที่กำหนด
หมายเหตุ : เมื่อแผนที่มีการตั้งค่าdisplay: noneที่fitBoundsฟังก์ชั่นอ่านขนาดของแผนที่เป็น0x0และดังนั้นจึงไม่ได้ทำอะไร หากต้องการเปลี่ยนวิวพอร์ตในขณะที่ซ่อนแผนที่ให้ตั้งค่าแผนที่เป็นvisibility: hiddenดังนั้นจึงมั่นใจได้ว่า Div แผนที่มีขนาดจริง


3
จากการที่การไม่getPositionวิธีการมาจากไหน?
Pratheep

6
@Pratheep - เป็นส่วนหนึ่งของคลาส google.maps.Marker developers.google.com/maps/documentation/javascript/…
อดัม

ทำงานเหมือนจับใจ! ขอบคุณ
Joseph N.

9
เช่นเดียวกับมือใหม่ที่ออกไปข้างนอกด้วยคำถามเดียวกันกับ Pratheep ... คุณรู้เรื่องนี้ถ้าคุณเคยมีประสบการณ์กับ Maps API แต่คุณสามารถส่งต่อLatLngLiteralแทนการมีอินสแตนซ์ของตัวทำเครื่องหมายได้ เช่นbounds.extend({lat: 123, lng: 456}).
Kyle Baker

1
เคล็ดลับพิเศษสำหรับทุกคนที่สนใจ คุณสามารถกำหนดช่องว่างภายในโดยใช้fitBounds(bounds, int)ซึ่งจะช่วยให้คุณมีช่องว่างเล็ก ๆ ระหว่างเครื่องหมายและขอบแผนที่ (หรือพื้นที่น้อยลงถ้าคุณต้องการ) ดูเอกสารประกอบ
MickelsonMichael

178

หากต้องการขยายคำตอบที่ได้รับด้วยลูกเล่นที่มีประโยชน์:

var markers = //some array;
var bounds = new google.maps.LatLngBounds();
for(i=0;i<markers.length;i++) {
   bounds.extend(markers[i].getPosition());
}

//center the map to a specific spot (city)
map.setCenter(center); 

//center the map to the geometric center of all markers
map.setCenter(bounds.getCenter());

map.fitBounds(bounds);

//remove one zoom level to ensure no marker is on the edge.
map.setZoom(map.getZoom()-1); 

// set a minimum zoom 
// if you got only 1 marker or all markers are on the same address map will be zoomed too much.
if(map.getZoom()> 15){
  map.setZoom(15);
}

//Alternatively this code can be used to set the zoom for just 1 marker and to skip redrawing.
//Note that this will not cover the case if you have 2 markers on the same address.
if(count(markers) == 1){
    map.setMaxZoom(15);
    map.fitBounds(bounds);
    map.setMaxZoom(Null)
}

ปรับปรุง:
การวิจัยเพิ่มเติมในหัวข้อแสดงให้เห็นว่า fitBounds () เป็น asynchronic และที่ดีที่สุดคือการทำให้การจัดการซูมด้วยฟังที่กำหนดไว้ก่อนที่จะเรียก Fit Bounds
ขอบคุณ @Tim, @ xr280xr ตัวอย่างเพิ่มเติมในหัวข้อ: SO: setzoom-after-fitbounds

google.maps.event.addListenerOnce(map, 'bounds_changed', function(event) {
  this.setZoom(map.getZoom()-1);

  if (this.getZoom() > 15) {
    this.setZoom(15);
  }
});
map.fitBounds(bounds);

4
เพิ่มที่ดี ขอบคุณ!
paneer_tikka

1
ฉันได้รับการตอบกลับโดย. getZoom () คำตอบนี้ช่วยให้ผมแก้ได้โดยใช้addListenerOnceในzoom_changedการตั้งค่าการซูมหลังจากที่คุ้มค่าที่ได้รับการเริ่มต้น
xr280xr

1
ขอบคุณ @ d.raev แต่การตั้งค่าการซูมสูงสุดเมื่อขอบเขตที่ตั้งไว้แล้วไม่ทำงาน สิ่งที่คุณต้องทำคือตั้งค่าตัวเลือก "maxZoom" เมื่อเริ่มต้นแผนที่ของคุณ developers.google.com/maps/documentation/javascript/…
ทิม

1
ในส่วนเกี่ยวกับการปรับซูม ( UPDATE ) คุณกำลังผสม vars และ scopes สองสามชุด คุณสามารถใช้yourMap, และmap thisอาจเป็นความคิดที่ดีที่จะทำให้มันสอดคล้องกันมากขึ้น
Gustavo Straube

11

ขนาดของอาเรย์ต้องมากกว่าศูนย์ Οมิฉะนั้นคุณจะได้ผลลัพธ์ที่ไม่คาดคิด

function zoomeExtends(){
  var bounds = new google.maps.LatLngBounds();
  if (markers.length>0) { 
      for (var i = 0; i < markers.length; i++) {
         bounds.extend(markers[i].getPosition());
        }    
        myMap.fitBounds(bounds);
    }
}

8

มีMarkerClustererยูทิลิตี้ฝั่งไคลเอ็นต์นี้สำหรับ Google Map ตามที่ระบุไว้ที่นี่ในบทความนักพัฒนา Google Mapนี่คือข้อมูลคร่าวๆของการใช้งาน:

มีหลายวิธีในการทำสิ่งที่คุณขอ:

  • การจัดกลุ่มตามกริด
  • การจัดกลุ่มตามระยะทาง
  • การจัดการเครื่องหมายวิวพอร์ต
  • ตารางฟิวชั่น
  • Marker Clusterer
  • MarkerManager

คุณสามารถอ่านเกี่ยวกับพวกเขาได้ที่ลิงค์ที่ให้ไว้ข้างต้น

Marker Clustererใช้การจัดกลุ่มตามระบบกริดเพื่อจัดกลุ่มเครื่องหมายทั้งหมดที่ต้องการกริด การจัดกลุ่มตามตารางทำงานโดยการแบ่งแผนที่ออกเป็นสี่เหลี่ยมจัตุรัสขนาดที่แน่นอน (ขนาดจะเปลี่ยนไปในการซูมแต่ละครั้ง) จากนั้นจัดกลุ่มเครื่องหมายในแต่ละตารางสี่เหลี่ยม

ก่อนจัดกลุ่ม ก่อนจัดกลุ่ม

หลังจากจัดกลุ่ม หลังจากจัดกลุ่ม

ฉันหวังว่านี่คือสิ่งที่คุณกำลังมองหาและนี่จะช่วยแก้ปัญหาของคุณ :)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.