메뉴 닫기

Folium 마커에서 좌표 받아 서버로 보내기

lostring 개발을 계속하고 있다. 카카오맵, 구글맵을 거쳐서 결국 Folium을 사용하기로 했다. geopandas를 활용해서 데이터를 쉽게 지도에도 표시할수도 있고 생각보다 사용법도 직관적이면서 간단해서였다.

folium에서 ClickForMarker을 사용하면 클릭할때마다 지도에 Marker가 생긴다.

나는 1개의 마커만 필요했고, 또 클릭시에 자동으로 폼에 클릭한 위치의 좌표를 전달하는 기능이 필요했다.

그래서 기존 ClickForMarker를 상속받아 ClickForOneMarker 클래스를 만들었다. 더블클릭시 기존 마커가 사라지는 기능도 그래도 적용되었다.

구체적으로 구현방식은 marker를 글로벌 변수로 선언하고 클릭시마다 위치를 변경하도록 코드를 수정했고, 클릭시 받은 데이터를 getByelementId를 통해 해당 폼의 latitude, longitude value를 수정해주었다.

LatLngPopup의 경우는 애초에 팝업이 한개씩만 생긴다. span 태그 대신 a href를 활용하면 get방식으로 서버에 요청을 보낼수도 있다.

from jinja2 import Template
import folium


class ClickForOneMarker(folium.ClickForMarker):
    _template = Template(u"""
            {% macro script(this, kwargs) %}
                var new_mark = L.marker();
                function newMarker(e){
                    new_mark.setLatLng(e.latlng).addTo({{this._parent.get_name()}});
                    new_mark.dragging.enable();
                    new_mark.on('dblclick', function(e){ {{this._parent.get_name()}}.removeLayer(e.target)})
                    var lat = e.latlng.lat.toFixed(4),
                       lng = e.latlng.lng.toFixed(4);
                    new_mark.bindPopup({{ this.popup }});
                    parent.document.getElementById("latitude").value = lat;
                    parent.document.getElementById("longitude").value =lng;
                    };
                {{this._parent.get_name()}}.on('click', newMarker);
            {% endmacro %}
            """)  # noqa

    def __init__(self, popup=None):
        super(ClickForOneMarker, self).__init__(popup)


class LatLngtoForm(folium.LatLngPopup):
    _template = Template(u"""
            {% macro script(this, kwargs) %}
                var {{this.get_name()}} = L.popup();
                function latLngPop(e) {
                    data = [e.latlng.lat.toFixed(4) , e.latlng.lng.toFixed(4)];
                    parent.document.getElementById("latitude").value =data[0];
                    parent.document.getElementById("longitude").value =data[1];
                    {{this.get_name()}}
                        .setLatLng(e.latlng)
                        .setContent( '<span data='+data.toString()+' id="locate">여기</span>')
                        .openOn({{this._parent.get_name()}});
                    }
                {{this._parent.get_name()}}.on('click', latLngPop);
            {% endmacro %}
            """)  # noqa

    def __init__(self):
        super(LatLngtoForm, self).__init__()
        self._name = 'LatLngPopup'

아래 LatLngtoForm 도 비슷하게 동작한다. 원래 LatLngPopup 을 가져와서 클릭시 data를 폼으로 보내는것만 수정하였다.

Related Posts

답글 남기기

이메일 주소는 공개되지 않습니다.

%d 블로거가 이것을 좋아합니다: