[OpenLayers3] 코드로 도형 그리기

ol3에서 코드를 통해 도형을 지도에 생성하고자 할 때 사용하는 API를 정리해 봅니다. 먼저 아래의 지도 웹 화면은 총 4개의 Feature를 벡터 레이어에 추가해 표시하고 있습니다. 즉, 텍스트 스타일의 포인트 피쳐, 이미지 스타일의 포인트 피쳐, 폴리라인 피쳐, 폴리곤 피쳐입니다. 피쳐는 1700cc죠? 여기서 각 피쳐를 마우스로 클릭하면 피쳐에 대해 미리 저장해둔 속성값을 alert 창으로 표시해 줍니다. 참고로 Feature는 좌표 데이터와 속성 데이터를 함께 갖는 개념의 데이터랍니다.

자, 이제 위의 지도 페이지에 대한 코드를 살펴보겠습니다. 먼저 필요한 CSS와 js 라이브러리를 포함하는 코드입니다.




다음으로 UI에 대한 코드를 살펴 보겠습니다. 지도가 표시되는 div가 있고, 이 div에 대한 크기를 css로 지정하고 있습니다.




    

이제 다음은 스크립트 코드에 대해 살펴볼텐데요. 먼저 웹 페이지의 모든 css 및 외부 라이브러리 로딩과 UI가 준비되었을 때 호출되는 jQuery의 ready 이벤트를 아래처럼 만들어 둡니다.


위의 코드 중 … 부분에 앞으로 더 많은 코드를 추가할 것인데요. Feature를 추가할 수 있는 레이어를 위한 데이터 소스는 ol.source.Vector입니다. 또한 이 소스를 통해 생성할 수 있는 레이어는 ol.layer.Vector이구요. 아래의 코드처럼 필요한 벡터 소스와 레이어에 대한 객체를 생성합니다.

var vectorSource = new ol.source.Vector();
var vectorLayer = new ol.layer.Vector({ source: vectorSource });

위에서 생성한 레이어는 지도에 추가되어야 합니다. 아래 코드의 6번째 줄을 보면 앞서 생성해 둔 레이어 객체 변수가 보입니다.

var map = new ol.Map({
    layers: [
        new ol.layer.Tile({
            source: new ol.source.OSM()
        }),
        vectorLayer
    ],
    
    target: 'map',
    
    controls: ol.control.defaults({
        attributionOptions: ({
            collapsible: false
        })
    }),

    view: new ol.View({
        center: [14827315, 4785815],
        zoom: 5
    })
});

위의 코드를 좀더 살펴보면, 지도 객체의 생성을 위해 ol.Map의 생성자를 호출하고 있는데요. 이 생성자에서 받는 옵션 객체를 보면 layers 키 값으로 Open Street Map 레이어와 앞서 만들어 둔 벡터 레이어를 지정해 레이어를 구성하고 있습니다. 그리고 9번의 target은 지도 표시될 div의 id이구요. 17번은 초기에 지도가 표시될 좌표와 줌 레벨값을 지정하고 있습니다.

다음으로 4개의 Feature를 추가하는 사용자 정의 함수를 어래처럼 호출합니다.

addImagePoint(vectorSource);
addTextPoint(vectorSource);
addPolyline(vectorSource);
addPolygon(vectorSource);

먼저 addImagePoint 함수를 살펴보면 다음과 같습니다.

function addImagePoint(/* ol.source.Vector */ src) {
    var feature = new ol.Feature(
        {
            geometry: new ol.geom.Point([14827315, 4785815])
        }
    );

    var style = new ol.style.Style({
        image: new ol.style.Icon({
            src: 'http://www.gisdeveloper.co.kr/images/kochu.png',
            scale: 0.7,
        })
    });

    feature.setStyle(style);
    feature.set('name', '이미지 포인트 Feature');

    src.addFeature(feature);
}

Feature의 정의는 3가지가 필요합니다. 하나는 도형, 즉 지오메트리(Geometry)의 좌표값이고 이 도형을 그리기 위한 스타일이며, 마지막으로 속성값의 지정입니다. 2-6번 코드가 포인트 지오메트리의 좌표값을 지정하는 코드이며, 8~13번은 해당 포인트를 화면에 표시할때 이미지 스타일 객체를 생성하는 코드입니다. 그리고 15번의 setStyle을 통해 스타일을 지정합니다. 그리고 16번은 속성을 key 값과 value 값을 통해 지정합니다. 이렇게 생성된 피쳐는 벡터 레이어의 소스에 addFeature 함수를 통해 18번 코드처럼 추가됩니다.

나머지 3개에 대한 함수에 대한 코드는 아래와 같습니다.

