MiniProject 2 - 응급실 네비게이션

기준맨·2023년 2월 22일
0

MiniProject

목록 보기
2/2

MiniProject

개요

  • 전국 응급실 정보
  • 크롤링한 정보 folium을 활용해 지도 위에 마킹
  • (가능하다면) naver map api 활용해서 내 위치와 최단 거리 병원 정보 및 최단 거리 표시

응급실 정보 크롤링

국립중앙의료원 의 전국 응급실 정보를 크롤링한다.

# 필요한 모듈 import
import requests as req
import pandas as pd
from bs4 import BeautifulSoup as BS
import json
# 전국 응급실 정보 크롤링
hospital_list = []
temp_dict = {}
for page in range(1, 39):
    url = f'https://www.nmc.or.kr/nmc/emrrm/emrrm/nearEmrrmList.do?menuNo=200323&cdVal1=a013&cdVal2=&pageIndex={page}'
    res = req.get(url)
    soup = BS(res.text, "html.parser")
    a_tag = soup.select("a[data-clipboard-text]")
    for hospital in a_tag:
        hospital_data = hospital["data-clipboard-text"]
        temp_dict['name'] = hospital_data.split('/')[0].strip()
        temp_dict['phone'] = hospital_data.split('/')[1].strip()
        temp_dict['address'] = hospital_data.split('/')[2].split('(')[0].strip()
        if temp_dict['name'] != 'https:':
            hospital_list.append(temp_dict)
            temp_dict = {}
        else:
            temp_dict = {}
# to json dump
with open('hospital_data.json', 'w', encoding='utf-8') as f:
    f.write(json.dumps(hospital_list, ensure_ascii = False, indent = 4))

응급실 지도 생성

# 필요 모듈 import
import numpy as np
import pandas as pd
import folium
from folium import Choropleth
from folium import plugins
from folium import Marker
from folium.plugins import MarkerCluster
import googlemaps
import json
from math import sin, cos, sqrt, atan2
# 불필요한 경고문 제거
import warnings
warnings.filterwarnings('ignore')
# 구글맵 활용을 위한 key 지정
gmap_key = "yourkey"
gmaps = googlemaps.Client(key=gmap_key)
# json 불러오기 및 DataFrame 생성
geo_path = open('hospital_data.json', encoding='UTF8')
geo_data = json.load(geo_path)
df = pd.DataFrame(geo_data)
# 지도 생성
korea_map = folium.Map(zoom_start=7, location=[37.5502, 126.982])
# 주소를 위도, 경도로 변경
lat = []
lng = []
for index in df.index:
    try:
        address = geo_data[index]['address']
        geo = gmaps.geocode(address)[0]['geometry']['location']
        lat.append(geo['lat'])
        lng.append(geo['lng'])
    except:
        lat.append(np.nan)
        lng.append(np.nan)
# DataFrame에 새로운 컬럼 생성후 value 지정
df['lat'] = lat
df['lng'] = lng
# 결측치 확인
df[df['lng'].isnull()]
df[df['lat'].isnull()]

# 결측치 수정 >> 병원 한곳만 주소가 적용이 안돼 하드코딩으로 데이타 프레임에 주소 넣어줌
# 좌표찾기 : https://coordinates-gps.gosur.com/ko/
df.loc[102, 'lng'] = 127.2623
df.loc[102, 'lat'] = 36.4796
# 병원 위치 지도에 마커
for index, data in enumerate(df.index):
    Marker(location = [df.iloc[index]['lat'],df.iloc[index]['lng']],
           popup=df.iloc[index]['name'],
           icon=folium.Icon(color='red',icon='star')
          ).add_to(korea_map)

마커가너무 많아 지도가 지저분해 보여 MakerCluster로 정리해주고자 함

# 지도 초기화
korea_map = folium.Map(zoom_start=7, location=[37.5502, 126.982])
# 마커 클러스터 생성
mc = MarkerCluster()
# 마커 클러스터를 활용해 지도에 마커 생성
for index, data in enumerate(df.index):
    mc.add_child(    
        Marker(location = [df.iloc[index]['lat'],df.iloc[index]['lng']],
               popup=df.iloc[index]['name'],
               icon=folium.Icon(color='red',icon='star')
              )
    )
korea_map.add_child(mc)

가장 가까운 병원 찾기

# 현재 위치 = 서울역
current_lat = 37.5562 
current_lng = 126.9723

# 가장 가까운 장소의 인덱스
# 가장 먼 거리 값을 저장하기 위해 최대값(inf)으로 설정
nearest_index = None
nearest_distance = float('inf')

# 모든 마킹 장소와의 거리를 계산
for index, data in enumerate(df.index):
    lat = df.iloc[index]['lat']
    lng = df.iloc[index]['lng']

    # 두 지점 사이의 거리를 계산
    # 참고 : https://stackoverflow.com/questions/19412462/getting-distance-between-two-points-based-on-latitude-longitude
    dlat = lat - current_lat
    dlng = lng - current_lng
    a = sin(dlat / 2)**2 + cos(current_lat) * cos(lat) * sin(dlng / 2)**2
    c = 2 * atan2(sqrt(a), sqrt(1 - a))
    distance = 6371 * c

    # 가장 가까운 장소인지 확인
    if distance < nearest_distance:
        nearest_index = index
        nearest_distance = distance

if nearest_index is not None:
    print("The Nearest Hospital is:")
    print("Index:", nearest_index)
    print("Name:", df.iloc[nearest_index]['name'])
    print("Phone:", df.iloc[nearest_index]['phone'])
    print("Address:", df.iloc[nearest_index]['address'])
    print("Latitude:", df.iloc[nearest_index]['lat'])
    print("Longitude:", df.iloc[nearest_index]['lng'])
else:
    print("No location found.")
# 출력
The Nearest Hospital is:
Index: 110
Name: 서울적십자병원
Phone: 02-2002-8000
Address: 서울특별시 종로구 새문안로 9, 적십자병원
Latitude: 37.5671402
Longitude: 126.9670566
# 위에서 뽑은 가장 가까운 병원과 내 위치와의 직선 경로
# 경로 표시
folium.PolyLine(
    locations=[(current_lat, current_lng), (df.iloc[nearest_index]['lat'], df.iloc[nearest_index]['lng'])],
    color='red',
    weight=2.5,
    opacity=1
).add_to(korea_map)

# 마커 표시
folium.Marker(
    location=[current_lat, current_lng],
    popup='Starting Point'
).add_to(korea_map)
folium.Marker(
    location=[df.iloc[nearest_index]['lat'], df.iloc[nearest_index]['lng']],
    popup='Nearest Place'
).add_to(korea_map)

  • 2023-02-22 : 예전에 구상했던 프로젝트를 드디어 구현해봤다,, 근데 경로 찾기는 도로상황(자동차 도로, 도보, 건물 등등)을 다운받아와서 구현해야 하는듯하다,, folium 으로만 되지는 않을듯,,?
  • 추가하고싶은 것 : 내 위치 적용, 네비게이션

0개의 댓글