คำตอบนี้แบ่งออกเป็นหลายส่วน:
การวิเคราะห์และการลดปัญหาแสดงวิธีการหาจุดที่ต้องการด้วยรูทีน "canned"
ภาพประกอบ: ต้นแบบการทำงานให้รหัสการทำงาน
ตัวอย่างแสดงตัวอย่างของการแก้ปัญหา
ข้อผิดพลาดการพูดคุยปัญหาที่อาจเกิดขึ้นและวิธีรับมือกับพวกเขา
การใช้ ArcGISความคิดเห็นเกี่ยวกับการสร้างเครื่องมือ ArcGIS ที่กำหนดเองและสถานที่ที่จะได้รับรูทีนที่จำเป็น
การวิเคราะห์และการลดปัญหา
เรามาเริ่มด้วยการสังเกตว่าในรูปแบบทรงกลม (รอบที่ดีที่สุด) จะมีทางออกเสมอ - ในความเป็นจริงแล้วมีสองวิธี รับคะแนนฐาน A, B และ C แต่ละคู่จะกำหนด "เส้นแบ่งครึ่งตั้งฉาก" ซึ่งเป็นชุดของจุดที่เท่ากันจากจุดที่กำหนดทั้งสอง เส้นแบ่งครึ่งนี้เป็น geodesic (วงกลมใหญ่) รูปทรงกลมทรงรีคือวงรี : สอง geodesics ตัดกัน (ในสองจุดที่ไม่ซ้ำกัน) ดังนั้นจุดตัดของเส้นแบ่งครึ่งของ AB และเส้นแบ่งครึ่งของ BC คือ - โดยนิยาม - เท่ากันจาก A, B และ C ดังนั้นจึงเป็นการแก้ปัญหา (ดูรูปแรกด้านล่าง)
สิ่งต่าง ๆ ดูซับซ้อนกว่าในวงรีแต่เนื่องจากมันเป็นการรบกวนรอบตัวเล็ก ๆ เราจึงสามารถคาดหวังพฤติกรรมที่คล้ายกันได้ (การวิเคราะห์สิ่งนี้จะนำเราไปไกลเกินไป) สูตรที่ซับซ้อนที่ใช้ (ภายในภายใน GIS) เพื่อคำนวณระยะทางที่แม่นยำในรูปวงรีไม่ใช่ปัญหาแทรกซ้อนแนวความคิด แต่โดยทั่วไปแล้วปัญหาจะเหมือนกัน เพื่อดูว่าปัญหาง่ายจริงเพียงใดให้รัฐค่อนข้างนามธรรม ในคำแถลงนี้ "d (U, V)" หมายถึงระยะทางที่แท้จริงและแม่นยำมากระหว่างจุด U และ V
ให้สามคะแนน A, B, C (เป็นคู่ lat-lon) บนทรงรีหาจุด X ที่ (1) d (X, A) = d (X, B) = d (X, C) และ ( 2) ระยะทางทั่วไปนี้มีขนาดเล็กที่สุด
ทั้งสามระยะทางทั้งหมดขึ้นอยู่กับที่ไม่รู้จักX ดังนั้นความแตกต่างในระยะทาง u (X) = d (X, A) - d (X, B) และ v (X) = d (X, B) - d (X, C) เป็นฟังก์ชันที่มีมูลค่าจริงของ X อีกครั้งค่อนข้างเป็นนามธรรมเราอาจรวบรวมความแตกต่างเหล่านี้เป็นคู่ที่สั่งซื้อ นอกจากนี้เรายังจะใช้ (lat, lon) เป็นพิกัดสำหรับ X ช่วยให้เราพิจารณาว่าเป็นคู่ที่สั่งซื้อด้วยเช่นกันพูดว่า X = (phi, lambda) ในการตั้งค่านี้ฟังก์ชั่น
F (phi, lambda) = (u (X), v (X))
เป็นฟังก์ชั่นจากส่วนหนึ่งของพื้นที่สองมิติที่รับค่าในพื้นที่สองมิติและปัญหาของเราลดลง
ค้นหาความเป็นไปได้ทั้งหมด (phi, lambda) ซึ่ง F (phi, lambda) = (0,0)
นี่คือที่ที่สิ่งที่เป็นนามธรรมจ่ายออกไป: มีซอฟต์แวร์ที่ยอดเยี่ยมมากมายที่มีอยู่เพื่อแก้ปัญหานี้ วิธีการทำงานคือคุณเขียนรูทีนเพื่อคำนวณFจากนั้นส่งผ่านไปยังซอฟต์แวร์พร้อมกับข้อมูลใด ๆ เกี่ยวกับข้อ จำกัด ของอินพุต ( phiต้องอยู่ระหว่าง -90 ถึง 90 องศาและแลมบ์ดาต้องอยู่ระหว่าง -180 ถึง 180 องศา) มันจะแยกออกไปเป็นเสี้ยววินาทีและส่งคืน (โดยทั่วไป) เพียงหนึ่งค่า ( phi , lambda ) หากสามารถหาได้
มีรายละเอียดที่จะจัดการเนื่องจากมีศิลปะในการนี้: มีวิธีการแก้ปัญหาต่าง ๆ ให้เลือกขึ้นอยู่กับวิธีF "พฤติกรรม"; ช่วยในการ "คัดท้าย" ซอฟต์แวร์โดยให้จุดเริ่มต้นที่สมเหตุสมผลสำหรับการค้นหา (นี่คือวิธีหนึ่งที่เราจะได้รับโซลูชันที่ใกล้ที่สุดแทนที่จะเป็นซอฟต์แวร์อื่น) และโดยปกติคุณจะต้องระบุว่าคุณต้องการให้โซลูชันนั้นถูกต้องมากน้อยเพียงใด (เพื่อให้ทราบว่าจะหยุดการค้นหาเมื่อใด) (สำหรับข้อมูลเพิ่มเติมเกี่ยวกับสิ่งที่นักวิเคราะห์ระบบสารสนเทศภูมิศาสตร์จำเป็นต้องทราบเกี่ยวกับรายละเอียดดังกล่าวซึ่งเกิดขึ้นมากในปัญหา GIS กรุณาเยี่ยมชมหัวข้อแนะนำที่จะรวมอยู่ในหลักสูตรวิทยาศาสตร์คอมพิวเตอร์สำหรับวิชาเทคโนโลยีเชิงพื้นที่และดูในส่วน )
ภาพประกอบ: ต้นแบบการทำงาน
การวิเคราะห์แสดงให้เห็นว่าเราต้องเขียนโปรแกรมสองสิ่ง: การประมาณค่าเริ่มต้นอย่างหยาบของการแก้ปัญหาและการคำนวณค่าFเอง
การประเมินเบื้องต้นสามารถทำได้โดย "เฉลี่ยทรงกลม" ของสามจุดฐาน สิ่งนี้ได้มาจากการแทนค่าพวกมันในพิกัดคาร์ทีเซียน (x, y, z), คำนวณค่าเฉลี่ยของพิกัดเหล่านั้นและคาดการณ์ค่าเฉลี่ยนั้นกลับไปยังทรงกลมและแสดงพิกัดละติจูดและลองจิจูดอีกครั้ง ขนาดของทรงกลมนั้นไม่มีสาระสำคัญและการคำนวณจึงตรงไปตรงมา: เนื่องจากนี่เป็นเพียงจุดเริ่มต้นเราไม่จำเป็นต้องคำนวณรูปวงรี
สำหรับต้นแบบการทำงานนี้ฉันใช้Mathematica 8
sphericalMean[points_] := Module[{sToC, cToS, cMean},
sToC[{f_, l_}] := {Cos[f] Cos[l], Cos[f] Sin[l], Sin[f]};
cToS[{x_, y_, z_}] := {ArcTan[x, y], ArcTan[Norm[{x, y}], z]};
cMean = Mean[sToC /@ (points Degree)];
If[Norm[Most@cMean] < 10^(-8), Mean[points], cToS[cMean]] / Degree
]
( If
เงื่อนไขสุดท้ายทดสอบว่าค่าเฉลี่ยอาจล้มเหลวอย่างเห็นได้ชัดเพื่อระบุลองจิจูดถ้าเป็นเช่นนั้นกลับไปที่ค่าเฉลี่ยเลขคณิตตรงของละติจูดและลองจิจูดของอินพุต - อาจไม่ใช่ตัวเลือกที่ดี แต่อย่างน้อยก็เป็นค่าที่ถูกต้อง สำหรับผู้ที่ใช้รหัสนี้เพื่อเป็นแนวทางในการใช้งานโปรดทราบว่าข้อโต้แย้งของMathematica ArcTan
นั้นตรงกันข้ามกับการใช้งานอื่น ๆ ส่วนใหญ่อาร์กิวเมนต์แรกคือพิกัด x ส่วนที่สองคือพิกัด y และส่งคืนมุมที่ทำโดยเวกเตอร์ ( x, y).)
เท่าที่ส่วนที่สองไปเนื่องจากMathematica - like ArcGIS และ GISes อื่น ๆ เกือบทั้งหมด - มีรหัสเพื่อคำนวณระยะทางที่แม่นยำบนรี ellipsoid แทบไม่มีอะไรจะเขียน เราเพียงเรียกรูทีนการรูท:
tri[a_, b_, c_] := Block[{d = sphericalMean[{a, b, c}], sol, f, q},
sol = FindRoot[{GeoDistance[{Mod[f, 180, -90], Mod[q, 360, -180]}, a] ==
GeoDistance[{Mod[f, 180, -90], Mod[q, 360, -180]}, b] ==
GeoDistance[{Mod[f, 180, -90], Mod[q, 360, -180]}, c]},
{{f, d[[1]]}, {q, d[[2]]}},
MaxIterations -> 1000, AccuracyGoal -> Infinity, PrecisionGoal -> 8];
{Mod[f, 180, -90], Mod[q, 360, -180]} /. sol
];
สิ่งสำคัญที่สุดของการใช้งานนี้คือวิธีที่มันจำเป็นต้อง จำกัด ละติจูด ( f
) และลองจิจูด ( q
) โดยการคำนวณมันแบบโมดูโล 180 และ 360 องศาตามลำดับ วิธีนี้หลีกเลี่ยงการ จำกัด ปัญหา (ซึ่งมักสร้างภาวะแทรกซ้อน) พารามิเตอร์การควบคุมMaxIterations
ฯลฯ ถูกปรับแต่งเพื่อให้รหัสนี้ให้ความแม่นยำที่เป็นไปได้มากที่สุดเท่าที่จะทำได้
หากต้องการดูการทำงานลองนำไปใช้กับจุดฐานทั้งสามที่ให้ไว้ในคำถามที่เกี่ยวข้อง :
sol = tri @@ (bases = {{-6.28530175, 106.9004975375}, {-6.28955287, 106.89573839}, {-6.28388865789474, 106.908087643421}})
{-6.29692, 106.907}
ระยะทางที่คำนวณระหว่างคำตอบนี้กับจุดสามจุดคือ
{1450.23206979, 1450.23206979, 1450.23206978}
(เหล่านี้คือเมตร) พวกเขาเห็นพ้องผ่านหลักสำคัญที่สิบเอ็ด (ซึ่งแม่นยำเกินไปจริง ๆ แล้วเนื่องจากระยะทางนั้นไม่ค่อยแม่นยำถึงดีกว่ามิลลิเมตรหรือมากกว่านั้น) นี่คือภาพของจุดสามจุด (สีดำ) เส้นแบ่งครึ่งทั้งสามของพวกเขาและวิธีแก้ปัญหา (สีแดง):
ตัวอย่าง
เพื่อทดสอบการนำไปปฏิบัตินี้และทำความเข้าใจกับวิธีการทำงานของปัญหาได้ดีขึ้นนี่คือโครงร่างของความคลาดเคลื่อนกำลังสองเฉลี่ยของรูทในระยะทางสำหรับจุดฐานที่เว้นระยะสามจุด (ความคลาดเคลื่อน RMS นั้นได้มาจากการคำนวณความแตกต่างทั้งสาม d (X, A) -d (X, B), d (X, B) -d (X, C) และ d (X, C) -d (X , A), หาค่าเฉลี่ยกำลังสองของพวกเขาและรับสแควร์รูทมันเท่ากับศูนย์เมื่อ X แก้ปัญหาและเพิ่มขึ้นเมื่อ X เคลื่อนที่ห่างจากโซลูชันและวัดว่า "ปิด" เราจะเป็นวิธีแก้ปัญหาได้ทุกที่ )
คะแนนฐาน (60, -120), (10, -40), และ (45,10) จะแสดงเป็นสีแดงในการฉายภาพ Plate Carree; วิธีแก้ปัญหา (49.2644488, -49.9052992) - ซึ่งต้องใช้การคำนวณ 0.03 วินาที - เป็นสีเหลือง ความคลาดเคลื่อน RMS นั้นน้อยกว่าสามนาโนเมตรแม้จะมีระยะทางที่เกี่ยวข้องทั้งหมดเป็นระยะทางหลายพันกิโลเมตร พื้นที่มืดแสดงค่าขนาดเล็กของ RMS และพื้นที่แสงแสดงค่าสูง
แผนที่นี้แสดงให้เห็นถึงวิธีแก้ไขปัญหาอื่นอย่างชัดเจนซึ่งอยู่ใกล้กับ (-49.2018206, 130.0297177) (คำนวณเป็น RMS สองนาโนเมตรโดยการตั้งค่าการค้นหาเริ่มต้นตรงข้ามกับโซลูชั่นแรก)
ผิดพลาด
ความไม่แน่นอนเชิงตัวเลข
เมื่อจุดฐานเกือบ collinear และอยู่ใกล้กันการแก้ปัญหาทั้งหมดจะเกือบครึ่งโลกและยากที่จะปักลงอย่างแม่นยำ เหตุผลก็คือการเปลี่ยนแปลงเล็ก ๆ น้อย ๆ ในสถานที่ต่างๆทั่วโลก - เคลื่อนไปทางหรือออกจากจุดฐาน - จะทำให้เกิดการเปลี่ยนแปลงเล็ก ๆ น้อย ๆ อย่างไม่น่าเชื่อในความแตกต่างของระยะทาง มีความแม่นยำและความแม่นยำไม่เพียงพอที่สร้างขึ้นในการคำนวณระยะทางธรณีวิทยาตามปกติเพื่อตรึงผลลัพธ์
ตัวอย่างเช่นเริ่มต้นด้วยคะแนนฐานที่ (45.001, 0), (45, 0) และ (44.999,0) ซึ่งแยกตาม Prime Meridian เพียง 111 เมตรระหว่างแต่ละคู่tri
ได้รับโซลูชัน (11.8213, 77.745 ) ระยะทางจากจุดถึงจุดฐานคือ 8,127,964.998 77; 8,127,964.998 41; และ 8,127,964.998 65 เมตรตามลำดับ พวกเขาเห็นด้วยกับมิลลิเมตรที่ใกล้ที่สุด! ฉันไม่แน่ใจว่าผลลัพธ์นี้แม่นยำเพียงใด แต่จะไม่แปลกใจหากการใช้งานอื่น ๆ ส่งคืนสถานที่ห่างไกลจากจุดนี้แสดงให้เห็นว่ามีความเสมอภาคที่ดีของระยะทางสามระยะ
เวลาในการคำนวณ
การคำนวณเหล่านี้เนื่องจากพวกเขาเกี่ยวข้องกับการค้นหาจำนวนมากโดยใช้การคำนวณระยะทางที่ซับซ้อนไม่เร็วนักซึ่งมักจะต้องใช้เวลาเพียงเสี้ยววินาทีที่เห็นได้ชัดเจน แอปพลิเคชันแบบเรียลไทม์จำเป็นต้องทราบสิ่งนี้
การใช้งาน ArcGIS
Python เป็นสภาพแวดล้อมการเขียนสคริปต์ที่ต้องการสำหรับ ArcGIS (เริ่มต้นด้วยรุ่น 9) แพคเกจ scipy.optimizeมี rootfinder หลายตัวแปรroot
ที่ควรทำในสิ่งที่FindRoot
ไม่อยู่ในMathematicaรหัส แน่นอนว่า ArcGIS นั้นมีการคำนวณระยะทางรีที่แม่นยำ ส่วนที่เหลือนั้นคือรายละเอียดการใช้งานทั้งหมด: ตัดสินใจว่าจะรับพิกัดจุดฐานได้อย่างไร (จากเลเยอร์ที่ผู้ใช้พิมพ์จากไฟล์ข้อความจากเมาส์หรือไม่) และวิธีแสดงผลลัพธ์จะเป็นอย่างไร ปรากฏบนหน้าจอเป็นจุดกราฟิกเป็นวัตถุจุดใหม่ในเลเยอร์เขียนอินเทอร์เฟซนั้นพอร์ตรหัสMathematica ที่แสดงที่นี่ (ตรงไปตรงมา) และคุณจะได้รับการตั้งค่าทั้งหมด