Cách tạo linestrings với một góc và độ dài xác định, được cố định vào một điểm


8

Tôi muốn tạo các linestrings với một góc xác định (ví dụ 160 °) và chiều dài (ví dụ 2m) được cố định với một số điểm của một linestring khác. Vì vậy, tôi muốn sử dụng hàm ST_DumpPoints để tìm các điểm và liên kết các chuỗi được tạo với chúng. Có cách nào để khai báo một góc (α) trong quá trình tạo linestring không? Dưới đây là một hình ảnh ví dụ:

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

Tôi muốn tạo ra các linestrings màu xanh.

BIÊN TẬP

Góc (α2) trong ảnh không thực sự mẫu mực. Nhưng thay vào đó là một góc phương vị 160 ° (như α1).

CẬP NHẬT

Câu trả lời từ Evil Genius đã giúp tôi tính toán độ rộng tối đa của một đa giác với một khía cạnh nhất định.

Câu trả lời:


11

Bạn có thể thực hiện điều này một vài cách khác nhau tùy thuộc vào loại đầu ra mà bạn muốn, nhưng khái niệm này là như nhau. Nhìn chung, việc thực hiện một phép quay đơn giản theo sau là một bản dịch thay vì cố gắng tính tọa độ trong một bước duy nhất.

Trong trường hợp này, các bước cơ bản là:

  • Tạo một dòng có độ dài mong muốn tại gốc (0,0). Đường này sẽ chạy dọc theo trục mà bạn muốn đo góc của mình và đặt nó ở chính giữa.
  • Xoay dòng xung quanh gốc.
  • Dịch dòng theo tọa độ của điểm mà bạn muốn nó được căn giữa.

Khung nhìn PostGIS sau đây tạo các dòng từ kịch bản ví dụ của bạn. Một vài điều được giả định:

  • Cột hình học được gọi là shape
  • Góc được đo từ trục x. Bản vẽ ví dụ của bạn hơi khó hiểu kể từ lần đầu tiên bạn đề cập đến 40 độ, đã vẽ một đường thẳng đứng chấm, nhưng sau đó nói rằng nó nên ở khoảng 160 độ. Tôi đã giải thích điều đó có nghĩa là bạn thực sự muốn đo từ trục x.
  • Dữ liệu được chiếu theo cùng đơn vị mà bạn muốn đo (ví dụ: mét).

    CREATE OR REPLACE VIEW <viewname> AS
    WITH vertices AS
    (SELECT 
          objectid, 
          (ST_DumpPoints(shape)).path[1] AS v_id, 
          (ST_DumpPoints(shape)).geom AS vertex
    FROM <source_data>
    )
    SELECT
        objectid,
        v_id,
        ST_SetSRID(ST_Translate(ST_Rotate(ST_MakeLine(ST_MakePoint( 1.0,0.0), 
                                                      ST_MakePoint(-1.0,0.0)),
                                          radians(40)), ST_X(vertex), ST_Y(Vertex)),
                                          ST_SRID(vertex)) AS newline
    FROM vertices

Để phá vỡ những gì thực sự xảy ra với dòng cuối cùng đó, bắt đầu từ phần bên trong nhất: ST_SetSRID(ST_Translate(ST_Rotate(ST_MakeLine(ST_MakePoint( 0,1.0), ST_MakePoint(0,-1.0)), radians(40)), ST_X(vertex), ST_Y(Vertex)), ST_SRID(vertex)) AS newline

  • ST_MakePoint(1.0,0.0)ST_MakePoint(-1.0,0.0): Tạo các điểm cuối cho một đường nằm ngang có độ dài mong muốn của chúng tôi và tập trung vào điểm gốc.
  • ST_MakeLine(...): Sử dụng điểm cuối mới được tạo của chúng tôi để tạo một dòng.
  • ST_Rotate(..., radians(40)): Xoay dòng mới xung quanh gốc.
  • ST_Translate(..., ST_X(vertex), ST_Y(vertex)): Căn giữa đường xoay vào điểm tham chiếu (đầu vào) của chúng tôi.
  • ST_SetSRID(..., ST_SRID(vertex)): Cung cấp cho dòng mới cùng SRID như hình dạng đầu vào.

Nếu bạn đang sử dụng PostGIS 2.0, bạn có thể đơn giản hóa việc này vì bạn có thể chỉ định một nguồn gốc khác cho ST_Rotate. Nếu bạn muốn xoay theo một góc dựa trên độ dốc của đường, bạn sẽ phải tính toán đó trước và thêm nó vào góc xoay.

Nếu dữ liệu không được chiếu trong cùng một đơn vị mà bạn muốn đo, bạn vẫn có thể làm điều gì đó tương tự, nhưng bạn sẽ cần thêm một bước:

  • Tạo một dòng (được chiếu trong một cái gì đó sử dụng những gì bạn muốn đo)
  • Quay
  • Phản hồi lại dự phóng mục tiêu của bạn
  • Dịch đến điểm đích

Biên tập

Bây giờ tôi hiểu ý của bạn qua góc độ. Về cơ bản, bạn muốn xoay theo chiều kim đồng hồ từ trục Y (0 là lên, 90 là đúng, 180 là xuống, v.v.).

Bạn vẫn cần phải sử dụng radianschức năng vì ST_Rotatemong đợi góc theo radian. Bạn sẽ có thể có được góc chính xác với hai thay đổi nhỏ:

  • Bắt đầu với một đường thẳng đứng (sử dụng ST_MakePoint(0.0,1.0)ST_MakePoint(0.0,-1.0))
  • Nhân góc của bạn với -1. Điều này sẽ làm cho nó tiêu cực, gây ra ST_rotatexoay nó theo chiều kim đồng hồ.radians(<angle> * -1)

Bạn là một thiên tài xấu xa! Cảm ơn bạn. Nó hoạt động hoàn hảo, nhưng thiết lập góc bên phải. Tôi làm việc với các góc (được lưu trữ trong một cột), giống như một điểm phơi sáng hoặc khía cạnh (0 đến 360 độ). Ví dụ, một khía cạnh của 200 ° (như hướng địa lý SSW): khi tôi vẽ sơ đồ đường thẳng, chúng không có góc vuông. Sử dụng độ () hướng địa lý giống như SSE và sử dụng radian () như SW.
Stefan

@StefanB. Tôi rất vui vì nó hữu ích! Tôi đã chỉnh sửa câu trả lời của mình (ở dưới cùng) để cho thấy cách bạn có thể thực hiện được góc bạn muốn.
Evil Genius

Nó hoạt động. Ý tưởng tuyệt vời!
Stefan
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.