微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

python – 将像素转换为LatLng来自谷歌静态图像的坐标

我正在加载 google static Map API的图像,加载的卫星图像是一个宽达数百米的地方.

https://maps.googleapis.com/maps/api/staticmap?center=53.4055429,-2.9976502&zoom=16&size=400x400&maptype=satellite&key=YOUR_API_KEY

此外,图像分辨率显示为10米,如下所示

enter image description here

.

enter image description here

我的问题是

因为我知道居中的地理位置(53.4055429,-2.9976502)和这个静态图像的分辨率,我怎么能够扩展它来计算图像中左上或右下的地理位置,最后计算图像的每个像素

解决方法

它是什么样的解决方

看起来你不需要javascript解决方案,但python不能在浏览器中使用它,而是在服务器上使用它.我已经创建了一个python示例,但它是我将要站立的数学,数学就是计算坐标所需的全部内容.让我用js来做它以使代码片段在浏览器中工作.你可以看到,python和js给出了相同的结果.

跳到答案

如果您只需要每像素度数的公式,那么您就是这样.它们很简单,你不需要任何外部库,只需要python的数学.可以进一步解释.

#!/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: ',0)
print 'SE: ',h)

the script输出

$python getcoords.py
NE:  (53.40810128625675,-2.9933586655761717)
SW:  (53.40298451374325,-3.001941734423828)
NW:  (53.40810128625675,-3.001941734423828)
SE:  (53.40298451374325,-2.9933586655761717)

我们必须从什么开始

我们在网址https://maps.googleapis.com/maps/api/staticmap?center=53.4055429,-2.9976502\u0026amp;zoom=16\u0026amp;size=400×400\u0026amp;maptype=satellite\u0026amp;key=YOUR_API_KEY中需要一些参数 – 坐标,缩放,大小以像素为单位.

我们来介绍一些初始变量:

var config = {
    lat: 53.4055429,lng: -2.9976502,zoom: 16,size: {
        x: 400,y: 400,}
};

512像素的地球数学

数学如下.当使用图像尺寸512(see the docs for size and zoom)时,缩放1代表地球赤道360°的全视图.见example at zoom 1.这是非常重要的一点.比例(每像素度数)不依赖于图像大小.当更改图像大小时,可以看到相同的比例:比较12 – 第二个图像是较大图像的裁剪版本. googleapis的最大图片尺寸为640.

每次放大increases resolution twice.因此,经度方面的图像宽度为

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和y坐标找到像素的坐标.

var config = {
    lat: 53.4055429,}
};

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',config.size.y));
console.log('NW',0));
console.log('Something at 300,128',getCoordinates(300,128));

附:您可能会问我,为什么我将cos(lat)乘数放在纬度上,而不是作为经度公式的除法器.我发现,谷歌选择在不同的纬度上每个像素具有恒定的经度比例,因此,cos作为乘数用于纬度.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