function addPolygon(/* ol.source.Vector */ src) {
    var feature = new ol.Feature({
        geometry: new ol.geom.Polygon(
            [
                [
                    [13768449, 4871327],
                    [14556056, 5287144],
                    [14445986, 4166883],
                    [13995925, 3861135],
                    [13768449, 4871327],
                ]
            ]
        )
    });

    var style = new ol.style.Style({
        stroke: new ol.style.Stroke({
            color: 'blue',
            width: 3
        }),
        fill: new ol.style.Fill({
            color: 'rgba(0,0,255,0.6)'
        })
    });

    feature.setStyle(style);
    feature.set('name', '폴리곤 Feature');

    src.addFeature(feature);
}

function addPolyline(/* ol.source.Vector */ src) {
    var feature = new ol.Feature({
        geometry: new ol.geom.LineString([
            [16030985, 5565986],
            [15480638, 4318534],
            [14384837, 3780417],                            
        ])
    });

    var style = new ol.style.Style({
        stroke: new ol.style.Stroke({
            color: 'red',
            width: 4
        })
    });

    feature.setStyle(style);
    feature.set('name', '폴리라인 Feature');

    src.addFeature(feature);
}

function addTextPoint(/* ol.source.Vector */ src) {
    var feature = new ol.Feature({
        geometry: new ol.geom.Point([13778283, 4331832])
    });

    var style = new ol.style.Style({
        text: new ol.style.Text({
            text: "ol3",
            scale: 2,
            offsetY: 0,
            stroke: new ol.style.Stroke({
                color: 'black',
                width: 1
            }),
            fill: new ol.style.Fill({
                color: 'yellow'
            })
        })
    });

    feature.setStyle(style);
    feature.set('name', '텍스트 포인트 Feature');

    src.addFeature(feature);
}

각 함수를 보면 도형의 형태에 따른 지오메트리의 타입과 해당 좌표값의 지정에 대한 형태만 다르고 스타일이나 속성값을 지정하는 형태는 유사합니다. 여기서는 지오메트리에 대해 Point과 Polyline에 대한 LineString 그리고 Polygon 만을 언급하였는데요. 이외에도 MultiLineString, MultiPolygon, MultiPoint 등도 있습니다.

이제 끝으로 피쳐를 마우스로 클릭하면 해당 피쳐에 대한 속성값을 표시하는 코드를 살펴 보겠습니다.

map.on('singleclick', function (evt) {
    var feature = map.forEachFeatureAtPixel(evt.pixel, function (feature, layer) {
        return feature;
    });

    if (feature) {
        alert(feature.get('name'));
    }
});

지도에 대한 singleclick 이벤트를 등록했고, 이 이벤트를 통해 클릭한 피쳐와 피쳐의 소속 레이어를 얻을 수 있는 forEachFeatureAtPixel 함수를 이용하고 있습니다. 앞서 피쳐를 생성할때 name이라는 키값으로 속성값을 저장해 두었는데요. 위의 코드에서 사용하고 있는 것을 볼 수 있습니다.

아래는 위에서 설명한 전체 코드에 대한 다운로드입니다.

“[OpenLayers3] 코드로 도형 그리기”에 대한 6개의 댓글

  1. 안녕하세요 현재 openlayers를 공부하는 학생인데요
    1.구글 위경도를 이용해서 네이버나 vworld 지도에 폴리곤을 그리고 싶은데 어떻게 해야 가능한지 궁금합니다
    2.현재 예제에 나와있는 polygon 좌표는 어떤걸 기준으로 생성하신건지 궁금합니다…

      1. 답변 감사드립니다. 그런데 폴리곤을 그리는 [13768449, 4871327],
        [14556056, 5287144],
        [14445986, 4166883],
        [13995925, 3861135],
        [13768449, 4871327], 요 숫자들이 왜이렇게 큰지 잘 모르겠습니다…ㅇㅅㅇ…

        vworld는 osm과 같아서 그런지 잘 그려지는데 daum이랑 지도는 그려지지 않아요 ㅠ 경위도 좌표계로 변환하는 방법이 무엇인지 잘 몰라 transform, proj4.defs(“EPSG:5179″,”+proj=tmerc +lat_0=38 +lon_0=127.5 +k=0.9996 +x_0=1000000 +y_0=2000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs”);
        ol.proj.setProj4 = proj4; 요런 방법 등등 다 써봤는데 잘 안나오네요 ㅠㅠ 한번만 더 도와주세요 ㅠㅠ

          1. 안녕하세요 EPSG:5179는 네이버꺼인걸 저도 알고 있습니다 . 다음은 5181로 설정을해줬습니다 하지만 뜨질 않네요 ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠ

김 형준에 답글 남기기 응답 취소

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다