天天看点

利用R语言从高德地图生成AOI(Area Of Interests)

高德地图开放了POI的WEB API接口(也就是搜索那个API接口)。然而很多时候我们并不满足于将地物抽象成一个点。在城市这个尺度分析的时候,大型的住宅小区抽象成点往往就难以满足需求了,更何况还有更大面积的景区、学校之类。这个时候,兴趣区(Area Of Interests)就是我们需要的东西了。遗憾的是,高德并没有开放这个API接口,百度貌似也没有。但还是可以通过高德的地物详情查询接口获取兴趣区的边界坐标信息,很多人已经摸索出了解决方案,基本都是基于Python的,我这里狗尾续貂,用R语言来解决一下。最后生成的类型是sf。

p_load("httr",'tidyverse','jsonlite','sf','rgdal','rlist')
library('Rgctc2')
           

需要用的到的包环境,Rgctc2是我为了在高德坐标系和wgs84坐标系之间转换搞的一个小包,可以在这里下载。

获取AOI ID

前人似乎都是通过查看页面源代码的方式来获取ID的,似乎高德提供了一个很简便的方法。

利用R语言从高德地图生成AOI(Area Of Interests)

搜索地物,点击高德用以标记AOI对象的蓝绿色文字(没有形状标识的纯文字,好像一般都是AOI对象),AOI区域会被蓝色边框的透明多边形蒙住。这个时候地址栏会变化,最后那一串字符就是我们需要的ID了。

当然,这个方法需要手工操作,如果需要的兴趣区的数目很多就非常痛苦了。通过地址名(如XX小区)搜索可以在高德的API获得一系列与这个名称相关的POI的ID(小区本身的ID应该可以搜到,但是返回的结果里可能也会包含了小区的东南西北门甚至小区内部的便利店健身房什么的信息)。有些是多边形对象,有些就是点对象。利用下文里的方法获得相关信息后再进行筛选,(比如说筛选出多边形对象后再筛选出面积最大的),应该也可以根据你需要的那一类AOI对象的特征得到需要的结果。但是高德里的地物名称很可能和你搜索的不一样(比如笔者需要的景区,很多和笔者手中的景区规范名称不一致),所以我总觉得很难避免最后的人工筛查,在大数据量时可能都会很痛苦。在小数据量时,笔者这个手工的过程其实可以避免获得数据之后的筛查,保证所见即所得。

获取边界信息

利用R语言从高德地图生成AOI(Area Of Interests)

前人找到了

https://ditu.amap.com/detail/get/detail?id=

这个信息查询接口,我们只要把ID黏贴到后面就可以打开地物的信息页面了。万佛湖风景区的部分详情如图所示。shape后面那些数据对就是我们要的坐标信息了。到这里一切就很简单了,无非是获取信息—清洗数据—定义数据了。

poi_boundary_url = "https://ditu.amap.com/detail/get/detail?id=" #信息查询接口
id  = 'B01FE162TD'
boundary_request = paste(poi_boundary_url,id,sep='') #生成查询网址
aoi = GET(boundary_request) %>% content(as="text",encoding="UTF-8") %>% fromJSON(flatten = TRUE)                           #获取详情页信息
aoi_shape=aoi %>% '[['('data')  %>% '[['('spec') %>% '[['('mining_shape') %>% '[['('shape')                                     #提取坐标数据
aoi_polygon = aoi_shape %>% str_split(';') %>% '[['() %>% as.matrix(ncol=) %>% apply(,str_split,',')               #提取得到的数据是字符串类型,需要分割
aoi_polygon2 = aoi_polygon[[]] %>% lapply(as.numeric) %>%  #由字符串转换为数字
               list.rbind %>% gcj02_wgs84_matrix_matrix %>% list %>% #由高德坐标系转换为wgs84坐标系
               st_polygon  %>% st_sfc(crs = )  #定义为面对象后定义为sf类型中需要的sfc对象
aoi_sf = st_sf(name=aoi$data$base$name,aoi_polygon2) #与地物名称合并,生成一个sf对象
           

代码部分到这里就结束了,可以把上面的代码生成一个函数,然后构建一个循环就可以了。来检验一下成果

plot(aoi_sf$aoi_polygon2)
           
利用R语言从高德地图生成AOI(Area Of Interests)

切记: 这个信息查询的接口并非高德开放的API接口,所以千万不能用并行程序同时获得信息,只能一个个的循环,而且循环的间隔需要留长一点,每次获取信息最好能间隔10秒左右吧,而且最好不规则。否则,高德是会限制你这个IP使用的哦。这是我一个星期和高德斗智斗勇得来的教训。这也算是抛砖引玉吧,如果有可以绕开这个限制的方法,请务必留言。

继续阅读