- UID
- 4963
- 注册时间
- 2014-4-15
- 在线时间
- 小时
- 最后登录
- 1970-1-1
- 精华
- 阅读权限
- 20
- 听众
- 收听
|
专注系列化、高质量的R语言教程
推文索引 | 联系小编 | 咨询服务
本系列介绍osmextract工具包,该工具包可以用来下载和导入OpenStreetMap数据。与osmdata工具包相比,它可以下载大尺寸的数据。
本篇目录如下:
1 oe_providers函数
2 提供商数据库
3 分区
3.1 第一层次分区
3.2 第二层次分区
3.3 第三层次分区
3.4 第四层次分区
3.5 geofabrik_zones
3.6 bbbike_zones
本篇会涉及到矢量数据的处理,因此除了加载osmextract工具包外,还需加载sf工具包:
library(osmextract)
library(sf)
1 oe_providers函数
osmextract工具包并不是直接从OpenStreetMap(OSM)下载数据的,而是从其他网站(称为provider,提供商)那里下载OSM的数据摘录(data extract)。
使用oe_providers()函数可以查看当前可用的数据提供商:
oe_providers()
## available_providers database_name number_of_zones number_of_fields
## 1 geofabrik geofabrik_zones 475 8
## 2 bbbike bbbike_zones 236 5
## 3 openstreetmap_fr openstreetmap_fr_zones 1135 6
可以看到,默认情况下有三个数据提供商可用。它们的名称和地址分别如下:
geofabrik:https://download.geofabrik.de/bbbike:https://download.bbbike.org/osm/openstreetmap_fr:http://download.openstreetmap.fr/
2 提供商数据库
以上输出内容还列举了各个提供商的其他信息。第二列database_name是对应数据库的名称,第三列number_of_zones(分区数目)是数据库的行数,第四列number_of_fields(字段数据)是数据库属性数据的列数。
使用data()函数可以加载这些数据库:
data("geofabrik_zones")
data("bbbike_zones")
data("openstreetmap_fr_zones")
以openstreetmap_fr_zones为例,先来查看它的数据类型和各字段名称:
class(openstreetmap_fr_zones)
## [1] "sf" "data.frame"
names(openstreetmap_fr_zones)
## [1] "id" "name" "parent" "level"
## [5] "pbf" "pbf_file_size" "geometry"
可以看到,它实际是一个sf格式的矢量文件。它的每一行对应一个分区(zone),各字段含义如下:
id:分区ID;name:分区名称;parent:包含该分区的上一层区域名称;level:分区层次;pbf:该分区数据摘录的下载网址;pbf_file_size:数据摘录的大小,单位为字节(byte);geometry:sf数据的几何信息。
3 分区
分区(zone)是数据提供商对全球区域的划分,仍以openstreetmap_fr_zones为例,先来查看它的level列:
unique(openstreetmap_fr_zones$level)
## [1] 1 2 3 4
可以看到,它的分区共有4个层次,下面依次进行展示。
3.1 第一层次分区
使用取子集函数subset()筛选出数据框的level字段为1的行:
zone1 <- subset(openstreetmap_fr_zones, level == "1")
使用ggplot2工具包进行绘图:
library(ggplot2)
ggplot(zone1) +
geom_sf(aes(fill = id)) +
theme_minimal()
从上图可以看到,该提供商在第一层次共划分了6个分区。通过右侧图例可以大致看出各分区所指代的区域,并且这6个分区并未覆盖全球所有区域。
为了方便观察,在上图基础上再叠加全球陆地边界:
## 全球陆地范围
world <- spData::world
world <- st_transform(world, st_crs(openstreetmap_fr_zones))
world <- st_union(world)
ggplot(zone1) +
geom_sf(aes(fill = id)) +
## alpha = 0可只显示陆地边界
geom_sf(data = world, alpha = 0.1) +
theme_minimal()
3.2 第二层次分区
使用类似的方法筛选出第二层次的分区并绘图:
zone2 <- subset(openstreetmap_fr_zones, level == "2")
ggplot(zone2) +
geom_sf(aes(fill = id)) +
geom_sf(data = world, alpha = 0) +
theme_minimal() +
theme(legend.position = "none") +
lims(x = c(-180, 60))
第二层次的分区数较多,因此省略了图例;第二层次的名为“China”的分区并未包含我国全部领土,因此将x范围(即经度范围)限定在(-180, 60)之间,不显示涉及我国的区域。
如果说第一层次分区是以大洲、大陆为基准,那么第二层次分区则是以全球次级区域、面积较大国家为基准。
需要注意的是,分区范围既包含陆地区域,也包含海洋区域,因此即使一些以国家为基准的分区,边界也不一定与国界线相同,例如:
uk <- subset(openstreetmap_fr_zones, name == "United Kingdom")
ggplot(uk) +
geom_sf(aes(fill = id)) +
geom_sf(data = world, alpha = 0) +
theme_minimal() +
lims(x = c(-10,3), y = c(48, 62))
从覆盖范围上看,第二层次分区比第一层次分区更广,但仍未覆盖全球区域。从集合关系上看,第二层次分区并不是对第一层次分区的内部进行细分,“层次”高低主要是指区域尺度的大小。
3.3 第三层次分区
筛选并绘制第三层次的分区:
zone3 <- subset(openstreetmap_fr_zones, level == "3")
ggplot(zone3) +
geom_sf(aes(fill = id)) +
geom_sf(data = world, alpha = 0) +
theme_minimal() +
theme(legend.position = "none") +
lims(x = c(-180, 60))
第三层次分区主要以国家和地区的次级区域为基准。对于一些内陆区域,分区边界即是区域边界,例如安徽省:
anhui = subset(openstreetmap_fr_zones, name == "Anhui")
ggplot(anhui) +
geom_sf(aes(fill = id)) +
geom_sf(data = world, alpha = 0) +
theme_minimal() +
lims(x = c(70, 140), y = c(3, 55))
第三层次分区的parent都不为空,通过该字段可以筛选出某个国家在该层次所有的分区:
brazil = subset(openstreetmap_fr_zones, parent == "brazil")
ggplot(brazil) +
geom_sf(aes(fill = id)) +
geom_sf(data = world, alpha = 0) +
theme_minimal() +
theme(legend.position = "none") +
lims(x = c(-80, -20), y = c(-45, 10))
3.4 第四层次分区
筛选并绘制第四层次的分区:
zone4 <- subset(openstreetmap_fr_zones, level == "4")
ggplot(zone4) +
geom_sf(aes(fill = id)) +
geom_sf(data = world, alpha = 0) +
theme_minimal() +
theme(legend.position = "none") +
lims(x = c(-180, 60))
第四层次分区只覆盖全球很少一部分区域,相较于第三层次分区,区域尺度更小。
3.5 geofabrik_zones
再来看看geofabrik_zones的第一层次分区:
zone12 <- subset(geofabrik_zones, level == "1")
ggplot(zone12) +
geom_sf(aes(fill = id)) +
geom_sf(data = world, alpha = 0) +
theme_minimal()
相比于openstreetmap_fr_zones,geofabrik_zones第一层次分区覆盖的范围更广,没有覆盖的区域基本上是海洋。
读者可自行探索geofabrik_zones的其他层次分区。
3.6 bbbike_zones
与其他两个数据提供商不同,bbbike_zones的分区只有一个层次:
unique(bbbike_zones$level)
## [1] 3
绘制地图:
ggplot(bbbike_zones) +
geom_sf(size = 1.2, col = "red") +
geom_sf(data = world, alpha = 0) +
theme_bw()
可以看到,bbbike_zones的分区是很多“点”。通过查看name字段可以知道,这些“点”是指城市。
不过当我们将地图放大到局部区域,就可以发现这些分区并不是“点”,而是矩形区域,大小与城市规模有关:
ggplot(bbbike_zones) +
geom_sf(aes(fill = id)) +
geom_sf(data = world, alpha = 0) +
theme_minimal() +
theme(legend.position = "none") +
lims(x = c(-10, 30), y = c(35, 60))
|
|