안녕하세요 캡틴개구리입니다.

이번시간은 Openlayers3(OL3)와 Leaflet에 Feature 이벤트 연동을 알아보겠습니다.

Feature Event 요약 기능

 - 지도 마커 클릭 시, 팝업 창 호출

 - 지도 클릭 시, 좌표정보 호출


그전에 결과화면부터 보겠습니다.

서비스바로가기


Openlayers3 와 Leaflet 라이브러리를 받을 수 있는 곳은 아래와 같습니다. 

OpenLayers3 :  https://openlayers.org/ 

Leaflet : http://leafletjs.com/

VWORLD :  http://map.vworld.kr



1. Openlayers3 Feature Event 추가


활용라이브러리 : ol.Map, ol.layer.Tile, ol.source.Vector, ol.layer.Vector, ol.Feature, ol.geom.Point, ol.style.Style, ol.style.Icon, ol.Overlay 


먼저 Openlayers3(이하 OL3)  <script></script>부분입니다.


OL3 지도 및 마커 띄우기


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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<script>
    //openlayers 지도 띄우기
    var iconFeature = new ol.Feature({
        //아이콘 위치좌표
        geometry: new ol.geom.Point([14129600.824512500.74]),
        name'I am a Progworks.',
    });
 
    var iconStyle = new ol.style.Style({
        image: new ol.style.Icon(/** @type {olx.style.IconOptions} */ ({
            anchor: [146],
            anchorXUnits: 'fraction',
            anchorYUnits: 'pixels',
            src: 'https://openlayers.org/en/v3.20.1/examples/data/icon.png'
        }))
    });
 
    iconFeature.setStyle(iconStyle);
    var vectorSource = new ol.source.Vector({
        features: [iconFeature]
    });
 
    var vectorLayer = new ol.layer.Vector({
        source: vectorSource
    });
     
    var raster = new ol.layer.Tile({
        source: new ol.source.XYZ({
            url: 'http://xdworld.vworld.kr:8080/2d/Base/201802/{z}/{x}/{y}.png'
        })
    });
        
    var map = new ol.Map({
           
        layers: [raster,vectorLayer],
          
        target: document.getElementById('map'),
          
        view: new ol.View({
          center: [14129600.824512500.74],
          maxZoom: 19,
          zoom: 14
        })
    });
</script>
cs

다음은 Feature Event를 가져오도록 하겠습니다. 참고로 OL3에서는 마커 표시와 지도의 좌표정보 불러오기가 별도의 example로 존재합니다.

각각의 example를 하나로 합치면서 OL3에서 제공하는 소스와는 조금 다르다는점 참고하시면 좋을것 같습니다.

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
<script>
    var element = document.getElementById('popup');    
    var coordElement = document.getElementById('olPopup');
    
    var popup = new ol.Overlay({
        element: element,
            positioning: 'bottom-center',
            stopEvent: false,
            offset: [-18-50]
    });
    map.addOverlay(popup);
    
    map.on('click'function(evt) {
        var feature = map.forEachFeatureAtPixel(evt.pixel,function(feature) {
            return feature;
        });
        if (feature) {
            
            var coordinates = feature.getGeometry().getCoordinates();
            popup.setPosition(coordinates);
            $(element).popover({
              'placement''top',
              'animation'false,
              'html'true,
              'content': feature.get('name')
            });
            $(element).popover('show');
            $(coordElement).popover('destroy');
        } else {
            $(element).popover('destroy');
        }
    });
    
    var olPopup = new ol.Overlay({
        element: document.getElementById('olPopup')
    });
    map.addOverlay(olPopup);
 
    map.on('click'function(evt) {
        var feature = map.forEachFeatureAtPixel(evt.pixel,function(feature) {
            return feature;
        });
        
        if(feature == null){
            var coordinate = evt.coordinate;
            var hdms = ol.coordinate.toStringHDMS(ol.proj.transform(coordinate, 'EPSG:3857''EPSG:4326'));
    
            $(coordElement).popover('destroy');
            olPopup.setPosition(coordinate);
            $(coordElement).popover({
                'placement''top',
                'animation'false,
                'html'true,
                'content''<p>현재 위치 좌표정보</p><code>' + hdms + '</code>'
            });
            $(coordElement).popover('show');
        } else{
            $(coordElement).popover('destroy');
        }
    });
 
        // change mouse cursor when over marker
    map.on('pointermove'function(e) {
        if (e.dragging) {
            $(element).popover('destroy');
            return;
        }
        var pixel = map.getEventPixel(e.originalEvent);
        var hit = map.hasFeatureAtPixel(pixel);
        map.getTarget().style.cursor = hit ? 'pointer' : '';
    });
</script>
cs

5행 : 마커 클릭 시, 나타나는 팝업의 위치 구현

13행~32행 : OL3 map 클릭 이벤트 (마커)

34행 : 지도 클릭 시, 좌표정보 팝업의 위치구현

39행~60행 : OL3 map 클릭 이벤트 (지도)

63행~71행 : 마커 위로 마우스 이동 시 포인터 활성화 및 지도 좌표정보 팝업 숨김 구현

OL3 Feature Event <body></body>입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<body>
    <div class="container-fluid">
        <div class="row content">
            <div class="col-sm-6" style="border-right: 1px solid;">
                <h1>Oepnlayers 3</h1>
                <div id="map" class ="map">
                    <div id="popup"></div>
                </div>
                <div style="display: none;">
                    <div id="olPopup" title="Welcome to ol3"></div>
                </div>
            </div>
        </div>
    </div>
</body>
cs


2. Leaflet Feature Event

활용라이브러리 : L.map, L.tileLayer, L.marker, L.popup


먼저 leaflet  <script></script>부분입니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<script>
//leaflet 지도 띄우기
    var leafletMap = L.map('leafletMap').setView([37.5247030824278714129046.928310394],14)
    //Vworld Tile 변경
    L.tileLayer('http://xdworld.vworld.kr:8080/2d/Base/201802/{z}/{x}/{y}.png').addTo(leafletMap);
    
    var marker = L.marker([37.5247030824278714129046.928310394]).addTo(leafletMap)
        .bindPopup("I am a Progworks.").openPopup();
    
    var leafletPopup = L.popup();
    
    function onMapClick(e) {
        leafletPopup
            .setLatLng(e.latlng)
            .setContent("현재 위치 좌표정보 <br>" + e.latlng.toString())
            .openOn(leafletMap);
    }
 
    leafletMap.on('click', onMapClick);
});
</script>
cs


이번에도 지도는 VWORLD를 이용했습니다.

3행~ 5행 : 지도 띄우기
7행~8행 : 마커 위치 및 내용 넣기
10행 : 팝업
12행 : 클릭이벤트

다음은 <body></body>입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<body>
    <div class="container-fluid">
        <div class="row content">
            <div class="col-sm-6" style="border-left: 1px solid;">
                <h1>leaflet</h1>
                <div id="leafletMap"></div>
            </div>
            <div class="col-sm-6" style="border-right: 1px solid; border-top: 1px solid;">
                
            </div>
            <div class="col-sm-6" style="border-left: 1px solid; border-top: 1px solid;">
                
            </div>
        </div>
    </div>
</body>
cs

결과화면은 아래와 같습니다.

서비스바로가기

+ Recent posts