위도/경도에 따라 두 점 사이의 거리를 구합니다.
저는 다음 공식을 구현해 보았습니다.http://andrew.hedges.name/experiments/haversine/ aplet은 테스트 중인 두 가지 점에 적용됩니다.
하지만 내 코드는 작동하지 않는다.
from math import sin, cos, sqrt, atan2
R = 6373.0
lat1 = 52.2296756
lon1 = 21.0122287
lat2 = 52.406374
lon2 = 16.9251681
dlon = lon2 - lon1
dlat = lat2 - lat1
a = (sin(dlat/2))**2 + cos(lat1) * cos(lat2) * (sin(dlon/2))**2
c = 2 * atan2(sqrt(a), sqrt(1-a))
distance = R * c
print "Result", distance
print "Should be", 278.546
돌아오는 거리는 5447.05546147입니다. 왜요?
업데이트: 2018년 4월: GeoPy 버전 1.13 이후 Vincenty distance가 폐지되었습니다.대신 사용하세요!
위의 답변은 지구가 구라고 가정하는 Haversine 공식에 기초하고 있으며, 이것은 약 0.5%의 오차를 초래한다.help(geopy.distance)
빈센트 거리는 WGS-84와 같은 보다 정확한 타원형 모델을 사용하며 지오피로 구현됩니다.예를들면,
import geopy.distance
coords_1 = (52.2296756, 21.0122287)
coords_2 = (52.406374, 16.9251681)
print geopy.distance.geodesic(coords_1, coords_2).km
거리를 인쇄하다279.352901604
디폴트 타원체 WGS-84를 사용하여 km를 설정합니다(선택할 수도 있습니다)..miles
또는 다른 여러 거리 단위 중 하나).
편집: 참고로 두 점 사이의 거리를 빠르고 쉽게 찾을 수 있는 방법이 필요한 경우 Haversine을 다시 구현하는 대신 아래 Kurt의 답변에서 설명하는 방법을 사용하는 것을 강력히 권장합니다.근거는 게시물을 참조하십시오.
이 답변은 OP에서 발생한 특정 버그에 대한 답변에 초점을 맞추고 있습니다.
Python에서는 모든 trig 함수가 도수가 아닌 라디안을 사용하기 때문입니다.
숫자를 수동으로 라디안으로 변환하거나 산술 모듈의 함수를 사용할 수 있습니다.
from math import sin, cos, sqrt, atan2, radians
# approximate radius of earth in km
R = 6373.0
lat1 = radians(52.2296756)
lon1 = radians(21.0122287)
lat2 = radians(52.406374)
lon2 = radians(16.9251681)
dlon = lon2 - lon1
dlat = lat2 - lat1
a = sin(dlat / 2)**2 + cos(lat1) * cos(lat2) * sin(dlon / 2)**2
c = 2 * atan2(sqrt(a), sqrt(1 - a))
distance = R * c
print("Result:", distance)
print("Should be:", 278.546, "km")
거리는 이제 올바른 값을 반환합니다.278.545589351
km.
(저와 같이) 검색 엔진을 사용하여 바로 사용할 수 있는 솔루션을 찾고 있는 분에게는 설치를 권장합니다.설치 방법pip install mpu --user
이렇게 사용하여 해버사인 거리를 구합니다.
import mpu
# Point one
lat1 = 52.2296756
lon1 = 21.0122287
# Point two
lat2 = 52.406374
lon2 = 16.9251681
# What you were looking for
dist = mpu.haversine_distance((lat1, lon1), (lat2, lon2))
print(dist) # gives 278.45817507541943.
대체 패키지는 입니다.
종속성을 원하지 않는 경우 다음을 사용할 수 있습니다.
import math
def distance(origin, destination):
"""
Calculate the Haversine distance.
Parameters
----------
origin : tuple of float
(lat, long)
destination : tuple of float
(lat, long)
Returns
-------
distance_in_km : float
Examples
--------
>>> origin = (48.1372, 11.5756) # Munich
>>> destination = (52.5186, 13.4083) # Berlin
>>> round(distance(origin, destination), 1)
504.2
"""
lat1, lon1 = origin
lat2, lon2 = destination
radius = 6371 # km
dlat = math.radians(lat2 - lat1)
dlon = math.radians(lon2 - lon1)
a = (math.sin(dlat / 2) * math.sin(dlat / 2) +
math.cos(math.radians(lat1)) * math.cos(math.radians(lat2)) *
math.sin(dlon / 2) * math.sin(dlon / 2))
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
d = radius * c
return d
if __name__ == '__main__':
import doctest
doctest.testmod()
또 다른 패키지는
from haversine import haversine, Unit
lyon = (45.7597, 4.8422) # (lat, lon)
paris = (48.8567, 2.3508)
haversine(lyon, paris)
>> 392.2172595594006 # in kilometers
haversine(lyon, paris, unit=Unit.MILES)
>> 243.71201856934454 # in miles
# you can also use the string abbreviation for units:
haversine(lyon, paris, unit='mi')
>> 243.71201856934454 # in miles
haversine(lyon, paris, unit=Unit.NAUTICAL_MILES)
>> 211.78037755311516 # in nautical miles
두 벡터의 모든 점 사이의 거리에 대해 성능을 최적화한다고 주장합니다.
from haversine import haversine_vector, Unit
lyon = (45.7597, 4.8422) # (lat, lon)
paris = (48.8567, 2.3508)
new_york = (40.7033962, -74.2351462)
haversine_vector([lyon, lyon], [paris, new_york], Unit.KILOMETERS)
>> array([ 392.21725956, 6163.43638211])
나는 훨씬 더 단순하고 견고한 솔루션에 도달했다.geodesic
부터geopy
패키지는 어차피 프로젝트에서 사용할 가능성이 높기 때문에 추가 패키지 설치가 필요하지 않습니다.
저의 솔루션은 다음과 같습니다.
from geopy.distance import geodesic
origin = (30.172705, 31.526725) # (latitude, longitude) don't confuse
dist = (30.288281, 31.732326)
print(geodesic(origin, dist).meters) # 23576.805481751613
print(geodesic(origin, dist).kilometers) # 23.576805481751613
print(geodesic(origin, dist).miles) # 14.64994773134371
좌표를 기준으로 거리를 계산하는 방법은 여러 가지가 있습니다(예: 위도 및 경도).
설치 및 Import
from geopy import distance
from math import sin, cos, sqrt, atan2, radians
from sklearn.neighbors import DistanceMetric
import osrm
import numpy as np
좌표 정의
lat1, lon1, lat2, lon2, R = 20.9467,72.9520, 21.1702, 72.8311, 6373.0
coordinates_from = [lat1, lon1]
coordinates_to = [lat2, lon2]
haversine 사용
dlon = radians(lon2) - radians(lon1)
dlat = radians(lat2) - radians(lat1)
a = sin(dlat / 2)**2 + cos(lat1) * cos(lat2) * sin(dlon / 2)**2
c = 2 * atan2(sqrt(a), sqrt(1 - a))
distance_haversine_formula = R * c
print('distance using haversine formula: ', distance_haversine_formula)
sklearn에서 haversine 사용
dist = DistanceMetric.get_metric('haversine')
X = [[radians(lat1), radians(lon1)], [radians(lat2), radians(lon2)]]
distance_sklearn = R * dist.pairwise(X)
print('distance using sklearn: ', np.array(distance_sklearn).item(1))
OSRM 사용
osrm_client = osrm.Client(host='http://router.project-osrm.org')
coordinates_osrm = [[lon1, lat1], [lon2, lat2]] # note that order is lon, lat
osrm_response = osrm_client.route(coordinates=coordinates_osrm, overview=osrm.overview.full)
dist_osrm = osrm_response.get('routes')[0].get('distance')/1000 # in km
print('distance using OSRM: ', dist_osrm)
지오피 사용
distance_geopy = distance.distance(coordinates_from, coordinates_to).km
print('distance using geopy: ', distance_geopy)
distance_geopy_great_circle = distance.great_circle(coordinates_from, coordinates_to).km
print('distance using geopy great circle: ', distance_geopy_great_circle)
산출량
distance using haversine formula: 26.07547017310917
distance using sklearn: 27.847882224769783
distance using OSRM: 33.091699999999996
distance using geopy: 27.7528030550408
distance using geopy great circle: 27.839182219511834
import numpy as np
def Haversine(lat1,lon1,lat2,lon2, **kwarg):
"""
This uses the ‘haversine’ formula to calculate the great-circle distance between two points – that is,
the shortest distance over the earth’s surface – giving an ‘as-the-crow-flies’ distance between the points
(ignoring any hills they fly over, of course!).
Haversine
formula: a = sin²(Δφ/2) + cos φ1 ⋅ cos φ2 ⋅ sin²(Δλ/2)
c = 2 ⋅ atan2( √a, √(1−a) )
d = R ⋅ c
where φ is latitude, λ is longitude, R is earth’s radius (mean radius = 6,371km);
note that angles need to be in radians to pass to trig functions!
"""
R = 6371.0088
lat1,lon1,lat2,lon2 = map(np.radians, [lat1,lon1,lat2,lon2])
dlat = lat2 - lat1
dlon = lon2 - lon1
a = np.sin(dlat/2)**2 + np.cos(lat1) * np.cos(lat2) * np.sin(dlon/2) **2
c = 2 * np.arctan2(a**0.5, (1-a)**0.5)
d = R * c
return round(d,4)
우버의 H3를 이용하실 수 있습니다.point_dist()
라트, 엘지, 엘지, 엘지.,, ( km 、 m ) rads 。Km을 내다
예:
import h3
coords_1 = (52.2296756, 21.0122287)
coords_2 = (52.406374, 16.9251681)
distance = h3.point_dist(coords_1, coords_2, unit='m') # to get distance in meters
이것이 유용하기를 바랍니다!
2022년에는 보다 최신의 Javascript 라이브러리를 이용하여 이 문제를 해결하는 라이브 Javascript 코드를 게시할 수 있습니다.일반적인 장점은 사용자가 최신 디바이스에서 실행되는 웹 페이지에서 결과를 보고 실행할 수 있다는 것입니다.
// Using WGS84 ellipsoid model for computation
var geod84 = geodesic.Geodesic.WGS84;
// Input data
lat1 = 52.2296756;
lon1 = 21.0122287;
lat2 = 52.406374;
lon2 = 16.9251681;
// Do the classic `geodetic inversion` computatioin
geod84inv = geod84.Inverse(lat1, lon1, lat2, lon2);
// Present the solution (only the geodetic distance)
console.log("The distance is " + (geod84inv.s12/1000).toFixed(5) + " km.");
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/geographiclib-geodesic@2.0.0/geographiclib-geodesic.min.js">
</script>
혼합된 2022년을 할 수 .javascript+python
라이브러리를 하여 이 , "Python 라이브러리 "Python 라이브러리", "Python 라이브러리"geographiclib
일반적인 장점은 사용자가 최신 기기에서 실행되는 웹 페이지에서 결과를 볼 수 있다는 것입니다.
async function main(){
let pyodide = await loadPyodide();
await pyodide.loadPackage(["micropip"]);
console.log(pyodide.runPythonAsync(`
import micropip
await micropip.install('geographiclib')
from geographiclib.geodesic import Geodesic
lat1 = 52.2296756;
lon1 = 21.0122287;
lat2 = 52.406374;
lon2 = 16.9251681;
ans = Geodesic.WGS84.Inverse(lat1, lon1, lat2, lon2)
dkm = ans["s12"] / 1000
print("Geodesic solution", ans)
print(f"Distance = {dkm:.4f} km.")
`));
}
main();
<script src="https://cdn.jsdelivr.net/pyodide/v0.20.0/full/pyodide.js"></script>
가장 간단한 방법은 haversine 패키지를 사용하는 것입니다.
import haversine as hs
coord_1 = (lat, lon)
coord_2 = (lat, lon)
x = hs.haversine(coord_1,coord_2)
print(f'The distance is {x} km')
다른 javascript+python
through를 통해.pyodide
★★★★★★★★★★★★★★★★★」webassembly
Python Libraries Python을 하여 위한 pandas+geographiclib
실현가능성도 있습니다. 특별히 요.pandas
수 있는 경우 를 " "에 합니다.solution
pandas. 공통의 요구에 따라 합니다.Panda는 공통의 요구를 위해 입력/출력을 위한 많은 유용한 기능을 제공합니다. 메서드 법방 itstoHtml
는 웹 합니다.
편집 이 답변의 코드가 일부 iPhone 및 iPad 기기에서 성공적으로 실행되지 않는 것을 발견했습니다.그러나 새로운 미드레인지 Android 기기에서는 정상적으로 작동합니다.저는 이 문제를 수정하고 빠른 시일 내에 업데이트 할 방법을 찾겠습니다.
다른 답변과 마찬가지로 OP 질문에 대한 직접적인 답변이 아니라는 것을 알고 있습니다.하지만 최근 외부에서는 StackOverflow의 많은 답변이 구식이며 사람들을 이곳에서 멀리하려고 한다고 말했다.
async function main(){
let pyodide = await loadPyodide();
await pyodide.loadPackage(["pandas", "micropip"]);
console.log(pyodide.runPythonAsync(`
import micropip
import pandas as pd
import js
print("Pandas version: " + pd.__version__)
await micropip.install('geographiclib')
from geographiclib.geodesic import Geodesic
import geographiclib as gl
print("Geographiclib version: " + gl.__version__)
data = {'Description': ['Answer to the question', 'Bangkok to Tokyo'],
'From_long': [21.0122287, 100.6],
'From_lat': [52.2296756, 13.8],
'To_long': [16.9251681, 139.76],
'To_lat': [52.406374, 35.69],
'Distance_km': [0, 0]}
df1 = pd.DataFrame(data)
collist = ['Description','From_long','From_lat','To_long','To_lat']
div2 = js.document.createElement("div")
div2content = df1.to_html(buf=None, columns=collist, col_space=None, header=True, index=True)
div2.innerHTML = div2content
js.document.body.append(div2)
arr="<i>by Swatchai</i>"
def dkm(frLat,frLon,toLat,toLon):
print("frLon,frLat,toLon,toLat:", frLon, "|", frLat, "|", toLon, "|", toLat)
dist = Geodesic.WGS84.Inverse(frLat, frLon, toLat, toLon)
return dist["s12"] / 1000
collist = ['Description','From_long','From_lat','To_long','To_lat','Distance_km']
dist = []
for ea in zip(df1['From_lat'].values, df1['From_long'].values, df1['To_lat'].values, df1['To_long'].values):
ans = dkm(*ea)
print("ans=", ans)
dist.append(ans)
df1['Distance_km'] = dist
# Update content
div2content = df1.to_html(buf=None, columns=collist, col_space=None, header=True, index=False)
div2.innerHTML = div2content
js.document.body.append(div2)
# Using Haversine Formula
from math import sin, cos, sqrt, atan2, radians, asin
# approximate radius of earth in km from wikipedia
R = 6371
lat1 = radians(52.2296756)
lon1 = radians(21.0122287)
lat2 = radians(52.406374)
lon2 = radians(16.9251681)
# https://en.wikipedia.org/wiki/Haversine_formula
def hav(angrad):
return (1-cos(angrad))/2
h = hav(lat2-lat1)+cos(lat2)*cos(lat1)*hav(lon2-lon1)
dist2 = 2*R*asin(sqrt(h))
print(f"Distance by haversine formula = {dist2:8.6f} km.")
`));
}
main();
<script src="https://cdn.jsdelivr.net/pyodide/v0.20.0/full/pyodide.js"></script>
Pyodide implementation<br>
언급URL : https://stackoverflow.com/questions/19412462/getting-distance-between-two-points-based-on-latitude-longitude
'programing' 카테고리의 다른 글
AWS: 컴퓨터에서 RDS 데이터베이스에 연결할 수 없음 (0) | 2022.10.02 |
---|---|
CodeIgniter의 뷰 내에 뷰를 포함하는 최선의 방법 (0) | 2022.10.02 |
케이스를 올바르게 사용하는 방법..MySQL의 경우 (0) | 2022.09.19 |
Java에서 클래스의 다른 인스턴스를 실행하는 스레드 간에 정적 변수를 동기화하려면 어떻게 해야 합니까? (0) | 2022.09.19 |
오브젝트의 모든 속성을 인쇄하는 방법 (0) | 2022.09.19 |