2010-07-15 23 views
6

Tôi đã tạo một bộ định vị cửa hàng khá phức tạp. Người dùng nhập mã zip của họ và bảng trả về kết quả với các điểm đánh dấu tương ứng trên bản đồ. Họ có thể trang qua các kết quả và các điểm đánh dấu di chuyển xa hơn và xa hơn nữa và chức năng fitbounds() hoạt động tốt để thu nhỏ đến mức thu phóng thích hợp để phù hợp với các điểm đánh dấu. Vấn đề là nếu bạn quay trở lại các địa điểm gần hơn, thì fitbounds() sẽ không phóng to. Ngay cả khi bạn nhập tìm kiếm mới, nó không phóng to xung quanh các điểm đánh dấu mới đó - nó tập trung vào chúng nhưng vẫn ở bất kỳ mức thu phóng nào lúc trước. Tôi hy vọng điều này có ý nghĩa. Nếu bất cứ ai biết những gì tôi cần phải thêm để làm cho nó phóng to lại vào kết quả gần hơn xin vui lòng giúp đỡ. Đây là các chức năng của google mà tôi gọi vào cuối chức năng đẩy điểm đánh dấu của tôi:Fitbounds V3 API Google Maps() thu nhỏ nhưng không bao giờ ở

map.setCenter(bounds.getCenter()); 
    map.panToBounds(bounds); 
    map.fitBounds(bounds); 

Cảm ơn!

Trả lời

0
map.setZoom(10); 

Tôi tin phạm vi chấp nhận được là 1-20. Chỉ có số nguyên, số thập phân đã phá vỡ bản đồ theo kinh nghiệm của tôi.

4

Đúng vậy, fitBounds chỉ đảm bảo rằng giới hạn được cung cấp hiển thị. Nó không phóng to đến mức thích hợp.

Trước tiên, bạn có thể gọi setZoom(20), sau đó fitBounds.

3

Hmm, thú vị .. Tôi sử dụng PHP để lặp qua tất cả các tọa độ điểm đánh dấu (đến) và tính giá trị của southWest và northEast; các coords xuất xứ là nửa chừng giữa hai. Nếu tất cả các tọa độ điểm đánh dấu rất gần nhau, thì hệ số thu phóng được đặt bởi fitBounds cao hơn nhiều (phóng to) so với 15 được sử dụng khi tạo bản đồ. Đó là lý do tại sao tôi đã thêm hàng cuối cùng ..

var map; 

