将坐标转换为屏幕上的像素(然后再返回)

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 来轻松完成此操作。

【讨论】:

啊哈!我projectunproject 正是我想要的。那行得通,但我现在意识到我没有提到我在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

【讨论】:

以上是关于将坐标转换为屏幕上的像素(然后再返回)的主要内容,如果未能解决你的问题,请参考以下文章

如何将地理坐标转换为固定比例的像素?

个人笔记三维GIS开发-cesium坐标系统

将坐标从图像转换为屏幕

OpenGL工作流程

matlab像素坐标值转换为经纬度

如何将子视图上的触摸事件的坐标转换为其父视图中的坐标?