簡體   English   中英

如何使用geom_sf從坐標繪制帶有多個孔的多邊形?

[英]How can I use geom_sf to plot a polygon with multiple holes from coordinates?

我的物體上有多個孔。 我可以使用geom_polypathZ.Lin提供的一些幾何圖形識別成功繪制它們。 請參見geom_polypath(aes(x = x, y = y, group = section))

我使用geom_sf繪制這些相同的對象。 我不清楚使用sf對象時如何維護此幾何信息。

st_cast的文檔指出

ids整數向量,表示應如何對幾何進行分組(默認值:無分組)

這是一個線索嗎? 我仍然不清楚。

字母“ g”的xml文件在這里

library(tidyverse)
library(transformr)
library(ggpolypath)
library(sf)

get_letter <- function(){
  letter_xml <- readRDS("tmp/letter_g")

  # Extract coordinates from Picture object
  x <- letter_xml@paths$text@letters[1]$path@x
  y <- letter_xml@paths$text@letters[1]$path@y

  one_letter <- tibble(
    x, 
    y,
    x.n = names(x),
    id = 1
  )

  one_letter <- one_letter %>%
    mutate(is.move = x.n == "move") %>%
    mutate(section = cumsum(is.move)) %>%

    group_by(section) %>%
    mutate(section.length = n()) %>%
    ungroup() %>%
    filter(section.length >= 3)

  one_letter <- select(one_letter, x, y, id, section)
}

letter_to_sf <- function(one_letter){
  one_letter_sf <- one_letter %>%
    st_as_sf(coords = c("x", "y")) %>%
    summarise(geometry = st_combine(geometry)) %>%
    st_cast(to = "POLYGON") %>% 
    st_normalize()

  df2 <- data.frame(
    id = 1,
    one_letter_sf$geometry
  )
}
one_letter <- get_letter()
one_letter_sf <- letter_to_sf(one_letter)

# Incorrect using xy df
ggplot(one_letter) +
  geom_polygon(aes( x = x, y = y))

# Correct using xy df
ggplot(one_letter) +
  geom_polypath(aes(x = x, y = y, group = section))

# Incorrect using sf
ggplot(one_letter_sf) +
  geom_sf(aes(geometry = geometry))

我覺得這是一種不太笨拙的不同方法。 我們必須放棄使用內置的st_as_sf(coords = )方法,但是鑒於我們有原始觀點,我認為這樣做更有必要。 我們使用以下事實: st_polygon包含點矩陣列表,其中第一個矩陣之后的后續矩陣是孔。 因此,我們可以簡單地按section拆分原始數據幀(也可以使用base::split ),遍歷各組並強制轉換為矩陣,將結果放入列表中,然后將結果直接傳遞給st_polygon 然后,您可以將此POLYGON幾何體( sfg )包裝在sfc ,然后再包裝在sf對象中,以取回可以進行ggplot的數據ggplot樣式對象。

library(tidyverse)
library(sf)
#> Linking to GEOS 3.7.1, GDAL 2.4.0, PROJ 5.2.0

