Tính chiều dài đa giác dọc theo một đường thẳng?


8

Tôi cần tính toán độ dài của đa giác dọc / chiếu trên một dòng. Một hình ảnh để hiển thị ý tưởng:

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

Tôi có hàng ngàn đa giác được "chiếu" trên các dòng để xác minh xem chúng thuộc về bao nhiêu mét. Các đa giác là không đều, với định hướng khác nhau, một phần của chúng giao nhau trong dòng, một phần của chúng không.

Tôi đã thử:

  1. Định vị các tính năng dọc theo công cụ đường trong ArcGIS Pro, nhưng nó chỉ cung cấp chiều dài của đường cho phần chồng chéo của một đa giác (mô tả công cụ ở đây trợ giúp ESRI )

  2. Hình học giới hạn tối thiểu với tùy chọn 'vỏ lồi', nhưng nó chỉ cho khoảng cách giữa các điểm đối cực của đa giác, không tương đồng với dòng của tôi (mô tả công cụ ở đây trợ giúp ESRI

Tôi có thiếu một công cụ cho việc này trong ArcGIS hoặc QGIS không? Bạn sẽ có một giải pháp cho việc này?


Là dòng của bạn là một đường thẳng?
JiyuuSensei

Vì bạn có một yêu cầu duy nhất, có vẻ như không hợp lý khi một công cụ như vậy không tồn tại. Bạn chắc chắn có thể mã hóa một công cụ như vậy bằng cách sử dụng các hàm trig và các hàm trợ giúp hình học khác nhau, nhưng trước tiên bạn cần chọn một nền tảng phần mềm.
Vince

@JiyuuSensei không, thực ra đó là mạng đa tuyến - như mạng đường bộ hoặc mạng đường ống. Vì vậy, điều này sẽ hoạt động như tính toán "độ dài đa giác" này cho đoạn đường gần nhất của mạng. Vì vậy, về cơ bản, ý tưởng về cách Định vị các tính năng dọc theo công cụ dòng hoạt động như thế nào.
Konrad Gje

Câu trả lời:


7

Sử dụng QGIS:

(1) Tạo lớp điểm của các đỉnh đa giác bằng công cụ Trích xuất đỉnh (trong Hộp công cụ xử lý QGIS> Hình học vectơ).

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

(2) Mở bảng thuộc tính của lớp Vertices mới được tạo .

(3) Khởi động Máy tính Trường và;

(3A) Tạo một trường mới, hãy gọi nó là min_poly để lưu khoảng cách tối thiểu và đưa ra biểu thức:

minimum(
 line_locate_point(
  geometry:=geometry(get_feature_by_id('Lines', '1')), point:=$geometry), 
 group_by:="fid")

Lưu ý: bạn sẽ cần thay đổi tên người 'Lines'dùng dòng thực tế của mình và '1'thành id dòng bạn có trong bảng thuộc tính.

(3B) Tạo một trường mới khác, hãy gọi nó là max_poly để lưu khoảng cách tối đa và đưa ra biểu thức:

maximum(
 line_locate_point(
  geometry:=geometry(get_feature_by_id('Lines', '1')), point:=$geometry), 
 group_by:="fid")

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

Vì lớp Vertices giữ trường fid từ id đa giác ban đầu, bạn sẽ tìm thấy min_polymax_poly là khoảng cách tối thiểu / tối đa dọc theo đường cho mỗi đa giác.

(Ví dụ trên cho thấy đa giác đầu tiên fid = 1 kéo dài từ 8.688 đến 24,45, trong khi đa giác thứ hai fid = 2 là từ 35.062 đến 42.496).


5

Tôi không biết cách thực hiện với QGIS hoặc ArcGIS nhưng những gì bạn muốn có cảm giác như chiều rộng của hộp giới hạn định hướng. Như một bằng chứng về khái niệm tôi đã xoay hình ảnh mẫu của bạn để đường chiếu nằm ngang.

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

Sau đó, tôi số hóa các đa giác từ hình ảnh và tạo phong bì cho chúng. Chiều rộng của phong bì trả lời câu hỏi của bạn.

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

Những gì còn thiếu là một công cụ tạo hộp giới hạn ở một góc nhất định. QGIS không có công cụ hộp giới hạn tối thiểu theo định hướng nhưng người dùng không thể đưa ra một góc cố định cho điều đó. Có lẽ bạn có thể áp dụng giải pháp PostGIS từ câu trả lời được chấp nhận cho câu hỏi này Tạo "hộp giới hạn xiên" với tỷ lệ chiều rộng / chiều cao tối đa? .


Câu trả lời này sẽ là cách tiếp cận tốt nhất vì rất dễ có được hộp giới hạn định hướng trong QGIS (với chiều rộng và chiều cao của đường bao) nhưng hai mặt của hộp giới hạn định hướng này nhất thiết phải tương đương với đường tham chiếu và điều kiện này không được đảm bảo . Đây là vấn đề với đa giác không đều.
xunilk

2

Dựa trên câu trả lời của @ kazuhito, tôi đã kết hợp một biểu thức hacky duy nhất trong Máy tính Trường QGIS sẽ làm điều tương tự trong một bước.

Tuy nhiên tôi có thể tưởng tượng điều này sẽ rất tốn tài nguyên trên các bộ dữ liệu lớn hơn. Tôi nghĩ rằng vấn đề này phù hợp nhất với việc triển khai Python, rõ ràng xử lý tham chiếu và lặp lại tốt hơn nhiều so với Máy tính Trường.

array_last(array_sort(array_foreach(
generate_series(1,num_points($geometry)-1),
line_locate_point(aggregate('lines','collect',$geometry),
point_n($geometry,@element))),1)) 
- array_first(array_sort(array_foreach(
generate_series(1,num_points($geometry)-1),
line_locate_point(aggregate('lines','collect',$geometry),
point_n($geometry,@element))),1))

Điều này trước tiên tạo ra một 'mảng' số nút bằng cách sử dụng generate_series(), chỉ định mức tối đa là số nút trong mỗi đa giác - đây là num_points($geometry), trừ đi 1 để bỏ qua nút đầu tiên / nút cuối được lặp lại.

Sau đó, bạn có thể chuyển các giá trị của mảng này thông qua một hàm để tạo ra một mảng khác bằng cách sử dụng array_foreach(). Ở đây, chúng ta chuyển số nút đa giác (được biểu thị là @element) point_n(), trả về hình dạng thực của nút đó, sau đó chúng ta đưa nó vào line_locate_point()để xác định độ dài của nó dọc theo dòng được chỉ định (xem Lưu ý quan trọng bên dưới).

Mảng kết quả sau đó được sắp xếp theo thứ tự tăng dần bằng cách sử dụng array_sort(), sau đó cho phép chúng ta có được khoảng cách "ngoài cùng bên trái" và "ngoài cùng bên phải" dọc theo dòng sử dụng array_last()array_first(). Trừ hai và kết quả là "chiều dài" của đa giác dọc theo đường thẳng.

Xem bên dưới để biết ví dụ về biểu thức trên được hiển thị dưới dạng nhãn trong đa giác (cộng với khoảng cách dòng "ngoài cùng bên trái" và "ngoài cùng bên phải" tách ra khỏi biểu thức trên). Để so sánh tôi cũng đã bao gồm các đỉnh được trích xuất và các giá trị khoảng cách dòng có liên quan. Các đỉnh màu xanh lá cây là các đỉnh "ngoài cùng bên trái" và "ngoài cùng bên phải" dọc theo đường thẳng. Lưu ý đa giác trên cùng bên trái nơi điểm màu xanh lá cây thực sự nằm dọc theo đường thẳng hơn điểm bên phải bên dưới nó, do góc của đường ...

Lưu ý quan trọng :

Hình dạng lớp đường được tham chiếu ở đây bằng cách sử dụng aggregate(). Bạn sẽ cần thay đổi tên lớp ( 'lines') theo yêu cầu và nếu bạn có nhiều dòng, bạn nên thêm bộ lọc để chỉ định dòng nào bạn muốn so sánh với nó, ví dụ : aggregate('lines','collect',$geometry,"name"='TrainLine1'). Để làm cho điều này tự động hoạt động trên dòng gần nhất, tôi thực sự khuyên dùng SQL hoặc Python trên Field Calc.

Ngoài ra, điều này sẽ tính toán "chiều dài" của Đa giác ALONG dòng, bao gồm cả nếu dòng bị xoắn theo ví dụ của tôi. Nếu bạn muốn khoảng cách đường thẳng ... có thể tính toán distance()giữa các nút có liên quan?

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


1

Cách tiếp cận tốt nhất trong QGIS để làm điều đó (xem xét hàng ngàn đa giác được "chiếu" trên một đường tham chiếu) là xác định hộp giới hạn được xoay bởi góc giữa đường tham chiếu và trục X. Góc này được xác định dễ dàng bằng cách sử dụng công cụ trích xuất đỉnh (trong Hộp công cụ xử lý QGIS -> hình học vectơ) cho đường tham chiếu. Từ ví dụ về hình ảnh sau, góc yêu cầu được xác định bằng giá trị trong bảng thuộc tính của lớp Vertices sử dụng công thức này:

90 - 63.91873763467915 = 26,081262365320853 độ.

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

Giới thiệu góc trên trong công cụ Xoay của Hộp công cụ xử lý và chạy nó:

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

được tạo ra một lớp xoay có hộp giới hạn có trong bảng thuộc tính của nó chiều dài của đa giác được chiếu trên đường tham chiếu. Cuối cùng có thể được quan sát bằng cách chạy công cụ này của Hộp công cụ xử lý:

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

Ở hình ảnh sau, chiều dài của đa giác được chiếu trên một dòng là giá trị được tìm thấy trong chiều rộng trường .

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

Có thể nhận thấy ở hình ảnh sau đây rằng chiều dài dự kiến ​​của đa giác được xem xét, nó sẽ như mong đợi vì đường tham chiếu được xoay bởi 26,081262365320853 độ (thu được bằng công cụ Xoay của Hộp công cụ xử lý) song song với trục X.

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

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.