Phân tích cạnh đa giác PostGIS (định hướng, chiều dài cạnh)


9

Tôi còn khá mới mẻ với thế giới của GIS và đặc biệt là PostGIS, vì vậy xin vui lòng cho tôi biết nếu câu trả lời có vẻ hiển nhiên ...

Tôi muốn làm phân tích trên một số tòa nhà. Một điều tôi quan tâm là bề mặt của chúng cùng với hướng tương ứng. Như minh họa trong hình dưới đây, tôi muốn có chiều dài và hướng (bình thường) của tất cả các cạnh trong một loạt các đa giác. Trong ví dụ tôi chỉ nhấn mạnh một bề mặt.

nhập mô tả hình ảnh ở đây

Một bảng kết quả có thể trông như thế này:

building_id | edge_id | orientation | edge_length
-------------------------------------------------
      1     |    1    |     315     |    10.0
      1     |    2    |      45     |     7.0
      1     |   ...   |     ...     |     ...

Tuy nhiên, tôi không chắc liệu đó có phải là một cách thông minh để lưu trữ kết quả để xử lý thêm hay không (ví dụ: tính khoảng cách từ cạnh đến tòa nhà tiếp theo, v.v.). Vì vậy, câu hỏi của tôi là gấp đôi:

  1. Có chức năng PostGIS hiệu quả nào có thể phân tích các cạnh của đa giác không? Trong trường hợp không có chức năng PostGIS riêng, tôi cũng sẽ quan tâm đến cách tiếp cận dựa trên Python.
  2. Điều gì sẽ là một cách thông minh để lưu trữ kết quả trong bảng PostGIS, vì các đa giác có thể có số cạnh khác nhau?

2
Trước tiên, hãy tạo các phân đoạn của đa giác: stackoverflow.com/questions/7595635/ , Sau đó, tọa độ điểm bắt đầu và điểm cuối sẽ chuyển đến các cột như x1, y1 và x2, y2 và hơn ST_Azimuth (ST_Startpoint (geometries), ST_Endpoint (hình học) . ( postgis.org/docs/ST_Azimuth.html )
Tamas Kosa

1
@TamasKosa: Bạn có bản chất của một câu trả lời hay. Tại sao không mở rộng nó thành một? Ngoài ra, đối với quy tắc, góc phương vị cần +/- pi / 2.
Martin F

1
@TamasKosa Đây là một cách tiếp cận tôi cũng đã nghĩ đến. Sử dụng ST_Ex thầmRing và sau đó nhận các góc phương vị như bạn nói. Làm thế nào tôi có thể lưu trữ kết quả một cách lý tưởng, vì các tòa nhà có thể có số cạnh khác nhau? Trong một bảng như tôi đã mô tả ở trên? Tôi đồng ý với MartinF, đây gần như là một câu trả lời;)
n1000

Chỉ tò mò, tại sao bạn muốn bình thường ... phơi nắng?
Martin F

1
Phần đầu tiên của câu hỏi của bạn đã được trả lời - bạn có thể sử dụng ST_Dumppoints và ST_Azimuth. Đối với phần thứ hai, vì không có phần tử không gian nào cho đầu ra, tôi sẽ nghĩ rằng một liên kết đến polygonID và edge_id như bạn sẽ tìm thấy.
John Powell

Câu trả lời:


10

Hôm qua tôi không có thời gian để tạo ra nó một cách chi tiết ... Xem giải pháp của tôi trong 4 bước:

CREATE OR REPLACE VIEW bd_segment AS
SELECT
      ST_PointN(geom, generate_series(1, ST_NPoints(geom)-1)) AS sp,
      ST_PointN(geom, generate_series(2, ST_NPoints(geom)  )) AS ep
    FROM
       -- extract the individual linestrings
       (SELECT (ST_Dump(ST_Boundary(the_geom))).geom
       FROM bd) AS linestrings;

CREATE OR REPLACE VIEW bd_segment_geom AS
SELECT sp, ep, st_makeline(sp, ep) 
FROM bd_segment;

CREATE OR REPLACE view bd_segment_id AS 
SELECT bd.gid, row_number() 
    OVER (order by bd.gid), degrees(st_azimuth(ff.sp, ff.ep)-1.57079633) AS az_deg,
    ST_LENGTH(ff.st_makeline) , ff.st_makeline FROM bd_segment_geom ff
JOIN bd ON st_touches(ff.st_makeline, bd.the_geom)
GROUP BY bd.gid, ff.sp, ff.ep, ff.st_makeline;

UPDATE bd_segment_id
SET az_deg = az_deg + 360
WHERE az_deg < 0;

Truy vấn cuối cùng cung cấp cho bạn các id tòa nhà với phép nối không gian bằng cách sử dụng st_touches. Hy vọng nó giúp. Cập nhật - Trong qgis giải pháp trông như thế này: nhập mô tả hình ảnh ở đây


1
Ấn tượng! Tôi đã nhận nó để làm việc. Cảm ơn bạn rất nhiều! Nó trở nên hơi chậm với một số lượng lớn các tòa nhà. Các góc phương vị không phải là quy tắc ngay bây giờ. Bạn cũng sẽ có một ý tưởng làm thế nào để giải quyết điều đó? Tôi không chắc chắn làm thế nào để tìm thấy bên "bên ngoài" của đa giác.
n1000

1
thêm 90 độ cho góc phương vị theo radian như thế này: độ (st_azimuth (ff.sp, ff.ep) +1.57079633). Nó sẽ tạo ra các giá trị đôi khi lớn hơn 360. nhưng với truy vấn cập nhật, bạn có thể thay thế các giá trị đó. Nếu bạn muốn sử dụng làm chế độ xem tĩnh, hãy tạo "XEM TẠO VẬT LIỆU" và lần đầu tiên nó sẽ không bị chậm.
Tamas Kosa

2
Không hẳn. Giả sử Bắc là 0 °, điều này sẽ cho bình thường về phía bên trong của đa giác / tòa nhà (như được thấy trong ảnh chụp màn hình của bạn). Nhưng bạn đã đúng - một cách đơn giản UPDATEnên thực hiện các mẹo. Cảm ơn một lần nữa cho giải pháp tuyệt vời này. Tôi sẽ đợi thêm vài ngày nữa nếu các câu trả lời khác xuất hiện, trước khi chấp nhận.
n1000

1
Thế còn ST_ForceRHR? Câu trả lời này thực sự có vẻ ổn.
Jakub Kania

@JakubKania Tôi đã cố gắng đưa ra một ST_ForceRHRgiải pháp, nhưng không thành công. Sẽ rất biết ơn về những gợi ý ... Tôi đã thửST_Dump(ST_Boundary(ST_ForceRHR(the_geom)))
n1000
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.