我在地图上有一条线索,用户可以跟随"通过鼠标悬停在图表上(时间和速度)。如果用户放大很多,则部分路径可能不可见。当用户想要查看未显示的部分路径时,我使用panTo方法...
传单的panTo方法目前也居中。我不想居中,我希望地图移动足够来显示一个点。 (panTo的问题是导致过多的地图滚动和恶劣的用户体验。)
我尝试过更改边界,但有时会缩小(不需要的)副作用。
任何方式我都可以做一个" minimal"哑剧?
这是一个(工作但未经修改)的解决方案; map是我们自己的map wrapper实用程序类,lmap是typescript中的leaflet map对象,toxy()是一个将lat / long转换为x / y值的方法。
if (!this.lmap.getBounds().contains(latlng)) {
let target = this.map.toxy(latlng);
let nw = this.map.toxy(this.lmap.getBounds().getNorthWest());
let se = this.map.toxy(this.lmap.getBounds().getSouthEast());
let x = 0, y = 0;
let margin = 75;
if (target.y < nw.y)
y = (-1 * (nw.y - target.y)) - margin;
else if (target.y > se.y)
y = (target.y - se.y) + margin;
if (target.x < nw.x)
x = (-1 * (nw.x - target.x)) - margin;
else if (target.x > se.x)
x = (target.x - se.x) + margin;
this.lmap.panBy(new L.Point(x, y));
}
答案 0 :(得分:3)
首先,使用map.getPixelBounds()
获取地图的边界(以CRS原点为单位测量)。然后,使用map.project(latlng, map.getZoom())
获取您感兴趣的点的坐标(以CRS原点为单位)。
如果您对此“来自CRS原点的像素”感到困惑,请阅读http://leafletjs.com/examples/extending/extending-2-layers.html处的“Pixel Origin”部分。
一旦你有这些像素坐标,检查点是否在视口内部应该是一个简单的事情,如果没有,那么每个方向的距离应该是多远。
答案 1 :(得分:0)
http://jsfiddle.net/jcollin6/b131tobj/2/
应该给你你想要的东西
function clamp(n,lower,upper) {
return Math.max(lower, Math.min(upper, n));
}
//Shamelessly stolen from https://gist.github.com/dwtkns/d5b9b60285b8b0067c53
function getNearestPointInPerimeter(l,t,w,h,x,y) {
var r = l+w,
b = t+h;
var x = clamp(x,l,r),
y = clamp(y,t,b);
var dl = Math.abs(x-l),
dr = Math.abs(x-r),
dt = Math.abs(y-t),
db = Math.abs(y-b);
var m = Math.min(dl,dr,dt,db);
return (m===dt) ? {x: x, y: t} :
(m===db) ? {x: x, y: b} :
(m===dl) ? {x: l, y: y} : {x: r, y: y};
}
L.ExtendedMap = L.Map.extend({
panInside: function (latlng, pad, options) {
var padding = pad ? pad : 0;
var pixelBounds = this.getPixelBounds();
var center = this.getCenter();
var pixelCenter = this.project(center);
var pixelPoint = this.project(latlng);
var sw = pixelBounds.getBottomLeft();
var ne = pixelBounds.getTopRight();
var topLeftPoint = L.point(sw.x + padding, ne.y + padding);
var bottomRightPoint = L.point( ne.x - padding, sw.y - padding);
var paddedBounds = L.bounds(topLeftPoint, bottomRightPoint);
if (!paddedBounds.contains(pixelPoint)) {
this._enforcingBounds = true;
var nearestPoint = getNearestPointInPerimeter(
sw.x + padding,
ne.y + padding,
ne.x - sw.x - padding * 2,
sw.y - ne.y - padding * 2,
pixelPoint.x,
pixelPoint.y
);
var nearestPixelPoint = L.point(nearestPoint.x,nearestPoint.y)
var diffPixelPoint = nearestPixelPoint.subtract(pixelPoint);
var newPixelCenter = pixelCenter.subtract(diffPixelPoint);
var newCenter = this.unproject(newPixelCenter);
if (!center.equals(newCenter)) {
this.panTo(newCenter, options);
}
this._enforcingBounds = false;
}
return this;
}
});
答案 2 :(得分:0)
使用这种方式
map.panTo([lat, lng]);
map.setZoom(Zoom);