经纬度绘图_用编程赋能工作系列——百度VS高德经纬度互转
上一篇?jiǎng)倢W(xué)會(huì)了如何獲取地址所在經(jīng)緯度以及經(jīng)緯度對(duì)應(yīng)地址,于是信心滿滿的準(zhǔn)備在老板面前露一手,準(zhǔn)備花點(diǎn)心思做個(gè)漂亮的可視化地圖放在報(bào)告亮眼的位置。
當(dāng)?shù)貓D跑出來(lái)的那一刻頓時(shí)傻眼了,臥槽這些點(diǎn)定位的位置明顯不對(duì)呀,酒店直定位到湖里了,這讓老板看到你說(shuō)后果嚴(yán)重不。
其實(shí)是因?yàn)榘俣鹊貓D的經(jīng)緯度和高德地圖經(jīng)緯度所使用的坐標(biāo)系編碼不同,所以如果你制圖的軟件或平臺(tái)是基于高德地圖服務(wù)的話,那么就需要使用對(duì)應(yīng)的高德標(biāo)準(zhǔn)的經(jīng)緯度來(lái)進(jìn)行繪圖,同理如果你用的服務(wù)是基于百度地圖的,必須使用百度標(biāo)準(zhǔn)的經(jīng)緯度坐標(biāo),如果拿到的是高德坐標(biāo)則必須經(jīng)過(guò)算法轉(zhuǎn)為百度標(biāo)準(zhǔn)。
今天這篇內(nèi)容就給大家分享如何使用R和Python對(duì)百度坐標(biāo)系和高德坐標(biāo)系的經(jīng)緯度進(jìn)行互轉(zhuǎn),解決地圖繪制最后一道坎兒。
內(nèi)容同樣是兩個(gè)模塊四小節(jié),使用R語(yǔ)言和Python分別進(jìn)行百度經(jīng)緯度轉(zhuǎn)高德經(jīng)緯度以及高德標(biāo)準(zhǔn)轉(zhuǎn)百度,這樣我們?cè)诮?jīng)緯度獲取和轉(zhuǎn)化處理上的技能掌握就比較系統(tǒng)了,不會(huì)再受制于工具和平臺(tái)服務(wù)的標(biāo)準(zhǔn)差異而苦惱。
一、R語(yǔ)言方案
1)百度經(jīng)緯度轉(zhuǎn)騰訊&高德
library("leaflet") library('baidumap') library('ggplot2') library('ggmap')dt1 <- read.table(pipe("pbpaste"), sep="t", header=T,stringsAsFactors =FALSE) #百度轉(zhuǎn)騰訊&高德 bMapTransQQMap <- function (lng,lat) {x_pi = 3.14159265358979324 * 3000.0 /180.0x = lng - 0.0065y = lat - 0.006z = sqrt(x^2 + y^2) - 0.00002 * sin(y * x_pi)theta = atan2(y,x) - 0.000003 * cos(x * x_pi)lngs = z * cos(theta)lats = z * sin(theta)return(data.frame(lng,lat,lngs,lats)) }result <- bMapTransQQMap(dt1$lon,dt1$lat)使用高德地圖服務(wù)來(lái)呈現(xiàn)百度坐標(biāo)系下的經(jīng)緯度,可以看到偏移量非常明顯。
leaflet(result) %>% setView(116.2938,40.00939, zoom = 13) %>%addTiles('http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}',tileOptions(tileSize=256, minZoom=9, maxZoom=17),group="高德地圖") %>%addCircleMarkers(lng = ~ lng,lat = ~lat,stroke = FALSE,fillOpacity = 1,radius =8)使用高德地圖服務(wù)來(lái)呈現(xiàn)經(jīng)百度坐標(biāo)系轉(zhuǎn)換高德坐標(biāo)系后的經(jīng)緯度,可以看到位置基本已經(jīng)還原了。
leaflet(result) %>% setView(116.2938,40.00939, zoom = 13) %>%addTiles('http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}',tileOptions(tileSize=256, minZoom=9, maxZoom=17),group="高德地圖") %>%addCircleMarkers(lng = ~ lngs,lat = ~lats,stroke = FALSE,fillOpacity = 1,radius =8)2)高德坐標(biāo)系轉(zhuǎn)百度坐標(biāo)系
# 騰訊&高德地圖轉(zhuǎn)百度 qqMapTransBMap <- function(lngs,lats){x_pi = 3.14159265358979324 * 3000.0 / 180.0x = lngs y = lats z = sqrt(x^2 + y^2) + 0.00002 * sin(y * x_pi)theta = atan2(y,x) + 0.000003 * cos(x * x_pi)lng_b = z * cos(theta) + 0.0065lat_b = z * sin(theta) + 0.006 return(data.frame(lngs,lats,lng_b,lat_b)) } result_b <- qqMapTransBMap(result$lngs,result$lats)使用百度地圖服務(wù)呈現(xiàn)高德坐標(biāo)系下的經(jīng)緯度,偏移情況仍然很嚴(yán)重。
options(baidumap.key = '***************') # 這里啟用的baidumap服務(wù),后臺(tái)調(diào)用百度地圖api, # 需要使用百度api開(kāi)發(fā)秘鑰,需自己申請(qǐng) bjMap <- getBaiduMap(location = c(116.284028,40.001732), width = 800, height =800, zoom = 16, scale = 2 , messaging = TRUE) ggmap(bjMap) + geom_point(data = result_b, aes(x = lngs, y = lats),shape = 21 , col = 'white',fill = 'red',size = 5) +theme_nothing()使用百度地圖服務(wù)呈現(xiàn)經(jīng)高德坐標(biāo)系轉(zhuǎn)百度坐標(biāo)系后的經(jīng)緯度,可以看到為止基本已經(jīng)還原到真實(shí)位置,誤差相對(duì)較小。
ggmap(bjMap) + geom_point(data = result_b, aes(x = lng_b, y = lat_b),shape = 21 , col = 'white',fill = 'red',size = 5) +theme_nothing()二、Python實(shí)現(xiàn)方案
3)百度坐標(biāo)系轉(zhuǎn)高德坐標(biāo)系
import pandas as pd import numpy as np import folium from folium import plugins df=pd.read_clipboard() def bMapTransQQMap(lng,lat):x_pi = 3.14159265358979324 * 3000.0 /180.0x = np.array(lng) - 0.0065y = np.array(lat) - 0.006z = np.sqrt(np.power(x,2) + np.power(y,2)) - 0.00002 * np.sin(y * x_pi)theta = np.arctan2(y,x) - 0.000003 * np.cos(x * x_pi)lngs = z * np.cos(theta)lats = z * np.sin(theta)return(pd.DataFrame({'lng':lng,'lat':lat,'lngs':lngs,'lats':lats})) result = bMapTransQQMap(df['lon'],df['lat'])使用folium庫(kù)(底層調(diào)用leaflet服務(wù))結(jié)合高德地圖服務(wù)來(lái)呈現(xiàn)百度標(biāo)準(zhǔn)的的經(jīng)緯度,誤差依然很大。
lng = np.array(result["lng"],dtype=float) lat = np.array(result["lat"],dtype=float) data1 = [(lat[i],lng[i]) for i in range(len(result))]map_osm = folium.Map(location=[39.996710,116.281012],zoom_start=115,tiles='http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}',attr="© <a href="http://ditu.amap.com/">高德地圖</a>") marker_cluster = plugins.MarkerCluster().add_to(map_osm) for i in data1:folium.Marker(i).add_to(marker_cluster) display(map_osm)百度坐標(biāo)系經(jīng)轉(zhuǎn)化為高德坐標(biāo)系之后,位置的精確度基本還原,明顯改善。
lng = np.array(result["lngs"],dtype=float) lat = np.array(result["lats"],dtype=float) data2 = [(lat[i],lng[i]) for i in range(len(result))]map_osm = folium.Map(location=[39.996710,116.281012],zoom_start=115,tiles='http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}',attr="© <a href='http://ditu.amap.com/'>高德地圖</a>") marker_cluster = plugins.MarkerCluster().add_to(map_osm) for i in data2:folium.Marker(i).add_to(marker_cluster) display(map_osm)4)高德坐標(biāo)系轉(zhuǎn)百度坐標(biāo)系
#騰訊&高德地圖轉(zhuǎn)百度 def qqMapTransBMap(lngs,lats):x_pi = 3.14159265358979324 * 3000.0 / 180.0x = np.array(lngs)y = np.array(lats )z = np.sqrt(np.power(x,2) + np.power(y,2)) + 0.00002 * np.sin(y * x_pi)theta = np.arctan2(y,x) + 0.000003 * np.cos(x * x_pi)lng_b = z * np.cos(theta) + 0.0065lat_b = z * np.sin(theta) + 0.006 return(pd.DataFrame({'lngs':lngs,'lats':lats,'lng_b':lng_b,'lat_b':lat_b}))result2 = qqMapTransBMap(result['lngs'],result['lats'])至此,兩種技術(shù)方案下的所有類型轉(zhuǎn)換均以搞定,雖然至今還沒(méi)明白算法里面的具體參數(shù)到底是啥意思,只是照葫蘆畫(huà)瓢把一篇博客上的java代碼翻譯了過(guò)來(lái)(再次感謝原作者提供的java代碼),不過(guò)原理不懂沒(méi)有關(guān)系,語(yǔ)法能看懂就OK了。
參考資料:
https://www.cnblogs.com/wrld/p/10845870.html
總結(jié)
以上是生活随笔為你收集整理的经纬度绘图_用编程赋能工作系列——百度VS高德经纬度互转的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: ZZULIOJ 1066:字符分类统计
- 下一篇: OJ1050: 阶乘的累加和(C语言实现