OSRM(Open Source Routing Machine)을 사용한 경로 탐색

15288 단어 Pythontech

개시하다


교통과 이동에 관한 프로그램을 쓸 때,항상 두 점 사이의 이동 경로와 거리를 계산하고 싶다[1]. 두 점이 평면상의 점(x1, y1)과 (x2, y2)의 거리를\sqrt{(x1-x2)^2+(y1-y2)^2}로 가정하면 즉시 계산할 수 있다. 목표가 평면상의 데이터가 될 때 특별한 어려움이 없다.
위도 경도 (lat 1,lon 1!예컨대
https://keisan.casio.jp/exec/system/1257670779
이렇게 계산하면 쉽게 이용할 수 있다.
R = 6371000 # Radius of the Earth
S1 = Point(35.18028,136.90667) # Nagoya
S2 = Point(35.68944,139.69167) # Tokyo

# ground distance
function dG(Si::Point, Sj::Point)
  φi, λi = deg2rad(Si.φ), deg2rad(Si.λ)
  φj, λj = deg2rad(Sj.φ), deg2rad(Sj.λ)
  v1 = sin( (φj - φi) / 2 )
  v2 = sin( (λj - λi) / 2 )
  return 2 * R * asin(sqrt( v1^2 + cos(φi) * cos(φj) * v2^2 ))
end

println("Example dG = $(dG(S1, S2)/1000) [km]")
대충 계산할 수 있다. 다른 한편, 교통과 이동에 관한 프로그램을 쓸 때 공의 거리를 기반으로 하지 않고 도로에서 이동하려는 거리가 대부분이다. OSRM을 이용하여 OpenStreetMap의 데이터에서 경로를 얻는 방법을 설명한다.

컨디션


OSRM입니다.
http://project-osrm.org/
이름과 같이 가장 짧은 경로를 계산하기 위한 기구입니다. 로컬에 열심히 설치할 수 있지만 도커에 사용할 수 있는 orsm-backend라는 컨테이너를 준비했기 때문에 그곳을 이용하기로 했습니다.어떤 방법으로든 docker pull을 실행할 수 있지만 Google map에 접근할 수 없는 환경에서 개발한 엔지니어 [2] 를 구상합니다.
우선 데이터와 용기의 준비,이번에는 최근 날씨가 더워진 것을 고려해 홋카이도의 오픈스트리트 맵 데이터를 활용하기로 했다. 통일된 단위로 다운로드할 수 있는 오픈스트리트 맵 데이터가 지오브릭에서 다운로드된 것(asia→Japan→Hokkkaido)이 있다. 컨테이너의 풀과 함께 아래 내용을 적는다.
docker pull osrm/osrm-backend
wget http://download.geofabrik.de/asia/japan/hokkaido-latest.osm.pbf

프리 프로세싱


먼저 얻은 osm.pbf 파일을 OSRM의 사전 처리에 놓습니다. 환경으로 현재 디렉터리에 hokkaido-latest가 있습니다.osm.pbf를 다운로드하면 아래 명령[3]을 누르면 된다. 일본 전체를 처리하는 데 시간이 좀 걸리지만 홋카이도 단위로 차 한 잔의 간격만 있으면 끝난다. Docker의 설정에 따르면 현재 디렉터리의 데이터는 용기의/data에 대응할 수 있다.
docker run -t -v "${PWD}:/data" osrm/osrm-backend \
    osrm-extract -p /opt/car.lua /data/hokkaido-latest.osm.pbf
docker run -t -v "${PWD}:/data" osrm/osrm-backend \
    osrm-partition /data/hokkaido-latest.osrm
docker run -t -v "${PWD}:/data" osrm/osrm-backend \
    osrm-customize /data/hokkaido-latest.osrm

백엔드 시작


위의 명령을 클릭하면 많은 파일이 생성됩니다. 이 상태에서 백엔드 (알고리즘은 mld; Multi-Level Dijkstra) 를 시작합니다.
docker run -t -i -p 5000:5000 -v "${PWD}:/data" osrm/osrm-backend \ 
    osrm-routed --algorithm mld /data/hokkaido-latest.osrm

파이톤에서 OSRM 활용


현재 docker의 용기가 시작 상태라고 가정합니다. 실행 프로그램의 환경에서 docker가 실행하는 환경에 대한 검색을 던지면 계산 결과가 JSON으로 되돌아옵니다.
두 점 사이의 위도 경도가 (lat 1,lon 1)일 때, (lat 2,lon 2)일 때 조회는
http://(docker ip):5000/route/v1/driving/{lon_1},{lat_1};{lon_2},{lat_2}
형식 제공(추가 매개 변수 교부). 자세한 내용은 OSRM 문서를 확인하십시오.
http://project-osrm.org/docs/v5.24.0/api/

이용 예


여기에는 다음과 같은 두 가지를 고려한다.
  • 시1: (43.069060141.4348117)
  • 점2: (44.0997897142.49705)
  • 이 두 가지 정보를 던져 JSON으로 해석하고 통과하는 경로를pytohon parse로 사용하면 아래와 같다(192.168.0.150은 이동docker의 PC이다).
    import requests
    
    loc_pick = [141.348117, 43.069060]
    loc_del = [142.449705, 44.0997897]
    query_url = "http://192.168.0.150:5000/route/v1/driving/{},{};{},{}?steps=true".format(loc_pick[0], loc_pick[1], loc_del[0], loc_del[1])
    response = requests.get(query_url)
    
    result = response.json()
    route = result["routes"][0]
    legs = route["legs"][0]["steps"]
    list_locations = []
    for point in legs:
        for it in point["intersections"]:
            list_locations.append(it["location"][::-1])
    
    이렇게 하면 목록에서 경로 정보를 얻을 수 있으며python의folium을 이용하여 그립니다.서버성 열람 (예:pythn-m http.server 후 접근) 을 하면 지도가 표시됩니다.
    import folium
    
    folium_map = folium.Map(location=loc_mid[::-1], zoom_start=14)
    folium.Marker(location=loc_pick[::-1], icon=folium.Icon(color='red')).add_to(folium_map)
    folium.Marker(location=loc_del[::-1]).add_to(folium_map)
    line = folium.vector_layers.PolyLine(locations=list_locations, color='black', weight=10)
    line.add_to(folium_map)
    folium_map.save("map.html")
    
    그려진 지도와 장소의 모양이 좋겠군요!

    오랜만에 Google map으로 두 점 사이의 경로를 검색한 그림을 Pet에게 보여 드리겠습니다.

    느낌이 조금 미묘하게 다르지만 인터넷과 멀리 떨어진 환경에서 볼 수 있는 정보로는 대개 이렇겠죠.
    OSRM + OpenStreetMap
    Google map


    괜찮은 것 같은데!이렇게 하면 Google map에서 사용할 수 없는 환경에서도 교통 및 이동 관련 프로그램을 진행할 수 있습니다.
    각주
    예를 들어 밀실(바깥 네트워크가 꺼진 상태)에 교통 앱을 쓴다고 가정해 보세요.↩︎
    JTC/JTBC 등에서 흔히 볼 수 있는 설정이다. 도커 풀은 회사 내 미러를 적절히 제작하거나 인장 릴레이로 풀을 할 수 있다.↩︎
    사실 작은 설정 파일 등을 두드려 조정할 수 있지만, 여기서는 기본적으로 두드린다. ↩︎

    좋은 웹페이지 즐겨찾기