瓦片地图坐标与经纬度换算公式python实现

经纬度和瓦片地图坐标对应关系本质上是由墨卡托投影实现

地图是显示在平面上的,因此需要将球面坐标转换为平面坐标,这个转换过程称为投影。最常见的投影是墨卡托(Mercator)投影,它具有等角性质,即球体上的两点之间的角度方位与平面上的两点之间的角度方位保持不变,因此特别适合用于导航。墨卡托于1569年提出的一种地球投影方法,该方法是圆柱投影的一种,又名”等角正轴圆柱投影”。

瓦片

经过Web墨卡托投影后,地图就变为平面的一张地图。考虑到有时候我们需要看宏观的地图信息(如世界地图里每个国家的国界),有时候又要看很微观的地图信息(如导航时道路的路况信息)。为此,我们对这张地图进行等级切分。在最高级(zoom=0),需要的信息最少,只需保留最重要的宏观信息,因此用一张256×256像素的图片表示即可;在下一级(zoom=1),信息量变多,用一张512×512像素的图片表示;以此类推,级别越低的像素越高,下一级的像素是当前级的4倍。这样从最高层级往下到最低层级就形成了一个金字塔坐标体系。

对每张图片,我们将其切分为256×256的图片,称为瓦片(Tile)。这样,在最高级(zoom=0)时,只有一个瓦片;在下一级(zoom=1)时有4个瓦片;在下一级(zoom=2)时有16个瓦片,以此类推

瓦片编码
瓦片生成后,就是一堆图片。怎么对这堆图片进行编号,是目前主流互联网地图商分歧最大的地方。总结起来分为四个流派:

  • 谷歌XYZ:Z表示缩放层级,Z=zoom;XY的原点在左上角,X从左向右,Y从上向下。
  • TMS:开源产品的标准,Z的定义与谷歌相同;XY的原点在左下角,X从左向右,Y从下向上。
  • QuadTree:微软Bing地图使用的编码规范,Z的定义与谷歌相同,同一层级的瓦片不用XY两个维度表示,而只用一个整数表示,该整数服从四叉树编码规则
  • 百度XYZ:Z从1开始,在最高级就把地图分为四块瓦片;XY的原点在经度为0纬度位0的位置,X从左向右,Y从下向上。
地图商 瓦片编码
高德地图 谷歌XYZ
谷歌地图 谷歌XYZ
OpenStreetMap 谷歌XYZ
腾讯地图 TMS
Bing地图 QuadTree
百度地图 百度XYZ

谷歌地图坐标转换公式

经纬度坐标(lon_deg, lat_rad)转瓦片坐标(xtile, ytile):

n = 2 ^ zoom
xtile = n * ((lon_deg + 180) / 360)
ytile = n * (1 - (log(tan(lat_rad) + sec(lat_rad)) / π)) / 2

python代码实现:

import math
def deg2num(lat_deg, lon_deg, zoom):
  lat_rad = math.radians(lat_deg)
  n = 2.0 ** zoom
  xtile = int((lon_deg + 180.0) / 360.0 * n)
  ytile = int((1.0 - math.asinh(math.tan(lat_rad)) / math.pi) / 2.0 * n)
  return (xtile, ytile)

瓦片坐标(xtile, ytile)转经纬度坐标(lon_deg, lat_rad):

n = 2 ^ zoom
lon_deg = xtile / n * 360.0 - 180.0
lat_rad = arctan(sinh(π * (1 - 2 * ytile / n)))
lat_deg = lat_rad * 180.0 / π

python代码实现:

import math
def num2deg(xtile, ytile, zoom):
  n = 2.0 ** zoom
  lon_deg = xtile / n * 360.0 - 180.0
  lat_rad = math.atan(math.sinh(math.pi * (1 - 2 * ytile / n)))
  lat_deg = math.degrees(lat_rad)
  return (lat_deg, lon_deg)

代码参考
Slippy map tilenames

介绍参考
瓦片坐标系学习笔记(ps. 该篇文章所列转换公式根据实际操作验证有误,以上篇参考文章中的公式为准)

猜你喜欢

转载自blog.csdn.net/a914541185/article/details/108076506