파이썬

작업 2 : Folium으로 울진 산불 지도에 표시해보기

이석사 중 2022. 3. 22. 20:39
728x90

작업 1과 연결됩니다

저번 첫 번째 작업 때는 ASOS에 풍속 풍향 자료를 가지고 그래프를 그려봤습니다

이번에 해볼 것은 지도에 각 관측 지점에 Marker에 표시를 하고 Popup창 형태로 

제가 그린 그림을 보여주게 만들어보려고 합니다

 

이를 위해서는 Folium이라는 라이브러리가 필요합니다

Folium 라이브러리는 지도 위에 반응형 Objcet들을 놓을 수 있는 라이브러리입니다

지도 위에 Marker를 놓거나 선을 그리고 텍스트를 추가한다거나를 할 수 있습니다

 

작업 1에 보시면 import folium으로 라이브러리를 불러왔기 때문에 이번 코드에는 포함되지 않았습니다

folium은 생소하신 분들이 꽤 있을거라고 생각합니다

그래서 설명을 최대한 추가해서 포스팅 해보겠습니다

 
# 가장 먼저 지도를 만드는 부분이 부분입니다
location은 지도의 중심을 정하고 zoom_start는 지도를 처음 만들었을 때 얼머나 확대해서 보여줄 건지를 설정합니다
숫자가 커질수록 확대 배율이 커집니다
 
m = folium.Map(location = [37.23924810841041, 128.82818895742335], zoom_start = 7)
 
 
 
# 이 부분이 조금 어려울 수 있지만 한 줄 한 줄 살펴보면 어려운 부분은 아닙니다
세 문단이 다 같은 구조이기 때문에 한 문단만 설명을 드리면 다른 문단도 이해되실 겁니다
def를 사용할 수도 있었습니다만 제가 하지 않은 이유는 저도 이 부분을 이해하는데 조금 걸려서 하나하나 천천히
해보다가 미처 수정을 못했습니다
 
첫 번째 줄은 인코딩 작업 부분입니다
인코딩의 정의를 먼저 보면 데이터의 양을 줄이기 위해서 코드화 시키는 작업을 말합니다
저는 html을 이용할 것이기 때문에 자료의 양을 줄이면 줄일수록 로딩하는 시간이 줄어듭니다
그래서 html에 들어갈 태그 부분에서는 인코딩 과정을 통해 자료의 크기를 줄여서 넣습니다
두 번째 줄이 html 태그부분입니다
 
세 번째 줄은 folium에 들어갈 iFrame입니다 
하지만 이 부분에서는 인코딩 과정을 거친 파일 그대로는 들어가지 못합니다 
그렇기 때문에 다시 디코딩으로 바꾸어주어야 합니다
디코딩 할때는 추가로 다른 형태로도 변환이 가능합니다 
파일명이 숫자나 영어로만 구성이 되어 있으면 UTF-8, 한글까지 있다면 euc-kr로 해주시면 됩니다
 
네번째 줄은 popup이라는 변수에 iFrame을 넣으면 됩니다
참고로 이 IFrame에는 이미지 뿐만이 아니라 유튜브 영상도 가능합니다
영상 하단에 공유 버튼을 누르고 맨 앞에 퍼가기를 누르면 자동으로 IFrame 코드를 만들어 줍니다
 
encoded1 = bs4.b64encode(open('Gangneung Final.jpg', 'rb').read())
im_tg1 = '<img src = "data:image/jpg;base64,{}">'.format
iframe1 = folium.IFrame(im_tg1(encoded1.decode('UTF-8')), width = 1000, height = 450)
popup1 = folium.Popup(iframe1)

encoded2 = bs4.b64encode(open('Donghae Final.jpg', 'rb').read())
im_tg2 = '<img src = "data:image/jpg;base64,{}">'.format
iframe2 = folium.IFrame(im_tg2(encoded2.decode('UTF-8')), width = 1000, height = 450)
popup2 = folium.Popup(iframe2)

encoded3 = bs4.b64encode(open('Uljin Final.jpg', 'rb').read())
im_tg3 = '<img src = "data:image/jpg;base64,{}">'.format
iframe3 = folium.IFrame(im_tg3(encoded3.decode('UTF-8')), width = 1000, height = 450)
popup3 = folium.Popup(iframe3)
 
 
# 이 부분은 이제 folium 지도에 Marker를 삽입하는 부분입니다
Marker는 지도에 목적지나 좌표를 표시하는 걸 말합니다
 

 

