มีเครื่องมือใดใน Python สำหรับทำการสร้างระยะทางวงกลม + สายที่ยอดเยี่ยม


20

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

มีเครื่องมืออะไรบ้างที่นั่น? ฉันควรใช้อะไร

คำตอบ:



8

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

รหัสโดย Alan Glennon http://enj.comกรกฎาคม 2010 (ผู้เขียนวางรหัสนี้ในโดเมนสาธารณะใช้ความเสี่ยงของคุณเอง)

-

def tweensegs (ลองจิจูด 1, ละติจูด 1, ลองจิจูด 2, ละติจูด 2, num_of_segments):

import math

ptlon1 = longitude1
ptlat1 = latitude1
ptlon2 = longitude2
ptlat2 = latitude2

numberofsegments = num_of_segments
onelessthansegments = numberofsegments - 1
fractionalincrement = (1.0/onelessthansegments)

ptlon1_radians = math.radians(ptlon1)
ptlat1_radians = math.radians(ptlat1)
ptlon2_radians = math.radians(ptlon2)
ptlat2_radians = math.radians(ptlat2)

distance_radians=2*math.asin(math.sqrt(math.pow((math.sin((ptlat1_radians-ptlat2_radians)/2)),2) + math.cos(ptlat1_radians)*math.cos(ptlat2_radians)*math.pow((math.sin((ptlon1_radians-ptlon2_radians)/2)),2)))
# 6371.009 represents the mean radius of the earth
# shortest path distance
distance_km = 6371.009 * distance_radians

mylats = []
mylons = []

# write the starting coordinates
mylats.append([])
mylons.append([])
mylats[0] = ptlat1
mylons[0] = ptlon1 

f = fractionalincrement
icounter = 1
while (icounter <  onelessthansegments):
        icountmin1 = icounter - 1
        mylats.append([])
        mylons.append([])
        # f is expressed as a fraction along the route from point 1 to point 2
        A=math.sin((1-f)*distance_radians)/math.sin(distance_radians)
        B=math.sin(f*distance_radians)/math.sin(distance_radians)
        x = A*math.cos(ptlat1_radians)*math.cos(ptlon1_radians) + B*math.cos(ptlat2_radians)*math.cos(ptlon2_radians)
        y = A*math.cos(ptlat1_radians)*math.sin(ptlon1_radians) +  B*math.cos(ptlat2_radians)*math.sin(ptlon2_radians)
        z = A*math.sin(ptlat1_radians) + B*math.sin(ptlat2_radians)
        newlat=math.atan2(z,math.sqrt(math.pow(x,2)+math.pow(y,2)))
        newlon=math.atan2(y,x)
        newlat_degrees = math.degrees(newlat)
        newlon_degrees = math.degrees(newlon)
        mylats[icounter] = newlat_degrees
        mylons[icounter] = newlon_degrees
        icounter += 1
        f = f + fractionalincrement

# write the ending coordinates
mylats.append([])
mylons.append([])
mylats[onelessthansegments] = ptlat2
mylons[onelessthansegments] = ptlon2

# Now, the array mylats[] and mylons[] have the coordinate pairs for intermediate points along the geodesic
# My mylat[0],mylat[0] and mylat[num_of_segments-1],mylat[num_of_segments-1] are the geodesic end points

# write a kml of the results
zipcounter = 0
kmlheader = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><kml xmlns=\"http://www.opengis.net/kml/2.2\"><Document><name>LineString.kml</name><open>1</open><Placemark><name>unextruded</name><LineString><extrude>1</extrude><tessellate>1</tessellate><coordinates>"
print kmlheader
while (zipcounter < numberofsegments):
        outputstuff = repr(mylons[zipcounter]) + "," + repr(mylats[zipcounter]) + ",0 "
        print outputstuff
        zipcounter += 1
kmlfooter = "</coordinates></LineString></Placemark></Document></kml>"
print kmlfooter

8

GeographicLib มีอินเทอร์เฟซหลาม :

สิ่งนี้สามารถคอมพิวเตอร์ geodesics บน ellipsoid (ตั้งค่าแบนเป็นศูนย์เพื่อรับวงกลมใหญ่) และสามารถสร้างจุดกึ่งกลางบน geodesic (ดูคำสั่ง "บรรทัด" ในตัวอย่าง)

ต่อไปนี้เป็นวิธีการพิมพ์คะแนนบนเส้นพิกัดดินจากเจเอฟเคไปยังสนามบินชางงี (สิงคโปร์):

from geographiclib.geodesic import Geodesic
geod = Geodesic.WGS84

g = geod.Inverse(40.6, -73.8, 1.4, 104)
l = geod.Line(g['lat1'], g['lon1'], g['azi1'])
num = 15  # 15 intermediate steps

for i in range(num+1):
    pos = l.Position(i * g['s12'] / num)
    print(pos['lat2'], pos['lon2'])

->
(40.60, -73.8)
(49.78, -72.99)
(58.95, -71.81)
(68.09, -69.76)
(77.15, -65.01)
(85.76, -40.31)
(83.77, 80.76)
(74.92, 94.85)
...

พอร์ตหลามของ GeographicLib อยู่ในขณะนี้ที่pypi.python.org/pypi/geographiclib
cffk

ดูกระดาษนี้: CFF Karney อัลกอริทึมสำหรับ Geodesics, J. Geod, DOI: dx.doi.org/10.1007/s00190-012-0578-z
cffk

7

pyprojมีฟังก์ชั่นGeod.nptsที่จะส่งกลับอาร์เรย์ของคะแนนตามเส้นทาง โปรดทราบว่ามันไม่ได้รวมคะแนนเทอร์มินัลไว้ในอาร์เรย์ดังนั้นคุณต้องคำนึงถึง:

import pyproj
# calculate distance between points
g = pyproj.Geod(ellps='WGS84')
(az12, az21, dist) = g.inv(startlong, startlat, endlong, endlat)

# calculate line string along path with segments <= 1 km
lonlats = g.npts(startlong, startlat, endlong, endlat,
                 1 + int(dist / 1000))

# npts doesn't include start/end points, so prepend/append them
lonlats.insert(0, (startlong, startlat))
lonlats.append((endlong, endlat))

ขอบคุณ! วิธีการแก้ปัญหาให้โดยที่รู้จักกันดีและห้องสมุดที่ใช้อย่างหนาแน่นที่นี่ :)
tdihp

3

geopy A กล่องเครื่องมือ Geocoding สำหรับ Python

http://code.google.com/p/geopy/wiki/GettingStarted#Calculating_distances


1
+1 ไม่เห็นฟังก์ชันการทำงานที่ทำจุดกึ่งกลางตามพื้นที่ทางภูมิศาสตร์ แต่ชุดเครื่องมือที่ดีมากที่ต้องรู้ (จัดการรูปวงรี calcs) ขอบคุณ.
ล็นนอน

-2

ฉันไม่ได้ใช้แพ็คเกจนี้ แต่ดูเหมือนว่าน่าสนใจและวิธีแก้ปัญหาที่เป็นไปได้: http://trac.gispython.org/lab/wiki/Shapely


7
AFAIK หุ่นดีไม่ทำการคำนวณ spheroidal:Shapely is a Python package for set-theoretic analysis and manipulation of **planar** features
fmark
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.