การวัดระยะทางที่ดีขึ้นใน Web Mercator Projection


10

ฉันทำงานกับสแต็ค ESRI จัดเก็บเลเยอร์ของฉันใน sql-spatial-enabled-SDE- geodatabase (ประเภทเรขาคณิตเว็บ Mercator-3857)

ฉันกำลังสร้างแอปพลิเคชันการจับคู่เว็บดังนั้นโดยค่าเริ่มต้นไทล์จะอยู่ในเว็บ Mercator ด้วยเช่นกัน 3857

ผ่าน procs ที่เก็บไว้ฉันใช้ STD Distance เพื่อค้นหาระยะทางจากตำแหน่งของผู้ใช้ (พิกัดใน Mercator ของเว็บ) ไปยังเลเยอร์ต่างๆ

ปัญหาคือเนื่องจากการบิดเบือนของ Web Mercator ทำให้ระยะทางของฉันลดลงเรื่อย ๆ ยิ่งห่างจากเส้นศูนย์สูตร

ฉันเคยคิดถึงการจัดเก็บเลเยอร์ของฉันในรูปแบบ sql-spatial-geography (มากกว่ารูปทรงเรขาคณิต) แต่:

  • ฉันคิดว่าข้อความค้นหาระยะทางของฉันจะใช้เวลานานขึ้น (ระยะทาง calcs บนพื้นผิวทรงกลม)
  • ฉันจะต้องนำเข้าข้อมูลจำนวนมากอีกครั้ง
  • บริการ arcgis จะไม่เร็วเท่าที่พวกเขาจะต้องฉายได้ทันที

ถ้าฉันไปที่ Google Maps และคำนวณระยะทางระยะทางที่ส่งกลับจะแม่นยำมากยิ่งขึ้นแม้ในพื้นที่ Nortern / ภาคใต้ดังนั้นฉันคิดว่า Google ต้องแก้ไขความผิดเพี้ยนที่เกิดจากการฉายเว็บ Mercator

คำถามของฉันแล้ว: มีค่าปัจจัยอย่างง่าย ๆ ที่สามารถนำไปใช้กับ Calcs ทางไกลในการฉายเว็บ Mercator เพื่อให้ได้ระยะทาง "ถูกต้อง" หรือไม่?

คำตอบ:


12

สำหรับระยะทางสั้น ๆ คุณสามารถคูณระยะทางที่คำนวณได้ด้วยcos(lat)เนื่องจากขนาดของการฉายภาพ Mercator นั้นเป็นสัดส่วนกับเส้นตัดวงกลมของละติจูด (เส้นตัดขวางคือ1/cos) ดู http://en.wikipedia.org/wiki/Mercator_project#Mathematics_of_the_project


ภาคผนวกด้วย@ jeremiah-england :ในขณะที่การแก้ไขข้างต้นจะถูกต้องเมื่อมันมาถึงการประมาณการ Mercator จริง Web Mercator (EPSG: 3857) ไม่ใช่ Mercator EPSG เรียกมันว่า "Pseudo-Mercator" ปัญหาคือว่ามันใช้ WGS84, รูปแบบ eliptical และฉายมันโดยใช้การคำนวณ Mercator Mercury (ซึ่ง Google ใช้เพราะมันเร็วกว่า) หากคุณวัดระยะทาง1/cos(phi)ด้วย Mercator ของเว็บคุณจะอยู่ที่ 0.6% จากเส้นศูนย์สูตร ดูการนำเสนอของ Noel Zinn ใน Web Mercatorสำหรับรายละเอียดเพิ่มเติม

จากการนำเสนอที่กล่าวถึงข้างต้นวิธีการต่อไปนี้สามารถใช้ในการคำนวณระยะทางที่แม่นยำยิ่งขึ้นจากพิกัดของ Mercator ของเว็บ ที่ได้รับdx- ความแตกต่างพิกัดแนวนอน (ทิศทาง WE) และdy- ความแตกต่างพิกัดแนวตั้ง (ทิศทาง SN):

e = 0.081819191
adjustedX = dx * cos(lat) / sqrt(1 - e^2 * sin(lat)^2)
adjustedY = dy * cos(lat) * (1 - e^2) / pow(1 - e^2 * sin(lat)^2, 3/2)
adjustedDistance = hypot(adjustedX, adjustedY)

