Как разбить многоугольник по прямой линии на графике? - PullRequest
0 голосов
/ 27 октября 2019

Я уже давно борюсь с этим. Я нашел несколько подобных вопросов здесь, но все они казались излишними для этой конкретной проблемы. У меня есть два частично перекрывающихся полигона, которые я хочу вычесть (вычитая sel_pol из base_pol). После этого полученный полигон (diff) должен быть дополнительно разбит по вертикальной прямой x=20. Вот где я застрял.

Сначала я использовал пакет sf. Это помогло мне вычесть два многоугольника друг из друга и получить полученные вершины diff многоугольника. Однако я не смог найти никакой функциональности для разделения получающегося полигона на x=20 внутри пакета sf, поэтому я обратился к другому пакету, lwgeom.

К сожалению, здесь у меня есть две основные проблемы. Во-первых, функция st_split возвращает вершины в странном формате: GEOMETRYCOLLECTION (POLYGON ((5 0.55, 5 0.6, 19 0.6, 23 0.5, 20.5 0.5, 17 0.55, 5 0.55))), и я не уверен, как использовать это для передачи вершин дальше по моему коду таким же интуитивно понятным способом, как я мог бы использовать sf, иВо-вторых, полученные вершины неверны. Он не разрезал многоугольник diff.

Очевидно, я здесь что-то не так делаю. Мне также не нравится тот факт, что я должен использовать две отдельные библиотеки для такой основной операции. Если бы кто-нибудь мог дать мне подсказку о том, как сделать этот процесс более аккуратным, я был бы очень признателен.

Мой воспроизводимый пример выглядит следующим образом:

library(ggplot2)
library(sf)
library(lwgeom)

rm(list = ls())

group_prc <- data.frame(x = c(5, 23, 19, 5), y = c(0.5, 0.5, 0.6, 0.6), group = "prc")
group_exp <- data.frame(x = c(5, 24, 17, 5), y = c(0.45, 0.45, 0.55, 0.55), group = "exp")
base_pol<- Polygons(list(Polygon(group_prc[, c("x", "y")])), "base")
sel_pol <- Polygons(list(Polygon(group_exp[, c("x", "y")])), "sel")
shape <- SpatialPolygons(list(base_pol, sel_pol))

diff <- shape["base"]-shape["sel"]
diffVert <- diff@polygons[[1]]@Polygons[[1]]@coords
diffVert

dat <- rbind(group_prc, group_exp, data.frame(diffVert, group = "diff"))
dat
ggplot(dat, aes(x = x, y = y, fill = group)) + geom_polygon(alpha = 0.5) + geom_vline(xintercept = 20)

splitRes <- st_split(st_polygon(list(diff@polygons[[1]]@Polygons[[1]]@coords)), 
                     st_linestring(rbind(c(20,20), c(0, 1))))
splitRes

А вот визуальное представление. Фиолетовая область - это то, что я называю diff в моем коде, и я хотел бы получить вершины (и, в конечном итоге, область) всего, что находится слева от x=20 многоугольника diff.

enter image description here

1 Ответ

0 голосов
/ 27 октября 2019

Мне удалось решить эту хитрость. Нет необходимости в пакете lwgeom. По сути, я определил достаточно длинную прямоугольную форму как data.frame и преобразовал ее в sf -совместимый SpatialPolygon объект.

Затем, имея три SpatialPolygon объекта, я теперь мог вычесть их друг из друга, точно так же, как я делал это ранее, когда получил diff. Я исключил diff из приведенного ниже кода, так как в любом случае это было только временное решение.

library(sf)
library(rgeos)

group_prc <- data.frame(x = c(5, 23, 19, 5), y = c(0.5, 0.5, 0.6, 0.6), group = "prc")
group_exp <- data.frame(x = c(5, 24, 17, 5), y = c(0.45, 0.45, 0.55, 0.55), group = "exp")
group_lim <- data.frame(x = c(20, 20, 500, 500), y = c(0, 1, 1, 0), group = "lim")
prc_pol <- Polygons(list(Polygon(group_prc[, c("x", "y")])), "prc")
exp_pol <- Polygons(list(Polygon(group_exp[, c("x", "y")])), "exp")
lim_pol <- Polygons(list(Polygon(group_prcmax[, c("x", "y")])), "lim")
shape <- SpatialPolygons(list(prc_pol, exp_pol, lim_pol))

out_pol <-  shape["prc"]-shape["exp"]-shape["lim"]

out_pol@polygons[[1]]@Polygons[[1]]@coords

И вывод этого кадра данных:

      x         y
[1,]  5 0.5500000
[2,]  5 0.6000000
[3,] 19 0.6000000
[4,] 20 0.5750000
[5,] 20 0.5071429
[6,] 17 0.5500000
[7,]  5 0.5500000
...