Sự khác biệt về vị trí đích giữa pyproj và geopy


8

Tôi đang xem xét các cách tính toán (bằng Python) vị trí đích từ một điểm và phạm vi cho trước.

Dựa trên so sánh kết quả từ 2 thư viện trong chủ đề ( geopypyproj), tôi nhận thấy rằng có sự khác biệt ngày càng tăng trong đầu ra cuối cùng. Ví dụ, ở 100 km là khoảng thứ tự của decimet. Đây là một ví dụ tối thiểu về những gì tôi muốn nói:

from __future__ import absolute_import, division, print_function

long_1 = -1.729722
lat_1 = 53.320556
bearing = 96.021667
distance = 124.8  #in km

# using geopy

import geopy
from geopy.distance import VincentyDistance

origin = geopy.Point(lat_1, long_1)
destination = VincentyDistance(kilometers=distance).destination(origin, bearing)
gp_lat_2 = destination.latitude
gp_long_2 = destination.longitude

# using pyproj

from pyproj import Geod
g = Geod(ellps='WGS84')
prj_long_2, prj_lat_2, prj_bearing_2 = g.fwd(long_1, lat_1, bearing, distance*1000)

# results comparison
print("        | pyproj        | geopy")
print("long_2   %.6f     %.6f" % (prj_long_2, gp_long_2))
print("lat_2    %.6f     %.6f" % (prj_lat_2, gp_lat_2))

print("> DELTA pyproj, geopy")
print("delta long_2   %.7f" % (prj_long_2 - gp_long_2))
print("delta lat_2    %.7f" % (prj_lat_2 - gp_lat_2))

Tôi đã nhận được những kết quả này:

        | pyproj        | geopy
long_2   0.127201         0.127199
lat_2    53.188432        53.188432

> DELTA pyproj, geopy
delta long_2   0.0000021
delta lat_2    -0.0000002

Câu hỏi chính của tôi là liệu tôi có làm gì sai không (cả hai cài đặt nên được sử dụng WGS84).

Nếu không, sự khác biệt là do các công thức khác nhau được sử dụng (Vincenty cho geopyso với Karney cho pyproj)? Ví dụ, lỗi làm tròn được trích dẫn ở đây .

Câu trả lời:


6

Có vẻ như bạn đã làm mọi thứ chính xác. Bạn có thể đánh giá các lỗi từ mỗi phương pháp bằng cách thực hiện các phép tính nghịch đảo để tìm khoảng cách cho tọa độ gốc và tọa độ đích, sau đó đánh giá phần dư của khoảng cách. Đây là một bài tập khứ hồi.

# For Vincenty's method:
geopy_inv_dist = geopy.distance.vincenty(origin, destination).m
# For Karney's method:
prj_inv_dist = g.inv(long_1, lat_1, prj_long_2, prj_lat_2)[2]  # s12

print("> inverse distance residule (m)")
print("geopy  %.7f" % (distance * 1000 - geopy_inv_dist))
print("prj    %.7f" % (distance * 1000 - prj_inv_dist))

Trình diễn:

> inverse distance residule (m)
geopy  0.1434377
prj    0.0000000

Vì vậy, bạn có thể thấy rằng phương pháp của Vincenty xác định khoảng cách nghịch đảo so với số thập phân khác nhau cho cùng tọa độ. Phương pháp của Karney có lỗi trong độ chính xác của máy, nhỏ hơn 15 nanomet. Trong ví dụ này, sai số là 0,1455nm, xung quanh đường kính của một nguyên tử hydro.


Vấn đề có lẽ là với phương pháp đích của geopy . Hãy so sánh cách triển khai thứ hai của phương pháp Vincenty với các phiên bản PostGIS 2.1, được hiển thị ở đây . (PostGIS phiên bản 2.2 với Proj 4.9 trở lên sử dụng các phương thức của Karney ). Khoảng cách còn lại của chuyến đi khứ hồi từ PostGIS 2.1 luôn nhỏ hơn 1 cm. Trong ví dụ này, nó là 255 nm:

SELECT PostGIS_Version(),
  ST_AsText(origin) AS origin,
  ST_AsText(ST_Project(origin, distance, azimuth)) AS destination,
  ST_Distance(ST_Project(origin, distance, azimuth), origin) AS roundtrip_distance,
  distance - ST_Distance(ST_Project(origin, distance, azimuth), origin) AS postgis_residual
FROM (
  SELECT 124.8 * 1000 AS distance, radians(96.021667) AS azimuth,
    ST_SetSRID(ST_MakePoint(-1.729722, 53.320556), 4326)::geography AS origin
) AS f;
-[ RECORD 1 ]------+-----------------------------------------
postgis_version    | 2.1 USE_GEOS=1 USE_PROJ=1 USE_STATS=1
origin             | POINT(-1.729722 53.320556)
destination        | POINT(0.12720134063267 53.1884316458524)
roundtrip_distance | 124799.999999745
postgis_residual   | 2.54993210546672e-007

Cảm ơn bạn cho câu trả lời cực kỳ kỹ lưỡng, cực kỳ thông minh này!
Jason Scheirer

@ mike-t, cảm ơn bạn đã trả lời tốt đẹp! Tôi thích ý tưởng về nguồn thứ ba .. Tôi đã mở một geopyvé: github.com/geopy/geopy/issues/140
gmas80 24/07/2015

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.