ฉันจะสร้างรูปหลายเหลี่ยมล้อมรอบโลกได้อย่างไร


14

ฉันใช้แผนที่แผ่นพับเพื่อสร้างความท้าทายรอบโลก ฉันต้องการเพิ่มรูปหลายเหลี่ยมซึ่งมุ่งหน้าไปทางทิศตะวันออกจากโตเกียวจากนั้นปรากฏทางตะวันตกของอเมริกาใต้บนแผนที่ - แต่ฉันกลับได้เส้นที่ข้ามแผนที่ในทิศทางตรงกันข้าม (ดูเส้นสีเหลือง)

ป้อนคำอธิบายรูปภาพที่นี่

ฉันคิดว่านี่อาจเกี่ยวข้องกับดาต้าไลน์และ / หรือระบบพิกัด ใครสามารถอธิบายทฤษฎีเบื้องหลังสิ่งที่ฉันต้องทำเพื่อให้เรื่องนี้ทำงานได้ ฉันกำลังใช้การประมาณการแบบ bluemarble จาก Nasa:

var bluemarble = new L.TileLayer.WMS("http://demo.opengeo.org/geoserver/wms", {
layers: 'bluemarble',
attribution: "Data © NASA Blue Marble, image service by OpenGeo",
minZoom: 2,
maxZoom: 5
});

2
คุณต้องแบ่งรูปหลายเหลี่ยมที่ + -180 องศาเมริเดียน สิ่งนี้ต้องการการค้นหาละติจูดซึ่งเส้นรอบรูปข้ามข้ามเส้นลมปราณนั้น GIS ของคุณอาจมีวิธีในการทำลาย ถ้าไม่แก้ปัญหาที่ง่ายจะได้รับจากรหัสที่แสดงไว้ในหัวข้อที่เกี่ยวข้อง คุณสามารถรันโค้ดแบบนี้บนแพลตฟอร์มของคุณได้หรือไม่?
whuber

ฉันเห็นด้วยกับเสียงหวือ ฉันต้องทำงานที่คล้ายกันโดยมีรูปหลายเหลี่ยมข้าม + - 180 คุณต้องแบ่งออกเป็นหลาย polylines / polygones ทุกครั้งที่คุณข้าม + -180
Steve

คำตอบ:


13

คุณต้องแบ่งรูปหลายเหลี่ยมที่ + -180 องศาเมริเดียน สิ่งนี้ต้องการการค้นหาละติจูดซึ่งเส้นรอบรูปข้ามข้ามเส้นลมปราณนั้น GIS ของคุณอาจมีวิธีในการทำลาย ถ้าไม่แก้ปัญหาที่ง่ายจะได้รับจากรหัสที่แสดงไว้ในหัวข้อที่เกี่ยวข้อง นี่คือรายละเอียดบางอย่าง

  • รูปหลายเหลี่ยมจะแสดงเป็นลำดับของจุดยอดแต่ละรูปแบบที่กำหนดใน (lat, lon) ด้วย -180 <= lon <= 180 คุณต้องตรวจสอบแต่ละคู่ที่ต่อเนื่องกันเพื่อดูว่ามันข้ามเส้นแวง + -180 หรือไม่ มีการทดสอบอย่างรวดเร็ว: หากค่าสัมบูรณ์ของความแตกต่างของลองจิจูดเป็น 180 หรือมากกว่านั้นจะมีการข้าม

  • ภายในแต่ละเซ็กเมนต์ (lat0, lon0) -> (lat1, lon1) ที่ข้าม + -180 meridian คุณต้องแบ่ง polyline ออกเป็นสองส่วนที่ข้าม

กุญแจสำคัญคือการค้นหาละติจูดของจุดพักด้วยความแม่นยำที่สมเหตุสมผล สิ่งนี้ทำได้ง่ายที่สุดด้วยแบบจำลองดินทรงกลม: ข้อผิดพลาด (เมื่อเทียบกับแบบจำลองวงรีที่แม่นยำกว่า) จะเล็กเกินไปที่จะสังเกตเห็น