อัตราส่วนระหว่างการปรับนี้และcos(lat)ใหญ่กว่าในทิศทาง SN ตั้งแต่0.9933ที่เส้นศูนย์สูตรถึง1.0034ที่ขั้ว อัตราส่วนทิศทางเราเริ่มต้นด้วย1ที่เส้นศูนย์สูตรและเติบโตไป1.0034ที่เสา

โปรดทราบว่าการแก้ไขนี้ยังทำงานได้ดีพอสมควรสำหรับระยะทางสั้น ๆ เท่านั้นซึ่งสามารถคาดเดารูปทรงเรขาคณิตของพื้นผิวโลกได้


1
และสำหรับระยะทางไกลกว่านี้คุณสามารถใช้ละติจูดเฉลี่ยของจุดปลายสองจุดcos((l1 + l2)/2)ซึ่งจะทำให้ระยะทางของเส้นทางแบบ rhumb-line / fixed แน่นอนมากกว่าระยะทางวงกลมใหญ่
MerseyViking

ที่เปลี่ยนรูปทรงกลมเท่านั้น แต่ไม่ได้ให้ความแม่นยำเช่นเดียวกับการฉายภาพในพื้นที่
falcacibar

1
@falcibar - ฉันไม่เห็นว่าการเลือกละติจูดหมายถึงการเปลี่ยนรูปทรงกลม
mkadunc

@MerseyViking: ขอบคุณลืมพูดถึงว่าละติจูดที่ดีที่สุดที่จะใช้สำหรับการคำนวณจะเป็นค่าเฉลี่ยของสองจุดเปรียบเทียบ
mkadunc

1
+1 สำหรับคำตอบ @Mersey: ทำไมการแก้ไขค่าเฉลี่ยละติจูดจึงใช้งานได้ ท้ายที่สุดแล้วการบิดเบือนใน Mercator อาจกลายเป็นเรื่องใหญ่โดยพลการ ดูเหมือนว่ามีข้อผิดพลาดบางอย่างที่อาจเกิดขึ้นซึ่งการแก้ไขอย่างง่ายจะไม่น่าเชื่อถือ
whuber

6

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

ไม่มีอะไรจะหยุดคุณจากการมีสองช่องว่างในตาราง - หนึ่งใน Mercator เป็นGEOMETRYประเภทและหนึ่งใน WGS84 เป็นGEOGRAPHYประเภท (อย่างน้อยไม่ได้อยู่ใน SQL Server ฉันไม่แน่ใจเกี่ยวกับ ArcSDE)

คุณควรจะสามารถสร้างสคริปต์การประมวลผลทางภูมิศาสตร์อย่างง่ายซึ่งจะเติมข้อมูลทั้งสองฟิลด์ด้วยข้อมูลดั้งเดิมของคุณ หากมีการแก้ไขและการอัปเดตบ่อยครั้งสิ่งนี้อาจไม่ใช่ตัวเลือก

เมื่อคุณมีสองช่องคุณสามารถใช้ Mercator เพื่อแสดงผลอย่างรวดเร็วและแปลงคะแนนที่ผู้ใช้ป้อนเป็น Lat / Lon เป็นระยะทาง

นี่เป็นข้อดีสองข้อที่สำคัญ:

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

ความเร็วการสืบค้นจะซับซ้อนกว่านี้ แต่ผู้ใช้อาจไม่สามารถสังเกตเห็นได้ คุณอาจต้องการทดสอบกับหนึ่งคุณลักษณะคลาสก่อนตัดสินใจเลือกโซลูชัน นอกจากนี้คุณจะต้องแปลงคะแนนที่ผู้ใช้ป้อนจาก Mercator (ซึ่งควรเป็นเรื่องเล็กน้อยและสามารถทำได้ในเบราว์เซอร์)

แม้ว่าจะเป็นประเภทภูมิศาสตร์แม้ว่ายังมีข้อผิดพลาดอยู่:

การยอมรับข้อผิดพลาดสำหรับวิธีการทางภูมิศาสตร์อาจมีขนาดใหญ่เท่ากับขอบเขต 1.0e-7 *

จากMSDN


น่าเสียดายที่ SDE จะอนุญาตสำหรับคอลัมน์อวกาศหนึ่งคอลัมน์เท่านั้น: help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#//… - ฉันยังไม่ได้พยายามสร้างมุมมองและลงทะเบียนกับ SDE แต่นั่นอาจจะเป็น เป็นแนวทางที่เป็นไปได้
Allan Adair

