Lựa chọn các tính năng trong số trên trên hoặc trên dưới một dòng sử dụng R


8

Đưa ra một dòng và một tập hợp các điểm, tôi không thể tìm ra cách sử dụng sfđể xác định phía nào của dòng mỗi điểm rơi.

Một ví dụ tái sản xuất nhỏ sau đây, được điều chỉnh từ một câu hỏi khác

# Load Libraries ----------------------------------------------------------

library('sf')

# Test data ---------------------------------------------------------------

points.df <- data.frame(
    'x' = c(-53.50000, -54.15489, -54.48560, -52.00000, -52.57810, -49.22097, -48.00000),
    'y' = c(-38.54859, -41.00000, -38.80000, -38.49485, -38.00000, -40.50000, -37.74859)
)


line.df <- data.frame(
    'x' = c(-54.53557, -52.00000, -50.00000, -48.00000, -46.40190),
    'y' = c(-39.00000, -38.60742, -38.08149, -38.82503, -37.00000)
)

# Create 'sf' objects -----------------------------------------------------

points.sf <- st_as_sf(points.df, coords = c("x", "y"))

st_crs(points.sf) <- st_crs(4326) # assign crs

line.sf <- st_sf(id = 'L1', st_sfc(st_linestring(as.matrix(line.df), dim = "XY")))
st_crs(line.sf) <- st_crs(4326) # assign crs


# Plots -------------------------------------------------------------------

xmin <- min(st_bbox(points.sf)[1], st_bbox(line.sf)[1])
ymin <- min(st_bbox(points.sf)[2], st_bbox(line.sf)[2])
xmax <- max(st_bbox(points.sf)[3], st_bbox(line.sf)[3])
ymax <- max(st_bbox(points.sf)[4], st_bbox(line.sf)[4])

plot(points.sf, pch = 19, xlab = "Longitude", ylab = "Latitude",
     xlim = c(xmin,xmax), ylim = c(ymin,ymax), graticule = st_crs(4326), axes = TRUE)

plot(line.sf, col = "#C72259", add = TRUE)
text(st_coordinates(points.sf), as.character(1:7), pos = 3)

đầu ra cốt truyện

Trong ví dụ này, thật dễ dàng để xác minh rằng các điểm 2 và 6 nằm ở phía nam của dòng và phần còn lại ở phía bắc. Làm thế nào tôi có thể tự động hóa việc ghi nhãn?

sfCâu trả lời không dựa trên cũng được chào đón.

Câu trả lời:


8

Câu trả lời được cung cấp có liên quan đến câu hỏi này Làm thế nào để đặt một đối tượng SpatialPoints để lấy các điểm nằm ở mỗi bên của một đối tượng SpatialLines bằng R? nhưng sử dụng sfthư viện thay vì sp.

Kiểm tra mã nhận xét dưới đây.

# Load Libraries ----------------------------------------------------------

library('sf')

# Test data ---------------------------------------------------------------

points.df <- data.frame(
  'x' = c(-53.50000, -54.15489, -54.48560, -52.00000, -52.57810, -49.22097, -48.00000),
  'y' = c(-38.54859, -41.00000, -38.80000, -38.49485, -38.00000, -40.50000, -37.74859),
  'id' = as.character(c(1:7))
)


line.df <- data.frame(
  'x' = c(-54.53557, -52.00000, -50.00000, -48.00000, -46.40190),
  'y' = c(-39.00000, -38.60742, -38.08149, -38.82503, -37.00000)
)

# Create 'sf' objects -----------------------------------------------------

points.sf <- st_as_sf(points.df, coords = c("x", "y"))

st_crs(points.sf) <- st_crs(4326) # assign crs

line.sf <- st_sf(id = 'L1', st_sfc(st_linestring(as.matrix(line.df), dim = "XY")))
st_crs(line.sf) <- st_crs(4326) # assign crs    

# Plots -------------------------------------------------------------------

xmin <- min(st_bbox(points.sf)[1], st_bbox(line.sf)[1])
ymin <- min(st_bbox(points.sf)[2], st_bbox(line.sf)[2])
xmax <- max(st_bbox(points.sf)[3], st_bbox(line.sf)[3])
ymax <- max(st_bbox(points.sf)[4], st_bbox(line.sf)[4])

plot(points.sf, pch = 19, xlab = "Longitude", ylab = "Latitude",
     xlim = c(xmin,xmax), ylim = c(ymin,ymax), graticule = st_crs(4326), axes = TRUE)

plot(line.sf, col = "#272822", lwd = 2, add = TRUE)
text(st_coordinates(points.sf), as.character(points.sf$id), pos = 3)

bản đồ1

# Create Polygons from line -----------------------------------------------

# Add x and y offsets (in degrees units)
offsetX <- 0
offsetY <- 3

polySideUp <- rbind(c(st_bbox(line.sf)['xmax'] + offsetX, 
                       st_bbox(line.sf)['ymax'] + offsetY),
                     c(st_bbox(line.sf)['xmin'] - offsetX, 
                       st_bbox(line.sf)['ymax'] + offsetY),
                     as.data.frame(st_coordinates(line.sf))[,c(1,2)],
                     c(st_bbox(line.sf)['xmax'] + offsetX, 
                       st_bbox(line.sf)['ymax'] + offsetY))

