การคำนวณระยะทางระหว่างจุดและเส้นเสมือนสอง lat / lngs


14

โปรดดูตัวอย่างและรูปภาพที่เกี่ยวข้อง

ฉันต้องการที่จะประสบความสำเร็จต่อไปนี้: ให้สองสถานที่ (ลาดพร้าว / LNG) ซึ่งมีการแสดงด้านล่างเป็นและB จากนี้จะมีการลากเส้นเสมือนและระยะห่างระหว่างบรรทัดนี้กับCจะถูกคำนวณ (ในการวัดใด ๆ )

การวาดภาพ

ฉันประสบความสำเร็จในขณะนี้ใน Google Maps API v3 แต่อยากจะสามารถทำสิ่งนี้ได้เบื้องหลังในภาษาที่ฉันเลือก เคล็ดลับ / ความคิดใด ๆ จะได้รับการชื่นชมอย่างมาก!


AB เป็นวงที่ยิ่งใหญ่หรือไม่?
Kirk Kuykendall

@ Kirk, No, AB เป็นเพียงเส้นตรง
คุก

@Michael นั่นเป็นจุดที่น่าสนใจ ฉันจะต้องดูมัน!
นักโทษ

@ Prisoner @ Kirk แท้จริง "เส้นตรง" จะผ่านใต้พื้นผิวโลก โดยทั่วไปแล้วการฉายภาพรัศมีของมันกลับสู่พื้นผิวจะเป็นส่วนหนึ่งของวงกลมขนาดใหญ่ (โดยใช้แบบจำลองทรงกลมโลก)
whuber

1
@ นักโทษที่เป็นข้อมูลพิเศษที่มีประโยชน์อย่างมาก! ใช่คุณถูกต้อง. คุณยังต้องชดเชยความจริงที่ว่าการใช้ (lat, lon) บิดเบือนระยะทางตะวันออก - ตะวันตกเมื่อเทียบกับทิศเหนือ - ใต้ ตามที่ @Jose ให้คำแนะนำให้ฉายพิกัด นี่อาจเป็นเรื่องง่ายเหมือนการคูณความยาวล่วงหน้าด้วยโคไซน์ของละติจูดเฉลี่ยแล้วทำท่าว่าคุณอยู่บนระนาบแบบยุคลิด
whuber

คำตอบ:


6
def get_perp( X1, Y1, X2, Y2, X3, Y3):
    """************************************************************************************************ 
    Purpose - X1,Y1,X2,Y2 = Two points representing the ends of the line segment
              X3,Y3 = The offset point 
    'Returns - X4,Y4 = Returns the Point on the line perpendicular to the offset or None if no such
                        point exists
    '************************************************************************************************ """
    XX = X2 - X1 
    YY = Y2 - Y1 
    ShortestLength = ((XX * (X3 - X1)) + (YY * (Y3 - Y1))) / ((XX * XX) + (YY * YY)) 
    X4 = X1 + XX * ShortestLength 
    Y4 = Y1 + YY * ShortestLength
    if X4 < X2 and X4 > X1 and Y4 < Y2 and Y4 > Y1:
        return X4,Y4
    return None

ความยาวที่สั้นที่สุดคือระยะทางที่คุณต้องการยกเว้นว่าฉันเข้าใจผิด?


ใช่ฉันกำลังมองหาระยะทางที่สั้นที่สุดจาก C ถึงส่วนของเส้น นี่คือสิ่งที่คณิตศาสตร์นี้คำนวณหรือไม่
นักโทษ

1
มันใช้งานได้ดีจริง ๆ ฉันผ่านจุดสามจุด (A, B, C) ในต่อไปนี้: i.imgur.com/bK9oB.jpgและมันกลับมาพร้อมกับ lat / lng ของ X. การทำงานที่ยอดเยี่ยม!
นักโทษ