@Allan - ดีที่รู้ ข้อดีอีกข้อหนึ่งสำหรับการใช้ SDE! ตารางที่มีรูปทรงเรขาคณิตเพียง 4326 อันและกลับไปที่ตารางเดิม + มุมมองเชิงพื้นที่ควรบรรลุวัตถุประสงค์เดียวกัน
geographika

3

คำแนะนำทางเลือกจาก ESRI คือการใช้ "บริการเรขาคณิต" ซึ่งเกี่ยวข้องกับการส่งรูปทรงเรขาคณิตไปยังเซิร์ฟเวอร์ ArcGIS และส่งคืนผลลัพธ์ หากคุณไม่คาดหวังว่าจะเกิดปัญหาคอขวดโดยใช้บริการบนเว็บนี่อาจเป็นวิธีที่มีประสิทธิภาพมาก ฉันใช้วิธีการเดียวกันในแอปพลิเคชัน Silverlight

นี่คือรายการบล็อกดั้งเดิมจาก ESRI: http://blogs.esri.com/Dev/blogs/arcgisserver/archive/2010/03/05/Measuring-distances-and-areas-when-your-map-uses-the -Mercator-projection.aspx

ในบล็อกมีตัวอย่าง JavaScript ที่ง่ายขึ้นและยังมีแอปพลิเคชันตัวอย่างแบบเต็มรูปแบบที่นี่: http://serverapps.esri.com/javascript_examples/compare_measurements.htm


0

เช่นเดียวกับ google earth คุณสามารถเปลี่ยนรูปทรงเรขาคณิตให้เป็นพื้นที่ฉายภาพ WGS84 ในพื้นที่หรือภาพ WGS84 ขั้นสูงเช่น SIRGAS ในอเมริกาใต้

คุณสามารถดูในhttp://www.spatialreference.orgสำหรับพิกัดของการฉายภาพแบบ "zonified" เกือบทั้งหมดและคุณสามารถสร้างตารางและอื่น ๆ เพื่อแปลงมันขึ้นอยู่กับโซน

เราจินตนาการถึงโซนของตาราง

|   minx     |    miny    |    maxx    |   maxy     |  srid  |
+------------+------------+------------+------------+--------+
|234567.34314|234567.34334|234567.34334|234567.34334|  1234  |

ค่า minx, miny, maxx, maxy ทั้งหมดที่เก็บใน Spherical Mercator (Web Mercator) ดังนั้นฉันจะใช้ postgis เป็นตัวอย่าง

SELECT ST_Distance(
         ST_Transform( -- transform/reproject
            ST_SetSRID(geom_line, 3857) -- geom_line with forced srid assignation to web mercator
            , ( -- here we get the first SRID from the spatial position of geom_line
                 SELECT  srid
                 FROM    zones
                 WHERE   ST_Contains(
                           ST_MakeBox2d(ST_Point(minx,miny),ST_Point(maxx,maxy))
                           , geom_line
                         )
                 LIMIT 1
            ))

หวังว่านี่จะเป็นประโยชน์ขอให้มีความสุขในวันนี้นะ


ฉันไม่แน่ใจ แต่จากการใช้ "STDistance" ของ Blomster ในคำถามของเขาดูเหมือนว่าเขาไม่ได้ใช้ PostGIS ถ้า Blomster ใช้ SQL Server จะไม่มีฟังก์ชัน ST_Transform
Allan Adair

ฉันให้ขั้นตอนและวิธีที่ดีที่สุดที่ฉันสามารถแก้ไขได้เขาสามารถจัดการกับส่วนที่เหลือเขาสามารถใช้การคัดค้านซอฟต์แวร์ได้ แต่น่าเสียดายจริงๆที่ SQL Server ไม่จัดการกับการคาดการณ์
falcacibar

อาจจะเปิดใช้งาน CLR และ. net library nettopologysuite อาจช่วยได้?
falcacibar

0

OpenLayers มีวิธีการยูทิลิตี้ในการคำนวณระยะห่างระหว่างสองจุด EPSG: 4326 (WGS84) ในรูปวงรี เนื่องจาก OpenLayers เป็นโอเพ่นซอร์สคุณสามารถดูวิธีการใช้งานได้ที่นี่: https://github.com/openlayers/openlayers/blob/release-2.12/lib/OpenLayers/Util.js#L750

สำหรับผู้ที่ใช้ OpenLayers และการควบคุมการวัดเพียงแค่เปิดใช้งาน geodesic ในตัวเลือกครอกที่จะใช้การคำนวณนี้

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