OpenLayers 3로 지도 서비스를 만들때 Google Map을 바탕지도로 사용하는 방법이다.
OpenLayers 3의 Quick Start에 소개된 것처럼
ol.Map에 ol.layer.Tile로 source를 등록하는게 정석이다.
<script type='text/javascript'> var map = new ol.Map({ target: 'map', layers: [ // 이미지 방식의 Tile이 깔리고 View에 의해 제어된다 new ol.layer.Tile({ // 여기에 new ol.source.Google()이 붙는 형태였음 source: new ol.source.OSM() }) ], view: new ol.View({ center: ol.proj.fromLonLat([37.41, 8.82]), zoom: 4 }) }); </script>
이 방식을 OpenLayers 2까지는 Google에서 제공을 했었는데,
* 참고 http://dev.openlayers.org/examples/google.html
OpenLayers 3부터 호환성을 문제로 Tile 서비스를 공식적으로 지원하지 않게 되었다.
* 정석으로 붙일 방법이 없어졌다는 말임
* 참고 : Paul Spencer’s post on the OL3 mailing list
그렇지만, 역시나 타국의 개발자들이 방법을 만들어놓았다.
[ 요약 ]
1) 구글 지도를 생성하고
– 마우스 포함해 모든 interaction을 비활성화 시킨 채로
2) 구글맵의 div 위에 OpenLayers를 Tile 없이 생성하여 겹친다. (= Div를 겹쳐 올린다)
3) OpenLayers의 지도 이벤트를 구글 지도 이벤트에 연결한다 (setCenter, setZoom)
– OSM 이벤트 ‘change:center’, ‘change:resolution’에 대해
– mapGoogle의 setCenter와 setZoom을 연결
4) control에 대한 시간차(delay)가 발생하는데, OpenLayers 3의 interactions 옵션을 조정해 Smooth Move 효과를 죽인다
이에 대한 샘플 코드는 Openlayer Samples에 있다.
* 다만 안정성을 담보할 수 없으므로 productation 시키지는 말라고 권고하고 있음
샘플페이지를 작성해 보았다. ==> GoogleMap
이 중 핵심부분만 살펴보면
<!-- 상위 div에서 position:relative; 스타일을 적용하고 하위에서 절대위치 지정 --> <div id="printableArea" style="width: 100%; height: 90%; margin: 0; padding:0; position:relative;"> <div id="map-google" style="position: absolute; left:0px; top:0px; z-index: 1; width: 100%; height: 100%; margin: 0; padding:0;"></div> <div id="map-main" style="position: absolute; left:0px; top:0px; z-index: 2; width: 100%; height: 100%; margin: 0; padding:0;"></div> <div class="row" style="position: absolute; bottom: -17px; z-index: 999; width:100%;"> <div id="location" style="float:left" class="col-md-6"></div> <div id="scale" class="pull-right" style="float:right">Scale</div> </div> <div id="info"> </div> </div>
// view에 의해 Vector Source의 좌표값이 변경된다 // **NOTE: 'EPSG:3857'을 사용해야 두 지도가 왜곡없이 겹쳐진다!! var viewMain = new ol.View({ center : ol.proj.transform( centerWGS84, 'EPSG:4326', srsName ), projection : srsName, // 'EPSG:3857' zoom: zoomDefault, minZoom: 10, // 작게 보는 축소 한계 maxZoom: 19, // 크게 보는 확대 한계 }); var mapMain = new ol.Map({ target : 'map-main', renderer : 'canvas', view : viewMain, controls : [ new ol.control.Zoom(), new ol.control.ZoomSlider(), mousePosition ], // 지도 조절시 부드러운 움직임을 없앤다 interactions: ol.interaction.defaults({ dragPan: false, mouseWheelZoom: false }).extend([ new ol.interaction.DragPan({kinetic: false}), new ol.interaction.MouseWheelZoom({duration: 0}) ]), layers : layerArr }); var mapGoogle; // google API키 위치 다음에 callback 함수 지정하는 부분이 있음: &callback=initMap function initMap() { // 구글 지도 생성 : <div id='map-google'>에 올려짐 // 대부분의 control들이 disable 된 상태다 mapGoogle = new google.maps.Map(document.getElementById('map-google'), { disableDefaultUI: true, keyboardShortcuts: false, draggable: false, disableDoubleClickZoom: true, scrollwheel: false, streetViewControl: false, center: {lat: centerWGS84[1], lng: centerWGS84[0]}, zoom: zoomDefault }); }; // ol3의 map change 이벤트를 google map과 연결한다 viewMain.on('change:center', function() { var center = ol.proj.transform( viewMain.getCenter(), srsName, 'EPSG:4326'); mapGoogle.setCenter(new google.maps.LatLng( center[1], center[0] )); }); // google map은 ol3의 zoom level과 호환됨 viewMain.on('change:resolution', function() { mapGoogle.setZoom( viewMain.getZoom() ); });
댓글 한 개