วิธีรับคะแนนที่ใกล้ที่สุดในระยะเวลาที่กำหนดไปยังจุดที่กำหนดได้อย่างไร


28

ฉันใช้ PostGIS มานานแล้ว แต่ไม่เคยใช้LINESTRINGเรขาคณิต ... ! :)

นี่คือสิ่งที่ฉันต้องการจะทำ: ฉันมีตารางของ linestrings (หมายถึงถนนของเมืองที่ระบุ SRID 3395) และฉันต้องการค้นหา linestrings ที่ใกล้ที่สุดไปยังจุดที่กำหนด (ตำแหน่ง GPS, SRID 4326)

วิธีการแก้ปัญหาที่ฉันพบคือการเลือก linestrings ทั้งหมดภายในจุดของฉันโดยใช้expand()วิธีการและกำหนดระยะห่างระหว่างแต่ละ linestring และจุดของฉันโดยใช้ST_Distance()วิธีการ

นี่คือ 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;

ผลลัพธ์ที่ฉันได้รับดูโอเค แต่ฉันรู้สึกว่ามีบางอย่างผิดปกติในการใช้งานของฉัน

1) พวกคุณคิดว่ามันexpand()จะได้รับความเกี่ยวข้องทั้งหมดหรือไม่?

2) คุณคิดว่าST_Distance()วิธีการใช้นั้นถูกต้องหรือไม่? ฉันเดาว่าฉันทำผิดเพราะระยะทางที่ฉันต้องการคือระยะทางที่เล็กที่สุดระหว่างจุดกับเส้นของฉันและไม่ใช่ระยะห่างระหว่างจุดนั้นกับจุดใดจุดหนึ่งของจุดหลอมเหลว

ภาพประกอบ:

ข้อความแสดงแทน

คำตอบ:


11

โฆษณา 1)ดูเอกสารสำหรับฟังก์ชั่นการใช้งานของคุณฉันจะพูดว่า: "ใช่แล้วคุณจะพบ linestrings ที่เกี่ยวข้องทั้งหมด"

ขยาย (เรขาคณิตลอย)

ฟังก์ชันนี้ส่งคืนกล่องขอบเขตที่ขยายในทุกทิศทางจากกล่องขอบของเรขาคณิตอินพุตโดยจำนวนเงินที่ระบุในอาร์กิวเมนต์ที่สอง มีประโยชน์มากสำหรับการค้นหาระยะทาง () เพื่อเพิ่มตัวกรองดัชนีลงในแบบสอบถาม

A & B

ตัวดำเนินการ "&&" เป็นตัวดำเนินการ "ทับซ้อน" ถ้ากล่องขอบของ A ทับกล่องขอบของ B ตัวดำเนินการจะคืนค่าจริง

โฆษณา 2)คุณควรจะสามารถบรรลุสิ่งที่คุณต้องการผ่าน:

line_interpolate_point(linestring, line_locate_point(LineString, Point))

line_interpolate_point (สถานที่ตั้ง)

สอดแทรกจุดตามเส้น อาร์กิวเมนต์แรกต้องเป็น LINESTRING อาร์กิวเมนต์ที่สองคือ float8 ระหว่าง 0 ถึง 1 แทนเศษส่วนของความยาวรวม 2d ที่จุดนั้นจะต้องอยู่

line_locate_point (LineString, Point)

ส่งคืนค่าทศนิยมระหว่าง 0 ถึง 1 ซึ่งแทนตำแหน่งของจุดที่ใกล้ที่สุดบน LineString ไปยังจุดที่กำหนดซึ่งเป็นเศษส่วนของความยาวบรรทัด 2d ทั้งหมด คุณสามารถใช้ตำแหน่งที่ส่งคืนเพื่อแยกจุด (line_interpolate_point)

ที่มา: http://main.merlin.com.ua/doc/postgis/docs/ch06.html


สำหรับจุดที่ 2) ฉันแค่สงสัยว่า ST_Distance ระหว่างเรขาคณิต POINT และเรขาคณิต LINESTRING ให้ระยะทางที่เล็กที่สุดที่เป็นไปได้ระหว่างวิทยานิพนธ์ (หรือที่รู้จักความยาวของเส้นตั้งฉากระหว่าง POINT และ LINGESTRING); ฉันไม่ต้องการระยะทางจากทุกเรขาคณิต LineString :)
Vivi

