Những công cụ nào trong Python có sẵn để thực hiện tạo khoảng cách vòng tròn lớn + tạo đường thẳng?


20

Tôi cần sử dụng Python để tạo khoảng cách vòng tròn lớn - cả số và tốt nhất là một loại 'đường cong' mà tôi có thể sử dụng để vẽ trong bản đồ phía máy khách. Tôi không quan tâm đến định dạng của đường cong - có thể là WKT hoặc một tập hợp các cặp tọa độ - nhưng chỉ muốn lấy dữ liệu ra.

Có những công cụ nào ngoài đó? Tôi nên dùng gì?

Câu trả lời:



8

Các câu trả lời được cung cấp bởi những người khác thì thanh lịch hơn một chút, nhưng đây là một câu trả lời siêu phàm, hơi không khoa trương, cung cấp những điều cơ bản. Hàm này có hai cặp tọa độ và số lượng phân đoạn do người dùng chỉ định. Nó mang lại một tập hợp các điểm trung gian dọc theo một đường tròn lớn. Đầu ra: văn bản đã sẵn sàng để viết dưới dạng KML. Hãy cẩn thận: Mã không xem xét các phản hạt và giả định một trái đất hình cầu.

Mã của Alan Glennon http://enj.com tháng 7 năm 2010 (tác giả đặt mã này vào phạm vi công cộng. Sử dụng có nguy cơ của riêng bạn).

-

def tweensegie (kinh độ1, vĩ độ1, kinh độ2, vĩ độ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 có giao diện python :

Điều này có thể máy tính trắc địa trên một ellipsoid (đặt làm phẳng thành 0 để có được các vòng tròn lớn) và có thể tạo các điểm trung gian trên trắc địa (xem các lệnh "Line" trong mẫu).

Dưới đây là cách in các điểm trên đường trắc địa từ JFK đến Sân bay Changi (Singapore):

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)
...

Cổng python của GeographicLib hiện có sẵn tại pypi.python.org/pypi/geographiclib
cffk

Xem thêm bài viết này: CFF Karney, Thuật toán cho trắc địa, J. Geod, DOI: dx.doi.org/10.1007/s00190-012-0578-z
cffk

7

pyproj có hàm Geod.npts sẽ trả về một mảng các điểm dọc theo đường dẫn. Lưu ý rằng nó không bao gồm các điểm đầu cuối trong mảng, vì vậy bạn cần đưa chúng vào tài khoản:

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))

Cảm ơn! Giải pháp được cung cấp bởi thư viện nổi tiếng và được sử dụng ồ ạt tại đây :)
tdihp


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.