one_letter <- tibble::tibble(
  x = c(317.422, 315.605, 310.16, 304.367, 300.527, 299.141, 299.141, 299.141, 299.797, 301.297, 301.719, 300.805, 298.199, 295.684, 294.172, 293.672, 293.672, 293.672, 294.172, 295.684, 298.199, 300.805, 301.719, 300.684, 297.75, 294.93, 293.246, 292.688, 292.688, 292.688, 294.367, 299.203, 306.891, 314.566, 317.125, 319.695, 327.41, 335.234, 340.207, 341.953, 341.953, 341.953, 340.152, 334.797, 325.941, 316.715, 313.641, 312.145, 307.656, 303.695, 301.5, 300.828, 300.828, 300.828, 301.121, 301.906, 303.047, 304.066, 304.406, 305.078, 306.82, 307.094, 308.059, 312.82, 317.008, 318.406, 320.199, 325.586, 331.316, 335.109, 336.484, 336.484, 336.484, 336.016, 334.609, 332.25, 329.828, 328.938, 328.953, 329.332, 330.355, 332.008, 333.723, 334.297, 334.863, 336.563, 338.102, 338.375, 338.004, 336.723, 336.188, 336.188, 336.188, 336.516, 337.395, 338.664, 339.793, 340.172, 340.664, 342.148, 343.793, 344.91, 345.328, 345.328, 345.328, 344.5, 342.234, 338.832, 335.664, 334.609, 333.41, 329.813, 326.332, 324.152, 323.328, 323.281, 322.734, 318.75, 317.422, 317.422, 317.719, 318.82, 322.137, 325.664, 327.996, 328.844, 328.844, 328.844, 328.023, 325.723, 322.172, 318.75, 317.609, 316.52, 313.258, 309.871, 307.672, 306.891, 306.891, 306.891, 307.727, 310.031, 313.469, 316.656, 317.719, 317.719, 317.813, 319.559, 324.809, 330.023, 333.281, 334.406, 334.406, 334.406, 333.215, 329.797, 324.387, 319.008, 317.219, 315.516, 310.41, 305.215, 301.898, 300.734, 300.734, 300.734, 301.906, 305.289, 310.66, 316.023, 317.813, 317.813),
  y = c(8101.36, 8101.36, 8100.18, 8096.9, 8091.93, 8087.22, 8085.66, 8084.56, 8081.29, 8078.09, 8077.52, 8077.23, 8075.97, 8073.87, 8071.21, 8068.79, 8067.98, 8067.23, 8064.98, 8062.39, 8060.21, 8058.79, 8058.44, 8058.05, 8056.45, 8053.89, 8050.75, 8047.95, 8047.02, 8045.46, 8040.79, 8036.11, 8033.15, 8032.13, 8032.13, 8032.13, 8033.22, 8036.35, 8041.29, 8046.18, 8047.81, 8049.44, 8054.32, 8059.05, 8061.93, 8062.91, 8062.91, 8062.91, 8063.15, 8063.99, 8065.55, 8067.38, 8067.98, 8068.39, 8069.6, 8070.93, 8071.82, 8072.16, 8072.16, 8072.16, 8071.58, 8071.45, 8071.03, 8069.53, 8068.88, 8068.88, 8068.88, 8070.09, 8073.45, 8078.52, 8083.29, 8084.88, 8085.88, 8088.91, 8092.53, 8095.71, 8097.88, 8098.47, 8099.19, 8101.34, 8103.39, 8104.62, 8105.03, 8105.03, 8105.03, 8104.52, 8103.37, 8103.05, 8102.77, 8101.41, 8100.18, 8099.77, 8099.41, 8098.35, 8097.18, 8096.39, 8096.09, 8096.09, 8096.09, 8096.54, 8097.78, 8099.61, 8101.3, 8101.86, 8102.7, 8105.23, 8107.9, 8109.66, 8110.3, 8110.3, 8110.3, 8109.68, 8107.85, 8104.8, 8101.63, 8100.56, 8100.69, 8101.36, 8101.36, 8101.36, 8094.8, 8094.8, 8094.05, 8092, 8088.89, 8085.95, 8084.97, 8084.01, 8081.13, 8078.12, 8076.14, 8075.44, 8075.44, 8075.44, 8076.13, 8078.1, 8081.17, 8084.17, 8085.17, 8086.12, 8088.97, 8092.03, 8094.06, 8094.8, 8094.8, 8094.8, 8056.27, 8056.27, 8055.66, 8053.93, 8051.15, 8048.35, 8047.42, 8046.52, 8043.83, 8041.07, 8039.3, 8038.67, 8038.67, 8038.67, 8039.27, 8041, 8043.75, 8046.5, 8047.42, 8048.34, 8051.1, 8053.89, 8055.65, 8056.27, 8056.27, 8056.27),
  id = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
  section = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L)
)

one_letter %>%
  group_by(section) %>%
  group_split() %>%
  map(~ select(.x, x, y) %>% as.matrix) %>%
  st_polygon() %>%
  st_sfc() %>%
  st_sf() %>%
  ggplot() +
  geom_sf()

reprex軟件包 (v0.2.1)創建於2019-03-04

這是我的第一種方法,盡管感覺有點笨拙。 我下載letter_g和制造的reprex版本one_letter ,這樣你就可以與合作。 首先要做的是通過按部分分組來獲得邊界和每個孔的多邊形,但是要從邊界多邊形擦除孔有點費時費力。 我在這里通過使用st_intersection並僅保留完全源自邊界的結果多邊形來做到這一點。 我還假設section變量的編號正確,因此邊界是第一組點。 如果我們不知道應該將哪個邊界作為邊界,那么我將不知道如何找到正確的漏洞。

我不確定此方法是否比將點手動轉換為st_polygon構造函數的格式st_polygon

library(tidyverse)
library(sf)
#> Linking to GEOS 3.7.1, GDAL 2.4.0, PROJ 5.2.0

