传单:按缩放级别获取缩放边界框
Leaflet: Get scaled bounding box by zoom level
我正在尝试预测下一个界限的样子。这是一个笨蛋:
https://plnkr.co/edit/sk6NRh51WZA2vpWP
这就是我的工作方式,但效率不高:
const originalMapElement = document.getElementById('map');
const lMap: any = L.map(originalMapElement);
// working but very inefficient
// ----------------------------
function getScaledBounds(center, zoom) {
const fakeDiv = document.createElement("div");
fakeDiv.style.display = "block";
fakeDiv.style.visibility = "hidden";
fakeDiv.style.width = originalMapElement.offsetWidth + "px";
fakeDiv.style.height = originalMapElement.offsetHeight + "px";
document.body.appendChild(fakeDiv);
const fakeMap = L.map(fakeDiv);
fakeMap.setView(center, zoom, { animate: false });
return fakeMap.getBounds();
}
我的另外两个编程方法非常接近,产生的结果与上面的第一个函数几乎但不完全相同:
function getScaledBounds(center, zoom) {
const centerPoint = lMap.project(center, zoom);
const viewHalf = lMap.getSize().divideBy(2);
const projectedBox = new L.Bounds(centerPoint.subtract(viewHalf), centerPoint.add(viewHalf));
return L.latLngBounds(
lMap.unproject(projectedBox.getBottomLeft(), zoom),
lMap.unproject(projectedBox.getTopRight(), zoom),
);
}
function getScaledBounds(center, zoom) {
const zoomFactor = Math.pow(2, zoom) * 2;
const dw = originalMapElement.offsetWidth / zoomFactor;
const dh = originalMapElement.offsetHeight / zoomFactor;
const centerPoint = lMap.project(center, zoom);
return L.latLngBounds(
lMap.unproject(new Point(centerPoint.x - dw, centerPoint.y + dh, false), zoom),
lMap.unproject(new Point(centerPoint.x + dw, centerPoint.y - dh, false), zoom),
);
}
有人能解决这个问题吗?或者有人可以解释为什么所有这些都会产生不同的结果,而在我的理解中它们应该 return 相同的值?
这很痛苦 :D 我没有找到我的问题的答案,但我至少能让代码正常工作:
function getScaledBoundsWorking(center, zoom) {
const bounds = lMap.getPixelBounds(center, zoom);
const sw = lMap.unproject(bounds.getBottomLeft(), zoom);
const ne = lMap.unproject(bounds.getTopRight(), zoom);
return L.latLngBounds(sw, ne);
}
https://plnkr.co/edit/ei6qg001clSoe0CI
我仍然很好奇其他方法究竟有什么问题。
lMap.unproject()
和 lMap.project()
不是线性函数。您在之前的方法中将它们视为线性的。
const viewHalf = lMap.getSize().divideBy(2);
获取显示尺寸的一半,但不一定匹配投影提供地图中间
在您的回答中,通过调用 lMap.unproject()
传递未修改的值,效果很好。
处理非线性关系时,如果不包括非线性因素,标准算术运算将无法正常工作。
我正在尝试预测下一个界限的样子。这是一个笨蛋: https://plnkr.co/edit/sk6NRh51WZA2vpWP
这就是我的工作方式,但效率不高:
const originalMapElement = document.getElementById('map');
const lMap: any = L.map(originalMapElement);
// working but very inefficient
// ----------------------------
function getScaledBounds(center, zoom) {
const fakeDiv = document.createElement("div");
fakeDiv.style.display = "block";
fakeDiv.style.visibility = "hidden";
fakeDiv.style.width = originalMapElement.offsetWidth + "px";
fakeDiv.style.height = originalMapElement.offsetHeight + "px";
document.body.appendChild(fakeDiv);
const fakeMap = L.map(fakeDiv);
fakeMap.setView(center, zoom, { animate: false });
return fakeMap.getBounds();
}
我的另外两个编程方法非常接近,产生的结果与上面的第一个函数几乎但不完全相同:
function getScaledBounds(center, zoom) {
const centerPoint = lMap.project(center, zoom);
const viewHalf = lMap.getSize().divideBy(2);
const projectedBox = new L.Bounds(centerPoint.subtract(viewHalf), centerPoint.add(viewHalf));
return L.latLngBounds(
lMap.unproject(projectedBox.getBottomLeft(), zoom),
lMap.unproject(projectedBox.getTopRight(), zoom),
);
}
function getScaledBounds(center, zoom) {
const zoomFactor = Math.pow(2, zoom) * 2;
const dw = originalMapElement.offsetWidth / zoomFactor;
const dh = originalMapElement.offsetHeight / zoomFactor;
const centerPoint = lMap.project(center, zoom);
return L.latLngBounds(
lMap.unproject(new Point(centerPoint.x - dw, centerPoint.y + dh, false), zoom),
lMap.unproject(new Point(centerPoint.x + dw, centerPoint.y - dh, false), zoom),
);
}
有人能解决这个问题吗?或者有人可以解释为什么所有这些都会产生不同的结果,而在我的理解中它们应该 return 相同的值?
这很痛苦 :D 我没有找到我的问题的答案,但我至少能让代码正常工作:
function getScaledBoundsWorking(center, zoom) {
const bounds = lMap.getPixelBounds(center, zoom);
const sw = lMap.unproject(bounds.getBottomLeft(), zoom);
const ne = lMap.unproject(bounds.getTopRight(), zoom);
return L.latLngBounds(sw, ne);
}
https://plnkr.co/edit/ei6qg001clSoe0CI
我仍然很好奇其他方法究竟有什么问题。
lMap.unproject()
和 lMap.project()
不是线性函数。您在之前的方法中将它们视为线性的。
const viewHalf = lMap.getSize().divideBy(2);
获取显示尺寸的一半,但不一定匹配投影提供地图中间
在您的回答中,通过调用 lMap.unproject()
传递未修改的值,效果很好。
处理非线性关系时,如果不包括非线性因素,标准算术运算将无法正常工作。