繁体   English   中英

将(旋转的)ImageOverlay中的X和Y坐标转换为纬度和经度

[英]Transform X and Y coordinates inside a (rotated) ImageOverlay to latitude and longitude

在阅读了Projection的文档以及一些失败的测试之后,我发现自己无法找到解决该问题的方法。

在所有解决方案中,我发现x和y坐标是相对于墨卡托地图投影的事实,但是在这种情况下,我将它们从放置在地图上一层的本地图像中获取。

假设我有一个400px * 200px的灰色图像,使用ImageOverlay.Rotated放置在传单地图上的位置:

var topleft = L.latLng(41.604766, 0.606402);
var topRight = L.latLng(41.605107, 0.606858);
var bottomleft = L.latLng(41.604610, 0.606613);

将此图像使用左上,右上和左下坐标作为参考放置在地图上。

结果是向北稍微旋转一个矩形。

如果我知道我将手机留在像素100,50(原始图像的左上角)处,该如何将笛卡尔坐标转换为经度和纬度以供地图显示?

如果它是一个与北方完全对齐的矩形,我想我可以得到topLeft和bottomLeft角之间的º差异,将其除以像素数,然后将结果与手机的Y相乘即可得到纬度。 使用先前的值,我会将其乘以手机的X以获取手机的经度。

但是鉴于形状是旋转的,所以世界并不平坦,而且我在地理和三角学方面真的很烂,我不确定它是否足够精确。

最后,我们说的是电话,而不是建筑物。 距离几米(2-4)距离还可以,但不能再建一个积木。

哦,您是在说我自己的Leaflet.ImageOverlay.Rotated 我很乐意为您服务。

您应该查看其源代码 所有的数学都在那里。 让我们来看一下这段代码:

    var pxTopLeft    = this._map.latLngToLayerPoint(this._topLeft);
    var pxTopRight   = this._map.latLngToLayerPoint(this._topRight);
    var pxBottomLeft = this._map.latLngToLayerPoint(this._bottomLeft);

这会将三个经纬度坐标转换为相对于屏幕的像素坐标 关于创建L.Layer子类小册子教程很好地解释了“层点”的含义。

假设您是在飞机上而不是在大地水准面上工作,则可以将这些计算替换为所需的任何其他投影。 换句话说:您可能希望将经纬度坐标转换为EPSG:3857球形墨卡托坐标(Leaflet使用的显示投影)。 如果这样做,以后可以将插值的EPSG:3857坐标转换为EPSG:4326“普通纬度-经度”坐标。

    // Calculate the skew angles, both in X and Y
    var vectorX = pxTopRight.subtract(pxTopLeft);
    var vectorY = pxBottomLeft.subtract(pxTopLeft);

CSS转换需要倾斜角度才能使图像正确变形。 这也许是违反直觉的,但是ImageOverlay.Rotated使用CSS的skew()而不是rotate 但是您不需要偏斜角,只需要那些微分向量即可。

如果要vectorX进行可视化, vectorX是沿着图像顶侧(从左到右)的2D矢量,而vectorY是沿着左侧(从顶到底部)的2D矢量。

假设输入范围为[[0..1],[0..1]](其中0为图像的顶部或左侧,则这些矢量),您可以获取图像中任意点的屏幕坐标。和1为底部或右侧)。 但是您可能不想使用相对于图像的高度/宽度的数字,因为在您的问题中您提到了像素。 因此,让我们抓住像素。

    var imgW = this._rawImage.width;
    var imgH = this._rawImage.height;

好。 我们从ImageOverlay.Rotated提取了所有需要的数学位。


现在,如果您将先前的矢量除以以像素为单位的图像尺寸...

    var vectorXperPx = vectorX.divideBy(imgW);
    var vectorYperPx = vectorY.divideBy(imgW);

这些向量从原始图像的一个像素到其左侧(x)或下方(y)的像素。 因此,给定原始图像的像素(x,y),相对于图像角的投影矢量将为:

    var deltaVector = 
               xPixelCoordinate.scaleBy(vectorXPerPx)
          .add(yPixelCoordinate.scaleBy(vectorYPerPx))

从屏幕的左上角到图像的(xPixelCoordinate,yPixelCoordinate)像素,这就是屏幕坐标中的向量。

现在添加图像左上角的屏幕坐标,设置如下:

    var finalCoordinateForImagePixel = pxTopLeft.add(deltaVector);

当我们使用latLngToLayerPoint ,结果将相对于该参考框架。 想要找回来吗? 简单:

    var finalCoordinateForImagePixelInLatLong = 
           map.layerPointToLatLng(finalCoordinateForImagePixel);

但是鉴于形状是旋转的,所以世界并不平坦,而且我在地理和三角学方面真的很烂,我不确定它是否足够精确。

如果使用Leaflet用于显示的坐标参考系(EPSG:3857)或任何同构坐标系(相对于屏幕的像素坐标,相对于图层原点的像素坐标),就不会有问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM