将坐标转换为屏幕上的像素(然后再返回)
Posted
技术标签:
【中文标题】将坐标转换为屏幕上的像素(然后再返回)【英文标题】:Convert coordinates to pixels on screen (and back again) 【发布时间】:2017-04-29 05:22:46 【问题描述】:这就是我正在做的事情: 单击地图上的标记以打开侧面板并将地图居中 标记。侧面板占据了屏幕右侧的 3/4。
这是我需要做的: 根据面板打开后留下的 1/4 视口居中标记。
我可以获取标记的像素坐标,并在面板动画打开时计算它需要转换到的位置。问题是flyTo()
只接受LngLatLike
对象,我无法将像素坐标转换为纬度和经度。 Leaflet.js 有一个名为 containerPointToLatLng()
的函数,在我切换到 Mapbox GL 之前就派上用场了。
鉴于 Mapbox GL 的复杂性,尽管它很新颖,但我只能想象这是一种可能性。 但是怎么做呢?
【问题讨论】:
【参考方案1】:project 和 unproject 方法使很多这样的逻辑成为可能。如果您单击某个 lngLat,并且您希望定位地图,使该地理位置水平居中并位于 1/8 标记处,您可以:
-
获取地理位置并使用
project
将其转换为像素位置
将该像素位置右移 (1/2-1/8) = 4/8-1/8 = 3/8 = 0.375 * map._containerDimensions()[0]
,并加上该数字
使用unproject
将移动的像素位置转回地理位置
或者,您也可以通过在您的 flyTo
调用中使用 offset option 来轻松完成此操作。
【讨论】:
啊哈!我project
和unproject
正是我想要的。那行得通,但我现在意识到我没有提到我在flyTo
期间放大到一个固定的缩放点,这只有在我保持相同的缩放级别时才有效。知道如何适应吗?
只需将zoom
属性添加到您的选项对象。 Docs。我喜欢在这里使用offset,因为它会为您计算——只需传入PointLike 值[x, y]。【参考方案2】:
我的情况类似,只有我的侧导航菜单是 400 像素(相同的主体)。 我遇到了同样的两个障碍:
-
为 flyto 函数计算从像素到 lat/lng 的校正
针对不同的缩放级别进行校正
@tmcw 的第一个答案做得非常好,但不幸的是我的offset option in flyto function 不再可用。
为了得到不同缩放级别之间的线性比例,您需要根据docs划分2zoom1:2zoom2。
完整示例:
// Desired zoom level at the end of flyTo
const zoomLevel = 16;
const zoomCorrection = Math.pow(2, this.map.getZoom()) / Math.pow(2, zoomLevel);
// Desired left shift/offset in px at the end of the flyTo. Use minus for right shift.
const leftShift = 200;
const lat = SelectedMarker.longitude;
const lng = SelectedMarker.latitude;
const coordinates = this.map.project([lat, lng]);
const offsetcoordinates = this.map.unproject([coordinates.x + (leftShift * zoomCorrection), coordinates.y]);
this.map.flyTo(
animate: true,
zoom: zoomLevel,
center: [offsetcoordinates.lng, offsetcoordinates.lat],
);
【讨论】:
【参考方案3】:即使这是一个老问题, 对于所有有相同要求的人(像我一样),我在 mapbox 站点中找到了一个official example
【讨论】:
以上是关于将坐标转换为屏幕上的像素(然后再返回)的主要内容,如果未能解决你的问题,请参考以下文章