วิธีการแปลงละติจูดหรือลองจิจูดเป็นเมตร?


127

ถ้าฉันมีการอ่านละติจูดหรือลองจิจูดในรูปแบบ NMEA มาตรฐานมีวิธี / สูตรง่ายๆในการแปลงการอ่านเป็นเมตรซึ่งฉันสามารถนำไปใช้ใน Java (J9) ได้หรือไม่

แก้ไข: โอเคดูเหมือนว่าสิ่งที่ฉันต้องการจะทำนั้นไม่สามารถทำได้ง่ายๆแต่สิ่งที่ฉันต้องการทำคือ:

สมมติว่าฉันมีจุด lat และทางยาวและ lat และ long ของผู้ใช้มีวิธีง่ายๆในการเปรียบเทียบเพื่อตัดสินใจว่าจะบอกผู้ใช้ว่าพวกเขาอยู่ในระยะทางที่ใกล้พอสมควรหรือไม่? ฉันรู้ว่าสมเหตุสมผลเป็นเรื่องที่ทำได้ง่ายหรือยังคงเป็นคณิตศาสตร์ -Y ที่มากเกินไป?


2
คุณหมายถึง UTM หรือไม่? en.wikipedia.org/wiki/…
Adrian Archer

1
การแปลง lat / long เป็นเมตรหมายความว่าอย่างไร เมตรจากไหน คุณกำลังมองหาวิธีคำนวณระยะทางตามพื้นผิวโลกจากพิกัดหนึ่งไปยังอีกพิกัดหนึ่งหรือไม่?
Baltimark

2
กำหนด "จุดอ้างอิง" กำหนด "สมเหตุสมผล" นี่คือสิ่งที่คุณต้องการทราบจริงๆ: "คุณคำนวณระยะห่างระหว่างจุดสองจุดโดยระบุละติจูดและลองจิจูดได้อย่างไร"
Baltimark

2
ฉันสะดุดกับคำถามนี้ที่ต้องการทำแบบสอบถาม SQL เกี่ยวกับละติจูดและลองจิจูดและพบบทความที่ยอดเยี่ยมนี้พร้อมรหัส Java ที่ด้านล่าง มันอาจสนใจคุณเช่นกัน
Kristof Van Landschoot

คำตอบ:


173

นี่คือฟังก์ชันจาวาสคริปต์:

function measure(lat1, lon1, lat2, lon2){  // generally used geo measurement function
    var R = 6378.137; // Radius of earth in KM
    var dLat = lat2 * Math.PI / 180 - lat1 * Math.PI / 180;
    var dLon = lon2 * Math.PI / 180 - lon1 * Math.PI / 180;
    var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
    Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *
    Math.sin(dLon/2) * Math.sin(dLon/2);
    var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
    var d = R * c;
    return d * 1000; // meters
}

คำอธิบาย: https://en.wikipedia.org/wiki/Haversine_formula

สูตรฮาเวอร์ไซน์กำหนดระยะห่างของวงกลมใหญ่ระหว่างจุดสองจุดบนทรงกลมโดยพิจารณาจากลองจิจูดและละติจูด


2
สำหรับผู้ที่มองหาไลบรารีเพื่อแปลงระหว่าง wgs และ utm: github.com/urbanetic/utm-converter
Aram Kocharyan

3
จะขอบคุณมากถ้ามีใครสามารถเพิ่มความคิดเห็นเชิงอธิบายเกี่ยวกับโค้ดด้านบนได้ ขอบคุณล่วงหน้า!
Ravindranath Akila

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

ฉันจะเพิ่มระดับความสูงในการคำนวณนี้ได้อย่างไร
dangalg

62

เนื่องจากคุณกำลังมองหาสูตรง่ายๆนี่อาจเป็นวิธีที่ง่ายที่สุดโดยสมมติว่าโลกเป็นทรงกลมที่มีเส้นรอบวง 40075 กม.

ความยาวเป็นเมตรละติจูด 1 ° = 111.32 กม. เสมอ

ความยาวเป็นเมตร 1 °ของลองจิจูด = 40075 กม. * cos (ละติจูด) / 360


2
สมการลองจิจูดทำงานอย่างไร? ด้วยละติจูด 90 องศาคุณคาดว่าจะแสดงใกล้ 111 กม. แต่จะแสดงเป็น 0 แทน ในทำนองเดียวกันค่าใกล้เคียงก็ใกล้ 0 เช่นกัน
Reece