one_letter <- tibble::tibble(
  x = c(317.422, 315.605, 310.16, 304.367, 300.527, 299.141, 299.141, 299.141, 299.797, 301.297, 301.719, 300.805, 298.199, 295.684, 294.172, 293.672, 293.672, 293.672, 294.172, 295.684, 298.199, 300.805, 301.719, 300.684, 297.75, 294.93, 293.246, 292.688, 292.688, 292.688, 294.367, 299.203, 306.891, 314.566, 317.125, 319.695, 327.41, 335.234, 340.207, 341.953, 341.953, 341.953, 340.152, 334.797, 325.941, 316.715, 313.641, 312.145, 307.656, 303.695, 301.5, 300.828, 300.828, 300.828, 301.121, 301.906, 303.047, 304.066, 304.406, 305.078, 306.82, 307.094, 308.059, 312.82, 317.008, 318.406, 320.199, 325.586, 331.316, 335.109, 336.484, 336.484, 336.484, 336.016, 334.609, 332.25, 329.828, 328.938, 328.953, 329.332, 330.355, 332.008, 333.723, 334.297, 334.863, 336.563, 338.102, 338.375, 338.004, 336.723, 336.188, 336.188, 336.188, 336.516, 337.395, 338.664, 339.793, 340.172, 340.664, 342.148, 343.793, 344.91, 345.328, 345.328, 345.328, 344.5, 342.234, 338.832, 335.664, 334.609, 333.41, 329.813, 326.332, 324.152, 323.328, 323.281, 322.734, 318.75, 317.422, 317.422, 317.719, 318.82, 322.137, 325.664, 327.996, 328.844, 328.844, 328.844, 328.023, 325.723, 322.172, 318.75, 317.609, 316.52, 313.258, 309.871, 307.672, 306.891, 306.891, 306.891, 307.727, 310.031, 313.469, 316.656, 317.719, 317.719, 317.813, 319.559, 324.809, 330.023, 333.281, 334.406, 334.406, 334.406, 333.215, 329.797, 324.387, 319.008, 317.219, 315.516, 310.41, 305.215, 301.898, 300.734, 300.734, 300.734, 301.906, 305.289, 310.66, 316.023, 317.813, 317.813),
  y = c(8101.36, 8101.36, 8100.18, 8096.9, 8091.93, 8087.22, 8085.66, 8084.56, 8081.29, 8078.09, 8077.52, 8077.23, 8075.97, 8073.87, 8071.21, 8068.79, 8067.98, 8067.23, 8064.98, 8062.39, 8060.21, 8058.79, 8058.44, 8058.05, 8056.45, 8053.89, 8050.75, 8047.95, 8047.02, 8045.46, 8040.79, 8036.11, 8033.15, 8032.13, 8032.13, 8032.13, 8033.22, 8036.35, 8041.29, 8046.18, 8047.81, 8049.44, 8054.32, 8059.05, 8061.93, 8062.91, 8062.91, 8062.91, 8063.15, 8063.99, 8065.55, 8067.38, 8067.98, 8068.39, 8069.6, 8070.93, 8071.82, 8072.16, 8072.16, 8072.16, 8071.58, 8071.45, 8071.03, 8069.53, 8068.88, 8068.88, 8068.88, 8070.09, 8073.45, 8078.52, 8083.29, 8084.88, 8085.88, 8088.91, 8092.53, 8095.71, 8097.88, 8098.47, 8099.19, 8101.34, 8103.39, 8104.62, 8105.03, 8105.03, 8105.03, 8104.52, 8103.37, 8103.05, 8102.77, 8101.41, 8100.18, 8099.77, 8099.41, 8098.35, 8097.18, 8096.39, 8096.09, 8096.09, 8096.09, 8096.54, 8097.78, 8099.61, 8101.3, 8101.86, 8102.7, 8105.23, 8107.9, 8109.66, 8110.3, 8110.3, 8110.3, 8109.68, 8107.85, 8104.8, 8101.63, 8100.56, 8100.69, 8101.36, 8101.36, 8101.36, 8094.8, 8094.8, 8094.05, 8092, 8088.89, 8085.95, 8084.97, 8084.01, 8081.13, 8078.12, 8076.14, 8075.44, 8075.44, 8075.44, 8076.13, 8078.1, 8081.17, 8084.17, 8085.17, 8086.12, 8088.97, 8092.03, 8094.06, 8094.8, 8094.8, 8094.8, 8056.27, 8056.27, 8055.66, 8053.93, 8051.15, 8048.35, 8047.42, 8046.52, 8043.83, 8041.07, 8039.3, 8038.67, 8038.67, 8038.67, 8039.27, 8041, 8043.75, 8046.5, 8047.42, 8048.34, 8051.1, 8053.89, 8055.65, 8056.27, 8056.27, 8056.27),
  id = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
  section = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L)
)

one_letter %>%
  st_as_sf(coords = c("x", "y")) %>%
  group_by(section) %>%
  summarise(do_union = FALSE) %>%
  st_cast("POLYGON") %>%
  mutate(hole = section > 1) %>%
  group_by(hole) %>%
  summarise(do_union = FALSE) %>%
  st_intersection() %>%
  filter(origins == "1") %>%
  ggplot() +
  geom_sf()

reprex軟件包 (v0.2.1)創建於2019-03-04

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM