จุดในอัลกอริทึมรูปหลายเหลี่ยมสำหรับหลายเหลี่ยม


11

ฉันมีแผนที่ Google พร้อมโพลิกอนมากมาย

นี่คือปัญหาที่ฉันสนใจ: เนื่องจาก lat, lng point เป็นวิธีที่ดีที่สุดในการกำหนดรูปหลายเหลี่ยมทั้งหมดที่จุดนี้อยู่

วิธีที่ชัดเจนคือการเรียกใช้อัลกอริทึม "จุดในรูปหลายเหลี่ยม" ซ้ำ ๆ กันสำหรับรูปหลายเหลี่ยมแต่ละอัน แต่ฉันสงสัยว่าถ้ามีอัลกอริทึมที่มีประสิทธิภาพในการตอบคำถามเหล่านี้โดยเฉพาะอย่างยิ่งถ้าคุณมีรูปหลายเหลี่ยมหลายพัน


ฉันไม่ค่อยรู้อะไรเกี่ยวกับ Google Maps API แต่เบราว์เซอร์นั้นมีแนวโน้มที่จะไม่เป็นสถานที่ที่ดีที่สุดในการทำแบบสอบถามขนาดใหญ่เช่นนี้ PostGIS (ฟรี), ArcServer หรือ Oracle Spatial มีแนวโน้มที่จะจัดการกับคำขอเช่นนี้ได้ดีขึ้น
canisrufus

ฉันสนใจอัลกอริทึมมากกว่าสิ่งอื่นใด BTW คุณจะทำสิ่งนี้ใน PostGIS ได้อย่างไร
numan

URL ต่อไปนี้พูดเกี่ยวกับจุดในรูปหลายเหลี่ยม .. (ฉันไม่เคยใช้มัน) .. ลองดู .. มันอาจให้ความคิดบางอย่าง eriestuff.blogspot.com/2008/02/…

3
นี่คือความคิดเห็นที่จำเป็นของฉันว่า "จุดในรูปหลายเหลี่ยม" ไม่สมเหตุสมผลสำหรับจุดบนทรงกลมเนื่องจากรูปหลายเหลี่ยมบนทรงกลมแบ่งทรงกลมออกเป็นสองส่วนอย่างใดอย่างหนึ่งซึ่งมีสิทธิที่จะถูกเรียกว่า 'ภายใน' ขั้วเหนือหรือขั้วใต้ 'ด้านใน' รูปหลายเหลี่ยมที่กำหนดเส้นศูนย์สูตรหรือไม่? โปรดจำไว้ว่า lat ยาวไม่ได้คาร์ทีเซียน ...
Spacedman

4
@ ระยะห่างคุณสับสน "รูปหลายเหลี่ยม" กับ "รูปหลายเหลี่ยม" จุดในรูปหลายเหลี่ยมทำให้รู้สึกสมบูรณ์แบบในทรงกลม รูปหลายเหลี่ยมนั้นเป็นมากกว่าแค่ขอบเขต (รูปหลายเหลี่ยมแบบปิด): มันประกอบด้วยการตกแต่งภายใน แม้ว่าขอบเขตของรูปหลายเหลี่ยมจะแบ่งขอบเขตทรงกลมออกเป็นสองส่วนที่เชื่อมต่อกัน แต่ก็มีหลายวิธีในการกำหนดให้หนึ่งในนั้นเป็นรูปด้านในของรูปหลายเหลี่ยมเช่นโดยวิธีการวางแนวปฐมนิเทศ (เช่นการตกแต่งภายในอยู่ทางด้านซ้าย ) หรือโดยใช้การแสดงภาพแรสเตอร์
whuber

คำตอบ:


12

เช่นเดียวกับคำถามเกือบทั้งหมดแนวทางที่ดีที่สุดนั้นขึ้นอยู่กับ "การใช้เคส" และวิธีแสดงคุณสมบัติ กรณีการใช้งานโดยทั่วไปจะแตกต่างกันโดย (a) ว่ามีวัตถุจำนวนมากหรือน้อยในแต่ละชั้นและ (b) หรือไม่ว่าทั้งสองชั้น (หรือทั้งสอง) อนุญาตให้ precomputing โครงสร้างข้อมูลบางส่วน; นั่นคือไม่ว่าจะหนึ่งหรือทั้งสองอย่างเพียงพอและไม่เปลี่ยนแปลงเพื่อให้การลงทุนใน precomputation คุ้มค่า

