Plotting OpenStreetMap with ggmap
ggmap, ggplot2, openstreetmap, r
Solution
There is a way to generate your map without using external packages: don't use `osmar`...
This link, to the excellent Mapzen website, provides a set of shapefiles of administrative areas in Poland. If you download and unzip it, you will see a shapfile set called `warsaw.osm-admin.*`. This is a polygon shapefile of all the districts in Poland, conveniantly indexed by osm_id(!!). The code below assumes you have downloaded the file and unzipped it into the "directory with your shapefiles".
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, e.g.,
spp <- pol[pol$osm_id==-2536107,]
to extract the relevant district, and (2) the shapefile is not projected in WGS84 (long/lat). 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. 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. When you use `fortify(...)` on this, `ggplot` tries to combine them into a single sequence of points. 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. 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.
There is a way to "fix" the SpatialLines object, but it's not trivial. 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(...)`. 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. So if you create a SpatialLines list with just the first 11 paths, you can convert `warszawa.sp` to a polygon. This is not general however, as I can't predict how or if it would work with other `SpatialLines` objects converted from `osm`. 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)
Problem
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. 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.