9
ละติจูดคือ 0 °ที่เส้นศูนย์สูตรและ 90 °ที่ขั้ว (ไม่ใช่ตรงข้าม) สำหรับเส้นศูนย์สูตรสูตรจะให้ 40075 กม. * cos (0 °) / 360 = 111 กม. สำหรับเสาสูตรจะให้ 40075 * cos (90 °) / 360 = 0 กม.
เบ็น

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

29

สำหรับการประมาณระยะทางสั้น ๆ ระหว่างสองพิกัดฉันใช้สูตรจาก http://en.wikipedia.org/wiki/Lat-lon :

m_per_deg_lat = 111132.954 - 559.822 * cos( 2 * latMid ) + 1.175 * cos( 4 * latMid);
m_per_deg_lon = 111132.954 * cos ( latMid );

.

ในโค้ดด้านล่างฉันได้ทิ้งตัวเลขดิบไว้เพื่อแสดงความสัมพันธ์กับสูตรจาก wikipedia

double latMid, m_per_deg_lat, m_per_deg_lon, deltaLat, deltaLon,dist_m;

latMid = (Lat1+Lat2 )/2.0;  // or just use Lat1 for slightly less accurate estimate


m_per_deg_lat = 111132.954 - 559.822 * cos( 2.0 * latMid ) + 1.175 * cos( 4.0 * latMid);
m_per_deg_lon = (3.14159265359/180 ) * 6367449 * cos ( latMid );

deltaLat = fabs(Lat1 - Lat2);
deltaLon = fabs(Lon1 - Lon2);

dist_m = sqrt (  pow( deltaLat * m_per_deg_lat,2) + pow( deltaLon * m_per_deg_lon , 2) );

รายการวิกิพีเดียระบุว่าระยะทางอยู่ภายใน 0.6 ม. สำหรับ 100 กม. ตามยาวและ 1 ซม. สำหรับ 100 กม. ในระยะแฝง แต่ฉันยังไม่ได้ตรวจสอบสิ่งนี้เนื่องจากทุกที่ที่อยู่ใกล้ความแม่นยำนั้นใช้ได้


3
โปรดทราบว่าในปี 2560 หน้า Wikipedia มีสูตรอื่น (ดูเหมือนละเอียดอ่อน)
Gorka Llona

3
ใช่สูตรใน Wikipedia จะแตกต่างกันเล็กน้อย แต่ดูเหมือนว่าสูตรอื่น ๆ ของ Wikipediaจะขึ้นอยู่กับผลลัพธ์ที่คล้ายกันจากคำตอบ SO ที่ยอดเยี่ยมนี้ซึ่งมีคนผ่านการคำนวณมาแล้ว
not2qubit

10

ละติจูดและลองจิจูดระบุจุดไม่ใช่ระยะทางดังนั้นคำถามของคุณจึงค่อนข้างไร้สาระ หากคุณกำลังถามเกี่ยวกับระยะทางที่สั้นที่สุดระหว่างสองจุด (lat, lon) โปรดดูบทความ Wikipedia นี้เกี่ยวกับระยะทางวงกลมใหญ่


9
เขากำลังพูดถึงการเปลี่ยนใจเลื่อมใสดังนั้นคำตอบของคุณจึงไม่ตรงประเด็น (ไม่ได้ตั้งใจเล่นสำนวน)
Paulo Neves

1
และสำหรับการอ้างอิงคู่มือการแปลงสำหรับการแปลงข้อมูลตำแหน่ง GPS www.microem.ru/pages/u_blox/tech/dataconvert/GPS.G1-X-00006.pdf
Paulo Neves

2
เขาต้องการทราบว่ากี่องศาต่อเมตรจึงจะสามารถหาระยะห่างระหว่างจุด 2 จุดได้ อ่านความหมายที่ซ่อนอยู่.
theAnonymous

1
และคำตอบของคุณไร้สาระมากขึ้น
jerinho.com

7

มีเครื่องมือมากมายที่จะทำให้ง่าย ดูคำตอบของ monjardinสำหรับรายละเอียดเพิ่มเติมเกี่ยวกับสิ่งที่เกี่ยวข้อง

