Làm thế nào để có được điểm gần nhất trên một đường thẳng đến một điểm nhất định?


28

Tôi đã sử dụng PostGIS từ lâu nhưng chưa bao giờ phải sử dụng LINESTRINGhình học ...! :)

Đây là những gì tôi muốn làm: Tôi có một bảng linestrings (đại diện cho các đường phố của một thành phố nhất định, SRID 3395) và tôi muốn tìm các linestrings gần nhất đến một điểm nhất định (vị trí GPS, SRID 4326).

Giải pháp tôi tìm thấy là chọn tất cả các linestrings trong điểm của tôi bằng expand()phương thức và xác định khoảng cách giữa mỗi linestring và điểm của tôi bằng ST_Distance()phương thức.

Đây là SQL:

SELECT myLineId, myLineName, ST_Distance(ST_Transform(GeomFromText('POINT(LON LAT)',4326),3395),myLineGeom) AS myLineDistance
FROM myLines
WHERE myLineGeom && expand(ST_Transform(GeomFromText('POINT(LON LAT)',4326),3395), 100)
ORDER BY myLineDistance;

Kết quả tôi nhận được trông ổn nhưng tôi có cảm giác có gì đó không ổn trong quá trình thực hiện.

1) Các bạn có nghĩ rằng expand()có thể có được tất cả các linestrings liên quan?

2) Các bạn có nghĩ rằng ST_Distance()phương pháp này là đúng để sử dụng? Tôi đoán tôi đang làm sai vì khoảng cách tôi muốn có là khoảng cách nhỏ nhất giữa điểm và đường của tôi chứ không phải khoảng cách giữa điểm và một trong những điểm của đường thẳng.

Hình minh họa:

văn bản thay thế

Câu trả lời:


11

quảng cáo 1) Nhìn vào tài liệu cho các chức năng đã sử dụng của bạn, tôi sẽ nói: "Có, tất cả các dòng liên quan sẽ được tìm thấy."

mở rộng (hình học, hình nổi)

Hàm này trả về một hộp giới hạn được mở rộng theo tất cả các hướng từ hộp giới hạn của hình dạng đầu vào, bằng một lượng được chỉ định trong đối số thứ hai. Rất hữu ích cho các truy vấn khoảng cách (), để thêm bộ lọc chỉ mục vào truy vấn.

A && B

Toán tử "&&" là toán tử "chồng chéo". Nếu hộp giới hạn của A chồng lên hộp giới hạn của B thì toán tử trả về true.

quảng cáo 2) Bạn sẽ có thể đạt được những gì bạn muốn thông qua:

line_interpolate_point(linestring, line_locate_point(LineString, Point))

line_interpolate_point (linestring, vị trí)

Nội suy một điểm dọc theo một dòng. Đối số đầu tiên phải là một LINE LINEING. Đối số thứ hai là float8 nằm giữa 0 và 1 đại diện cho tổng chiều dài 2d mà điểm phải được định vị.

line_locate_point (LineString, Point)

Trả về số float giữa 0 và 1 đại diện cho vị trí của điểm gần nhất trên LineString cho Điểm đã cho, dưới dạng một phần của tổng chiều dài dòng 2d. Bạn có thể sử dụng vị trí được trả về để trích xuất Điểm (line_interpolate_point)

Nguồn: http://main.merlin.com.ua/doc/postgis/docs/ch06.html


Đối với điểm 2), tôi chỉ tự hỏi liệu ST_Distance giữa hình học POINT và hình học LINESTRING có cho khoảng cách nhỏ nhất có thể giữa các luận đề (hay còn gọi là độ dài của đường vuông góc giữa POINT và LINGESTRING); tôi muốn có khoảng cách từ mọi hình học LINESTRING :)
Vivi

Và tôi đoán đó không phải là khoảng cách tôi đang tìm kiếm vì "hàm line_locate_point cung cấp cho bạn giá trị từ 0 đến 1 đại diện cho vị trí của điểm gần nhất trên LineString đến Điểm đã cho": /
Vivi

