Plotting points from a data.frame using OpenStreetMap
Asked Answered
D

2

8

I am a complete novice with spacial data. I have the following code that successfully plots a bounded map. I would like to add, as points the data.frame stores. I apologize in advance for not being able to figure this out from the OpenStreetMap documentation...code below:

library(OpenStreetMap)
stores <- data.frame(name=c("Commercial","Union","Bedford"),
                 longitude=c(-70.25042295455933,-70.26050806045532,-70.27726650238037),
                 latitude=c(43.657471302616806,43.65663299041943,43.66091757424481))
lat <- c(43.68093,43.64278)
lon <- c(-70.29548,-70.24097)
portland <- openmap(c(lat[1],lon[1]),c(lat[2],lon[2]),zoom=15,'osm')
plot(portland,raster=TRUE)
#can't figure out what to put here.

I suspect the format of stores isn't proper for spatial data.

Dotson answered 15/6, 2012 at 19:5 Comment(0)
B
10

I don't know the OpenStreetMap package. But I offer an alternative that still draws an OpenStreet Map, but uses the ggmap package to fetch and draw the map. The get_map function can fetch maps from a variety of sources: osm, google, stamen, and cloudmade; set with source. In addition the sources have different styles, set with maptype. The boundary of the map is given in a location vector. Alternatively, the location vector can give the centre of the map with an appropriate zoom level set. The map is drawn with ggplot2, and so points and labels can be added to the map as if they were being added to any ggplot object. To run the following, the ggmap and ggplot2 packages need to be installed.

library(ggmap)

stores <- data.frame(name=c("Commercial","Union","Bedford"),
        longitude=c(-70.25042295455933,-70.26050806045532,-70.27726650238037),
        latitude=c(43.657471302616806,43.65663299041943,43.66091757424481))
location = c(-70.2954, 43.64278, -70.2350, 43.68093)

# Fetch the map
portland = get_map(location = location, source = "osm")

# Draw the map
portlandMap = ggmap(portland)

# Add the points layer
portlandMap = portlandMap + geom_point(data = stores, aes(x = longitude, y = latitude), size = 5)

# Add the labels
portlandMap + geom_text(data = stores, aes(label = name, x = longitude+.001, y = latitude), hjust = 0)

The result is:

enter image description here

The labels could be getting lost in the background. In that case, something like this might be appropriate. It uses code from here to give the text an outline.

portlandMap = ggmap(portland) + geom_point(data = stores, aes(x = longitude, y = latitude), size = 5)

theta <- seq(pi/16, 2*pi, length.out=32)
xo <- diff(location[c(1,3)])/250
yo <- diff(location[c(2,4)])/250

for(i in theta) {
    portlandMap <- portlandMap + geom_text(data = stores,  
    aes_(x = stores$longitude + .001 + cos(i) * xo, 
         y = stores$latitude + sin(i) * yo, 
         label = stores$name), 
    size = 5, colour = 'black', hjust = 0)
 }

portlandMap + 
   geom_text(data = stores, aes(x = longitude + .001, y = latitude, label=name), 
     size = 5, colour = 'white', hjust = 0)

enter image description here

Beckwith answered 15/6, 2012 at 23:23 Comment(1)
There is an error when using get_map in 2022. Error: 'get_openstreetmap' is defunct See github.com/dkahle/ggmap/issues/117Longterm
M
4

Since google startend requiring billing information for using their api, here is a solution using OpenStreetMaps only.

sample data

library( OpenStreetMap )
library( ggplot2 )
stores <- data.frame(name=c("Commercial","Union","Bedford"),
                     longitude=c(-70.25042295455933,-70.26050806045532,-70.27726650238037),
                     latitude=c(43.657471302616806,43.65663299041943,43.66091757424481))
lat <- c(43.68093,43.64278)
lon <- c(-70.29548,-70.24097)

portland <- OpenStreetMap::openmap( c( lat[1], lon[1] ), c( lat[2], lon[2] ),zoom = 15, 'osm')

the OSM-map is in mercator, and the store-coordinates are lat-lon, so:
method 1: convert the map to latlon
method 2: convert or the coordinates to mercator

method 1 - convert map to latlon

autoplot( OpenStreetMap::openproj( portland ) ) +
  geom_point( data = stores, aes( x = longitude, y = latitude, size = 5 ) ) +
  geom_text( data = stores, aes( x = longitude + .001, y = latitude, label = name ), hjust = 0 ) +
  theme( legend.position = "none" )

enter image description here

method 2 - convert points to mercator

stores2 <- as.data.frame( 
  OpenStreetMap::projectMercator( lat = stores$latitude, 
                                  long = stores$longitude ) 
  )
stores2 <- cbind( stores, stores2)
autoplot( portland ) +
  geom_point( data = stores2, aes( x = x, y = y, size = 5 ) ) +
  geom_text( data = stores2, aes( x = x + 100, y = y, label = name ), hjust = 0 ) +
  theme( legend.position = "none" )

enter image description here

Mcfarlane answered 5/3, 2019 at 14:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.