我创建了一个非常复杂的商店定位器。用户输入他们的zip并且表格在地图上返回带有相应标记的结果。他们可以翻阅结果,标记会进一步向外移动,fitbounds()
功能可以很好地缩小到适当的缩放级别以适合标记。问题是,如果您回到更近的位置,fitbounds()
不会放大。即使您输入新的搜索,它也不会放大这些新标记 - 它们居中于它们但保留在任何位置以前的缩放级别。我希望这是有道理的。如果有人知道我需要添加什么来让它放大更接近的结果请帮助。这些是我在标记推送功能结束时调用的谷歌功能:
map.setCenter(bounds.getCenter());
map.panToBounds(bounds);
map.fitBounds(bounds);
谢谢!
答案 0 :(得分:10)
问题是:我们设置
var bounds = new google.maps.LatLngBounds();
以便我们以后可以将我们的标记放到地图上的有界区域。 GMaps将始终异步缩小以适应fitBounds(),但不会放大以实现相同(如前所述@broady)。这对于许多应用来说并不理想,因为一旦你走了并在地图上显示一系列标记导致地图缩小(可能<10),它就不会在没有用户手动这样做的情况下放大。
GMaps将继续使用(缺少更好的单词)最大缩小标记收集状态(抱歉)的界限。在每次调用新标记之前设置为“null”会为您提供一个新的地图。
要自动放大,只需设置LatLngBounds();像这样'null'(参见下面的伪示例以查看其位置):
bounds = new google.maps.LatLngBounds(null);
伪示例:
// 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
}
答案 1 :(得分:8)
这里没有什么花哨的东西。首先适合边界然后平移它。这将为您提供适当的缩放并包含整个边界。
map.fitBounds(bounds);
map.panToBounds(bounds);
答案 2 :(得分:4)
没错,fitBounds
只有确保提供的界限是可见的。它不会放大到适当的水平。
您可以先调用setZoom(20)
,然后调用fitBounds。
答案 3 :(得分:3)
嗯,有趣..我使用PHP循环遍历所有(将)标记坐标并计算southWest和northEast的值;原点的坐标在两者之间。如果所有标记坐标彼此非常接近,则由fitBounds设置的缩放系数比在地图创建时使用的15更高(放大)。这就是我添加最后一行的原因..
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);
});
所以,自从您发布问题或者我已经重新编程了该功能。我需要有关您的代码的更多信息。
答案 4 :(得分:3)
帮助我的原因是使用0填充作为fitBounds(bounds,padding)的第二个参数,这是完整的代码示例:
import matplotlib.pyplot as plt
population_ages = [22,55,62,45,21,22,34,42,42,4,99,102,110,120,121,122,130,111,115,112,80,75,65,54,44,43,42,48]
binns = [0,10,20,30,40,50,60,70,80,90,100,110,120,130]
plt.hist(x = population_ages,bins = binns,histtype='bar',rwidth=0.8)
plt.xlabel('x')
plt.ylabel('y')
plt.title('Interesting graph')
plt.legend()
plt.show()
答案 5 :(得分:2)
事实证明,当你调用map.getBounds()
时,它会返回视口,边缘周围有一点边距。由于此新边界大于当前边界,因此地图将始终缩小。我能够通过避免完全使用当前地图的边界并保持单独的LatLngBounds变量来解决它。每次我添加一个点我都会打电话:
markersBounds.extend(newMarkersLatLng);
map.fitBounds(markersBounds);
map.panToBounds(markersBounds);
要删除点(我总是添加它们),您可以使用第一个点创建一个新的LatLngBounds对象,然后扩展每个剩余点以获得新的边界:
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);
答案 6 :(得分:2)
在使用新标记在同一地图上第二次调用fitBounds时,我也遇到了地图缩放问题。这是对我有用的frankensolution:
// 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);
}
答案 7 :(得分:1)
从marker.setMap(null);
(用于从地图中删除标记)的GMap文档中检查以下引用:
请注意,上述方法不会删除标记。它删除了 地图上的标记。相反,如果您希望删除标记,则 应该将其从地图上删除,然后将标记本身设置为null。
我的问题是,当我从地图上删除标记时,它们仍存储在map.markers
中。因此,在设置bounds
时,它还会同时捕获所有以前的标记:
map.markers.forEach( (marker) => {
var latlng = new google.maps.LatLng(marker.position.lat(), marker.position.lng())
bounds.extend(latlng)
})
Console.logging bounds
显示,因此,边界将始终容纳所有较早的边界。
我的解决方案是在单独的markers
数组/对象中跟踪标记,该数组/对象为每个标记存储唯一的键(在我的情况下,链接到场所自动完成输入字段),并在出现以下情况时从其中删除标记从地图上删除标记。这样,我可以在生成bounds
时进行检查,以查看map.markers
中的当前标记是否在(最新的)markers
数组中。
map.markers.forEach( (marker) => {
// check if map marker is in this.markers (to make sure only current)
for (const [key, value] of Object.entries(markers)) {
if (marker == value) {
var latlng = new google.maps.LatLng(marker.position.lat(), marker.position.lng())
bounds.extend(latlng)
}
}
})
现在,更改标记后,我的地图可以正确放大。如果有人可以对上述方法进行任何改进,我想听听!
租金
答案 8 :(得分:0)
map.setZoom(10);
我相信可接受的范围是1-20。只有整数,小数在我的经历中打破了地图。
答案 9 :(得分:0)
fitBounds: function(bounds, mapId)
{
//bounds: bounds, id: map id
if (bounds==null) return false;
maps[mapId].fitBounds(bounds);
},
这应该有帮助,我使用这种方法并且工作正常,在地图v2上有点不同的方式。
答案 10 :(得分:0)
我今天遇到了这个普遍问题,以为我会分享一个解决方案。我意识到这与您的商店定位器略有不同&#39;问题,但它确实适用于许多方面。在我的情况下,我在地图上有一组标记,并添加一个,并希望确保所有标记现在都在视图中。此代码检查每个现有标记,以查看它是否在视图中,并在此过程中构建一个新的边界框,如果需要,将包含所有标记。最后,如果发现任何视图不在视图中,视图将被重置,因此它们都是。
(这使用Dojo的数组模块,只是围绕基本数组迭代的便利包装器)
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);
}
可以很容易地修改它以仅确保新标记在视图中,不循环并且仅对新标记执行contains()检查。
答案 11 :(得分:0)
确保地图的宽度或高度上没有CSS动画。动画会干扰fitBound()的缩放行为
昨天我大部分时间都在这个问题上,并且我至少遇到了12次StackOverflow帖子。但是我最终不得不独自解决这个问题。
删除下面的transition: all 0.5s ease;
行对我来说是固定的。
.google-map {
width: 100%;
height: 0px;
transition: all 0.5s ease;
}
.google-map.loaded {
height: 400px;
}