และฉันเดาว่ามันไม่ใช่ระยะทางที่ฉันกำลังมองหาตั้งแต่ "ฟังก์ชั่น line_locate_point ให้ค่าระหว่าง 0 และ 1 แสดงตำแหน่งของจุดที่ใกล้ที่สุดบน LineString ไปยังจุดที่กำหนด": /
Vivi

ฉันเกรงว่าคุณจะสูญเสียฉันในความคิดเห็นสุดท้ายของคุณ ตอนนี้ฉันไม่แน่ใจอีกต่อไปสิ่งที่คุณต้องการ;)
underdark

1
ขออภัย :) ฉันต้องการสิ่งนี้: ให้รูปทรงเรขาคณิต LINESTRING (แสดงถึงเส้นทาง) และรูปทรงเรขาคณิตจุดฉันต้องการมีรูปทรงเรขาคณิตจุดที่ใกล้ที่สุดซึ่งอยู่บนเส้นทาง (ซึ่งอาจไม่ใช่จุดของความหมายรูปทรงเรขาคณิต LINESTRING) ชัดเจนหรือไม่ บางทีฉันควรอัปเดตโพสต์ด้วยภาพวาด: D
Vivi

ฉันไม่สามารถอัปเดตโพสต์ของฉันดังนั้นนี่คือลิงก์ไปยังภาพวาดของสิ่งที่ฉันต้องการรับ: i.imgur.com/UwPxo.jpg
Vivi

7

สวัสดี

ก่อนอื่นคำถามเกี่ยวกับสิ่งที่ ST_ ระยะทางกลับมา ST_ ระยะทางส่งคืนระยะทางที่สั้นที่สุดระหว่างบรรทัดและจุด (หรือชนิดของรูปทรงเรขาคณิตที่ถูกป้อน) นั่นหมายความว่า ST_ ระยะทางระหว่างจุด (1 3) และระยะห่าง (0 0,0 10) จะกลับมา 1 ระยะทางจะไม่ถูกวัดระหว่าง จุดและ (0 0) หรือจุดและ (0 10) แต่จากจุด (1 3) ถึง (0 3)

ดังนั้นจากสิ่งที่ฉันเข้าใจ ST_Distance ให้คำตอบที่คุณต้องการ

หากคุณต้องการหาจุด (0 3) ในตัวอย่างด้านบนคุณสามารถใช้ ST_Closestpoint ได้ถ้าคุณมี PostGIS 1.5 สำหรับตัวอย่างของฉันคุณใช้แบบนี้: ST_Closestpoint ('LINESTRING (0 0,0 10)' :: geometry, ' POINT (1 3) ':: geometry) จากนั้นคุณควรจะได้คะแนน (0 3) ในทางกลับกันจุดบนบรรทัดที่ใกล้กับจุดของคุณมากที่สุด

HTH Nicklas


5

ฉันเจอแล้ว :) (ฉันเดาว่า: P)

การใช้ST_Line_Locate_Point()และST_Line_Interpolate_point()ฉันจัดการเพื่อให้ได้จุดซึ่งไม่ได้เป็นส่วนหนึ่งของคำนิยามของ LINESTRING แต่อยู่ในบรรทัดที่กล่าวไว้ :) สิ่งที่ฉันต้องทำคือการได้ระยะทางจากจุดของฉันจนถึงจุดนี้และฉันเสร็จแล้ว

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)

ST_Line_Locate_Point()วิธีการหาตำแหน่งของจุดที่ใกล้ที่สุดในสายไปยังจุดที่กำหนดให้ST_Line_Interpolate_Pointวิธีการเปิดสถานที่แห่งนี้เข้าไปในจุดที่


1
ระยะห่างระหว่างจุดกับเส้นตรงจะให้คำตอบเดียวกัน ทำไมคุณคิดว่าคุณต้องทำแบบนี้?
Nicklas Avén

1
ฉันคิดว่า ST_Distance สามารถใช้กับรูปแบบเรขาคณิตใดก็ได้ postgis.refractions.net/docs/ST_Distance.html :ST_Distance(geometry g1, geometry g2)
Magno C

2

กระทู้ที่เก็บถาวรของ Postgis นี้สามารถตอบคุณได้ที่http://postgis.refractions.net/pipermail/postgis-users/2007-June/016045.html


refractions.net ใช้งานไม่ได้สำหรับฉัน: "refractions.net หมดอายุในวันที่ 09/14/2010 และอยู่ระหว่างการต่ออายุหรือลบ"
underdark

@underdark มันใช้งานได้สำหรับฉัน
dassouki

@dassouki: มันแปลก: |
underdark

@underdark refractions.net ทำงานอีกครั้ง
ThomasG77
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.