Tôi sợ bạn mất tôi trong bình luận cuối cùng của bạn. Bây giờ tôi không chắc chắn nữa những gì bạn muốn;)
underdark

1
Xin lỗi :) Tôi muốn điều này: đưa ra hình học LINESTRING (đại diện cho một đường dẫn) và hình học POINT, tôi muốn có hình dạng POINT gần nhất nằm trên đường dẫn (có thể không phải là một điểm của định nghĩa hình học LINESTRING). Có rõ không? Có lẽ tôi nên cập nhật bài viết của mình bằng một bản vẽ: D
Vivi

Tôi không thể cập nhật bài viết của mình vì vậy đây là một liên kết đến bản vẽ về những gì tôi muốn nhận: i.imgur.com/UwPxo.jpg
Vivi

7

Ê

Đầu tiên câu hỏi về những gì ST_Distance trả về. ST_Distance trả về khoảng cách ngắn nhất giữa đường và điểm (hoặc loại hình hình học nào được nhập) Điều đó có nghĩa là ST_Distance giữa điểm (1 3) và linestring (0 0,0 10) sẽ trả về 1. Khoảng cách sẽ không được đo giữa điểm và (0 0) hoặc điểm và (0 10) nhưng từ điểm (1 3) đến (0 3).

Vì vậy, từ những gì tôi hiểu ST_Distance cung cấp cho bạn câu trả lời bạn muốn.

Nếu bạn muốn tìm điểm (0 3) trong ví dụ trên, bạn có thể sử dụng ST_Closestpoint nếu bạn có PostGIS 1.5 Ví dụ của tôi, bạn sử dụng nó như thế này: ST_Closestpoint ('LINESTRING (0 0,0 10)' :: hình học, ' ĐIỂM (1 3) ':: hình học) sau đó bạn sẽ nhận được điểm (0 3), điểm trên đường gần nhất với điểm của bạn.

NickH HTH


5

Tôi đã tìm thấy nó :) (Tôi đoán: P)

Sử dụng ST_Line_Locate_Point()ST_Line_Interpolate_point()tôi đã xoay sở để có được một điểm KHÔNG PHẢI là một phần của định nghĩa LINESTRING nhưng là trên dòng đã nói :) Tất cả những gì tôi phải làm là lấy khoảng cách từ điểm của tôi đến điểm này và tôi đã hoàn thành.

SELECT AsText(ST_Line_Interpolate_Point(myLineGeom,ST_Line_Locate_Point(myLineGeom,ST_Transform(GeomFromText('POINT(LON LAT)',4326),3395))))
FROM myLines
WHERE myGeom && expand(ST_Transform(GeomFromText('POINT(LON LAT)',4326),3395), 100)

Các ST_Line_Locate_Point()phương pháp tìm vị trí của các điểm gần nhất trên dòng vào vấn đề nhất định, ST_Line_Interpolate_Pointphương pháp chuyển vị trí này vào một điểm.


1
St_distance giữa điểm và đường thẳng sẽ cho bạn câu trả lời giống nhau. Tại sao bạn nghĩ rằng bạn phải làm theo cách này?
Nicklas Avén

1
Tôi nghĩ ST_Distance có thể được sử dụng với bất kỳ loại hình học nào. postgis.refraction.net/docs/ST_Distance.html :ST_Distance(geometry g1, geometry g2)
Magno C

2

Chủ đề lưu trữ Postgis này có thể trả lời bạn http://postgis.refraction.net/pipermail/postgis-users/2007-June/016045.html


refraction.net không hoạt động đối với tôi: "refraction.net đã hết hạn vào ngày 14 tháng 9 năm 2010 và đang chờ gia hạn hoặc xóa."
underdark

@underdark nó hoạt động với tôi
dassouki

@dassouki: thật lạ: |
underdark

@underdark refraction.net hoạt động trở lại
ThomasG77
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.