是什么样的解决方案
看起来你不需要 javascript 解决方案,但 python 不是在浏览器中而是在服务器上使用它。我已经创建了一个 python 示例,但我要坚持的是数学,数学就是计算坐标所需的全部。让我也用 js 来做,让代码片段在浏览器中工作。您可以看到,python 和 js 给出了相同的结果。
跳转到答案
如果您只需要每像素度数的公式,就在这里。它们很简单,你不需要任何外部库,只需要一个 python 的math
。可以进一步找到解释。
#!/usr/bin/python
import math
w = 400
h = 400
zoom = 16
lat = 53.4055429
lng = -2.9976502
def getPointLatLng(x, y):
parallelMultiplier = math.cos(lat * math.pi / 180)
degreesPerPixelX = 360 / math.pow(2, zoom + 8)
degreesPerPixelY = 360 / math.pow(2, zoom + 8) * parallelMultiplier
pointLat = lat - degreesPerPixelY * ( y - h / 2)
pointLng = lng + degreesPerPixelX * ( x - w / 2)
return (pointLat, pointLng)
print 'NE: ', getPointLatLng(w, 0)
print 'SW: ', getPointLatLng(0, h)
print 'NW: ', getPointLatLng(0, 0)
print 'SE: ', getPointLatLng(w, h)
的输出剧本 is
$ python getcoords.py
NE: (53.40810128625675, -2.9933586655761717)
SW: (53.40298451374325, -3.001941734423828)
NW: (53.40810128625675, -3.001941734423828)
SE: (53.40298451374325, -2.9933586655761717)
我们必须从什么开始
我们在url中需要一些参数https://maps.googleapis.com/maps/api/staticmap?center=53.4055429,-2.9976502&zoom=16&size=400x400&maptype=satellite&key=YOUR_API_KEY
– 坐标、缩放、像素大小。
让我们引入一些初始变量:
var config = {
lat: 53.4055429,
lng: -2.9976502,
zoom: 16,
size: {
x: 400,
y: 400,
}
};
512 像素地球的数学
数学如下。飞涨1
代表地球赤道全景360°
当使用图像尺寸时512
(有关大小和缩放的信息,请参阅文档)。请参阅缩放 1 时的示例。这是非常重要的一点。比例(每像素的度数)不取决于图像大小。当改变图像尺寸时,人们会看到相同的比例:比较1 and 2– 第二张图片是大图片的裁剪版本。最大图像尺寸为googleapis
is 640
.
每次放大分辨率提高两倍。因此,图像的经度宽度是
lngDegrees = 360 / 2**(zoom - 1); // full image width in degrees, ** for power
然后使用线性函数找到图像任意点的坐标。应该提到的是,线性度仅适用于高变焦图像,不能将其用于低变焦(如 5 或更低)。低变焦的数学运算稍微复杂一些。
lngDegreesPerPixel = lngDegrees / 512 = 360 / 2**(zoom - 1) / 2**9 = 360 / 2**(zoom + 8);
lngX = config.lng + lngDegreesPerPixel * ( point.x - config.size.x / 2);
纬度不同
赤道上的纬度和经度大小相同,但如果向北或向南,经度会变小,因为地球上的纬线环的半径较小 -r = R * cos(lat) < R
因此图像高度(以度为单位)变得更小(参见 P.S.)。
latDegrees = 360 / 2**(zoom - 1) * cos(lat); // full image height in degrees, ** for power
并分别
latDegreesPerPixel = latDegrees / 512 = 360 / 2**(zoom - 1) * cos(lat) / 2**9 = 360 / 2**(zoom + 8) * cos(lat);
latY = config.lat - latDegreesPerPixel * ( point.y - config.size.y / 2)
之后的标志config.lat
与 的符号不同lngX
由于地球经度方向与图像一致x
方向,但纬度方向相反y
图像上的方向。
所以我们现在可以创建一个简单的函数来使用其查找像素的坐标x
and y
图片上的坐标。
var config = {
lat: 53.4055429,
lng: -2.9976502,
zoom: 16,
size: {
x: 400,
y: 400,
}
};
function getCoordinates(x, y) {
var degreesPerPixelX = 360 / Math.pow(2, config.zoom + 8);
var degreesPerPixelY = 360 / Math.pow(2, config.zoom + 8) * Math.cos(config.lat * Math.PI / 180);
return {
lat: config.lat - degreesPerPixelY * ( y - config.size.y / 2),
lng: config.lng + degreesPerPixelX * ( x - config.size.x / 2),
};
}
console.log('SW', getCoordinates(0, config.size.y));
console.log('NE', getCoordinates(config.size.x, 0));
console.log('SE', getCoordinates(config.size.x, config.size.y));
console.log('NW', getCoordinates(0, 0));
console.log('Something at 300,128', getCoordinates(300, 128));
附:你可能会问我,为什么我放置cos(lat)
纬度的乘数,而不是作为经度公式的除数。我发现,谷歌选择在不同纬度上每个像素具有恒定的经度比例,所以,cos
将纬度作为乘数。