使用ggmap绘制OpenStreetMap

Mar*_*ski 4 r openstreetmap ggplot2 ggmap

我正试图让华沙地区在谷歌地图上绘制它们.使用此代码,其中2536107是OpenStreetMap单个华沙区的关系代码,几乎给了我想要的东西,但有一些错误.有一般大纲,但也有不应连接的点之间的线.我究竟做错了什么?

map <- get_googlemap('warsaw', zoom =10) 
warszawa <- get_osm(relation(2536107), full = T)
warszawa.sp <- as_sp(warszawa, what='lines')
warsawfort <- fortify(warszawa.sp)

mapa_polski <- ggmap(map, extent='device', legend="bottomleft") 
warsawfort2 <- geom_polygon(aes(x = long, y = lat), 
               data = warsawfort, fill="blue", colour="black", 
               alpha=0.0, size = 0.3)

base <- mapa_polski + warsawfort2 
base
Run Code Online (Sandbox Code Playgroud)

编辑:我认为它必须以某种方式与绘制每个点/线的顺序相关联,但我不知道如何解决这个问题.

jlh*_*ard 9

有一种方法可以在不使用外部包的情况下生成地图:不要使用osmar...

这个链接,通过优秀的Mapzen网站,提供了一套波兰行政区域的形状文件.如果你下载并解压缩它,你会看到一个名为shapfile的集合warsaw.osm-admin.*.这是波兰所有地区的多边形 shapefile,通过osm_id(!!)进行索引.下面的代码假定您已下载文件并将其解压缩到"包含shapefile的目录"中.

library(ggmap)
library(ggplot2)
library(rgdal)

setwd(" <directory with your shapefiles> ")
pol    <- readOGR(dsn=".",layer="warsaw.osm-admin")
spp    <- pol[pol$osm_id==-2536107,]
wgs.84 <- "+proj=longlat +datum=WGS84"
spp    <- spTransform(spp,CRS(wgs.84))

map    <- get_googlemap('warsaw', zoom =10) 
spp.df <- fortify(spp)

ggmap(map, extent='device', legend="bottomleft") +
  geom_polygon(data = spp.df, aes(x = long, y=lat, group=group), 
               fill="blue", alpha=0.2) +
  geom_path(data=spp.df, aes(x=long, y=lat, group=group), 
            color="gray50", size=0.3)
Run Code Online (Sandbox Code Playgroud)

两个细微差别:(1)osm ID存储为负数,因此您必须使用,例如,

spp    <- pol[pol$osm_id==-2536107,]
Run Code Online (Sandbox Code Playgroud)

提取相关区域,以及(2)在WGS84(long/lat)中不投影shapefile.所以我们必须使用以下方法重新投影:

spp    <- spTransform(spp,CRS(wgs.84))
Run Code Online (Sandbox Code Playgroud)

原因osmar不起作用的是路径的顺序错误.你warszawa.sp是一个SpatialLinesDataframe由一组路径组成的路径(在你的情况下为12),每个路径由一组线段组成.当您使用fortify(...)此时,ggplot尝试将它们组合成单个点序列.但由于路径不是凸起的顺序,例如,ggplot尝试将一条以东北方向结束的路径连接到一条从西南方向开始的路径.这就是你得到所有额外线条的原因.你可以通过着色段来看到这一点:

xx=coordinates(warszawa.sp)
colors=rainbow(11)
plot(t(bbox(warszawa.sp)))
lapply(1:11,function(i)lines(xx[[i]][[1]],col=colors[i],lwd=2))
Run Code Online (Sandbox Code Playgroud)

颜色为"彩虹"顺序(红色,橙色,黄色,绿色等).显然,线条不是那样的.

编辑回复@ ako的评论.

有一种方法可以"修复"SpatialLines对象,但这并非易事.该功能gPolygonize(...)rgeos包将采取的列表SpatialLines,并转换为一个SpatialPolygons对象,它可以在与ggplot使用fortify(...).一个巨大的问题(我坦白地说,我不明白)是OP的warszaw.sp对象有12行,其中两行似乎是重复的 - 这导致gPolygonize(...)失败.因此,如果仅使用前11个路径创建SpatialLines列表,则可以转换warszawa.sp为多边形.然而,这不是一般性的,因为我无法预测它是如何或是否与其他SpatialLines转换的对象一起使用osm.这是代码,它导致与上面相同的地图.

library(rgeos)
coords <- coordinates(warszawa.sp)
sll <- lapply(coords[1:11],function(x) SpatialLines(list(Lines(list(Line(x[[1]])),ID=1))))
spp <- gPolygonize(sll)
spp.df <- fortify(spp)
ggmap(map, extent='device', legend="bottomleft") +
  geom_polygon(data = spp.df, aes(x = long, y=lat, group=group), 
               fill="blue", alpha=0.2) +
  geom_path(data=spp.df, aes(x=long, y=lat, group=group), 
            color="gray50", size=0.3)
Run Code Online (Sandbox Code Playgroud)