Eka*_*ara 11 google-maps google-maps-api-3
我正在尝试设置界限,您可以使用Google Maps API V3拖动地图这是V2 http://econym.org.uk/gmap/example_range.htm的解决方案,效果非常好.
然而,使用API V3并不是那么好:当你使用相同的checkbounds()函数时,当你到达边界时地图会抽搐,而map.setCenter()会改变地图的中心.
怎么解决?API V3的解决方案是什么?
小智 19
我有同样的问题,但这应该排除它(它是相同的功能,听取的事件从'移动'或'拖'变为'中心变换',就像一个魅力!:
google.maps.event.addListener(map,'center_changed',function() { checkBounds(); });
function checkBounds() {
if(! allowedBounds.contains(map.getCenter())) {
var C = map.getCenter();
var X = C.lng();
var Y = C.lat();
var AmaxX = allowedBounds.getNorthEast().lng();
var AmaxY = allowedBounds.getNorthEast().lat();
var AminX = allowedBounds.getSouthWest().lng();
var AminY = allowedBounds.getSouthWest().lat();
if (X < AminX) {X = AminX;}
if (X > AmaxX) {X = AmaxX;}
if (Y < AminY) {Y = AminY;}
if (Y > AmaxY) {Y = AmaxY;}
map.setCenter(new google.maps.LatLng(Y,X));
}
}
Run Code Online (Sandbox Code Playgroud)
小智 6
如果地图调整大小或放大/缩小,您可能还需要考虑环绕坐标,曲线扭曲和居中到边界尺寸.如果您的边界占据整个地图的很大一部分(例如像大陆一样),则尤其需要这样做.
然而,checkBounds()的问题之一是它没有考虑到接近北极/南极的纬度值,这些纬度值具有非线性失真,这使得限制界限准确(我使用近似幻数在所有情况下都不起作用的乘数).通过右边,您应该首先将边界转换为线性2d世界坐标,以查看它在世界坐标方面离边界的距离,而不是将世界坐标中的实际目标中心点映射到目标实际纬度位置.对于经度值,这似乎不是很多问题,并且线性剪切方法看起来足够准确,主要问题是经度坐标的包装,这在下面的代码中(稍微说明).
// 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);
});
Run Code Online (Sandbox Code Playgroud)
ps对于checkBounds(),要从地图中心获取正确的2d世界坐标,给定2个lat/lng值,请使用map.getProjection().fromLatLngToPoint().比较2个点,找到它们之间的线性差异,并使用map.getProjection().fromPointToLatLng()将世界坐标的差异映射回lat/lng.这将为您提供lat/lng单位的精确剪辑偏移.
| 归档时间: |
|
| 查看次数: |
36085 次 |
| 最近记录: |