ปล่อยให้กลุ่มที่มีปัญหาเปลี่ยนจากจุด 0 ที่ (lat0, lon0) ไปยังจุดที่ 1 ที่ (lat1, lon1) จุดพักสามารถพบได้โดยการรันเซ็กเมนต์เส้นตรงในแบบ 3 มิติระหว่างจุดสองจุดดังที่แสดงในพิกัดคาร์ทีเซียนและค้นหาตำแหน่งที่พิกัด y เป็นศูนย์ พิกัดคาร์ทีเซียนมี

(x0, y0, z0) = (cos(lon0)*sin(lat0), sin(lon0)*sin(lat0), cos(lat0))

และการแสดงออกที่คล้ายกันให้ (x1, y1, z1) สำหรับจุดที่ 1 แก้สมการ

t * y0 + (1-t) * y1 = 0

สำหรับ t; นั่นคือ,

t = y1 / (y1 - y0).

ดังนั้นพิกัดของสี่แยกจึงเป็น

(x, y, z) = (t * x0 + (1-t) * x1, 0, t * z0 + (1-t) * z1)

จุดนี้ (ซึ่งอยู่ใต้พื้นผิวโลกอยู่ที่ไหนสักแห่งใต้ + -180 เมริเดียน) มีละติจูดเท่ากับ

lat2 = ATan(z/x).

จุดพักต้องแสดงด้วยสองวิธี เมื่อติดตั้งหลังจาก (lat0, lon0) เพื่อยกเลิกส่วนแรกของ polyline ที่เสียหายให้ใช้ (lat2, -180) หาก lon0 เป็นค่าลบและใช้อย่างอื่น (lat2, 180) เมื่อติดตั้งก่อน (lat1, lon1) เพื่อเริ่มส่วนที่สองของ polyline ที่เสียหายให้ทำตามกฎที่คล้ายกัน

ในกรณีพิเศษหนึ่งหรือทั้งสองของจุด 0 และจุด 1 อาจอยู่ใน + -180 เมริเดียน การทำตามขั้นตอนนี้จะทำให้คุณวางเซกเมนต์ที่มีความยาวเป็นศูนย์บนหนึ่งในชิ้นส่วน polyline ที่คุณสร้าง หากสิ่งนี้อาจทำให้เกิดปัญหากับ GIS ให้ทดสอบเงื่อนไขนี้

โปรดทราบว่ารูปหลายเหลี่ยมสามารถข้ามเส้นลมปราณนี้มากกว่าหนึ่งครั้ง ดังนั้นหลังจากพบจุดพักแรกและแบ่งเส้นแบ่งออกเป็นสองส่วนคุณต้องดำเนินการส่วนที่สองในลักษณะเดียวกัน


1
สิ่งที่ whuber พูดนั้นก็โอเค แต่ฉันคิดว่ามีการพิมพ์ผิดในประโยคต่อไปนี้:> เมื่อติดหลังจาก (lat0, lon0) เพื่อยุติส่วนแรกของโพลีไลน์ที่ใช้งานไม่ได้ (lat2, -180) ถ้า lat0 เป็นลบและ มิฉะนั้นใช้ (lat2, 180) ฉันคิดว่ามันจะต้องเป็น:> ใช้ (lat2, -180) ถ้าlon0เป็นค่าลบและใช้อย่างอื่น (lat2, 180)
Georgi

@Gorgi ขอบคุณสำหรับการจับ; ฉันคิดว่าคุณพูดถูกและฉันจะเปลี่ยนแปลง
whuber

ฉันต้องใช้สิ่งนี้ใน Leaflet.js นี่คือรหัสของฉัน: gist.github.com/mikeatlas/0b69b354a8d713989147
Mike Atlas

ขอบคุณ @ ไมค์ ฉันชอบภาพประกอบซิกแซก: นั่นเป็นสถานการณ์ที่ฉันจินตนาการในขณะที่ฉันเขียนคำตอบนี้ หากคุณต้องการการทดสอบที่รุนแรงมาก ๆ ลองดูว่าเกิดอะไรขึ้นกับโพลีไลน์ที่วิ่งตามเส้นลมปราณ + -180 องศา (และข้ามทั้งสองขั้ว)!
whuber

@whuber ฉันอาจต้องลอง: / จะโพสต์ผลลัพธ์
Mike Atlas

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