일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- Python
- r
- riotapi
- kepler.gl
- 지도
- 오류
- 인코등
- 에러
- geopnadas
- 시각화
- 오픈API
- geopandas에러
- API
- 코로나
- kepler
- geopandas설치
- 파이썬
- Folium
- matplotlib
- 마커클러스터
- map
- 공공데이터포털
- QGIS라벨링
- 라이엇
- 라이엇api
- 막대그래프
- OSMnx
- pipwin
- covid19
- covid
- Today
- Total
Nerdy
Shp 파일을 사용하여 OSMnx 최단 경로 분석 본문
약 2년전 본 블로그에 기술한 'OSMnx와 Folium을 이용한 특정 지역 최단경로 분석 및 시각화' 내용에 잘못된 문제점이 많아 다시 작성할겸 이번엔 Shp 파일을 활용하여 geopandas도 사용해서 다시 분석했다.
문제점은 다음과 같았다.
1. 도착지를 동대문역으로 지정했는데 대상 지역 그래프는 동대문구를 호출(동대문역 시군구는 종로구....)
2. ox.nearset_nodes를 적용 시, 당연히 동대문역 node 값은 미존재
3. 좌표계 투영된 project_graph 값을 넣지 않고 원 그래프 데이터 입력
4. 결과는 당연히 불일치
과거의 응애시절... 반성하고 싶다.. 진짜...ㅎ
위 문제점을 파악하고 다시 분석을 진행했으며 코드는 아래와 같다.
1. 데이터 수집
우선 지하철 역사 정보와 좌표 정보가 포함된 Shp 파일을 불러온다. 철도 데이터 포텔에서 데이터를 구했으나.. QGIS로 확인해보니 특정 호선의 역사는 이상한 위치에 포인트가 찍힌다.
좌표계(CRS)는 EPSG:4326이며 5179, 5181 등 죄다 시도해봤으나 그냥 데이터의 문제가 있는 것으로 본다.
2. 대상 지역을 그래프 형태로 변환하여 가져오기
import folium
import networkx as nx
import pandas as pd
import osmnx as ox
import matplotlib as mpl
import matplotlib.pyplot as plt
import geopandas as gpd
from shapely.geometry import Point
gdf_subway = gpd.read_file('지하철_shp/서울지하철_매핑.shp') # data load
G = ox.graph_from_place('서울, 대한민국', network_type='drive')
G_proj = ox.project_graph(G, to_crs = "EPSG:4326") # 4326 좌표계 그래프 투영
fig, ax = ox.plot_graph(G_proj)
기존과 동일하게 graph_from_place 함수를 사용해 원하는 지역의 OSM 지도 형식을 그래프로 담아준다.
원하는 지역을 넣을 때 다음과 같이 진행한다.
- www.openstreetmap.org 사이트를 들어가 원하는 지역을 입력한다.
- 검색결과 찾고자 하는 지역의 단위가 나온다.
- 단위형식은 다음과 같다
- 종로구(city), 서울(state), 대한민국(country)
종로구와 동대문 그래프가 필요하기에 처음에는 두 시군구를 불러온 후 병합했으나 서로 간의 노드 연결성이 없어서 서울시 전체를 불러왔다.
만약 특정 시군구 2개 이상만 불러오고 싶다면, 직접 노드를 연결해줘야 한다.(물론 매우 까다로움...)
3. 출발지와 도착지 좌표 설정 및 최단 경로 분석
start = gdf_subway[(gdf_subway['역사명'] == '청량리역') & (gdf_subway['노선명'] == '경의중앙선')].geometry.iloc[0]
end = gdf_subway[(gdf_subway['역사명'] == '종로5가') & (gdf_subway['노선명'] == '1호선')].geometry.iloc[0]
orig_node = ox.nearest_nodes(G_proj, start.x, start.y)
dest_node = ox.nearest_nodes(G_proj, end.x, end.y)
# 최단 경로 계산
route = nx.shortest_path(G_proj, orig_node, dest_node, weight='length')
route_len = nx.shortest_path_length(G_proj, orig_node, dest_node, weight='length') / 1000
print(round(route_len, 1), "킬로미터") # 4.4 킬로미터
GeoDataFrame으로 만든 지하철 정보에서 대상 지역을 추출한 수 ox.nearest_nodes 함수에 좌표계 적용된 그래프와 출발지와 도착지의 x, y 좌표 정보를 입력하고 nx.shortest_path 함수를 사용하여 최단 경로를 계산한다.
4. 최종 시각화
# Folium 맵을 사용하여 경로 시각화
route_map = ox.plot_route_folium(G_proj, route)
route_map
ox.plot_route_folium 함수를 사용하여 최종적인 최단경로를 지도 내 시각화를 한다.
explore() 함수도 있으니 참고하면 좋을거 같다.
카카오맵을 통해 경로 탐색한 결과와 비교하면 유사한 시각화와 킬로미터 거리가 산출된 것을 알 수 있다.
'Python > [Geopandas]' 카테고리의 다른 글
pipwin을 사용해서 geopandas 쉽게 설치하기 (0) | 2023.04.19 |
---|