使用ggmap绘制OpenStreetMap

时间:2014-07-09 18:33:17

标签: r ggplot2 openstreetmap 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

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

2 个答案:

答案 0 :(得分:9)

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

This link,在优秀的Mapzen网站上,提供了一套波兰行政区域的形状文件。如果您下载并解压缩它,您将看到一个名为warsaw.osm-admin.*的shapfile集。这是波兰所有地区的 polygon shapefile,由osm_id(!!)进行索引。下面的代码假设您已经下载了该文件,并将其解压缩到&#34;目录中,并附带您的shapefile&#34;。

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)

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

spp    <- pol[pol$osm_id==-2536107,]

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

spp    <- spTransform(spp,CRS(wgs.84))

osmar无效的原因是路径的顺序错误。您的warszawa.spSpatialLinesDataframe,由一组路径(在您的情况下为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))

颜色在&#34; rainbow&#34;订单(红色,橙色,黄色,绿色等)。显然,这些线不是那个顺序。

编辑回应@ ako的评论。

有一种方法来修复&#34; 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)

答案 1 :(得分:2)

我不确定这是一般的挂断 - 我可以重现你的例子并看到问题。我的第一个想法是你没有提供group = id,它通常用于有很多行的多边形,但是你有行,所以不应该这样。

我能够正确显示它的唯一方法是将线条更改为多边形关闭脚本。 Qgis' line to polygon没有得到这个“正确”,得到一个大的甜甜圈洞,所以我使用了ArcMap,它产生了一个完整的多边形。如果这是一次性的,可能适用于您的工作流程。可能性不大。在这种情况下,也许RGDAL可以将线条转换为多边形,假设这确实是一个普遍的问题。

读取多边形shapefile并强化它后,您的代码运行没有问题。 enter image description here