function mapInit() { 
    var origin = new google.maps.LatLng(59.33344615, 18.0678188); 
    var options = { 
    zoom: 15, 
    center: origin, 
    mapTypeControlOptions: { 
     mapTypeIds: [google.maps.MapTypeId.ROADMAP, google.maps.MapTypeId.HYBRID] 
    }, 
    mapTypeId: google.maps.MapTypeId.ROADMAP 
    }; 

    map = new google.maps.Map(document.getElementById("googlemap"), options); 

    var southWest = new google.maps.LatLng(59.3308415, 18.0643054); 
    var northEast = new google.maps.LatLng(59.3360508, 18.0713322); 
    var bounds = new google.maps.LatLngBounds(southWest, northEast); 
    map.fitBounds(bounds); 

    google.maps.event.addListenerOnce(map, "idle", function() { 
    if (map.getZoom() > 16) map.setZoom(16); 
    }); 

Vì vậy, Google đã lập trình lại chức năng kể từ khi bạn đăng câu hỏi hoặc .. Tôi cần thêm thông tin về mã của bạn.

0
fitBounds: function(bounds, mapId) 
    { 
     //bounds: bounds, id: map id 
     if (bounds==null) return false; 
     maps[mapId].fitBounds(bounds); 
    }, 

Điều này sẽ giúp ích, tôi sử dụng phương pháp này và hoạt động tốt, trên bản đồ v2 một chút khác biệt.

7

Không có gì ưa thích cần thiết ở đây. Đầu tiên phù hợp với giới hạn sau đó chảo vào nó. Điều này sẽ cung cấp cho bạn zoom thích hợp và chứa toàn bộ giới hạn.

map.fitBounds(bounds); 
map.panToBounds(bounds); 
+1

Điều này dường như hoạt động. Tôi tự hỏi những gì 'panToBounds' là nghĩa vụ phải làm mà không có' fitBounds'. – dbkaplun

9

Vấn đề là thế này: chúng tôi đặt

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

để chúng ta sau này có thể phù hợp với các dấu hiệu của chúng tôi đến một khu vực bị chặn trên bản đồ. GMaps sẽ luôn thu nhỏ không đồng bộ thành fitBounds() tương ứng, nhưng sẽ không phóng to để đạt được như cũ (như đã lưu ý trước đây bởi @broady). Đây không phải là lý tưởng cho nhiều ứng dụng khi bạn đã đi và hiển thị một loạt các điểm đánh dấu trên bản đồ khiến bản đồ thu nhỏ (có thể là < 10), nó sẽ không phóng to lại mà không cần người dùng tự làm như vậy.

GMaps sẽ tiếp tục sử dụng giới hạn của (thiếu từ tốt hơn) thu nhỏ nhất trạng thái thu thập điểm đánh dấu (xin lỗi). Đặt thành 'null' trước mỗi cuộc gọi cho các điểm đánh dấu mới cung cấp cho bạn bản đồ mới để làm việc.

Để tự động phóng to, chỉ cần đặt LatLngBounds(); để 'null' như vậy (xem ví dụ giả bên dưới để xem vị trí của nó):

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

Pseudo dụ:

// map stuff/initiation 
... 

var bounds = new google.maps.LatLngBounds(); 
var gmarkers = []; 

function CreateMarker (obj) { 
    myLatLng = new google.maps.LatLng(obj['latitude'], obj['longitude']); 
    marker = new google.maps.Marker({ 
     position: myLatLng, 
     map: map 
    }); 
    google.maps.event.addListener(marker, 'click', (function(marker, i) { 
     return function() { 
      infowindow.setContent(obj['job']); 
      infowindow.open(map, marker); 
     } 
    })(marker, i)); 
    bounds.extend(myLatLng); 
    gmarkers.push(marker); 
} 

.... 

// here's an AJAX method I use to grab marker coords from a database: 

$.ajax({ 
    beforeSend: function() { 
     clear_markers(gmarkers); // see below for clear_markers() function declaration 
    }, 
    cache: false, 
    data: params, 
    dataType: 'json', 
    timeout: 0, 
    type: 'POST', 
    url: '/map/get_markers.php?_=<?php echo md5(session_id() . time() . mt_rand(1,9999)); ?>', 
    success: function(data) { 
     if (data) { 
      if (data['count'] > 0) { 
       var obj; 
       var results = data['results']; 

       // Plot the markers 
       for (r in results) { 
        if (r < (data['count'])) { 
         CreateMarker(results[r]); 
        } 
       } 
      } 
     } 
    }, 
    complete: function() { 
     map.fitBounds(bounds); 
    } 
}); 

// clear_markers() 
function clear_markers(a) { 
    if (a) { 
     for (i in a) { 
      a[i].setMap(null); 
     } 
     a.length = 0; 
    } 
    bounds = new google.maps.LatLngBounds(null); // this is where the magic happens; setting LatLngBounds to null resets the current bounds and allows the new call for zoom in/out to be made directly against the latest markers to be plotted on the map 
} 
+0

Cảm ơn John Smith! Đề xuất của bạn là cách duy nhất tôi có thể khiến tôi phóng to lại sau khi xóa một điểm đánh dấu. Tôi đánh giá cao các chi tiết trong bài đăng của bạn. – gorelog

+0

Cảm ơn người đàn ông ... bạn đã lưu ngày của tôi :-) – Legionar

1

Nó chỉ ra rằng khi bạn gọi map.getBounds() nó trả về khung nhìn với một biên độ nhỏ xung quanh các cạnh. Vì giới hạn mới này lớn hơn giới hạn hiện tại nên bản đồ sẽ luôn thu nhỏ. Tôi đã có thể giải quyết nó bằng cách tránh sử dụng các giới hạn của bản đồ hiện tại hoàn toàn và duy trì một biến LatLngBounds riêng biệt. Mỗi lần tôi thêm một điểm tôi gọi:

markersBounds.extend(newMarkersLatLng); 
map.fitBounds(markersBounds); 
map.panToBounds(markersBounds); 

Để xóa các điểm (Tôi đã luôn luôn bổ sung chúng), bạn có thể làm một LatLngBounds mới đối tượng với điểm đầu tiên, sau đó mở rộng mỗi điểm còn lại để có được giới hạn mới của bạn:

var markersBounds = new google.maps.LatLngBounds(markers[0].getPosition(), 
               markers[0].getPosition()); 
for(var i=1; i<markers.length; i++){ 
    markersBounds.extend(markers[i].getPosition()); 
} 

map.fitBounds(markersBounds); 
map.panToBounds(markersBounds); 
1

