Tìm cạnh đối diện của đa giác
Tôi có một đa giác và biết 2 điểm. Một là tâm của đa giác và một nằm ngoài đa giác. Tôi đang cố gắng tìm điểm đối diện của đa giác nơi chuỗi đường thẳng của 2 điểm đã biết cắt đa giác.
Dưới đây là SQL tôi đang sử dụng để tìm điểm đó bằng cách lấy chuỗi dòng và kéo dài nó ra khỏi đa giác, sau đó lấy điểm giao cuối cùng.
st_astext(st_endpoint(ST_Intersection(pg.poly_geog::geometry,
(
select
st_makeline(a,
st_translate(b,
sin(az2) * len,
cos(az2) * len))
from
(
select
a,b,
ST_Azimuth(b,a) as az2,
ST_Distance(a,b) + 0.00001 as len
from
(select
st_makepoint(c1.longitude, c1.latitude)::geography::geometry as a,
ST_Centroid(st_astext(pg.poly_geog))::geography::geometry as b )a )b))))
Điều này dường như hoạt động cho đến khi tôi bắt đầu chạy nhiều thử nghiệm hơn và nhận thấy rằng nó chỉ hoạt động nếu chuỗi dòng giữa các điểm nằm trong một tiêu đề nhất định. Nếu chuỗi dòng có tiêu đề từ phải sang trái thì nó hoạt động tốt và tôi có thể nhận được điểm giao đầu tiên và tính toán trên của điểm giao đối diện. Nếu chuỗi dòng đang đi theo hướng kết hợp cho một đa giác khác thì tôi đang nhận điểm được trả về từ cùng phía với giao điểm ban đầu.
Nếu tôi chuyển xung quanh điểm st_endpoint thành điểm st_start thì nó chỉ thay đổi theo hướng mà hàm hoạt động.
Ive cũng đã thử ST_GeometryN nhưng điều đó cũng chỉ hoạt động theo một hướng nhất định.
Làm cách nào tôi có thể làm cho điều này hoạt động bất kể tiêu đề trên chuỗi dòng hoặc làm cách nào để xác định xem tôi cần sử dụng điểm đầu hay điểm cuối
Trả lời
Tôi không chắc liệu tôi có hiểu chính xác bản dịch tự động của văn bản câu hỏi của bạn hay không, nhưng đánh giá bằng mã SQL và hình ảnh,
chạy tập lệnh dưới dạng CTE
(nếu cần, bạn có thể chuyển đổi nó thành một biểu mẫu truy vấn con, điều này sẽ khiến bạn thoải mái hơn)
WITH
tbla AS (SELECT ST_MakeLine(a.geom, ST_Centroid(b.geom)) geom FROM pnt a, polygon b),
tblb AS (SELECT ST_Azimuth(ST_StartPoint(geom), ST_EndPoint(geom)) as azimuth, ST_Distance(ST_StartPoint(geom), ST_EndPoint(geom)) + 0.00001 as length FROM tbla),
tblc AS (SELECT ST_MakeLine(a.geom, ST_Translate(a.geom, sin(azimuth)*length, cos(azimuth)*length)) geom FROM tbla a, tblb b),
tbld AS (SELECT ST_Intersection(a.geom, ST_ExteriorRing(b.geom)) geom FROM tblc a JOIN polygon b ON ST_Intersects(a.geom, b.geom))
SELECT (ST_Dump(geom)).geom geom FROM tbld;
Kiểm tra kết quả của bạn,
Chữ viết có tên: ST_PolygonPunchedThroughArrow... 🙂
Nếu bạn chỉ đang tìm kiếm 1 điểm đối lập, chỉ cần tiếp tục logic nghiên cứu địa lý xa hơn một chút, chẳng hạn như sau:
WITH
tbla AS (SELECT ST_MakeLine(a.geom, ST_Centroid(b.geom)) geom FROM pnt a, polygon b),
tblb AS (SELECT ST_Azimuth(ST_StartPoint(geom), ST_EndPoint(geom)) as azimuth, ST_Distance(ST_StartPoint(geom), ST_EndPoint(geom)) + 0.00001 as length FROM tbla),
tblc AS (SELECT ST_MakeLine(a.geom, ST_Translate(a.geom, sin(azimuth)*length, cos(azimuth)*length)) geom FROM tbla a, tblb b),
tbld AS (SELECT ST_Intersection(a.geom, ST_ExteriorRing(b.geom)) geom FROM tblc a JOIN polygon b ON ST_Intersects(a.geom, b.geom)),
tble AS (SELECT (ST_Dump(geom)).geom geom FROM tbld)
SELECT (a.geom) geom, ST_Distance(a.geom, b.geom) dist FROM tble a, tbla b ORDER BY dist DESC LIMIT 1;
Dịch bằng www.DeepL.com/Translator (phiên bản miễn phí)