위 이미지처럼 말이죠

Marker도 꾸미는게 가능합니다 

다양한 Parameter들을 사용하면 됩니다

popup은 marker를 클릭했을 때 출력이 됩니다

위 변수와 연결해서 popup에는 작업 1에서 그렸던 이미지가 출력이 됩니다

 

tooltip은 클릭하지 않아도 마우스만 가져가도 반응을 합니다

이 안에는 텍스트를 입력해서 이 marker가 어디인지 무엇인지 설명을 쓸 수 있습니다

 

icon은 위 이미지에 빨간색 marker처럼 아이콘의 모양이나 색을 말합니다

참고로 아이콘은 커스터마이징이 가능하다고 합니다

하지만 저는 기본에 먼저 충실해야한다고 생각해서 하지는 않았습니다

marker 커스텀이 궁금하신분은 구글에 검색해보시면 될 것 같습니다

folium.Marker(location = [37.75190572562024, 128.87602079548995],
              popup = popup1,
              tooltip = 'Gangneung WS&WD',
              icon = folium.Icon(color = 'blue', icon = 'info-sign')).add_to(m)

folium.Marker(location = [37.52476110330951, 129.11434915898977],
              popup = popup2,
              tooltip = 'Donghae WS&WD',
              icon = folium.Icon(color = 'black', icon = 'info-sign')).add_to(m)

folium.Marker(location = [36.99309228754014, 129.40046808107004],
              popup = popup3,
              tooltip = 'Uljin WS&WD',
              icon = folium.Icon(color = 'purple', icon = 'info-sign')).add_to(m)

folium.Marker(location = [37.03838589390969, 129.3029204478493],
              tooltip = '울진 산불 발화 추정지',
              icon = folium.Icon(color = 'red', icon = 'fire')).add_to(m)
 

# 보기만 해도 어지럽다 그죠? 숫자들이 막 널려 있습니다

하지만 절대 어려운 부분이 아닙니다

울진 산불 피해 면적을 원래 히트맵 처럼 그려보려고 했으나 아직 folium 라이브러리 사용이 미숙하기도 하고

자료 제공도 별로 되어 있지 않아서 구글 맵에서 제가 직접 손수 가져왔습니다

뉴스 기사에 사진을 보고 면적을 그려서 외곽 좌표들을 가져왔습니다

 

자신만의 자료를 이용하시는 분이 아니시라면 그냥 이거 쓰시는 걸 추천 드립니다

loc_data = [[37.43257035053921, 129.1580286164189], [37.427943658338044, 129.13642245686484],
            [37.410591015917106, 129.12768288670813], [37.369030371019136, 129.08586333495705],
            [37.328784179117434, 129.05565047840392], [37.272466390665656, 128.9924312636463],
            [37.222221677952106, 128.9885470102433], [37.18741725531182, 128.9890325419187],
            [37.13401930754679, 129.00602615055672], [37.07280552688731, 129.02889210660433],
            [36.97371109356131, 129.01582708755433], [36.92607375721665, 129.08850125601998],
            [36.91954577488309, 129.2240508286638], [36.975015806741105, 129.3693991655951],
            [37.04999918572766, 129.37103229297634], [37.10342039860362, 129.33347036320757],
            [37.11839763732041, 129.29100905129505], [37.20624777961364, 129.2763109048638],
            [37.3165874477099, 129.21132417317665], [37.38150053762106, 129.19580946305476],
            [37.423015454164606, 129.18274444400475], [37.43257035053921, 129.1590286164189]]
 
# 위에서 자표들을 잔뜩 가져온 이유는 Poly line을 통해 면적의 윤곽 정도는 그려보려고 했습니다

Poly line은 2개 이상의 점을 이어서 선을 그려주는 method입니다

이것도 marker로 마찬가지로 tooltip이나 color 설정이 가능합니다

folium.PolyLine(locations = loc_data,
                tooltip = '화재 면적',
                color = 'red').add_to(m)
# 대망의 마지막 html 형태로 저장하는 부분입니다
save라는 method를 통해 저장을 우선하고
작업 1때 import한 webbrowser를 이용해서 열어주면 됩니다
 
m.save('Adventure.html')
webbrowser.open_new('Adventure.html')
 
이건 이 코드를 통해 만들어진 html파일 입니다
궁금하신 분들을 한 번 열어보셔도 좋을 것 같습니다
앞으로도 사소한 작업이어도 기억보단 기록을 하기 위해 올려보겠습니다

Adventure.html
0.52MB

728x90