从Google静态图像将像素转换为LatLng坐标 [英] Converting Pixels to LatLng Coordinates from google static image

查看:107
本文介绍了从Google静态图像将像素转换为LatLng坐标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从



我的问题是



因为我已经知道中心地理定位(53.4055429,-2.9976502)和这个静态图像的分辨率,我将如何扩展它以计算左上或右下的地理位置图像,并最终计算图像的每个像素 解决方案



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



跳转到答案



如果您只需要每像素度数的公式,那么您就是。它们很简单,你不需要任何外部库,只需要一个python的 math

 #!/ usr / bin / python 
导入数学

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)

脚本的输出为

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

p>

我们必须从开始



需要在 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 表示当使用图像尺寸 512 <地点>时,地球赤道 360° / code>(查看尺寸和缩放的文档)。请参阅示例放大1 。这是非常重要的一点。比例(每像素度数)不取决于图像大小。当人们更改图片大小时,您会看到相同的比例:compare 1 2 - 第二幅图像是较大图像的裁剪版本。 googleapis 的最大图片大小为 640



每次放大两次提高解析度。因此,你的图像的经度宽度是

  lngDegrees = 360/2 **(zoom  -  1); //完整图像宽度(度),**为权力

然后使用线性函数为任何图像的点。应该提到的是,线性只适用于高放大的图像,不能用于像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 ,因此图像高度以度为单位变小(参见PS)。

  latDegrees = 360/2 **(zoom  -  1)* cos(lat); //完整图像高度,**为电源



  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);返回{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 ); console.log('NW',getCoordinates(0,0)); console.log('Something at 300,128',getCoordinates(300,128));



PS你可能会问我为什么我把 cos(lat)乘数放在纬度上,而不是经度公式的分频器。我发现,谷歌选择在不同纬度上每像素具有恒定的经度缩放比例,因此, cos 以纬度作为乘数。


I am loading a image from google static Map API, the loaded satellite image is a place with hundreds of meters wide and length.

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

Additionally, the image resolution shows to be 10 meters, as shown below

.

My question is

as i have known the centered geolocation (53.4055429,-2.9976502) and resolution of this static image, how would i be able to extend it to calculate the geolocation of left up or right bottom in the image, and finally calculate each pixel of the image

解决方案

What kind of solution is it

Looks like you need not a javascript solution but for python to use it not in browser but on a server. I've created a python example, but it is the math that I am going to stand on, math is all you need to calculate coordinates. Let me do it with js as well to make snippet work in browser. You can see, that python and js give the same results.

Jump to the answer

If you just need formulae for degrees per pixel, here you are. They are simple enough and you don't need any external libraries but just a python's math. The explanation can be found further.

#!/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 output of the script is

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

What we have to start with

We have some parameters needed in url https://maps.googleapis.com/maps/api/staticmap?center=53.4055429,-2.9976502&zoom=16&size=400x400&maptype=satellite&key=YOUR_API_KEY – coordinates, zoom, size in pixels.

Let's introduce some initial variables:

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

The math of the Earth of 512 pixels

The math is as follows. Zoom 1 stands for full view of the Earth equator 360° when using image size 512 (see the docs for size and zoom). See the example at zoom 1. It is a very important point. The scale (degrees per pixel) doesn't depend on the image size. When one changes image size, one sees the same scale: compare 1 and 2 – the second image is a cropped version of the bigger one. The maximum image size for googleapis is 640.

Every zoom-in increases resolution twice. Therefore the width of your image in terms of longitude is

lngDegrees = 360 / 2**(zoom - 1); // full image width in degrees, ** for power

Then use linear function to find coordinates for any point of the image. It should be mentioned, that linearity works well only for high zoomed images, you can't use it for low zooms like 5 or less. Low zooms have slightly more complex math.

lngDegreesPerPixel = lngDegrees / 512 = 360 / 2**(zoom - 1) / 2**9 = 360 / 2**(zoom + 8); 
lngX = config.lng + lngDegreesPerPixel * ( point.x - config.size.x / 2);

Latitude degrees are different

Latitude degree and longitude degree on the equator are of the same size, but if we go north or south, longitude degree become smaller since rings of parallels on the Earth have smaller radii - r = R * cos(lat) < R and therefore image height in degrees becomes smaller (see P.S.).

latDegrees = 360 / 2**(zoom - 1) * cos(lat); // full image height in degrees, ** for power

And respectively

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)

The sign after config.lat differs from the sign for lngX since earth longitude direction coincide with image x direction, but latitude direction is opposed to y direction on the image.

So we can make a simple function now to find a pixel's coordinates using its x and y coordinates on the picture.

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));

P.S. You can probably ask me, why I place cos(lat) multiplier to latitude, not as a divider to longitude formula. I found, that google chooses to have constant longitude scale per pixel on different latitudes, so, cos goes to latitude as a multiplier.

这篇关于从Google静态图像将像素转换为LatLng坐标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