Question

I'm trying to plot flat maps in RGL's 3d environment because it should enable maps to be custom zoomed/tilted for a projection that best suits both the data and required output image aspect. This thread describes the process for plotting images using rgl.surface(). But its not clear if this method is adaptable for OSM/other map objects. Very grateful for any ideas you may have.

This is the starting point, which fails because Error in is.matrix(z) : 'z' is missing. Any idea how I can insert some zeros for z coordinates?

require(rgl)
open3d()               # R crashes if this is done later(?)
#Sys.setenv(NOAWT=1)   # fix an {OSM} X11 issue in Mac
require(OpenStreetMap)
require(ggplot2)

lat <- c(53, 50); lon <- c(-5, 1)
map <- openmap(c(lat[1],lon[1]),c(lat[2],lon[2]), 5, 'osm')
map <- openproj(map)
rgl.surface(map)
Was it helpful?

Solution

You need to create a matrix of zeroes for heights and use the col= argument to surface3d to set the colour of the image.

Getting all the dimensions and ordering and all that out of the map object is a faff, so here's a function to do it:

map3d <- function(map,...){
  if(length(map$tiles)!=1){
    stop("multiple tiles not implemented")
  }

  nx = map$tiles[[1]]$xres
  ny = map$tiles[[1]]$yres

  xmin = map$tiles[[1]]$bbox$p1[1]
  xmax = map$tiles[[1]]$bbox$p2[1]
  ymin = map$tiles[[1]]$bbox$p1[2]
  ymax = map$tiles[[1]]$bbox$p2[2]

  xc = seq(xmin,xmax,len=ny)
  yc = seq(ymin,ymax,len=nx)
  colours = matrix(map$tiles[[1]]$colorData,ny,nx)
  m = matrix(0,ny,nx)
  surface3d(xc,yc,m,col=colours,...)

}

Which gives us:

shiny map

Now, note it only works if there's one tile in the returned map, but the principle is there.

Also, I'm not totally convinced the coordinate alignment is exact. The coordinates may be centre of pixels or edges of the image, so maybe there's a +1 missing somewhere. And I'm not sure if it applies to the gray border or not.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top