Tôi cũng gặp sự cố với cách phóng to bản đồ khi gọi điện thoại fitBounds lần thứ hai trên cùng bản đồ với điểm đánh dấu mới. Đây là cách giải thích hiệu quả đối với tôi:

// This is a stationary point tho dynamic will work too 

var myLat = someLat, 
    myLng = someLong; 

var map = false, 
    markersArray = []; 

function makeOrderMap(lat, lng) { // pass in dynamic point when updating map 

    var mapOptions = { 
     center: new google.maps.LatLng(myLat, myLng), 
     zoom: 16, 
     mapTypeId: google.maps.MapTypeId.ROADMAP 
    }; 
    deleteOverlays(); // remove any existing markers.. 
    if(!map) { 
    map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions); 
    } 

    // Find the mid-point to center the map 

    midLat = (parseFloat(lat) + parseFloat(myLat))/2; 
    midLng = (parseFloat(lng) + parseFloat(myLng))/2; 
    map.setCenter(new google.maps.LatLng(midLat, midLng)); 
    var newSpot = new google.maps.LatLng(lat, lng); 

    placeMarker(mapOptions.center);  
    placeMarker(newSpot); 

    // determine the distance between points for deciding the zoom level 

    var dist = distHaversine(mapOptions.center, newSpot); 

    var zoom = 10; 
    if(dist < 1.25) { 
    zoom = 15; 
    } else if(dist < 2.5) { 
    zoom = 14; 
    } else if(dist < 5) { 
    zoom = 13; 
    } else if(dist < 10) { 
    zoom = 12; 
    } else if(dist < 20) { 
    zoom = 11; 
    } 
    map.setZoom(zoom); 
} 


rad = function(x) {return x*Math.PI/180;} 

distHaversine = function(p1, p2) { 
    var R = 6371; // earth's mean radius in km 
    var dLat = rad(p2.lat() - p1.lat()); 
    var dLong = rad(p2.lng() - p1.lng()); 

    var a = Math.sin(dLat/2) * Math.sin(dLat/2) + 
      Math.cos(rad(p1.lat())) * Math.cos(rad(p2.lat())) * Math.sin(dLong/2) * Math.sin(dLong/2); 
    var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
    var d = R * c; 

    return d.toFixed(3); 
} 

function deleteOverlays() { 
    if (markersArray) { 
     for (i in markersArray) { 
      markersArray[i].setMap(null); 
     } 
    markersArray = [];  
    markersArray.length = 0; 
    }  
} 

function placeMarker(location, alt_icon) { 

    var marker = new google.maps.Marker({ 
     position: location, 
     map: map 
     }); 

    // add marker in markers array 
    markersArray.push(marker); 
} 
+0

Cảm ơn, đã làm việc từ bạn thực hiện như một dịch vụ góc: https://gist.github.com/zmijevik/047c40f4fc0bea27fd7c –

0

Tôi gặp phải vấn đề chung này hôm nay, tôi nghĩ tôi sẽ chia sẻ một giải pháp. Tôi nhận ra điều này hơi khác với vấn đề 'định vị cửa hàng' của bạn, nhưng nó áp dụng theo nhiều cách. Trong trường hợp của tôi, tôi có một bộ sưu tập các điểm đánh dấu trên bản đồ và đang thêm một điểm đánh dấu, và muốn đảm bảo tất cả các điểm đánh dấu hiện đang được xem. Mã này kiểm tra từng điểm đánh dấu hiện có để xem điểm đánh dấu của nó trong chế độ xem và trên đường đi, xây dựng một hộp giới hạn mới có chứa tất cả, nếu được yêu cầu. Cuối cùng, nếu bất kỳ đã được tìm thấy không được xem, xem được thiết lập lại để tất cả chúng được.

(này sử dụng mô-đun mảng Dojo, đơn giản là một wrapper tiện xung quanh lặp mảng cơ bản)

var origBounds = map.getBounds(), 
    newBounds = new google.maps.LatLngBounds(null), 
    anyFailed = false; 
array.forEach(markers, function (m) { 
    newBounds.extend(m.position); 
    if (!origBounds.contains(m.position)) { 
     anyFailed = true; 
    } 
}); 
if (anyFailed) { 
    map.setCenter(newBounds.getCenter()); 
    map.fitBounds(newBounds); 
} 

Người ta có thể dễ dàng sửa đổi này chỉ đảm bảo điểm đánh dấu mới là theo quan điểm, bởi không lặp và chỉ cần làm một chứa() kiểm tra điểm đánh dấu mới.

Các vấn đề liên quan