问题
For each coordinate I have, I find the distance from the equator in kilometers giving me two distances:
from pyproj import Geod
wgs84_geod = Geod(ellps='WGS84')
_,_, lon_dist = wgs84_geod.inv(0, 0,lon, 0)
_,_, lat_dist = wgs84_geod.inv(0, 0,0, lat)
As a sanity check,I can recalculate the original coordinate from these values as follows (assume the direction from the equator coordinate (0,0) is North and West:
_, new_lat, _ = wgs84_geod.fwd(0,0, 0, lat_dist)
new_lon, _, _ = wgs84_geod.fwd(0, 0, 90, lon_dist)
This gives me back the same coordinates I started with.
Now I want to find the closest kilometer point to my coordinate. I round the lon_dist and lat_dist to kilometers from the equator values.
lat_km_dist = round(lat_dist/1000)*1000 #to nearest km and back to meters
lon_km_dist = round(lon_dist/1000)*1000
I get coordinates using these distances in the same way as before
_, km_lat, _ = wgs84_geod.fwd(0,0, 0, lat_km_dist)
km_lon, _, _ = wgs84_geod.fwd(0, 0, 90, lon_km_dist)
The logic should be that for multiple coordinates in the same area, the closest distance between any km_lat, km_lon pair should be 1km. This is true in the North/South axis, but for longitudes the distance varies depending on which latitude I'm at. I'm attaching two screenshots to visualize the problem where the km_lat, km_lon coordinates are represented by black circles at the center of polygons with an area of 1km.
How can I correct for this?
回答1:
What this algorithm is essentially doing is that it constructs an equidistant mesh (with points 1km apart) on the equator (lat=0) and the main meridian (lon=0). It then effectively constructs a grid on the ellipsoid as a Cartesian product of these points.
However, the lat/lon coordinates do not form a Cartesian frame, the resulting parallels/meridians generated by these grid points define "squares" the size of which depends not only on the particular longitude, but latitude as well. On a perfect sphere, this would work in the north-south direction since then an equidistant (in terms of great-circle distance) grid on lon=0 is also equidistant in the latitude (difference in latitude being equal to the difference in distance over the radius of the sphere).
In other words, if you fix two latitudes lat1
, lat2
and for a particular longitude lon
move from (lat1, lon)
, (lat2, lon)
1km in, say, westward direction, then these newly obtained points won't have the same longitude...
I am not fully sure what you are trying to achieve but if the goal is to obtain some representative points not too close to each other, then perhaps hierarchical clustering in terms of the great-circle distance could provide reasonable results...
EDIT:
As an approximative workaround, you could get most likely away by choosing another reference point than (0, 0)
- the new reference point shouldn't be too far away from the area that you are trying to describe (something like a "bottom-left" corner of the area of interest). If the entire area of interest doesn't cover a significant part of the globe (large span of latitudes) then the discrepancies will be quite small so that they will be probably almost invisible in the GoogleMaps visualization...
So if you are interested in Denmark (judging by the screenshots), then something like the following might work:
lat_ref, lon_ref = 53.637976, 6.694138
_,_, lon_dist = wgs84_geod.inv(lon_ref,lat_ref, lon, 0)
_,_, lat_dist = wgs84_geod.inv(lon_ref,lat_ref, 0, lat)
lat_km_dist = round(lat_dist/1000)*1000 #to nearest km and back to meters
lon_km_dist = round(lon_dist/1000)*1000
_, km_lat, _ = wgs84_geod.fwd(lon_ref,lat_ref, 0, lat_km_dist)
km_lon, _, _ = wgs84_geod.fwd(lon_ref,lat_ref, 90, lon_km_dist)
来源:https://stackoverflow.com/questions/42673048/convert-latitude-longitude-to-distance-from-equator-in-kilometers-and-round-to