polySideDown <- rbind(c(st_bbox(line.sf)['xmax'] + offsetX, 
                       st_bbox(line.sf)['ymin'] - offsetY),
                     c(st_bbox(line.sf)['xmin'] - offsetX, 
                       st_bbox(line.sf)['ymin'] - offsetY),
                     as.data.frame(st_coordinates(line.sf))[,c(1,2)],
                     c(st_bbox(line.sf)['xmax'] + offsetX, 
                       st_bbox(line.sf)['ymin'] - offsetY))

# Create sf objects
polySideUp <- st_sf("id" = 'sideUp', st_sfc(st_polygon(list(as.matrix(polySideUp))), crs = 4326))
polySideDown <- st_sf("id" = 'sideDown', st_sfc(st_polygon(list(as.matrix(polySideDown))), crs = 4326))

# Plot
plot(polySideUp, xlab = "Longitude", ylab = "Latitude", col = "#C72259", 
     xlim = c(xmin - offsetX, xmax + offsetX), ylim = c(ymin - offsetY, ymax + offsetY), graticule = st_crs(4326), axes = TRUE)
plot(polySideDown, col = "#53A8BD", add = TRUE)
plot(points.sf$geometry, pch = 19, add = TRUE)
plot(line.sf, col = "#272822", lwd = 2, add = TRUE)
text(st_coordinates(points.sf), as.character(points.sf$id), pos = 3)

bản đồ2

# Select points in side up
pointsInSideUp <- st_intersection(points.sf, polySideUp)

print(pointsInSideUp)

in1

# Select points in side down
pointsInSideDown <- st_intersection(points.sf, polySideDown)

print(pointsInSideDown)

in2

# Plot intersection
plot(polySideUp, xlab = "Longitude", ylab = "Latitude", col = "#C72259", 
     xlim = c(xmin - offsetX, xmax + offsetX), ylim = c(ymin - offsetY, ymax + offsetY), graticule = st_crs(4326), axes = TRUE)
plot(polySideDown, col = "#53A8BD", add = TRUE)
plot(pointsInSideUp, pch = 19, col = "#53A8BD", add = TRUE)
plot(pointsInSideDown, pch = 19, col = "#C72259", add = TRUE)
plot(line.sf, lwd = 2, col = "#272822", add = TRUE)
text(st_coordinates(points.sf), as.character(points.sf$id), pos = 3)

bản đồ3


1
Chuyển đổi sang CRS khác có thể không phải là điều nên làm - có thể người hỏi sẽ muốn "phía bắc" và "phía nam" đề cập đến vĩ độ. Tôi không biết lý do tại sao bạn chọn cái cụ thể đó bởi vì nó hơi bị xoay so với thời gian dài tại thời điểm đó. Tôi sẽ gắn bó với lat-long hoặc mercator. Tôi sẽ xóa câu trả lời của mình vì đây là một triển khai tốt đẹp của tôi.
Spainedman

Xin chào @Spacesman! Bạn có nghĩa là chuyển đổi sang crs 32721? Bạn đúng mà không cần thiết. Đó là UTM khu 21 Nam; Tôi nghĩ rằng các điểm rơi trong khu vực đó nhưng tôi không chắc chắn. Tôi sẽ sửa đổi câu trả lời của mình bằng crs 4326. Cảm ơn!
Guzmán

OP đã hỏi bên trên / bên dưới trong bối cảnh 32721, nếu đó không phải là mục đích thì Q nên được cập nhật, không phải câu trả lời này cho Q. hiện tại (Q bao gồm phía trên / bên dưới và phía bắc / phía nam vì vậy nó hoàn toàn mơ hồ) .
mdsumner

1
CRS 32721 trong Q ban đầu của tôi đã đến đó đơn giản vì nó được sử dụng trong đoạn mã mà tôi đã tái sử dụng ... xấu của tôi! Tôi đã cập nhật câu hỏi của mình để thoát khỏi sự chuyển đổi có khả năng gây nhầm lẫn từ 4326 sang 3721.
HAVB

6

Thuật toán phác thảo, cũng đưa ra định nghĩa mạnh hơn về "phía bắc hoặc phía nam" của dòng:

Biến đường thẳng thành một đa giác bằng cách thêm hai đoạn đường phụ từ điểm cuối xuống Y = -Infinity hoặc ít nhất là xa hơn về phía nam so với điểm cực nam. Sau đó làm một bài kiểm tra điểm đa giác. Các điểm trong đa giác là phía nam của dòng.

Lặp lại để tạo một đa giác với các phân đoạn phụ cực dương (hoặc lớn). Điều đó cho bạn điểm phía bắc của dòng.

Các điểm trong cả hai đa giác đều không được xác định theo hướng bắc-nam của bản chất đường - chúng ở phía đông hoặc phía tây của đường.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.