使用R语言优雅的获取任意区域的POI,道路,河流等数据
POI是“Polnt of Information”的缩写,中文可以翻译为“信息点”。是地图上任何非地理意义的有意义的点,如商店,酒吧,加油站,医院,车站等。POI,道路网,河流等是我们日常研究中经常需要使用的数据。
目前这些数据的获取都有一定的难度,有的下载需要付费,使用代码爬取又需要编写复杂的代码。有时很难成功获得我们想要的数据。
OSM地图数据是指来自OpenStreetMap(开放街道地图)项目的地理信息数据。OpenStreetMap是一个由全球志愿者共同维护的开源地图项目,OSM地图数据的特点包括开放性和可编辑性,这意味着任何人都可以贡献和改进地图数据。这些数据涵盖了道路、建筑、水系、地形等多种地理要素,具有丰富的地理信息和细节。先看看效果:
今天使用R语言调用的就是OSM的各类数据,R语言中的osmdata 包提供有关全球各种空间属性和对象的空间数据。available_features() 函数可用于获取 OSM 中已识别特征的列表。可用功能的列表可以在 OSM wiki 中找到。
## [1] "4wd_only" "abandoned"
## [3] "abutters" "access"
## [5] "addr" "addr:city"
## [7] "addr:conscriptionnumber" "addr:country"
## [9] "addr:county" "addr:district"
## [11] "addr:flats" "addr:full"
## [13] "addr:hamlet" "addr:housename"
## [15] "addr:housenumber" "addr:inclusion"
## [17] "addr:interpolation" "addr:place"
## [19] "addr:postbox" "addr:postcode"
## [21] "addr:province" "addr:state"
## [23] "addr:street" "addr:subdistrict"
## [25] "addr:suburb" "addr:unit"
## [27] "admin_level" "aeroway"
## [29] "agricultural" "alt_name"
## [31] "amenity" "area"
## [33] "atv" "backward"
## [35] "barrier" "basin"
## [37] "bdouble" "bicycle"
## [39] "bicycle_road" "biergarten"
## [41] "boat" "border_type"
## [43] "boundary" "brand"
## [45] "bridge" "building"
## [47] "building:colour" "building:fireproof"
## [49] "building:flats" "building:levels"
## [51] "building:material" "building:min_level"
## [53] "building:part" "building:soft_storey"
## [55] "bus_bay" "busway"
## [57] "capacity" "castle_type"
## [59] "change" "charge"
## [61] "clothes" "construction"
## [63] "construction#Railways" "covered"
## [65] "craft" "crossing"
## [67] "crossing:island" "cuisine"
## [69] "cutting" "cycleway"
## [71] "denomination" "destination"
## [73] "diet" "direction"
## [75] "dispensing" "disused"
## [77] "drinking_water" "drive_in"
## [79] "drive_through" "ele"
## [81] "electric_bicycle" "electrified"
## [83] "embankment" "embedded_rails"
## [85] "emergency" "end_date"
## [87] "entrance" "est_width"
## [89] "fee" "female"
## [91] "fire_object:type" "fire_operator"
## [93] "fire_rank" "foot"
## [95] "footway" "ford"
## [97] "forestry" "forward"
## [99] "frequency" "fuel"
## [101] "gauge" "golf_cart"
## [103] "goods" "hazard"
## [105] "hazmat" "healthcare"
## [107] "healthcare:counselling" "healthcare:speciality"
## [109] "height" "hgv"
## [111] "highway" "historic"
## [113] "horse" "hot_water"
## [115] "ice_road" "incline"
## [117] "industrial" "inline_skates"
## [119] "inscription" "int_name"
## [121] "internet_access" "junction"
## [123] "kerb" "landuse"
## [125] "lanes" "lanes:bus"
## [127] "lanes:psv" "layer"
## [129] "leaf_cycle" "leaf_type"
## [131] "leisure" "lhv"
## [133] "lit" "loc_name"
## [135] "location" "male"
## [137] "man_made" "max_age"
## [139] "max_level" "maxaxleload"
## [141] "maxheight" "maxlength"
## [143] "maxspeed" "maxstay"
## [145] "maxweight" "maxwidth"
## [147] "military" "min_age"
## [149] "min_level" "minspeed"
## [151] "mofa" "moped"
## [153] "motor_vehicle" "motorboat"
## [155] "motorcar" "motorcycle"
## [157] "motorroad" "mountain_pass"
## [159] "mtb:description" "mtb:scale"
## [161] "name" "name:left"
## [163] "name:right" "name_1"
## [165] "name_2" "narrow"
## [167] "nat_name" "natural"
## [169] "noexit" "non_existent_levels"
## [171] "nudism" "office"
## [173] "official_name" "old_name"
## [175] "oneway" "opening_hours"
## [177] "opening_hours:drive_through" "operator"
## [179] "orientation" "oven"
## [181] "overtaking" "parking"
## [183] "parking:condition" "parking:lane"
## [185] "passing_places" "place"
## [187] "power" "power_supply"
## [189] "priority" "priority_road"
## [191] "produce" "proposed"
## [193] "protected_area" "psv"
## [195] "public_transport" "railway"
## [197] "railway:preserved" "railway:track_ref"
## [199] "recycling_type" "ref"
## [201] "reg_name" "religion"
## [203] "rental" "residential"
## [205] "roadtrain" "route"
## [207] "sac_scale" "sauna"
## [209] "service" "service_times"
## [211] "shelter_type" "shop"
## [213] "short_name" "shower"
## [215] "sidewalk" "site"
## [217] "ski" "smoothness"
## [219] "social_facility" "sorting_name"
## [221] "speed_pedelec" "start_date"
## [223] "step_count" "substation"
## [225] "surface" "tactile_paving"
## [227] "tank" "tidal"
## [229] "toilets" "toilets:wheelchair"
## [231] "toll" "topless"
## [233] "tourism" "tracks"
## [235] "tracktype" "traffic_calming"
## [237] "traffic_sign" "trail_visibility"
## [239] "trailblazed" "trailblazed:visibility"
## [241] "tunnel" "turn"
## [243] "type" "unisex"
## [245] "usage" "vehicle"
## [247] "vending" "voltage"
## [249] "water" "wheelchair"
## [251] "wholesale" "width"
## [253] "winter_road" "wood"
这些就是你可以调用的OSM数据种类
我们今天想使用的是某地区的医院,道路,河流等数据,它们分别属于"amenity","highway","waterway"。
下面我们开始具体代码:
#导入OSMdata和处理矢量数据的包
library(osmdata)
library(sf)
下一步就是创建 osmdata 查询,第一步是定义我们想要包含在查询中的地理区域,这通常是一个城市,osmdata提供了查询函数,十分方便。
nc_bb <- getbb("nanchang")
nc_bb
#这会返回南昌市的边界范围
## min max
## x 115.43870 116.56548
## y 28.15784 29.1223
确认没问题,我们就可以直接查询南昌市境内的所有医院:
nc_hospitals <- nc_bb %>%
opq() %>%
add_osm_feature(key = "amenity", value = "hospital") %>%
osmdata_sf()
然后我们就获得了南昌市医院的数据:nc_hospitals,当然上面的代码由于一些不能科学上网或者服务限制的原因,不出问题的话肯定会出问题。所以下面贴出改进后的代码:
原理一样只是写法变化了,我们直接使用我们本地的南昌市数据
library(osmdata)
library(sf)
zh = st_read("E:/Arcgis 地图资源/市县/市县/南昌市.shp")
bb = st_bbox(zh)
bb
nanc_hosiptal <- opq (bbox = c (115.43870,28.15784,116.56548,29.12239 )) %>% #
add_osm_feature(key = "amenity", value = "hospital") %>%
osmdata_sf ()
我们可以开心的可视化了:osm 数据支持“点”,“线”,“”面多种的数据类型,像医院我们就可以有面数据和点数据。我这里的demo将只展示面的,如果你想要南昌市医院的点数据,可以把“nanc_hosiptal$osm_polygons”改成“nanc_hosiptal$osm_point”
# install.packages("leaflet")
library(leaflet)
leaflet() %>%
addTiles() %>%
addPolygons(
data = nanc_hosiptal$osm_polygons,
label = nanc_hosiptal$osm_polygons$name
)
我们就可以得到:
最后,如果你想要在arcgis,或者QGIS中使用,可以将数据转化成shp格式或者GeoPackage,ESRI Shapefile只支持255列,列名限制为10个字符,文件大小限制为10G,所以这里转成shp保存下来必须要根据这些要求进行处理。因此这里最推荐使用GeoPackage,它是一个轻量级的空间数据库容器,没有奇奇怪怪的限制。它只需要一句话:
nch = nanc_hosiptal$osm_polygons
st_write(nch, "G:/R/nanc_hospital.gpkg")
我们可以打开QGIS看看,如下图,没有任何问题。通过这个方法实际上我们可以获取很多有意思的数据,上面提到的数据我们都可以通过这个方法下载。在这里不得不感叹OSM的强大。
今天就到这里结束了,小编也是摸索了很久才给大家带来这篇推文的,如果大家觉得有用希望点赞转发支持一下,我是加拿大一枝黄花,我们下期再见。