Gwyn Case
Gwyn Case

Reputation: 45

Create lines within polygons at given points

Given a spatial polygon

library(sf)

df <- data.frame(
  lon = c(119.4, 119.4, 119.4, 119.5, 119.5),
  lat = c(-5.192, -5.192, -5.167, -5.167, -5.191)
)

polygon <- df %>%
  st_as_sf(coords = c("lon", "lat"), crs = 4326) %>%
  summarise(geometry = st_combine(geometry)) %>%
  st_cast("POLYGON")

with some points inside it

df2 <- data.frame(
  lon = c(119.45, 119.49, 119.47),
  lat = c(-5.172, -5.190, -5.183)
)

points <- df2 %>%
  st_as_sf(coords = c("lon", "lat"), crs = 4326) %>%
  summarise(geometry = st_combine(geometry)) %>%
  st_cast("MULTIPOINT")

how can I draw a straight, horizontal line through each point, from one end of the polygon to the other? That is, draw three straight lines within the polygon, each line crossing through one of the points. I have found several examples of drawing lines that connect points, or use points as start and end locations, but in my case the points simply mark the desired y-values of the horizontal lines.

Thanks in advance!

Upvotes: 1

Views: 791

Answers (1)

dieghernan
dieghernan

Reputation: 3402

This approach just loops over the points and creates a new LINESTRING object with the x coordinates of the POLYGON and the y coordinates of the POINT:

library(sf)
library(dplyr)

df <- data.frame(
  lon = c(119.4, 119.4, 119.4, 119.5, 119.5),
  lat = c(-5.192,-5.192,-5.167,-5.167,-5.191)
)

polygon <- df %>%
  st_as_sf(coords = c("lon", "lat"), crs = 4326) %>%
  summarise(geometry = st_combine(geometry)) %>%
  st_cast("POLYGON")

plot(polygon)

df2 <- data.frame(lon = c(119.45, 119.49, 119.47),
                  lat = c(-5.172,-5.190,-5.183))

points <- df2 %>%
  st_as_sf(coords = c("lon", "lat"), crs = 4326) %>%
  summarise(geometry = st_combine(geometry)) %>%
  st_cast("MULTIPOINT")

plot(points, add = TRUE, col = "red")


# Solution via a loop

xminmax <- c(min(df$lon), max(df$lon))

# Iterate and create lines
for (i in 1:3) {
  l <- st_linestring(matrix(
    c(xminmax[1],
      df2[i, "lat"],
      xminmax[2],
      df2[i, "lat"]),
    nrow = 2,
    byrow = TRUE
  ))
  # Create final object line
  if (i == 1) {
    line <- l
  } else {
    line <- c(line, l)
  }
}

# Result is line MULTILINESTRING object


plot(line, col = "green", add = TRUE)

Created on 2021-02-15 by the reprex package (v1.0.0)

Upvotes: 2

Related Questions