library(reticulate)
library(sf)
location<- substr(getwd(),1,4)
# 调用Pyhton脚本连接 Neo4j, Neo4j的官方Python Driver比开源R Driver好用。
if (location != '/srv'){ # Rstudio 开发环境
part<- '~'
}else{ # 服务器部署环境
part<- '..'
}
path<- paste(part,"/scripts/","test_GeoCode.py",sep="")
#使用指定的Conda虚拟环境"openai"运行Python程序
use_condaenv(condaenv="base", conda = "/usr/lib64/anaconda3/bin/conda", required = TRUE)
t1<-proc.time()
source_python(path)
t2<-proc.time()
cat(t2-t1);cat("\n")
# 1.天地图 提供的是静态地图及标注夫妇,不是其它地图的地图调起API
TDURL_mask<- function (location,address, application_key){
url_a <- 'http://api.tianditu.gov.cn/staticimage? width=1024&height=1024&zoom=18&layers=vec_c,cva_c'
url_b <- paste("¢er=", location, "&markers=", location, "&markerStyles=-1,,", address, sep="")
url_c <- paste('&tk=', application_key, sep="")
URL <- URLencode(paste(url_a, url_b, url_c, sep=""))
# cat(URL)
# browseURL(URL)
return (URL)
}
# 2.腾讯地图
TxURL_mask<- function(location, address){
url_a <- 'https://apis.map.qq.com/uri/v1/marker?marker=coord:'
url_b <- paste(location, ";title:", address, ";addr:", address, sep="")
url_c <- '&ref=myapp'
URL <- URLencode(paste(url_a, url_b, url_c, sep=""))
# cat(URL)
# browseURL(URL)
return (URL)
}
# 3.高德地图
GaoDeURL_mask<- function(location, address){
url_a <- 'https://uri.amap.com/marker'
url_b <- paste("?markers=", location, ",", address, sep="")
url_c <- '&src=mypage&callnative=0'
URL <- URLencode(paste(url_a, url_b, url_c, sep=""))
# cat(URL)
# browseURL(URL)
return (URL)
}
# 4.百度地图
BaiDuURL_mask<- function(location, address){
url_a <- 'http://api.map.baidu.com/marker'
url_b <- paste("?location=", location, "&title=", address, "&content=", address, sep="")
url_c = '&output=html&src=webapp.baidu.openAPIdemo&zoom=20'
URL <- URLencode(paste(url_a, url_b, url_c, sep=""))
# cat(URL)
# browseURL(URL)
return (URL)
}
# 读取 GeoJSON 文件
gdf <- st_read('/home/jean/data/MapGDXZJD2014.json') # 替换为你的文件路径
# embed iframe inside shiny app
# https://stackoverflow.com/questions/33020558/embed-iframe-inside-shiny-app/33021018#33021018
shinyServer(function(input, output, session) {
vendor<- reactive({
input$vendor
})
address<- reactive({
input$address
})
observe({
print(vendor())
print(address())
})
lnglat<- reactive({
if (vendor()=='天地图')
TDGeoCode(address())
else if (vendor()=='腾讯')
TXGeoCode(address())
else if (vendor()=='高德')
GDGeoCode(address())
else if (vendor()=='百度')
BDGeoCode(address())
})
wgslnglat<- reactive({
tryCatch({
lng<- as.numeric(lnglat()[[1]])
lat<- as.numeric(lnglat()[[2]])
if (vendor()=='腾讯')
wgslocation<- geoChina::gcj2wgs(lat,lng)
else if (vendor()=='高德')
wgslocation<- geoChina::gcj2wgs(lat,lng)
else if (vendor()=='百度')
wgslocation<- geoChina::bd2wgs(lat,lng)
if (vendor()!='天地图')
wgslocation<- list(round(wgslocation[[2]],6),round(wgslocation[[1]],6))
else
wgslocation<- lnglat()
}, error = function(e){
print(e$message)
wgslocation<- list(NULL,NULL)
})
})
xzjd<-reactive({
tryCatch({
# 用WGS 84坐标
loaction<- wgslnglat()
# 创建一个坐标点
point <- st_point(c(loaction[[1]] , loaction[[2]])) # 经度在前,纬度在后
point_sf <- st_sfc(point, crs = st_crs(gdf))
# 查找包含该点的多边形
matches <- st_intersects(gdf, point_sf)
matches3<- matrix(matches,length(matches),1)
matches3<- as.data.frame(matches3)
matches3$index<- as.integer(row.names(matches3))
intersecting_indices<- matches3$index[which(matches3$V1==1)]
xzjd<- gdf[intersecting_indices,]
paste(xzjd$city[[1]],xzjd$county[[1]],xzjd$name[[1]],xzjd$xzdm[[1]],sep=":")
}, error = function(e){
print(e$message)
temp<- "找不到广东省内所属的乡镇街道"
})
})
output$longlat<-renderText({
paste(vendor(),paste(lnglat()[[1]],lnglat()[[2]],sep=" , "),sep=" : ")
})
output$wgslonglat<-renderText({
paste("WGS 84",paste(wgslnglat()[[1]],wgslnglat()[[2]],sep=" , "),sep=" : ")
})
output$xzjd<-renderText({
xzjd()
})
output$frame <- renderUI({
location<- lnglat()
if (vendor()=='天地图'){
# 天地图在高德中显示,要从WGS-> GCJ,注意这里调的是Python包
location2<- wgs2gcj(location[[1]], location[[2]])
# url<- TDURL_mask(paste(location[[1]],location[[2]],sep=","), address(), application_key)
url<- GaoDeURL_mask(paste(location2[[1]],location2[[2]],sep=","), address())
}else if (vendor()=='腾讯'){
url<- TxURL_mask(paste(location[[2]],location[[1]],sep=","), address())
}else if (vendor()=='高德'){
url<- GaoDeURL_mask(paste(location[[1]],location[[2]],sep=","), address())
}else if (vendor()=='百度'){
location2<- bd2gcj(location[[1]], location[[2]])
# url<- BaiDuURL_mask(paste(location[[2]],location[[1]],sep=","), address())
url<- TxURL_mask(paste(location2[[2]],location2[[1]],sep=","), address())
}
my_test <- tags$iframe(src=url, height=600, width="100%")
print(my_test)
my_test
})
})
fluidPage(
tags$head(
tags$script(HTML("
// 触发了shiny:inputchanged事件,屏蔽输入引起的改变
$(document).on('shiny:inputchanged', function(event) {
if (event.name === 'address') {
event.preventDefault();
}
});
// 点击时触发识别
$(document).on('click', '.btn-success', function (evt) {
evt.preventDefault();
var address = document.getElementById('address');
if (address.value ==null || address.value ==''){
alert('没有输入地址!');
}else{
try{
Shiny.setInputValue('address', address.value);
} catch(error){
alert(error);
}
}
});
"))
),
titlePanel("Shiny 调用地理编码服务示例"),
HTML("
<table width='100%'>
<tr>
<td width='20%'>
"),
selectInput(
'vendor',
'地图',
c('百度','高德','腾讯','天地图'),
selected = '天地图'
),
HTML("
</td>
<td width='60%'>
"),
textInput("address","地址:", value ="珠海市香洲区香山湖公园", width="400px"),
HTML("
</td>
<td width='20%'>
"),
actionButton("geocode", "解析并标示", class = "btn-success"),
HTML("
</td>
</tr>
<tr>
<td>
"),
textOutput("longlat"),
HTML("<br>"),
textOutput("wgslonglat"),
HTML("<br>"),
textOutput("xzjd"),
HTML("
</td>
<td colspan=2>
注:地址请输入城市名以便地图在指定的城市有效查找。<br>
百度地图的地图调起API及天地图的静态图API嵌入Shiny APP IFRAME碰到问题,
未找到原因,转换坐标系后暂时分别在高德、腾讯地图中标注显示。
如果地图的标注有偏差,说明是地图地理编码服务返回的坐标有偏差,
原因是地图里面可能没有收录附近的信息点。所以对同一个地址,
不同地图返回的坐标可能是不同的,因为它们收录的信息点不一样。
选择地图时要考察其信息点的数量与质量,解析的坐标是否比较准确。
查找所属乡镇街道代码用的是广东省2014年的乡镇街道行政区域矢量地图。
</td>
</tr>
<tr>
<td colspan=3>
"),
htmlOutput("frame"),
HTML("
</td>
</tr>
</table>
")
)