스텝4) naver map api 학습

2023. 8. 10. 16:09OpenSource/geoServer

반응형

참고 : https://navermaps.github.io/maps.js.ncp/docs/tutorial-Map.html

지도생성 및 기본동작

Map객체 : 특정 DOM요서에 지도를 표현!

var map = new naver.maps.Map('map', {
    mapTypeId: naver.maps.MapTypeId.HYBRID
 });

지도 초기화

지도를 초기화하려면 지도가 표현 될 DOM 요소 또는 DOM요소의 id를 명시해야 함.

<template>
    <div id="map" style="width: 700px; height: 400px"></div>
</template>
var map = new naver.maps.Map('map', {

지도 유형 설정

Map 객체는 지도유형을 저장하고 있음.
  - MapOptions를 이용하거나 setMapTypeId메서드를 이용 해야 함.

지도 유형은 참고 : https://navermaps.github.io/maps.js.ncp/docs/tutorial-MapTypes.html

 

NORMAL Type

TERRAIN Type

SATELLITE Type

지도 유형 저장소

유형 저장소(MapTypeRegistry)라는것으로 골라서 변형시킬수가 있다.

var registry = new naver.maps.MapTypeRegistry();

var map = new naver.maps.Map('map', {
    mapTypes: registry,
    mapTypeId: naver.maps.MapTypeId.SATELLITE
});

map.mapTypes.set(naver.maps.MapTypeId.SATELLITE, naver.maps.NaverStyleMapTypeOptions.getSatelliteMap());
map.mapTypes.set(naver.maps.MapTypeId.HYBRID, naver.maps.NaverStyleMapTypeOptions.getHybridMap());

map.setMapTypeId(naver.maps.MapTypeId.NORMAL); // error thrown

지도 이동

지도는 중심 좌표줌 레벨, 좌표 경계를 이용해야 이동 할 수 있음.
또한, 화면의 픽셀좌표를 이용해 원하는 화면 좌표만큼 이동 할 수 있음.
아래참고!
https://navermaps.github.io/maps.js.ncp/docs/tutorial-4-map-bounds.example.html

지도 투영과 좌표 체계

지도 투영(Projection)은 둥근 지구를 평면으로 전개하는것을 말한다.
투영법은 위/경도 좌표를 투영된 지도의 좌표로 옮기는 방법을 정의 한다.

Naver 지도 api v3는 투영과 관련된 2가지 객체를 제공.

  • Projection: 지도 좌표계를 평면 좌표계로 변환하는 방법을 정의
  • MapSystemProjection: Projection 객체를 이용해 지도의 타일 배치, 좌표 변환, 두 좌표의 거리 계산 방법을 정의

좌표 체계

지도 좌표(coord) : 실세계의 고유한 지점을 가리키는 좌표!
                              일반적으로 위도와 경도를 표시하는 WGS84표준을 사용.

위도와 경도를 정의하는 LatLng 클래스를 사용하거나, 다른 좌표계를 위해 Point 클래스를 사용하여 정의!
예를 들어, 다음과 같이 정의한 지도 좌표는 위도 37.5666805, 경도 126.9784147인 지점이며,
지리적으로는 서울 시청의 위치를 가리킵니다.

new naver.maps.LatLng(37.5666805, 126.9784147)

UTMK 투영법과 좌표계를 이용할 때는 서울 시청 지도 좌표를 다음과 같이 정의할 수 있습니다.

new naver.maps.Point(953937.9, 1952051.9)

세계 좌표(point) : api에서 지도 위의 고유한 한 점을 가리키는 좌표!
세계좌표(World Coordinate)는 Naver 지도 api v3에서 지도 위의 고유한 한 점을 가리키는데 사용하는 자표이며
Naver 지도 api v3은 지도 좌표를 일정한 범위 내의 세계 좌표로 변환 합니다. Why?
위도와 경도를 사용하는 지도좌표는 구면 좌표계! UTMK와 같은 좌표계는 평면좌표계!
이런 다양한 지도 좌표를 Naver 지도 api v3가 이해할 수 있는 세계좌표로 변환하여 지도를 실제 화면에 표시!!!

고로, Naver 지도 api v3은 현재 선택된 지도유형의 titileSize 속성을 참조
-> 세계좌표 범위를  MapSystemProjection이 자동으로 계산하도록 설계!!
MapSystemProjection은 지도유형에 설정된 투영 객체를 내부적으로 참조!
지도유형에 설정하는 투영객체는 세계좌표의 범위를 x축과 y축 모두 0~1의 값으로 계산되도록 구현되어야 합니다.

MapSystemProjection 객체는 Map객체의 getProjection 메소드를 이용해 접근할 수 있습니다.
지도 유형에 설정한 본래의 투영객체는 Map객체의 getPrimitveProjection 메소드를 이용해 접근할 수 있습니다.

아래는 MapSystemProjection 객체와 지도유형의 투영객체의 세계좌표 변환을 보여줍니다.
본래의 투영객체로 변환한 세계좌표에서 타일크기를 곱한 결과가 실제 api에서 사용하는 세계좌표라는것을 알수 있음.

map.getProjection() === map.getMapType().projection; // false
map.getPrimitiveProjection() === map.getMapType().projection; // true

var cityHall = new naver.maps.LatLng(37.5666805, 126.9784147);

var systemWorldPoint = map.getProjection().fromCoordToPoint(cityHall);
// 105.44749755859375, 163.32960205078126

var worldPoint = map.getPrimitiveProjection().fromCoordToPoint(cityHall);
// 0.41190428733825685,  0.6380062580108643

systemWorldPoint.equals( worldPoint.mul(256, 256) ); // true


화면 좌표(offset Coordinate) : 현재 지도 화면에서의 특정 지점에 해당하는 CSS 픽셀 좌표!
                               이 좌표는 지도의 DOM 컨테이너의 오프셋으로, 각종 오버레이를 지도 위에 배치하는데 사용 합니다.

var myMenu = document.createElement('div');
myMenu.style.position = 'absolute';
myMenu.style.zIndex = 10000;

map.getPanes().overlayLayer.appendChild(myMenu);

naver.maps.Event.addListener(map, 'rightclick', function(e) {
    var offset = e.offset;

    myMenu.style.left = offset.x +'px';
    myMenu.style.top = offset.y +'px';
});

DOM 이벤트

Naver 지도 api v3는 지도 UI 이벤트 외에 사용자가 DOM(Document Object Model) 이벤트를 수신하고
응답할 수 있도록 메소드를 제공!!
이 메소드를 이용하면 사용자는 브라우저마다 다른 DOM 이벤트 모델을 별도로 처리할 필요가 없습니다.

naver.maps.Event.addDOMListener( element:HTMLElement, eventName:String, listener:Function )
naver.maps.Event.removeDOMListener( listener:DOMEventListener | listeners:DOMEventListener[] | element:HTMLElement, eventName:String, listener:Function )

이벤트 리스너 등록

이벤트 리스너를 등록하면 DOM이벤트를 수신할 수 있습니다. addDOMListener 메소드를 이용해
특정 DOM에서 발생한 이벤트를 받아 핸들러를 실행하는 리스너를 등록 합니다.

DOMEventListener = {
    eventName: String,
    listener: Function,
    target: HTMLElement
}

DOMEventListener 객체는 등록된 리스너의 정보를 담고 있는 객체로 등록된 리스너를 제거할 때 이용 합니다.

이벤트 리스너 제거

이벤트 리스너를 등록 해제하려면 더이상 DOM 이벤트를 수신하지 않습니다.
removeDOMListener 메소드를 이용해 등록한 리스너를 제거 합니다.
이때, 인수로 DOMEventListener 객체(또는 객체 배열)를 전달 할 수 있습니다.

다음 예제는 지도를 클릭 했을 때! 마커가 있는 위치로 이동하며 줌 레벨을 변경하는 예제 입니다.

var mapOptions = {
    zoom: 4,
    center: new naver.maps.LatLng(37.3614483, 127.1114883)
};

var map = new naver.maps.Map('map', mapOptions);

var markerOptions = {
    position: map.getCenter(),
    map: map,
    title: 'Click to zoom'
};

var marker = new naver.maps.Marker(markerOptions);

var mapElement = map.getElement();

var listener = naver.maps.Event.addDOMListener(mapElement, 'click', function() {
    map.setZoom(8);
    map.setCenter(marker.getPosition());

    naver.maps.Event.removeDOMListener(listener);
});

KVO 상태변경 알림

KVO(Key-Value Observing) 상태 변경 알림은 NAVER 지도 API v3 객체의 상태 변경을 알려주는 이벤트입니다.
KVO 또는 KVOArray 클래스를 상속받은 NAVER 지도 API v3의 일부 객체는 자신의 상태를 가지고 있으며,
속성이 변경될 때마다 NAVER 지도 API v3은 속성이 변경되었다는 이벤트를 시작합니다.

KVO : 속성(키)이 변경되면 알려줍니다.
KVOArray : 배열형태의 KVO로 배열의 요소가 변경되면 알려줍니다.
KVO 상태 변경 알림은 아래와 같이 규칙에 따라 이름이 지정됨.

{Key}_changed

UI 이벤트

지도 UI 이벤트는 지도와 사용자의 상호작용으로 발생하는 이벤트 입니다.
다음과 같은 지도 UI 이벤트에 응답하도록 설계되었습니다.

지도를 클릭 했을 때 해당 위치를 console.log 메소드로 출력하는 예제

var mapOptions = {
    zoom: 4,
    center: new naver.maps.LatLng(37.3614483, 127.1114883)
};

var map = new naver.maps.Map('map', mapOptions);

naver.maps.Event.addListener(map, 'click', function(e) {
    console.log(e);
});

다음 예제는 마커에 등록한 리스너를 제거하는 예제

var mapOptions = {
    zoom: 4,
    center: new naver.maps.LatLng(37.3614483, 127.1114883)
};

var map = new naver.maps.Map('map', mapOptions);

var markerOptions = {
    position: map.getCenter(),
    map: map
};

var marker = new naver.maps.Marker(markerOptions);

var listener = naver.maps.Event.addListener(marker, 'click', function() {
    map.setZoom(8);
    map.setCenter(marker.getPosition());

    naver.maps.Event.removeListener(listener);
});

다음은 지도를 클릭 했을 때 해당 위치에 마커를 올리는 예제

var mapOptions = {
    zoom: 4,
    center: new naver.maps.LatLng(37.3614483, 127.1114883)
};

var map = new naver.maps.Map('map', mapOptions);

var listener = naver.maps.Event.addListener(map, 'click', function(e) {
    var marker = new naver.maps.Marker({
        position: e.coord,
        map: map
    });
});

오버레이 예제 : https://navermaps.github.io/maps.js.ncp/docs/tutorial-3-event-overlay.example.html

지도 컨트롤

컨트롤은 사용자가 지도와 상호작용할 수 있도록하는 Ui요소를 말합니다.
제공하는 컨트롤은 다음과 같습니다.
줌 컨트롤 : 지도의 줌 레벨을 조정할 수 있는 슬라이더 +/-버튼
축척 컨트롤 : 지도의 축척을 표시 합니다.
지도유형 컨트롤 : 일반지도/위성지도와 같은 지도유형을 전환할 수 있는 버튼
지도 데이터 저작권 컨트롤 : 지도 데이터의 저작권을 표시
네이버 로고 컨트롤 : 네이버 로고를 표시 합니다.(노출제어 불가)

지도 컨트롤 추가/제거

지도에 컨트롤을 추가하거나 제거하려면 MapOptions객체의 다음 속성을 사용 합니다.

{
    scaleControl: true,
    mapDataControl: true,
    mapTypeControl: false,
    zoomControl: false
}

더욱 자세한 내용은 https://navermaps.github.io/maps.js.ncp/docs/tutorial-Controls.html 참조!

레이어

레이어는 지도 타일 위에 겹쳐서 노출되는 지도유형을 말합니다.
5가지 레이어를 기본적으로 제공 합니다.

  • 자전거 전용도로와 자전거 관련 오버레이를 하나의 레이어로 제공
  • 교통상황을 나타내는 레이어를 제공
  • 거리뷰를 보여줄 수 있는 영역을 나타내는 레이어를 제공
  • 전국 토지 소개, 지번, 지목, 경계, 도로 철도 등을 나타내는 레이어를 제공
  • 일반 지도 유형과 위성 지도 유형을 함께 나타내는 겹쳐보기 레이어를 제공

기본 레이어 표시

기본 레이어를 표시하려면 각 레이어의 인스턴스를 생성하고 init후 Map객체의 setMap 메소드를 호출 합니다.

var cadastralLayer = new naver.maps.CadastralLayer();
var streetLayer = new naver.maps.StreetLayer();
var bicycleLayer = new naver.maps.BicycleLayer();
var trafficLayer = new naver.maps.TrafficLayer();

naver.maps.Event.once(map, 'init', function() {
    cadastralLayer.setMap(map);
    streetLayer.setMap(map);
    bicycleLayer.setMap(map);
    trafficLayer.setMap(map);
});

데이터 레이어

gis데이터를 기반으로 지도 위에 점, 선, 도형 등 쉽게 표현 할 수 있는 가상의 Data레이어를 제공 합니다.
GeoJSON, KML, GPX형식의 지리 공간 데이터를 지도 위에 표현할 수 있으며, 반대로 표시된 데이터를
GeoJSON 형식으로 저장할 수 있습니다.

오버레이

오버레이는 지리적 정보를 시각화하기 위해 지도 위에 추가할 수 있는 도형이나 개체 등을 말합니다.
오버레이는 지도의 지리 좌표와 연동되어 표시되므로 사용자가 지도를 확대/축소하거나 이동하면 오버레이도 함께 움직입니다.

NAVER 지도 API v3은 마커, 정보 창, 도형, 지상 오버레이 등 다양한 오버레이를 제공하며,
사용자가 직접 오버레이를 정의해 사용할 수 있도록 지원합니다.

마커

마커는 지도 위의 한 위치를 아이콘으로 표시하는 오버레이입니다.
아이콘은 이미지를 사용하거나, 벡터 그래픽 폴리곤 등으로 사용할 수 있습니다.

원하는 위치에 마커 올리기

마커를 사용하려면 Marker class의 객체를 생성해야 합니다.
생성자에는 MarkerOptions객체 리터럴을 인수로 넘겨서 마커의 속성을 설정해야 합니다.
마커는 지도상의 한 위치를 아이콘으로 표시하는 객체 입니다.
따라서 위치를 나타내는 position속성을 반드시 입력 해야 합니다.
그 외의 속성은 기본값을 제공!

다음 예제는 position 속성만 설정한 기본 마커를 네이버 그린팩토리 위에 올리는 예제

var map = new naver.maps.Map('map', {
    center: new naver.maps.LatLng(37.3595704, 127.105399),
    zoom: 10
});

var marker = new naver.maps.Marker({
    position: new naver.maps.LatLng(37.3595704, 127.105399),
    map: map
});

다음은 마커의 setPosition 메소드를 사용하여 지도에 클릭한 지점으로 마커의 위치를 옮기는 예제 

var map = new naver.maps.Map('map', {
    center: new naver.maps.LatLng(37.3595704, 127.105399),
    zoom: 10
});

var marker = new naver.maps.Marker({
    position: new naver.maps.LatLng(37.3595704, 127.105399),
    map: map
});

naver.maps.Event.addListener(map, 'click', function(e) {
    marker.setPosition(e.latlng);
});

정보 창

InfoWindow는 지도 위에 말풍선 모양의 콘텐츠를 표시할 수 있는 정보 창을 정의하는 객체입니다.
정보 창의 디자인은 NAVER 지도 API v3에서 제공하는 스타일을 사용할 수 있고,
스타일 관련 옵션으로 정보 창 테두리, 배경색, 말풍선 꼬리의 스타일을 설정할 수 있습니다.

마커 위에 정보 창 올리기

정보 창을 지도 위에 노출하려면 open(map, anchor) 메소드를 호출 합니다.
첫번째 파라미터인 map은 정보 창을 올릴 Map 객체를 설정 합니다.
두번째 파라미터인 anchor는 지도 위에서 정보창의 위치를 결정하는 인자 입니다.
anchor에 LatLng 또는 Point 객체로 지도 좌표를 설정하면 해당 좌표를 가리키도록 정보 창을 위치 시킵니다.
anchor는 지도 좌표뿐만 아니라 Marker객체와 같이 객체 내부에 지도 좌표속성과 해당 지도 좌표 위치에서의 
오프셋값인 anchor속성을 포함하는 KVO객체로도 설정할 수 있습니다.

해당 객체는 getPosition과 getAnchor 메서드가 구현되어 있어야 하고,
 
InfoWindow 객체는 이를 이용해 position과 anchor값을 계산하여 적절한 위치에 정보 창을 노출합니다.

다음은 마커 위에 정보 창을 노출하는 예제

var cityhall = new naver.maps.LatLng(37.5666805, 126.9784147);

var map = new naver.maps.Map('map', {
    center: new naver.maps.LatLng(37.5698411, 126.9783927),
    zoom: 10
});

var contentString = [
    '<div class="iw_inner">',
    '   <h3>서울특별시청</h3>',
    '   <p>서울특별시 중구 태평로1가 31 | 서울특별시 중구 세종대로 110 서울특별시청<br>',
    '       <img src="./img/hi-seoul.jpg" width="55" height="55" alt="서울시청" class="thumb" /><br>',
    '       02-120 | 공공,사회기관 > 특별,광역시청<br>',
    '       <a href="http://www.seoul.go.kr" target="_blank">www.seoul.go.kr/</a>',
    '   </p>',
    '</div>'
].join('');

var marker = new naver.maps.Marker({
    map: map,
    position: cityhall
});

var infowindow = new naver.maps.InfoWindow({
    content: contentString
});

naver.maps.Event.addListener(marker, "click", function(e) {
    if (infowindow.getMap()) {
        infowindow.close();
    } else {
        infowindow.open(map, marker);
    }
});

 

반응형