ในกรณีปัจจุบันสิ่งนี้จะให้ภาพจำลองต่อไปนี้ โดยปกติแล้วคะแนนจะเป็นแบบไดนามิกนั่นคือจะไม่ได้รับล่วงหน้า (ถ้ามีล่วงหน้าหรือในกลุ่มที่มีขนาดใหญ่มากการปรับให้เหมาะสมบางอย่างจากการเรียงลำดับจะพร้อมใช้งาน) ให้Qเป็นจำนวนจุดสอบถามและPเป็นจำนวนจุดยอดรูปหลายเหลี่ยม

ข้อมูลรูปหลายเหลี่ยมเวกเตอร์

(1) ไม่กี่จุดจุดรูปหลายเหลี่ยมไม่กี่ใน toto ใช้วิธีแรงเดรัจฉานเช่นคลาสสิกอัลกอริทึมสายแทง สำหรับวิธีการที่เหมาะสมใด ๆ ค่าใช้จ่ายคือ O (P * Q) เนื่องจากราคา O (1) เวลาในการเปรียบเทียบจุดหนึ่งกับขอบรูปหลายเหลี่ยมและการเปรียบเทียบทั้งหมดจะต้องทำ

(2) อาจมีจุดยอดรูปหลายเหลี่ยมหลายรูปแบบ แต่เป็นแบบไดนามิก:ทุกครั้งที่มีการใช้จุดในแบบสอบถามรูปหลายเหลี่ยมอาจมีการเปลี่ยนแปลง ใช้อัลกอริทึมแรงเดรัจฉานอีกครั้ง ราคายังคงเป็น O (P * Q) ซึ่งจะมีขนาดใหญ่เพราะPจะมีขนาดใหญ่ แต่ไม่มีการช่วยเหลือ หากการเปลี่ยนแปลงมีขนาดเล็กหรือควบคุม ( เช่นรูปหลายเหลี่ยมมีการเปลี่ยนแปลงรูปร่างเล็กน้อยหรือเพียงแค่เคลื่อนที่ไปรอบ ๆ อย่างช้าๆ) คุณอาจจะสามารถใช้เวอร์ชันของโซลูชันถัดไปและหาวิธีที่มีประสิทธิภาพในการปรับปรุงโครงสร้างข้อมูลเมื่อรูปหลายเหลี่ยมเปลี่ยนแปลง นั่นน่าจะเป็นเรื่องของการวิจัยแบบดั้งเดิม

(3) จุดยอดรูปหลายเหลี่ยมและรูปหลายเหลี่ยมคงที่ (นั่นคือชั้นรูปหลายเหลี่ยมจะไม่ค่อยเปลี่ยนแปลง) คำนวณโครงสร้างข้อมูลล่วงหน้าเพื่อสนับสนุนการค้นหา (ซึ่งอาจขึ้นอยู่กับการกวาดบรรทัดหรืออัลกอริธึมควอดทรี ) ค่าใช้จ่ายล่วงหน้าสำหรับอัลกอริธึมเหล่านี้คือ O (P * log (P)) แต่ค่าใช้จ่ายของการสืบค้นกลายเป็น O (Q * log (P)) ดังนั้นค่าใช้จ่ายทั้งหมดคือ O ((P + Q) * บันทึก ( P))

การปรับปรุงบางอย่างมีให้ในกรณีพิเศษเช่น

(a) รูปหลายเหลี่ยมทั้งหมดเป็นรูปนูน (การประมวลผลรูปหลายเหลี่ยมล่วงหน้าสามารถทำได้เร็วกว่า )