1
@ นางฟ้าสิ่งสุดท้ายสิ่งที่ฉันจะไปเกี่ยวกับการแก้ไขนี้เพื่อไปยังจุดที่ใกล้ที่สุด (ไม่ใช่แค่บรรทัด) ดังนั้นถ้าฉันใส่มันผ่านจุดร่วมเส้นฉันจะได้รับมันเพื่อตรวจสอบระยะทางไปยัง จุด?
นักโทษ

1
@ Fairy การเริ่มต้นที่ดี แต่ดูเหมือนว่าบ่อยครั้งที่รหัสนี้จะส่งคืนNoneเมื่อมีวิธีการแก้ปัญหาที่ถูกต้อง ปัญหาคือว่าเงื่อนไขสุดท้ายถือว่า X1 <X2 และ Y1 <Y2 ซึ่งไม่สามารถมั่นใจได้เสมอ ต้องมีการทดสอบความเป็นอยู่ที่ดีขึ้น
whuber

1
@Hairy ดูเหมือนว่าการแลกเปลี่ยนระหว่างคุณกับ @prisoner นี้มีประสิทธิผล ฉันต้องการเน้นย้ำว่าฉันไม่ได้เกี่ยวข้องอะไรกับ (หรือแม้แต่การควบคุมใด ๆ ) การเปลี่ยนแปลงใด ๆ ในการลงคะแนนหรือคะแนนที่อาจเกิดขึ้นและความคิดเห็นของฉันมีไว้เพื่อช่วยคุณปรับปรุงการตอบกลับของคุณเท่านั้น
whuber

11

บางทีฉันอาจทำให้มันซับซ้อนเกินไป แต่สิ่งที่คุณต้องการคือระยะทางจากจุดหนึ่งไปอีกบรรทัด นั่นคือระยะทางจากจุดตาม AB ที่เชื่อมโยง AB กับ C กับ orthogonal เส้นไปยัง AB เวกเตอร์ตั้งฉากกับ AB นี้ถูกกำหนดโดย

v=[x2-x1, -(y2-y1)] # Point A is [x1,y1] Point B is [x2,y2]

(ฉันใช้วงเล็บสี่เหลี่ยมจัตุรัสเพื่อกำหนดเวกเตอร์หรืออาร์เรย์สององค์ประกอบ) ระยะห่างระหว่าง C [xp, yp] และจุด A คือ

u=[x1-xp, y1-xp]

ระยะห่างระหว่างเส้นกับ C เป็นเพียงเส้นโครงของ u บนถึง v หากเราสมมุติว่า mod (v) = 1 (แค่ทำให้เป็นมาตรฐาน) จากนั้น

distance = u*v = abs( (x2-x1)*(y1-yp) - (x1-xp)*(y2-y1) )

ภาวะแทรกซ้อนเดียวคือคุณอาจต้องการให้แน่ใจว่าพิกัดของคุณไม่ใช่คู่ WGS84 lat / log แต่ถูกฉาย (หรือใช้พิกัดทางภูมิศาสตร์) คุณสามารถใช้OGRหรือProj4สำหรับสิ่งนี้


3
+ หลอกหลายล้านคะแนนสำหรับการไม่ใช้ฟังก์ชันตรีโกณมิติ, โดยวิธีการ คนจำนวนมากเกินไปดึง ArcTan ออกมาเมื่อพวกเขาควรจะดูสิ่งนี้: en.wikipedia.org/wiki/Dot_product
Herb

@ Jose ขอบคุณสำหรับคำตอบ! ฉันใช้ lat / long จาก google maps API ส่วนคณิตศาสตร์นั้นค่อนข้างใหม่สำหรับฉันดังนั้นฉันจะให้มันไปดูว่าฉันจะเกิดอะไรขึ้น มีเคล็ดลับอะไรเกี่ยวกับคณิตศาสตร์บ้างไหม? เช่น [x2-x1, - (y2-y1)] นั่นแปลว่าอะไร
นักโทษ