อย่างไรก็ตามการทำเช่นนี้ไม่ใช่เรื่องยากเสมอไป ดูเหมือนว่าคุณกำลังใช้ Java ดังนั้นฉันจะขอแนะนำให้ดูเป็นสิ่งที่ต้องการGDAL มันมีตัวห่อ java สำหรับกิจวัตรของพวกเขาและพวกเขามีเครื่องมือทั้งหมดที่จำเป็นในการแปลงจาก Lat / Lon (พิกัดทางภูมิศาสตร์) เป็น UTM (ระบบพิกัดที่คาดการณ์ไว้) หรือการฉายแผนที่ที่สมเหตุสมผลอื่น ๆ

UTM นั้นดีเพราะเป็นเมตรจึงใช้งานง่าย อย่างไรก็ตามคุณจะต้องได้รับโซน UTMที่เหมาะสมเพื่อให้ทำงานได้ดี มีรหัสง่ายๆผ่าน googling เพื่อค้นหาโซนที่เหมาะสมสำหรับคู่ lat / long


7

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

NOAA มีซอฟแวร์บางอย่างที่คุณสามารถดาวน์โหลดไปยังความช่วยเหลือเกี่ยวกับเรื่องนี้ในเว็บไซต์ของตน


6

นี่คือฟังก์ชัน bh-'เวอร์ชัน R ในกรณี:

measure <- function(lon1,lat1,lon2,lat2) {
    R <- 6378.137                                # radius of earth in Km
    dLat <- (lat2-lat1)*pi/180
    dLon <- (lon2-lon1)*pi/180
    a <- sin((dLat/2))^2 + cos(lat1*pi/180)*cos(lat2*pi/180)*(sin(dLon/2))^2
    c <- 2 * atan2(sqrt(a), sqrt(1-a))
    d <- R * c
    return (d * 1000)                            # distance in meters
}

2

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


1
ไม่ไมล์ทะเลกำหนดโดยมาตรฐานสากล ( v en.wikipedia.org/wiki/Nautical_mile ) เป็น 1852 ม. ความสัมพันธ์กับการวัดส่วนโค้งบนพื้นผิวของทรงกลมเช่นโลกในขณะนี้เป็นทั้งในอดีตและโดยประมาณ
High Performance Mark

2

มีหลายวิธีในการคำนวณสิ่งนี้ ทั้งหมดนี้ใช้การประมาณค่าโดยประมาณของตรีโกณมิติทรงกลมโดยที่รัศมีเป็นหนึ่งในโลก

ลองhttp://www.movable-type.co.uk/scripts/latlong.htmlสำหรับวิธีการและโค้ดในภาษาต่างๆ


1
    'below is from
'http://www.zipcodeworld.com/samples/distance.vbnet.html
Public Function distance(ByVal lat1 As Double, ByVal lon1 As Double, _
                         ByVal lat2 As Double, ByVal lon2 As Double, _
                         Optional ByVal unit As Char = "M"c) As Double
    Dim theta As Double = lon1 - lon2
    Dim dist As Double = Math.Sin(deg2rad(lat1)) * Math.Sin(deg2rad(lat2)) + _
                            Math.Cos(deg2rad(lat1)) * Math.Cos(deg2rad(lat2)) * _
                            Math.Cos(deg2rad(theta))
    dist = Math.Acos(dist)
    dist = rad2deg(dist)
    dist = dist * 60 * 1.1515
    If unit = "K" Then
        dist = dist * 1.609344
    ElseIf unit = "N" Then
        dist = dist * 0.8684
    End If
    Return dist
End Function
Public Function Haversine(ByVal lat1 As Double, ByVal lon1 As Double, _
                         ByVal lat2 As Double, ByVal lon2 As Double, _
                         Optional ByVal unit As Char = "M"c) As Double
    Dim R As Double = 6371 'earth radius in km
    Dim dLat As Double
    Dim dLon As Double
    Dim a As Double
    Dim c As Double
    Dim d As Double
    dLat = deg2rad(lat2 - lat1)
    dLon = deg2rad((lon2 - lon1))
    a = Math.Sin(dLat / 2) * Math.Sin(dLat / 2) + Math.Cos(deg2rad(lat1)) * _
            Math.Cos(deg2rad(lat2)) * Math.Sin(dLon / 2) * Math.Sin(dLon / 2)
    c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a))
    d = R * c
    Select Case unit.ToString.ToUpper
        Case "M"c
            d = d * 0.62137119
        Case "N"c
            d = d * 0.5399568
    End Select
    Return d
