Ayrıca koordinatları, eğri bozulmasını sarma dikkate almak gerekir ve harita boyutlandırır veya In/out yakınlaştırır eğer bağlı boyutlara centerizing olabilir. Bu özellikle, haritanız haritanın büyük bir yüzdesini (örneğin bir kıta gibi) alıyorsa gereklidir.
CheckBounds() ile ilgili sorunlardan biri, enlem değerlerinin sınırlarını sınırlayan doğrusal olmayan distorsiyonu olan kuzey/güney kutuplarına yakın olan enlem değerlerini hesaba katmamasıdır (I). Her durumda çalışmayan yaklaşık sihirli sayı çarpanları kullanın). Doğru olarak, dünya koordinatlarındaki gerçek hedef merkez noktasını hedef gerçek enlem konumuna getirmekten ziyade, sınırların dünya koordinatları açısından ne kadar uzak olduğunu görmek için sınırları 2d dünya koordinatlarına dönüştürmelisiniz.Boylam değerleri için, bu bir çok sorun gibi görünmüyor ve doğrusal kırpma yaklaşımı yeterince doğru görünüyor, asıl konu aşağıdaki kodda (bir şekilde) hesaplanan boylam koordinatlarının sarılmasıdır. checkBounds() için
// Persitant variables
var allowedBounds; // assign something here
var lastValidCenter; // initialize this using map.getCenter()
function checkBounds() { // when bounds changes due to resizing or zooming in/out
var currentBounds = map.getBounds();
if (currentBounds == null) return;
var allowed_ne_lng = allowedBounds.getNorthEast().lng();
var allowed_ne_lat = allowedBounds.getNorthEast().lat();
var allowed_sw_lng = allowedBounds.getSouthWest().lng();
var allowed_sw_lat = allowedBounds.getSouthWest().lat();
var wrap;
var cc = map.getCenter();
var centerH = false;
var centerV = false;
// Check horizontal wraps and offsets
if (currentBounds.toSpan().lng() > allowedBounds.toSpan().lng()) {
centerH = true;
}
else { // test positive and negative wrap respectively
wrap = currentBounds.getNorthEast().lng() < cc.lng();
var current_ne_lng = !wrap ? currentBounds.getNorthEast().lng() : allowed_ne_lng +(currentBounds.getNorthEast().lng() + 180) + (180 - allowed_ne_lng);
wrap = currentBounds.getSouthWest().lng() > cc.lng();
var current_sw_lng = !wrap ? currentBounds.getSouthWest().lng() : allowed_sw_lng - (180-currentBounds.getSouthWest().lng()) - (allowed_sw_lng+180);
}
// Check vertical wraps and offsets
if (currentBounds.toSpan().lat() > allowedBounds.toSpan().lat()) {
centerV = true;
}
else { // test positive and negative wrap respectively
wrap = currentBounds.getNorthEast().lat() < cc.lat(); if (wrap) { alert("WRAp detected top") } // else alert("no wrap:"+currentBounds); wrap = false;
var current_ne_lat = !wrap ? currentBounds.getNorthEast().lat() : allowed_ne_lat + (currentBounds.getNorthEast().lat() +90) + (90 - allowed_ne_lat);
wrap = currentBounds.getSouthWest().lat() > cc.lat(); if (wrap) { alert("WRAp detected btm") } //alert("no wrap:"+currentBounds);
var current_sw_lat = !wrap ? currentBounds.getSouthWest().lat() : allowed_sw_lat - (90-currentBounds.getSouthWest().lat()) - (allowed_sw_lat+90);
}
// Finalise positions
var centerX = cc.lng();
var centerY = cc.lat();
if (!centerH) {
if (current_ne_lng > allowed_ne_lng) centerX -= current_ne_lng-allowed_ne_lng;
if (current_sw_lng < allowed_sw_lng) centerX += allowed_sw_lng-current_sw_lng;
}
else {
centerX = allowedBounds.getCenter().lng();
}
if (!centerV) {
if (current_ne_lat > allowed_ne_lat) {
centerY -= (current_ne_lat-allowed_ne_lat) * 3; // approximation magic numbeer. Adjust as u see fit, or use a more accruate pixel measurement.
}
if (current_sw_lat < allowed_sw_lat) {
centerY += (allowed_sw_lat-current_sw_lat)*2.8; // approximation magic number
}
}
else {
centerY = allowedBounds.getCenter().lat();
}
map.setCenter(lastValidCenter = new google.maps.LatLng(centerY,centerX));
}
function limitBound(bound) // Occurs during dragging, pass allowedBounds to this function in most cases. Requires persistant 'lastValidCenter=map.getCenter()' var reference.
{
var mapBounds = map.getBounds();
if ( mapBounds.getNorthEast().lng() >= mapBounds.getSouthWest().lng() && mapBounds.getNorthEast().lat() >= mapBounds.getSouthWest().lat() // ensure no left/right, top/bottom wrapping
&& bound.getNorthEast().lat() > mapBounds.getNorthEast().lat() // top
&& bound.getNorthEast().lng() > mapBounds.getNorthEast().lng() // right
&& bound.getSouthWest().lat() < mapBounds.getSouthWest().lat() // bottom
&& bound.getSouthWest().lng() < mapBounds.getSouthWest().lng()) // left
{
lastValidCenter=map.getCenter(); // valid case, set up new valid center location
}
// if (bound.contains(map.getCenter()))
// {
map.panTo(lastValidCenter);
// }
}
// Google map listeners
google.maps.event.addListener(map, 'zoom_changed', function() {
//var zoom = map.getZoom();
checkBounds();
});
google.maps.event.addListener(map, "bounds_changed", function() {
checkBounds();
});
google.maps.event.addListener(map, 'center_changed', function() {
limitBound(allowedBounds);
});
P.S., uygun 2d Dünya 2 enlem/Ing değerleri verilen haritanın merkezine koordinat almak için, map.getProjection(). fromLatLngToPoint() kullanın. 2 noktayı karşılaştırın, aralarındaki doğrusal farkı bulun ve map.getProjection(). FromPointToLatLng() öğesini kullanarak dünya koordinatlarındaki farkı lat/lng ile eşleştirin. Bu, lat/lng birimlerinde doğru klip ofsetleri verecektir.
Bunu kullandım ve harika çalışıyor. Şerefe! –
'allowedBounds' nedir? – travis
allowedBounds bir [LatLngBounds nesne] olduğu (https://developers.google.com/maps/documentation/javascript/reference#LatLngBounds) (enlem/boylam temelde bir çift). Bu gerçekten iyi çalışıyor BTW, benim için tam olarak ne gerekiyorsa yapar! – strikernl