용의자 위치 추적 시스템 - 예측값 지도에 표시

2024. 11. 28. 22:23Python Flask & Database

이전에는 Flask에서 용의자 위치 정보를 전달하면 Javascript에서 전달받은 다음 알람으로 출력했다.

 

위치 정보를 지도에 표시하면 가시적으로 확인할 수 있기 때문에 해당 위치를 지도에 표시해보도록 한다.

 

파이썬에서 지도 정보를 활용하려면 folium을 사용하는데 미리 pip install folium 으로 깔아둔다.

그리고 region 테이블에 각 지역의 위도, 경도가 저장되어 있으므로 이를 활용한다. postgresql을 사용해도 되지만 이번에느 csv파일로 저장한다음 read_csv하여 지역 정보를 불러왔다.

 

앞에서 작성한 파이썬의 predict_offender_location 함수에 다음 부분을 추가해준다.

    # region_data.csv 파일 읽기
    region_data = pd.read_csv('region_data.csv')
    
    # 서울 중심 좌표
    seoul_center = [37.5665, 126.9780]

    # 지도 생성 및 마커 추가
    m = folium.Map(location=seoul_center, zoom_start=10)
    for index, row in region_data.iterrows():
        if (-90 <= row['latitude'] <= 90) and (-180 <= row['longitude'] <= 180):
            folium.Marker(
                location=[row['latitude'], row['longitude']],
                popup=f"Region {row['id']}",
                tooltip=f"Region {row['id']}"
            ).add_to(m)
    
    folium.Marker(
        location=[latitude, longitude],
        popup=f"용의자 추정 위치",
        tooltip=f"용의자 추정 위치"
        ).add_to(m)

    # 지도 HTML 파일로 저장하고 내용을 읽기
    m.save('templates/predict_offender_location_map.html')
    with open('templates/predict_offender_location_map.html', 'r', encoding='utf-8') as f:
        map_html = f.read()

 

초기 위치는 서울로 잡았고 배율은 10으로 설정한다.

지역 정도마다 위도, 경도가 있는데 이를 folium.Marker로 표시해 준다. 

 

그리고 지도를 HTML 파일로 저장하고 읽어서 map_html 변수에 저장한다.

    # 지도와 예측된 위치를 JSON으로 반환
    return jsonify({'latitude': latitude,
                    'longitude': longitude,
                    'map_html': map_html})

 

 

자바스크립트에서 map_html을 전달받으면 이를 map_container에 표시해준다.

document.getElementById('map_container').innerHTML = response.data.map_html;

 

오류 : 지도가 제대로 로드되지 않음

오류 원인

map_html은 정상적으로 전달 받았으나 지도가 map_html에 나타나지 않는다. 이는 자바스크립트에 innerHTML로 folium 지도를 넣을 때 스크립트가 제대로 로드되지 않아 발생하는 오류다.

 

해결 방법

이를 해결하기 위하여 iframe을 사용하였다.

iframe(Inline Frame)은 웹 페이지 안에 또 다른 HTML 문서를 삽입할 수 있는 HTML 요소입니다. 즉, 하나의 웹 페이지에 다른 웹 페이지나 콘텐츠를 포함할 수 있게 해준다.

 

        .then(function(response) {
            const mapContainer = document.getElementById('map_container');
            if (response.data.map_html) {
                // 새로운 iframe 요소 생성
                const iframe = document.createElement('iframe');
                iframe.srcdoc = response.data.map_html;  // map HTML을 iframe의 srcdoc으로 삽입
                iframe.width = '100%';
                iframe.height = '600px';
                iframe.style.border = 'none';
    
                // 기존 콘텐츠를 지우고 iframe 추가
                mapContainer.innerHTML = '';
                mapContainer.appendChild(iframe);
                console.log("Map successfully loaded into #map-container");
            } else {
                console.error("Map HTML is empty");
            }
        })

 

 

지도가 정상적으로 띄워졌다. 다만 지역의 위도, 경도를 파이썬 랜덤 함수로 넣은만큼 뒤죽박죽으로 알아보기 어려우며, 범인의 위치와 비교하기 어렵다.

 

다음 포스트에서는 지도를 예쁘게 정리해 본다.