百度地图和高德地图的侧重点不太一样。同样一个地名,在百度地图网站上搜索到的地点可能是商业网点,在高德地图网站上搜索到的地点可能是自然行政地点。
高德地图api
在高德地图中,搜索地名,如“乱石头川”,该地名会出现这样的链接
https://ditu.amap.com/place/B0FFGXCDLJ
这个高德地图连接中最后的“B0FFGXCDLJ”是什么意思?如何转化为经纬度坐标
在高德地图的链接中,B0FFGXCDLJ
是一个 地点的唯一标识符(POI ID),用于标识地图上的某个特定地点。它并不是直接的经纬度信息,而是高德地图内部用于定位和检索地点的编码。
如何将 POI ID 转换为经纬度坐标
要将 POI ID 转换为经纬度坐标,可以通过高德地图的 API 来实现。高德地图提供了丰富的API接口,其中 地理编码API 和 逆地理编码API 可以用于查询地点的详细信息,包括经纬度。
以下是一个使用 Python 和高德地图API将 POI ID 转换为经纬度坐标的示例代码:
import requests
# 高德地图API的Key(需要在高德地图开放平台申请)
AMAP_API_KEY = "你的API_KEY"
# POI ID
poi_id = "B0FFGXCDLJ"
# 高德地图的POI详情查询API
url = f"https://www.amap.com/detail/get/{poi_id}"
# 发起请求
response = requests.get(url, params={"key": AMAP_API_KEY})
data = response.json()
# 解析经纬度信息
if data.get("status") == "1" and data.get("info") == "OK":
location = data["data"]["spec"]["location"]
longitude, latitude = map(float, location.split(","))
print(f"提取的经纬度信息:经度 = {longitude}, 纬度 = {latitude}")
else:
print("无法获取经纬度信息,请检查POI ID或API Key是否正确。")
代码说明
API Key:需要在高德地图开放平台(https://lbs.amap.com/)注册账号并申请一个API Key。
API 请求:通过 https://www.amap.com/detail/get/{poi_id} 接口查询POI的详细信息。
解析数据:从返回的JSON数据中提取经纬度信息。location 字段通常包含经纬度,格式为“经度,纬度”。
在高德开放平台中,有如下功能。
坐标拾取器 | 高德地图API
示例运行
假设你已经申请了API Key并将其替换到代码中的 AMAP_API_KEY,运行代码后,输出结果可能如下:
提取的经纬度信息:经度 = 116.397428, 纬度 = 39.90923
注意事项
API Key 限制:高德地图API Key有调用次数限制,免费额度通常足够个人使用,但大量请求可能需要付费。
数据准确性:返回的经纬度信息是高德地图数据库中的数据,可能与实际位置有细微偏差。
错误处理:在实际使用中,建议添加更详细的错误处理逻辑,以应对网络请求失败、API Key无效等情况。
在拾取经纬点的时候,要选择合适的城市,防止异地重名。如下所示:
高德地图的坐标系是基于GCJ-02(火星坐标系),而WGS-84是国际上常用的地理坐标系。将高德地图的坐标转换为WGS-84坐标需要进行坐标转换。以下是一个简单的Python代码示例,使用了pyproj库来完成坐标转换。
坐标系的差异:高德地图的坐标系(GCJ-02)和WGS-84坐标系存在一定的偏差。简单的投影转换可能无法完全消除这种偏差,尤其是在高精度要求的场景中。
更精确的转换:如果需要更精确的转换,可以考虑使用专门的算法(如高斯投影反算)或调用高德地图提供的API进行转换。
代码如下:
import math
# 定义常量
PI = math.pi
A = 6378245.0
EE = 0.00669342162296594323
X_PI = PI * 3000.0 / 180.0
def transformlat(lng, lat):
ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * math.sqrt(math.fabs(lng))
ret += (20.0 * math.sin(6.0 * lng * PI) + 20.0 * math.sin(2.0 * lng * PI)) * 2.0 / 3.0
ret += (20.0 * math.sin(lat * PI) + 40.0 * math.sin(lat / 3.0 * PI)) * 2.0 / 3.0
ret += (160.0 * math.sin(lat / 12.0 * PI) + 320 * math.sin(lat * PI / 30.0)) * 2.0 / 3.0
return ret
def transformlng(lng, lat):
ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * math.sqrt(math.fabs(lng))
ret += (20.0 * math.sin(6.0 * lng * PI) + 20.0 * math.sin(2.0 * lng * PI)) * 2.0 / 3.0
ret += (20.0 * math.sin(lng * PI) + 40.0 * math.sin(lng / 3.0 * PI)) * 2.0 / 3.0
ret += (150.0 * math.sin(lng / 12.0 * PI) + 300.0 * math.sin(lng / 30.0 * PI)) * 2.0 / 3.0
return ret
def out_of_china(lng, lat):
return not (73.66 < lng < 135.05 and 3.86 < lat < 53.55)
def gcj02_to_wgs84(gcj_lng, gcj_lat):
if out_of_china(gcj_lng, gcj_lat):
return gcj_lng, gcj_lat # 不在中国范围内,直接返回原坐标
dlat = transformlat(gcj_lng - 105.0, gcj_lat - 35.0)
dlng = transformlng(gcj_lng - 105.0, gcj_lat - 35.0)
radlat = gcj_lat / 180.0 * PI
magic = math.sin(radlat)
magic = 1 - EE * magic * magic
sqrtmagic = math.sqrt(magic)
dlat = (dlat * 180.0) / ((A * (1 - EE)) / (magic * sqrtmagic) * PI)
dlng = (dlng * 180.0) / (A / sqrtmagic * math.cos(radlat) * PI)
mglat = gcj_lat + dlat
mglng = gcj_lng + dlng
wgs84_lng = gcj_lng * 2 - mglng
wgs84_lat = gcj_lat * 2 - mglat
return wgs84_lng, wgs84_lat
# 示例:高德地图的经纬度
while True:
gcInfo=input("请输入高德坐标信息:")
gcList=gcInfo.split(",")
gcj_lng = float(gcList[0]) # 经度
gcj_lat = float(gcList[1]) # 纬度
# 转换为WGS-84坐标
wgs84_lng, wgs84_lat = gcj02_to_wgs84(gcj_lng, gcj_lat)
print(f"高德地图坐标(GCJ-02): 经度={gcj_lng}, 纬度={gcj_lat}")
print(f"WGS-84坐标: 经度={wgs84_lng}, 纬度={wgs84_lat}")
即可完成。
百度地图api
百度地图点线面查询 api huiyan,网站如下:
https://huiyan.baidu.com/github/tools/coord/
在该网站上,可以选择一个点,然后知道其经纬度坐标和墨卡托坐标。
但是需要注意如下:
# * 各地图API坐标系统比较与转换;
# * WGS84坐标系:即地球坐标系,国际上通用的坐标系。设备一般包含GPS芯片或者北斗芯片获取的经纬度为WGS84地理坐标系,
# * 谷歌地图采用的是WGS84地理坐标系(中国范围除外);
# * GCJ02坐标系:即火星坐标系,是由中国国家测绘局制订的地理信息系统的坐标系统。由WGS84坐标系经加密后的坐标系。谷歌中国地图和搜搜中国地图采用的是GCJ02地理坐标系;
# * 3BD09坐标系:即百度坐标系,GCJ02坐标系经加密后的坐标系;
所以,要想把百度地图上的经纬度点转换为Arcgis底图中的坐标点,还需要进行解密,将3BD09坐标系的坐标位置还原为WGS84地理坐标系的坐标位置。代码如下
import math
from decimal import *
# -*- coding: utf-8 -*-
# /**
# * 各地图API坐标系统比较与转换;
# * WGS84坐标系:即地球坐标系,国际上通用的坐标系。设备一般包含GPS芯片或者北斗芯片获取的经纬度为WGS84地理坐标系,
# * 谷歌地图采用的是WGS84地理坐标系(中国范围除外);
# * GCJ02坐标系:即火星坐标系,是由中国国家测绘局制订的地理信息系统的坐标系统。由WGS84坐标系经加密后的坐标系。谷歌中国地图和搜搜中国地图采用的是GCJ02地理坐标系;
# * 3BD09坐标系:即百度坐标系,GCJ02坐标系经加密后的坐标系;
# */
import math
from decimal import *
class transfer:
def __init__(self,key=None):
self.a=6378245.0
self.ee=Decimal(0.00669342162296594323)
def transformLng(self,x,y):
ret=Decimal()
ret = 300.0+x+2.0*y+0.1*x*x+0.1*x*y+0.1*math.sqrt(math.fabs(x))
ret += (20.0 * math.sin(6.0 * x * math.pi) + 20.0 * math.sin(2.0 * x * math.pi)) * 2.0 / 3.0
ret += (20.0 * math.sin(x * math.pi) + 40.0 * math.sin(x / 3.0 * math.pi)) * 2.0 / 3.0
ret += (150.0 * math.sin(x / 12.0 * math.pi) + 300.0 * math.sin(x / 30.0* math.pi)) * 2.0 / 3.0
return ret
def transformLat(self,x,y):
ret = Decimal()
ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y+ 0.2 * math.sqrt(math.fabs(x))
ret += (20.0 * math.sin(6.0 * x * math.pi) + 20.0 * math.sin(2.0 * x * math.pi)) * 2.0 / 3.0
ret += (20.0 * math.sin(y * math.pi) + 40.0 * math.sin(y / 3.0 * math.pi)) * 2.0 / 3.0
ret += (160.0 * math.sin(y / 12.0 * math.pi) + 320 * math.sin(y * math.pi / 30.0)) * 2.0 / 3.0
return ret
def transfrom(self,lng,lat):
dLat = self.transformLat(lng - 105.0, lat - 35.0)
dLng = self.transformLng(lng - 105.0, lat - 35.0)
radLat = lat / 180.0 * math.pi
magic = math.sin(radLat)
magic = 1 - self.ee * Decimal(magic) * Decimal(magic)
sqrtMagic = math.sqrt(magic)
dLat = Decimal((dLat * 180.0)) / ((Decimal(self.a) * (1 - self.ee)) / (Decimal(magic) * Decimal(sqrtMagic)) * Decimal(math.pi))
dLng = (dLng * 180.0) / (self.a / sqrtMagic * math.cos(radLat) * math.pi)
mgLat = lat + float(dLat)
mgLng = lng + dLng
return mgLng,mgLat
#gps坐标转换为gcj02坐标系
def wg84_to_gcj02(self,wg84_lng,wg84_lat):
dLat=self.transformLat(wg84_lng-105.0,wg84_lat-35.0)
dLng=self.transformLng(wg84_lng-105.0,wg84_lat-35.0)
radLat = wg84_lat / 180.0 * math.pi
magic = math.sin(radLat)
magic = 1 - self.ee * Decimal(magic) * Decimal(magic)
sqrtMagic = math.sqrt(magic)
dLat = Decimal((dLat * 180.0)) / ((Decimal(self.a) * (1 - self.ee)) / (Decimal(magic) * Decimal(sqrtMagic)) * Decimal(math.pi))
dLng = (dLng * 180.0) / (self.a / sqrtMagic * math.cos(radLat) * math.pi)
gcj02Lat = wg84_lat + float(dLat)
gcj02Lng = wg84_lng + dLng
return gcj02Lng,gcj02Lat
#gcj02坐标转百度坐标
def gcj02_to_bd09(self,gcj02_lng,gcj02_lat):
x = gcj02_lng
y = gcj02_lat
z = math.sqrt(x * x + y * y) + 0.00002 * math.sin(y * math.pi)
theta = math.atan2(y, x) + 0.000003 * math.cos(x * math.pi)
bd09_Lng = z * math.cos(theta) + 0.0065
bd09_Lat = z * math.sin(theta) + 0.006
return bd09_Lng,bd09_Lat
#wg84坐标转百度坐标
def wg84_to_bd09(self,wg84_lng,wg84_lat):
gcj02lng,gcj02lat=self.wg84_to_gcj02(wg84_lng,wg84_lat)
return self.gcj02_to_bd09(gcj02lng,gcj02lat)
#百度坐标转GCJ02坐标
def bd09_to_gcj02(self,bd09_lng,bd09_lat):
x = bd09_lng - 0.0065
y = bd09_lat - 0.006
z = math.sqrt(x * x + y * y) - 0.00002 * math.sin(y * math.pi)
theta = math.atan2(y, x) - 0.000003 * math.cos(x * math.pi)
gcj02_lng = z * math.cos(theta)
gcj02_lat = z * math.sin(theta)
return gcj02_lng,gcj02_lat
#GCJ坐标转WG84坐标
def gcj02_to_wg84(self,gcj02_lng,gcj02_lat):
mlng,mlat=self.transfrom(gcj02_lng,gcj02_lat)
wg84_Lng=gcj02_lng*2-mlng
wg84_Lat=gcj02_lat*2-mlat
return wg84_Lng,wg84_Lat
#将百度坐标转WG84坐标
def bd09_to_wg84(self,bd09_lng,bd09_lat):
gcj02_lng, gcj02_lat=self.bd09_to_gcj02(bd09_lng,bd09_lat)
return self.gcj02_to_wg84(gcj02_lng,gcj02_lat)
tr=transfer()
#测试,转换正确
#循环输入坐标信息
while True:
xyInfo=input("请输入百度坐标信息:")
xyList=xyInfo.split(",")
bd09_lng=float(xyList[0])
bd09_lat=float(xyList[1])
#输出 百度坐标转WG84坐标
print("百度坐标信息:")
print(bd09_lng)
print(bd09_lat)
print("WGS坐标信息")
print(tr.bd09_to_wg84(bd09_lng,bd09_lat)[0])
print(tr.bd09_to_wg84(bd09_lng,bd09_lat)[1])
print()
即可转换完成。
综合代码
根据以上分析,总的代码如下:
choice=input("请选择高德坐标G 或者百度坐标B:")
choice=choice.upper()
if choice=="B":
import math
from decimal import *
# -*- coding: utf-8 -*-
# /**
# * 各地图API坐标系统比较与转换;
# * WGS84坐标系:即地球坐标系,国际上通用的坐标系。设备一般包含GPS芯片或者北斗芯片获取的经纬度为WGS84地理坐标系,
# * 谷歌地图采用的是WGS84地理坐标系(中国范围除外);
# * GCJ02坐标系:即火星坐标系,是由中国国家测绘局制订的地理信息系统的坐标系统。由WGS84坐标系经加密后的坐标系。谷歌中国地图和搜搜中国地图采用的是GCJ02地理坐标系;
# * 3BD09坐标系:即百度坐标系,GCJ02坐标系经加密后的坐标系;
# */
import math
from decimal import *
class transfer:
def __init__(self,key=None):
self.a=6378245.0
self.ee=Decimal(0.00669342162296594323)
def transformLng(self,x,y):
ret=Decimal()
ret = 300.0+x+2.0*y+0.1*x*x+0.1*x*y+0.1*math.sqrt(math.fabs(x))
ret += (20.0 * math.sin(6.0 * x * math.pi) + 20.0 * math.sin(2.0 * x * math.pi)) * 2.0 / 3.0
ret += (20.0 * math.sin(x * math.pi) + 40.0 * math.sin(x / 3.0 * math.pi)) * 2.0 / 3.0
ret += (150.0 * math.sin(x / 12.0 * math.pi) + 300.0 * math.sin(x / 30.0* math.pi)) * 2.0 / 3.0
return ret
def transformLat(self,x,y):
ret = Decimal()
ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y+ 0.2 * math.sqrt(math.fabs(x))
ret += (20.0 * math.sin(6.0 * x * math.pi) + 20.0 * math.sin(2.0 * x * math.pi)) * 2.0 / 3.0
ret += (20.0 * math.sin(y * math.pi) + 40.0 * math.sin(y / 3.0 * math.pi)) * 2.0 / 3.0
ret += (160.0 * math.sin(y / 12.0 * math.pi) + 320 * math.sin(y * math.pi / 30.0)) * 2.0 / 3.0
return ret
def transfrom(self,lng,lat):
dLat = self.transformLat(lng - 105.0, lat - 35.0)
dLng = self.transformLng(lng - 105.0, lat - 35.0)
radLat = lat / 180.0 * math.pi
magic = math.sin(radLat)
magic = 1 - self.ee * Decimal(magic) * Decimal(magic)
sqrtMagic = math.sqrt(magic)
dLat = Decimal((dLat * 180.0)) / ((Decimal(self.a) * (1 - self.ee)) / (Decimal(magic) * Decimal(sqrtMagic)) * Decimal(math.pi))
dLng = (dLng * 180.0) / (self.a / sqrtMagic * math.cos(radLat) * math.pi)
mgLat = lat + float(dLat)
mgLng = lng + dLng
return mgLng,mgLat
#gps坐标转换为gcj02坐标系
def wg84_to_gcj02(self,wg84_lng,wg84_lat):
dLat=self.transformLat(wg84_lng-105.0,wg84_lat-35.0)
dLng=self.transformLng(wg84_lng-105.0,wg84_lat-35.0)
radLat = wg84_lat / 180.0 * math.pi
magic = math.sin(radLat)
magic = 1 - self.ee * Decimal(magic) * Decimal(magic)
sqrtMagic = math.sqrt(magic)
dLat = Decimal((dLat * 180.0)) / ((Decimal(self.a) * (1 - self.ee)) / (Decimal(magic) * Decimal(sqrtMagic)) * Decimal(math.pi))
dLng = (dLng * 180.0) / (self.a / sqrtMagic * math.cos(radLat) * math.pi)
gcj02Lat = wg84_lat + float(dLat)
gcj02Lng = wg84_lng + dLng
return gcj02Lng,gcj02Lat
#gcj02坐标转百度坐标
def gcj02_to_bd09(self,gcj02_lng,gcj02_lat):
x = gcj02_lng
y = gcj02_lat
z = math.sqrt(x * x + y * y) + 0.00002 * math.sin(y * math.pi)
theta = math.atan2(y, x) + 0.000003 * math.cos(x * math.pi)
bd09_Lng = z * math.cos(theta) + 0.0065
bd09_Lat = z * math.sin(theta) + 0.006
return bd09_Lng,bd09_Lat
#wg84坐标转百度坐标
def wg84_to_bd09(self,wg84_lng,wg84_lat):
gcj02lng,gcj02lat=self.wg84_to_gcj02(wg84_lng,wg84_lat)
return self.gcj02_to_bd09(gcj02lng,gcj02lat)
#百度坐标转GCJ02坐标
def bd09_to_gcj02(self,bd09_lng,bd09_lat):
x = bd09_lng - 0.0065
y = bd09_lat - 0.006
z = math.sqrt(x * x + y * y) - 0.00002 * math.sin(y * math.pi)
theta = math.atan2(y, x) - 0.000003 * math.cos(x * math.pi)
gcj02_lng = z * math.cos(theta)
gcj02_lat = z * math.sin(theta)
return gcj02_lng,gcj02_lat
#GCJ坐标转WG84坐标
def gcj02_to_wg84(self,gcj02_lng,gcj02_lat):
mlng,mlat=self.transfrom(gcj02_lng,gcj02_lat)
wg84_Lng=gcj02_lng*2-mlng
wg84_Lat=gcj02_lat*2-mlat
return wg84_Lng,wg84_Lat
#将百度坐标转WG84坐标
def bd09_to_wg84(self,bd09_lng,bd09_lat):
gcj02_lng, gcj02_lat=self.bd09_to_gcj02(bd09_lng,bd09_lat)
return self.gcj02_to_wg84(gcj02_lng,gcj02_lat)
tr=transfer()
#测试,转换正确
#循环输入坐标信息
while True:
xyInfo=input("请输入百度坐标信息:")
xyList=xyInfo.split(",")
bd09_lng=float(xyList[0])
bd09_lat=float(xyList[1])
#输出 百度坐标转WG84坐标
print("百度坐标信息:")
elif choice=="G":
import math
# 定义常量
PI = math.pi
A = 6378245.0
EE = 0.00669342162296594323
X_PI = PI * 3000.0 / 180.0
def transformlat(lng, lat):
ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * math.sqrt(math.fabs(lng))
ret += (20.0 * math.sin(6.0 * lng * PI) + 20.0 * math.sin(2.0 * lng * PI)) * 2.0 / 3.0
ret += (20.0 * math.sin(lat * PI) + 40.0 * math.sin(lat / 3.0 * PI)) * 2.0 / 3.0
ret += (160.0 * math.sin(lat / 12.0 * PI) + 320 * math.sin(lat * PI / 30.0)) * 2.0 / 3.0
return ret
def transformlng(lng, lat):
ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * math.sqrt(math.fabs(lng))
ret += (20.0 * math.sin(6.0 * lng * PI) + 20.0 * math.sin(2.0 * lng * PI)) * 2.0 / 3.0
ret += (20.0 * math.sin(lng * PI) + 40.0 * math.sin(lng / 3.0 * PI)) * 2.0 / 3.0
ret += (150.0 * math.sin(lng / 12.0 * PI) + 300.0 * math.sin(lng / 30.0 * PI)) * 2.0 / 3.0
return ret
def out_of_china(lng, lat):
return not (73.66 < lng < 135.05 and 3.86 < lat < 53.55)
def gcj02_to_wgs84(gcj_lng, gcj_lat):
if out_of_china(gcj_lng, gcj_lat):
return gcj_lng, gcj_lat # 不在中国范围内,直接返回原坐标
dlat = transformlat(gcj_lng - 105.0, gcj_lat - 35.0)
dlng = transformlng(gcj_lng - 105.0, gcj_lat - 35.0)
radlat = gcj_lat / 180.0 * PI
magic = math.sin(radlat)
magic = 1 - EE * magic * magic
sqrtmagic = math.sqrt(magic)
dlat = (dlat * 180.0) / ((A * (1 - EE)) / (magic * sqrtmagic) * PI)
dlng = (dlng * 180.0) / (A / sqrtmagic * math.cos(radlat) * PI)
mglat = gcj_lat + dlat
mglng = gcj_lng + dlng
wgs84_lng = gcj_lng * 2 - mglng
wgs84_lat = gcj_lat * 2 - mglat
return wgs84_lng, wgs84_lat
# 示例:高德地图的经纬度
while True:
gcInfo=input("请输入高德坐标信息:")
gcList=gcInfo.split(",")
gcj_lng = float(gcList[0]) # 经度
gcj_lat = float(gcList[1]) # 纬度
# 转换为WGS-84坐标
wgs84_lng, wgs84_lat = gcj02_to_wgs84(gcj_lng, gcj_lat)
print(f"高德地图坐标(GCJ-02): 经度={gcj_lng}, 纬度={gcj_lat}")
print(f"WGS-84坐标: 经度={wgs84_lng}, 纬度={wgs84_lat}")
print(bd09_lng)
print(bd09_lat)
print("WGS坐标信息")
print(tr.bd09_to_wg84(bd09_lng,bd09_lat)[0])
print(tr.bd09_to_wg84(bd09_lng,bd09_lat)[1])
print()
即可完成。
一日一图
代码如下:
import turtle as t
# 设置画布
t.speed('fastest') # 设置绘图速度
t.hideturtle() # 隐藏海龟图标
t.bgcolor('black') # 设置背景颜色
# 绘制时空隧道
i = 0
while i < 235:
t.pencolor('cyan') # 设置画笔颜色为青色
t.penup() # 提起画笔
t.goto(0, 0) # 移动到中心点
t.forward(200) # 向前移动200单位
t.pendown() # 放下画笔
t.circle(100) # 绘制半径为100的圆
t.left(2) # 左转2度
i += 1
# 结束绘图
t.done()
-
设置画布:设置背景颜色为黑色,隐藏海龟图标,设置绘图速度为最快。
-
绘制时空隧道:通过循环绘制多个圆形,每次绘制后稍微左转,形成螺旋效果。
-
颜色选择:使用青色(
cyan
)作为画笔颜色,以增强未来感。 -
循环次数:循环多次,每次绘制一个圆形并左转2度,形成螺旋状的时空隧道效果。
生成图片如下: