[英]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.