Vous pourriez aussi prendre en compte les coordonnées d'emballage, déformation de la courbe, et centerizing aux dimensions liées si la carte redimensionne ou effectuer un zoom avant/arrière. Ceci est particulièrement nécessaire si vos limites occupent un grand pourcentage de la carte entière (par exemple, comme un continent). L'un des problèmes avec checkBounds() est qu'il ne prend pas en compte les valeurs de latitude proches des pôles nord/sud, qui ont une distorsion non linéaire qui limite les limites in-justes (I (0)). utiliser des multiplicateurs de nombres magiques approximatifs qui ne fonctionneront pas dans toutes les situations). De droite, vous devez d'abord convertir les bornes en coordonnées linéaires 2D pour voir à quelle distance elles sont en termes de coordonnées du monde, que de mapper le point central réel en coordonnées du monde à la position de latitude réelle cible.Pour les valeurs de longitude, cela ne semble pas très problématique et l'approche de l'écrêtage linéaire semble assez précise, le problème principal est avec l'enroulement des coordonnées de longitude qui est pris en compte (un peu) dans le code ci-dessous.
// 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 Pour CheckBounds(), pour obtenir une bonne monde 2d coordonnées du centre de la carte, étant donné 2 lat/valeurs lng, utilisez map.getProjection(). FromLatLngToPoint(). Comparez les 2 points, trouvez la différence linéaire entre eux et mappez la différence entre les coordonnées du monde et lat/lng en utilisant map.getProjection(). FromPointToLatLng(). Cela vous donnera des décalages de clip précis dans les unités lat/lng.
J'ai utilisé ceci et cela fonctionne génial. À votre santé! –
Que définit 'allowedBounds'? – travis
allowedBounds est un [objet LatLngBounds] (https://developers.google.com/maps/documentation/javascript/reference#LatLngBounds) (essentiellement une paire de latitudes/longitudes). Cela fonctionne très bien BTW, fait exactement ce qu'il devrait pour moi! – strikernl