Как преобразовать объект osmar (отношение OSM), содержащий несколько путей, в замкнутый полигон

Мне было интересно, как преобразовать объект osmar (отношение OSM) в замкнутый многоугольник, объединив его «внешние» пути. Отношение, которое я хочу получить, выглядит следующим образом: 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"

Первая проблема, которую я вижу, заключается в том, что пути расположены не в том порядке, как показано на веб-сайте OSM. На сайте OSM пути вроде правильно упорядочены. В объекте osmar порядок кажется случайным. Любая идея, как я могу объединить эти пути в замкнутый многоугольник?


person Mathias Versichele    schedule 10.12.2014    source источник


Ответы (2)


Просто подумал, что опубликую решение, которое я использую прямо сейчас:

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')
person Mathias Versichele    schedule 10.12.2014

Элементы Relation не обязательно должны быть правильно отсортированы. На самом деле для некоторых типов отношений даже невозможно найти подходящий порядок.

Чтобы упорядочить элементы отношения, взгляните на сами элементы. путь всегда начинается и заканчивается определенным идентификатор узла. Последовательные пути всегда будут иметь один и тот же идентификатор узла в начале или в конце. Для сортировки вам просто нужно определить, какие пути имеют одинаковые идентификаторы узлов в начале и в конце. Это будет работать только в том случае, если отношения не нарушены, что, к сожалению, может происходить время от времени.

Этот связанный вопрос также может вам помочь.

person scai    schedule 10.12.2014
comment
Не знал, что пути в отношениях не имеют фиксированного порядка, просто предположил, что они есть, поскольку список на веб-странице OSM, похоже, следовал фактическому порядку путей вокруг границы провинции. - person Mathias Versichele; 10.12.2014