如何从Google Maps Static API图像像素坐标转换为经纬度
像素转经纬度函数精度问题调试
我正在开发一个函数,输入x/y像素坐标、图像缩放级别(zoom)、图像缩放因子(scale)、图像中心经纬度(image_center_lat_lon)、图像像素尺寸(image_size),返回对应经纬度。该图像来自Google Maps Static API,采用墨卡托投影。我尝试多种计算实现像素到经纬度的转换,但结果存在小幅偏差。
两个精度不足的示例函数
示例1
import math def pixel_to_lat_lon(x, y, zoom, scale, image_center_lat_lon, image_size): C = 640 * scale * (2 ** zoom) # 地图宽/高的总像素数 lat_center, lon_center = image_center_lat_lon image_size_scaled = (image_size[0] * scale, image_size[1] * scale) # 计算图像中心的像素坐标 center_x = (lon_center + 180) / 360 * C center_y = (1 - math.log(math.tan(math.radians(lat_center)) + 1 / math.cos(math.radians(lat_center))) / math.pi) / 2 * C # 根据像素坐标计算经纬度 pixel_x = center_x - image_size_scaled[0] / 2 + x pixel_y = center_y - image_size_scaled[1] / 2 + y lon = pixel_x / C * 360 - 180 lat_rad = math.atan(math.sinh(math.pi * (1 - 2 * pixel_y / C))) lat = math.degrees(lat_rad) return lat, lon
示例2
import math def project(lat_lng, zoom, scale, tile_size): """将经纬度投影到世界坐标""" lat, lng = lat_lng siny = math.sin(lat * math.pi / 180.0) siny = min(max(siny, -0.9999), 0.9999) x = tile_size * (0.5 + lng / 360.0) * scale * (2 ** zoom) y = tile_size * (0.5 - math.log((1 + siny) / (1 - siny)) / (4 * math.pi)) * scale * (2 ** zoom) return x, y def unproject(world_coordinate, zoom, scale, tile_size): """将世界坐标反投影为经纬度""" x, y = world_coordinate lng = (x / (tile_size * scale * (2 ** zoom)) - 0.5) * 360.0 n = math.pi - 2.0 * math.pi * y / (tile_size * scale * (2 ** zoom)) lat = (180.0 / math.pi) * math.atan(0.5 * (math.exp(n) - math.exp(-n))) return lat, lng def pixel_to_lat_lon(x, y, zoom, scale, image_center_lat_lon, image_size): tile_size = 640 center_x, center_y = project(image_center_lat_lon, zoom, scale, tile_size) # 计算图像的中心像素 image_center_x = image_size[0] / 2 image_center_y = image_size[1] / 2 # 将输入的x/y转换为地图上的绝对像素坐标 abs_x = center_x + (x - image_center_x) abs_y = center_y + (y - image_center_y) # 将绝对像素坐标转换回经纬度 return unproject((abs_x, abs_y), zoom, scale, tile_size)
参考文档
- 《地图与瓦片坐标》
- 《Google Maps Static API参数说明(帮助理解zoom和scale)》
测试用例
测试用例1
{ "纬度": 25.64208985300285, "经度": -80.37262545716628, "缩放级别": 18, "缩放因子": 2, "图像尺寸": 640, "像素X": 767.4027099609375, "像素Y": 700.3953857421875 }
测试用例2
{ "纬度": 25.63934327097157, "经度": -80.35101258254728, "缩放级别": 18, "缩放因子": 2, "图像尺寸": 640, "像素X": 247.67588806152344, "像素Y": 239.9282989501953 }
预期结果(对应Google Maps UI中泳池中心的大致经纬度)
- 测试用例1:25.641942181931114, -80.37228858417026
- 测试用例2:25.640310082174018, -80.3520713140406
内容的提问来源于stack exchange,提问作者Jeremy Lin
相关产品推荐
相关产品推荐