End Function
Private Function deg2rad(ByVal deg As Double) As Double
    Return (deg * Math.PI / 180.0)
End Function
Private Function rad2deg(ByVal rad As Double) As Double
    Return rad / Math.PI * 180.0
End Function

ฉันเห็นลิงค์เต็มไปด้วยเสีย
tshepang

1

ในการแปลงละติจูดและลองจิจูดในการแทนค่า x และ y คุณต้องตัดสินใจว่าจะใช้เส้นโครงแผนที่ประเภทใด สำหรับฉัน Elliptical Mercator ดูเหมือนจะดีมาก ที่นี่คุณสามารถค้นหาการใช้งาน (ใน Java ด้วย)


0

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


3
ไม่ได้ผล! ระยะทาง x เป็น m แตกต่างกันสำหรับค่าละติจูดที่แตกต่างกัน ที่เส้นศูนย์สูตรคุณอาจหนีไปได้ แต่ยิ่งคุณเข้าใกล้ขั้วมากเท่าไหร่ก็จะยิ่งขยายวงรีออกไป
RickyA

3
แม้ว่าความคิดเห็นของคุณจะสมเหตุสมผล แต่ก็ไม่ได้ตอบคำถามของผู้ใช้เกี่ยวกับการแปลงความแตกต่างขององศา lat / lng เป็นเมตร
JivanAmara

0

ขึ้นอยู่กับระยะทางเฉลี่ยของ degress ในโลก

1 ° = 111 กม.;

การแปลงค่านี้เป็นเรเดียนและหารเป็นเมตรให้ใช้เลขวิเศษสำหรับ RAD เป็นเมตร: 0.000008998719243599958;

แล้ว:

const RAD = 0.000008998719243599958;
Math.sqrt(Math.pow(lat1 - lat2, 2) + Math.pow(long1 - long2, 2)) / RAD;

3
ในที่สุดคำตอบที่ตรงไปตรงมา :)
Ben Hutchison

จะเกิดอะไรขึ้นถ้าละติจูดคือ -179 และอีกเส้นคือ 179 ระยะ x ควรเป็น 2 องศาแทนที่จะเป็น 358
OMGPOP

7
อย่าใช้คำตอบนี้ (ด้วยเหตุผลบางประการจึงมีการโหวตเพิ่มขึ้น) ไม่มีการปรับขนาดระหว่างลองจิจูดและระยะทางแม้แต่ครั้งเดียว โลกไม่ได้แบน
CPBL

1
ฉันเชื่อว่ามันคือ 111.1
Abel Callejo

6
โปรดสังเกตว่าลองจิจูดหนึ่งองศาคือ 111 กม. ที่เส้นศูนย์สูตร แต่น้อยกว่าสำหรับละติจูดอื่น ๆ มีสูตรง่ายๆในการหาความยาวเป็นกม. ของลองจิจูด 1 °ในฟังก์ชันของละติจูด: 1 °ของลองจิจูด = 40000 กม. * cos (ละติจูด) / 360 (และแน่นอนว่าให้ 111 กม. สำหรับละติจูด = 90 °) โปรดสังเกตด้วยว่า 1 °ของลองจิจูดมักจะมีระยะห่างที่แตกต่างกันมากกว่า 1 °ของละติจูด
เบ็น

-1

หากคุณต้องการวิธีง่ายๆให้ใช้สูตร Haversineตามที่ระบุไว้ในความคิดเห็นอื่น ๆ หากคุณมีแอปพลิเคชันที่ไวต่อความแม่นยำโปรดจำไว้ว่าสูตร Haversine ไม่ได้รับประกันความแม่นยำที่ดีกว่า 0.5% เนื่องจากสมมติว่าโลกเป็นทรงกลม ที่จะต้องพิจารณาว่าโลกเป็นรูปไข่ spheroid พิจารณาใช้สูตร Vincenty ของ นอกจากนี้ฉันไม่แน่ใจว่าเราควรใช้รัศมีเท่าใดกับสูตร Haversine: {Equator: 6,378.137 km, Polar: 6,356.752 km, Volumetric: 6,371.0088 km}


it is assuming the earth is a circle^^ คนแปลก ๆ บางคนทำแบบนี้ในปัจจุบัน ... แต่สิ่งที่คุณหมายถึงนั้นน่าจะเป็นมากกว่าit is assuming the earth is a sphere;)
derHugo

-2

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

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