简体   繁体   English

使用ggmap绘制OpenStreetMap

[英]Plotting OpenStreetMap with ggmap

I'm trying to get districts of Warsaw and draw them on google map. 我正试图让华沙地区在谷歌地图上绘制它们。 Using this code, where 2536107 is relation code for OpenStreetMap single Warsaw district, gives me almost what I want but with a few bugs. 使用此代码,其中2536107是OpenStreetMap单个华沙区的关系代码,几乎给了我想要的东西,但有一些错误。 There is general outline but also lines between points which shouldn't be connected. 有一般大纲,但也有不应连接的点之间的线。 What am I doing wrong? 我究竟做错了什么?

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

Edit: I figured it must be somehow connected with order of plotting every point/line but I have no idea how to fix this. 编辑:我认为它必须以某种方式与绘制每个点/线的顺序相关联,但我不知道如何解决这个问题。

There is a way to generate your map without using external packages: don't use osmar ... 有一种方法可以在不使用外部包的情况下生成地图:不要使用osmar ...

This link , to the excellent Mapzen website, provides a set of shapefiles of administrative areas in Poland. 这个链接 ,通过优秀的Mapzen网站,提供了一套波兰行政区域的形状文件。 If you download and unzip it, you will see a shapfile set called warsaw.osm-admin.* . 如果您下载并解压缩它,您将看到一个名为warsaw.osm-admin.*的shapfile集。 This is a polygon shapefile of all the districts in Poland, conveniantly indexed by osm_id(!!). 这是波兰所有地区的多边形 shapefile,通过osm_id(!!)进行索引。 The code below assumes you have downloaded the file and unzipped it into the "directory with your shapefiles". 下面的代码假定您已下载文件并将其解压缩到“包含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)

Two nuances: (1) The osm IDs are stored as negative numbers, so you have to use, eg, 两个细微差别:(1)osm ID存储为负数,因此您必须使用,例如,

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

to extract the relevant district, and (2) the shapefile is not projected in WGS84 (long/lat). 提取相关区域,以及(2)在WGS84(long / lat)中不投影shapefile。 So we have to reproject it using: 所以我们必须使用以下方法重新投影:

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

The reason osmar doesn't work is that the paths are in the wrong order. osmar不起作用的原因是路径的顺序错误。 Your warszawa.sp is a SpatialLinesDataframe , made up of a set of paths (12 in your case), each of which is made up of a set of line segments. 您的warszawa.sp是一个SpatialLinesDataframe ,由一组路径(在您的情况下为12)组成,每个路径由一组线段组成。 When you use fortify(...) on this, ggplot tries to combine them into a single sequence of points. 当你对此使用fortify(...)时, ggplot尝试将它们组合成一个单独的点序列。 But since the paths are not in convex order, ggplot tries, for example, to connect a path that ends in the northeast, to a path the begins in the southwest. 但由于路径不是凸起的顺序,例如,ggplot尝试将一条以东北方向结束的路径连接到一条从西南方向开始的路径。 This is why you're getting all the extra lines. 这就是你得到所有额外线条的原因。 You can see this by coloring the segments: 你可以通过着色段来看到这一点:

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))

The colors are in "rainbow" order (red, orange, yellow, green, etc.). 颜色为“彩虹”顺序(红色,橙色,黄色,绿色等)。 Clearly, the lines are not in that order. 显然,线条不是那样的。

EDIT Response to @ako's comment. 编辑回复@ ako的评论。

There is a way to "fix" the SpatialLines object, but it's not trivial. 有一种方法可以“修复”SpatialLines对象,但这并非易事。 The function gPolygonize(...) in the rgeos package will take a list of SpatialLines and convert to a SpatialPolygons object, which can be used in ggplot with fortify(...) . rgeos包中的函数gPolygonize(...)将获取SpatialLines列表并转换为SpatialPolygons对象,该对象可以在带有fortify(...) ggplot中使用。 One huge problem (which I don't understand, frankly), is that OP's warszaw.sp object has 12 lines, two of which seem to be duplicates - this causes gPolygonize(...) to fail. 坦率地说,一个巨大的问题(我不明白)是OP的warszaw.sp对象有12行,其中两行似乎是重复的 - 这导致gPolygonize(...)失败。 So if you create a SpatialLines list with just the first 11 paths, you can convert warszawa.sp to a polygon. 因此,如果仅使用前11个路径创建SpatialLines列表,则可以将warszawa.sp转换为多边形。 This is not general however, as I can't predict how or if it would work with other SpatialLines objects converted from osm . 然而,这并不常见,因为我无法预测它是如何或是否与从osm转换的其他SpatialLines对象一起使用。 Here's the code, which leads to the same map as above. 这是代码,它导致与上面相同的地图。

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)

I am not sure this is a general hangup--I can reproduce your example and see the issue. 我不确定这是一般的挂断 - 我可以重现你的例子并看到问题。 My first thought was that you didn't supply group=id which are typically used for polygons with many lines, but you have lines, so that should not be needed. 我的第一个想法是你没有提供group = id,它通常用于有很多行的多边形,但你有线,所以不需要。

The only way I could get it to display properly was by changing your lines into a polygon off script. 我能够正确显示它的唯一方法是将线条更改为多边形脚本。 Qgis' line to polygon didn't get this "right", getting a large donut hole, so I used ArcMap , which produced a full polygon. Qgis' line to polygon没有得到这个“正确”,得到一个大的圆环孔,所以我使用了ArcMap ,它产生了一个完整的多边形。 If this is a one off that may work for your workflow. 如果这是一次性的,可能适用于您的工作流程。 Odds are it is not. 可能性不大。 In that case, perhaps RGDAL can transform lines to polygons, assuming that is indeed a general problem. 在这种情况下,也许RGDAL可以将线条转换为多边形,假设这确实是一个普遍的问题。

Upon reading the polygon shapefile and fortifying that, your code ran without problems. 在读取多边形shapefile并加强它后,您的代码运行没有问题。 在此输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM