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

标签 python google-maps google-maps-api-3 geolocation

我正在加载来自 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 的 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)

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)

我们必须从什么开始

我们在 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 (see the docs for size and zoom)。查看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,
    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以纬度作为乘数。

关于python - 将谷歌静态图像的像素转换为 LatLng 坐标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47106276/

相关文章:

javascript - 具有方向的 Google map 在移动设备上不起作用 : "No Routes Found"

javascript - 使用 JavaScript 进行 Python RQ 排队

ios - 如何在我所在位置的某个半径范围内找到使用我的应用程序的人

ios - 未找到 <GoogleMaps/GoogleMaps.h> 文件 Google Maps SDK for iOS

javascript - initMap 不是使用 google map API 的函数

javascript - 无法获取 Google map JavaScript API key

Python删除numpy数组中的行

python - ipdb 显示颜色代码而不是颜色

python - 在 Python 中生成特征化的唯一 ID

google-maps - 如何为 google maps api v3 对象创建自定义事件?