(b) การตกแต่งภายในรูปหลายเหลี่ยมทั้งหมดแยกออกจากกันซึ่งในกรณีนี้คุณสามารถคิดว่าสหภาพของพวกเขาเป็นรูปหลายเหลี่ยมเดียว (ซึ่งช่วยให้อัลกอริทึมที่มีประสิทธิภาพตรงไปตรงมาเช่นที่อยู่บนพื้นฐานของสมการและ

(c) รูปหลายเหลี่ยมส่วนใหญ่ไม่คดเคี้ยวมาก -นั่นคือพวกเขาครอบครองส่วนใหญ่ของกล่องขอบเขตของพวกเขา - ในกรณีที่คุณสามารถทำการทดสอบเริ่มต้นขึ้นอยู่กับกล่องขอบเขตเท่านั้นแล้วปรับแก้ปัญหานั้น นี่คือการเพิ่มประสิทธิภาพที่เป็นที่นิยม

(d) จำนวนคะแนนมีขนาดใหญ่ การเรียงลำดับอาจช่วยปรับปรุงเวลา ตัวอย่างเช่นเมื่อใช้อัลกอริทึมการกวาดจุดจากซ้ายไปขวาคุณจะต้องเรียงลำดับคะแนนในพิกัดแรกของพวกเขาเพื่อให้คุณสามารถกวาดล้างจุดต่าง ๆ ได้ในเวลาเดียวกับที่คุณกวาดข้ามขอบรูปหลายเหลี่ยม ฉันไม่ทราบว่าการเพิ่มประสิทธิภาพดังกล่าวได้รับการเผยแพร่แล้ว หนึ่งที่ได้รับการเผยแพร่แม้ว่าจะดำเนินการเป็นรูปสามเหลี่ยม จำกัดของการรวมกันของจุดและจุดยอดรูปหลายเหลี่ยม: เมื่อการคำนวณที่สมบูรณ์แล้วการระบุจุดภายในควรจะรวดเร็ว ค่าใช้จ่ายในการคำนวณจะขยายเป็น O (Q * บันทึก (Q) + (P + Q) * บันทึก (P + Q)

ข้อมูลรูปหลายเหลี่ยม Raster

มันง่ายอย่างเหลือเชื่อ: ดูเลเยอร์รูปหลายเหลี่ยมเป็นตัวบ่งชี้ไบนารีแรสเตอร์ (1 = ภายในรูปหลายเหลี่ยม, 0 = ภายนอก) (ซึ่งอาจต้องใช้ตารางการค้นหาเพื่อแปลงค่าแรสเตอร์เป็นตัวบ่งชี้ภายใน / ภายนอก) แต่ละโพรบจุดต้องใช้ความพยายาม O (1) ในการสร้างดัชนีเซลล์แรสเตอร์และอ่านค่าของมัน ความพยายามทั้งหมดคือ O (Q)

โดยทั่วไปแล้ว

โซลูชันไฮบริดที่ดีในกรณีของเวกเตอร์รูปหลายเหลี่ยมคงที่ (กรณีเวกเตอร์ 3 ด้านบน) เริ่มแรกเพื่อ rasterize รูปหลายเหลี่ยมบางทีแม้จะมีความละเอียดหยาบเวลานี้แยกความแตกต่างของเซลล์ใด ๆ ที่ตัดส่วนใดส่วนหนึ่งของเขตรูปหลายเหลี่ยม . การใช้โพรบแบบแรสเตอร์ (ราคา: O (1)) โดยทั่วไปแล้วจะทำให้ได้คำตอบที่ชัดเจน (เป็นที่รู้กันว่าจุดนั้นอยู่ด้านในหรือด้านนอก) แต่บางครั้งก็ส่งผลให้เกิดคำตอบแบบไม่ จำกัด (จุดตกอยู่ในเซลล์ ผ่าน) ซึ่งในกรณีนี้แบบสอบถามเวกเตอร์ O (log (P)) ราคาแพงกว่าจะถูกสร้างขึ้น วิธีนี้มีค่าใช้จ่ายในการจัดเก็บเพิ่มเติมสำหรับแรสเตอร์ แต่ในหลายกรณีแม้แต่แรสเตอร์ขนาดเล็ก (หนึ่ง MB จะอนุญาตให้ใช้กับแรสเตอร์ 2000 โดย 2000 ที่เก็บ {0,1,2, ค่า null}) สามารถมอบประโยชน์มหาศาลในเวลาคำนวณ . asymptotically,


7

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


1

ใน postgis ST_Intersectsใช้ดัชนีเพื่อค้นหาว่าจุดนั้นอยู่ในกล่องที่มีขอบเขตของรูปหลายเหลี่ยมหรือไม่จากนั้นทำการตรวจสอบอีกครั้งเพื่อดูว่ามันอยู่ในรูปหลายเหลี่ยมจริงหรือไม่ นั่นคือเร็วมักเร็วมาก

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

/ Nicklas

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