ฉันได้เพิ่มการแก้ไขสั้น ๆ สำหรับสิ่งนี้ โดยพื้นฐานแล้วมันเป็นสัญลักษณ์ของอาร์เรย์ แต่ถ้าคุณเก็บพิกัดของคุณในตัวแปร x1, x2, y1, y2 และ xp, yp คุณจะต้องเขียนทางด้านขวามือของสมการสุดท้ายที่ฉันมีให้ นี้สวยมากที่ถูกต้อง C, Java, JS, Python ฯลฯ รหัส :)
โฮเซ่

1
@Jose คุณกำลังคำนวณระยะทางจาก C ไปยังบรรทัด AB จากตัวเลขที่ฉันเชื่อว่า OP ต้องการระยะทางจาก C ถึงส่วนของเส้น AB สิ่งนี้ต้องการงานพิเศษเพื่อตรวจสอบว่าการฉายภาพของ C ไปยังเส้น AB อยู่ระหว่าง A และ B หรือไม่ ในกรณีหลังให้ใช้ความยาว CA และ CB ที่สั้นลง
whuber

1
@ Prisoner ความแตกต่างที่สำคัญคือเส้นที่ขยายตลอดไป (มันถูกกำหนดโดยเวกเตอร์ทิศทางและจุดหรือสองจุด) ในขณะที่ส่วนระหว่าง A และ B เป็นบิตของเส้นไม่มีที่สิ้นสุดที่อยู่ระหว่าง A และ B (มันมีความยาว จำกัด )
Jose

4

ด้วยความเกลียดชังคณิตศาสตร์นี้ฉันก็จะมาจากมุมที่แตกต่าง ฉันจะทำให้มันเป็นเส้น 'ที่เกิดขึ้นจริง' มากกว่าที่จะเป็นเส้นเสมือนแล้วใช้เครื่องมือที่มีอยู่

หาก A และ B แบ่งปันคุณลักษณะคุณสามารถเชื่อมต่อพวกเขาด้วยการวาดเส้น (Kosmo GIS มีเครื่องมือที่จะสร้างบรรทัดจากจุดและฉันเชื่อว่ายังมีปลั๊กอิน QGIS สำหรับสิ่งนี้) เมื่อคุณมีเส้นแล้วฟังก์ชั่น 'ใกล้' ในเลเยอร์จุด 'C' จะให้ระยะทางกับเส้น ให้ซอฟต์แวร์จัดการคณิตศาสตร์สำหรับคุณ!


ขอบคุณสำหรับความคิดเห็น แต่ขนขึ้นมาสำคัญกว่านี้!
นักโทษ

1
(+1) คุณสร้างจุดยอดเยี่ยม อัลกอริธึมการคำนวณเชิงเรขาคณิตนั้นมีความยุ่งยากในการฝึกฝนอย่างสมบูรณ์ (ดังที่เราเห็นได้จากรหัสทั้งหมดที่มีให้จนถึงตอนนี้ซึ่งมีประโยชน์และเป็นตัวอย่าง แต่ยังใช้งานไม่ได้) การใช้ขั้นตอน GIS ระดับสูงมักเป็นวิธีที่ดีในการรับรองว่าคุณจะได้รับคำตอบที่คาดหวังและถูกต้อง (หากคุณเชื่อถือ GIS ของคุณ ;-)
whuber

1

ถ้าคุณใช้จาวาบน Android มันเป็นเพียงบรรทัดเดียวที่มีฟังก์ชั่นห้องสมุด

import static com.google.maps.android.PolyUtil.distanceToLine;

distanceToLine:

public static double distanceToLine(LatLng p, LatLng start,LatLng end)

คำนวณระยะทางบนทรงกลมระหว่างจุด p และส่วนของเส้นตรงเริ่มต้นจนจบ

พารามิเตอร์: p - จุดที่จะวัด

start - จุดเริ่มต้นของส่วนของเส้น

end - ส่วนท้ายของส่วนของเส้น

คืนค่า: ระยะทางเป็นเมตร (สมมติว่าโลกเป็นทรงกลม)

เพียงเพิ่มไลบรารี่ของคุณ

dependencies {
    compile 'com.google.maps.android:android-maps-utils:0.5+'
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.