将坐标转换为屏幕上的像素(以及反向转换)

12
我正在做什么:点击地图上的标记来打开侧边面板并将地图居中于标记。该侧边面板占据屏幕右侧3/4。 我需要实现的内容:将标记居中于面板打开后剩余1/4视窗的中心位置。

我可以获取标记的像素坐标,并在面板动画打开时计算其需要转换到的位置。问题是,flyTo()只接受LngLatLike对象,我无法将我的像素坐标转换为经纬度。Leaflet.js有一个名为containerPointToLatLng()的函数,在我切换至Mapbox GL之前非常有用。

考虑到Mapbox GL的复杂性,尽管它很新,我想这可能是一种解决方法。但是如何实现呢?

3个回答

18
projectunproject方法使得很多类似的逻辑成为可能。如果您在某个lngLat位置单击,想让地图定位到该地理位置在水平方向上居中且在1/8处标记,您可以:
  1. 使用project将地理位置转换为像素位置
  2. 通过将(1/2-1/8) = 4/8-1/8 = 0.375 * map._containerDimensions()[0]这个数字加入到像素位置中,将其向右移动
  3. 使用unproject将移动后的像素位置转回地理位置
或者,您也可以在flyTo调用中使用偏移选项来轻松完成此操作。

啊哈!我找到了我需要的“project”和“unproject”。这个方法可以工作,但是我现在意识到我没有提到我在“flyTo”期间缩放到一个固定的缩放点,这只适用于我保持在相同的缩放级别时。有什么办法可以解决这个问题吗? - Tomelower
只需将 zoom 属性添加到您的选项对象中即可。文档。我喜欢在这里使用 offset,因为它会为您计算 - 只需传入一个 PointLike 值 [x, y]。 - Roy

4

现在MapBox网站上有一个示例,展示了如何使用padding选项(尽管offset同样有效)来实现此功能。


-1

我处于类似的情况,只是我的侧边导航菜单是400像素(同样的原则)。 我遇到了相同的两个障碍:

  1. 计算从像素到纬度/经度的校正值以用于flyto函数
  2. 校正不同缩放级别

@tmcw的答案对第一个问题做得非常好,但不幸的是,flyto函数中的offset option选项已不再可用。

显然,为了获得不同缩放级别之间的线性比率,您需要按照文档中的方法将2的zoom1次方除以2的zoom2次方。

完整示例:

// 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],
});

你正在让自己变得太难了。可以通过AnimationOptions对flyTo()应用偏移量。 - Yarin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接