How to convert an osmar object (OSM relation) containing several ways to a closed polygon

857 views Asked by At

I was wondering how to convert an osmar object (an OSM relation) to a closed polygon by merging its 'outer' ways. The relation I want to fetch is the following: http://www.openstreetmap.org/relation/416271.

library(osmar)
wv <- get_osm(relation(416271), full=T)
wv
osmar object
4337 nodes, 138 ways, 9 relations

str(wv)
List of 3
 $ nodes    :List of 2
  ..$ attrs:'data.frame':   4337 obs. of  9 variables:
  .. ..$ id       : num [1:4337] 22290863 22290866 22290869 22290872 22290875 ...
  .. ..$ visible  : Factor w/ 1 level "true": 1 1 1 1 1 1 1 1 1 1 ...
  .. ..$ timestamp: POSIXlt[1:4337], format: "2006-12-30 15:22:45" "2006-12-30 15:22:45" "2006-12-30 15:22:45" ...
  .. ..$ version  : num [1:4337] 1 1 1 1 1 1 1 1 1 1 ...
  .. ..$ changeset: num [1:4337] 175959 175959 175959 175959 175959 ...
  .. ..$ user     : Factor w/ 69 levels "3dShapes","AtonX",..: 63 63 63 63 63 63 63 63 63 63 ...
  .. ..$ uid      : Factor w/ 69 levels "10613","107257",..: 45 45 45 45 45 45 45 45 45 45 ...
  .. ..$ lat      : num [1:4337] 51.4 51.4 51.4 51.4 51.4 ...
  .. ..$ lon      : num [1:4337] 3.35 3.35 3.34 3.34 3.34 ...
  ..$ tags :'data.frame':   575 obs. of  3 variables:
  .. ..$ id: num [1:575] 22290863 22290863 22290866 22290866 22290869 ...
  .. ..$ k : Factor w/ 43 levels "addr:postcode",..: 2 39 2 39 2 39 2 39 2 39 ...
  .. ..$ v : Factor w/ 40 levels "1","117639","1819",..: 9 32 9 32 9 32 9 32 9 32 ...
  ..- attr(*, "class")= chr [1:3] "nodes" "osmar_element" "list"
 $ ways     :List of 3
  ..$ attrs:'data.frame':   138 obs. of  7 variables:
  .. ..$ id       : num [1:138] 29158308 31175543 45749525 51104371 60186141 ...
  .. ..$ visible  : Factor w/ 1 level "true": 1 1 1 1 1 1 1 1 1 1 ...
  .. ..$ timestamp: POSIXlt[1:138], format: "2014-10-13 12:16:16" "2014-05-18 20:22:47" "2014-10-13 12:17:01" ...
  .. ..$ version  : num [1:138] 17 4 15 8 5 4 8 3 10 27 ...
  .. ..$ changeset: num [1:138] 26046342 22413405 26046342 20050162 22413405 ...
  .. ..$ user     : Factor w/ 8 levels "bibi6","escada",..: 7 7 7 8 7 8 8 8 1 7 ...
  .. ..$ uid      : Factor w/ 8 levels "145231","2449622",..: 7 7 7 1 7 1 1 1 5 7 ...
  ..$ tags :'data.frame':   855 obs. of  3 variables:
  .. ..$ id: num [1:855] 29158308 29158308 29158308 29158308 29158308 ...
  .. ..$ k : Factor w/ 19 levels "admin_level",..: 1 4 5 8 9 10 11 12 13 14 ...
  .. ..$ v : Factor w/ 41 levels "2","2009-10-20 00:00:02",..: 1 20 7 15 17 16 14 18 13 41 ...
  ..$ refs :'data.frame':   4473 obs. of  2 variables:
  .. ..$ id : num [1:4473] 29158308 29158308 29158308 29158308 29158308 ...
  .. ..$ ref: num [1:4473] 3.21e+08 3.21e+08 3.21e+08 3.21e+08 3.21e+08 ...
  ..- attr(*, "class")= chr [1:3] "ways" "osmar_element" "list"
 $ relations:List of 3
  ..$ attrs:'data.frame':   9 obs. of  7 variables:
  .. ..$ id       : num [1:9] 416271 2239171 2239750 2239123 2239751 ...
  .. ..$ visible  : Factor w/ 1 level "true": 1 1 1 1 1 1 1 1 1
  .. ..$ timestamp: POSIXlt[1:9], format: "2014-12-01 08:23:50" "2014-10-06 16:01:00" "2014-10-06 16:01:02" ...
  .. ..$ version  : num [1:9] 164 13 12 9 9 24 16 14 14
  .. ..$ changeset: num [1:9] 27148003 25898929 25898929 25898929 25898929 ...
  .. ..$ user     : Factor w/ 3 levels "Bas de Wit","QuercE",..: 1 2 2 2 2 3 2 2 3
  .. ..$ uid      : Factor w/ 3 levels "201359","2434393",..: 2 3 3 3 3 1 3 3 1
  ..$ tags :'data.frame':   121 obs. of  3 variables:
  .. ..$ id: num [1:121] 416271 416271 416271 416271 416271 ...
  .. ..$ k : Factor w/ 33 levels "admin_level",..: 1 2 3 5 6 8 9 11 18 28 ...
  .. ..$ v : Factor w/ 73 levels "30000","31000",..: 10 12 61 21 65 66 64 39 65 58 ...
  ..$ refs :'data.frame':   600 obs. of  4 variables:
  .. ..$ id  : num [1:600] 416271 416271 416271 416271 416271 ...
  .. ..$ type: Factor w/ 3 levels "node","relation",..: 1 1 3 3 3 3 3 3 3 3 ...
  .. ..$ ref : num [1:600] 2.70e+09 1.65e+09 4.11e+06 1.26e+08 1.69e+08 ...
  .. ..$ role: Factor w/ 4 levels "admin_centre",..: 2 1 3 3 3 3 3 3 3 3 ...
  ..- attr(*, "class")= chr [1:3] "relations" "osmar_element" "list"
 - attr(*, "class")= chr [1:2] "osmar" "list"

One first problem I see is that the ways are not in the same order as shown on the OSM website. On the OSM website, it seems that ways are ordered correctly. In the osmar object, the order seems random. Any idea how I can merge these ways into a closed polygon ?

2

There are 2 answers

1
scai On

Relation elements don't have to be sorted correctly. In fact, it isn't even possible to find a suitable ordering for some types of relations.

To order relation elements take a look at the elements itself. A way always starts and ends with a specific node ID. Consecutive ways will always share the same node ID at the start or end. For sorting, you simply have to determine which ways share the same node IDs at their start and end. This will only work if the relation isn't broken, which may happen from time to time unfortunately.

This related question may also help you.

0
Mathias Versichele On

Just thought I would post the solution I am using right now:

library(osmar)
library(rgeos)

wv <- get_osm(relation(416271), full=T)
wv_lines <- as_sp(wv, 'lines')
wv_lines_closed <- gLineMerge(wv_lines)

list_of_Lines <- slot(wv_lines_closed, "lines")
wv_polygon <- SpatialPolygons(lapply(list_of_Lines, function(x) {
  Polygons(list(Polygon(slot(slot(x, "Lines")[[1]], "coords"))),
           ID=slot(x, "ID"))
}),
proj4string=CRS("+proj=longlat +ellps=WGS84"))
plot(wv_polygon, col='red')