OpenLayers | 2. 오픈레이어스(OpenLayers) 배경지도 추가(Google, OpenStreetMap(OSM), Vworld, Naver, Daum(Kakao))
OpenLayers | 2. 오픈레이어스(OpenLayers) 배경지도 추가(Google, Vworld, Naver, Daum(Kakao))
일반(Road)지도, 위성(Satellite)지도, 하이브리드(Hybrid)지도 타일(Tile)레이어 추가
지도서비스 생성시 백그라운드에 깔리는
배경지도를 추가하는 예제입니다.
OpenLayers에서 제공하는 소스(예 : ol.source.OSM)를
이용하여 추가하는 방법도 있지만
ol.layer.Tile 객체를 이용하여
타일레이어를 직접 추가하는 방법이 있습니다.
각 포털 지도의 좌표계와 타일링 규칙을 파악하여
ol.source.XYZ 소스로 추가합니다.
아래의 예제는
구글(Google), 오픈스트리트맵(OpenStreetMap), 브이월드(Vworld), 네이버(Naver), 다음(Kakao)의
일반지도, 위성(항공)지도, 하이브리드지도를 배경지도로 추가하는 방법입니다.
1. 예제 결과(Example Result)
Select로 배경지도를 변경합니다.
배경지도 :2. 예제 소스(Example Source)
1. proj4.js 라이브러리 추가
ol.Map 객체는 기본으로 구글좌표계(EPSG:3857)로 생성됩니다.
Daum(Kakao) 배경지도는 EPSG:5181(중부원점(GRS80) [200,000 500,000]) 좌표계이기 때문에
proj4.js를 추가하여 좌표계 설정해야 타일 이미지가 Transform되어
EPSG:3857 좌표계인 ol.Map 지도에 보여질 수 있습니다.
2. 배경지도 레이어(Layer) 추가
ol.Map 객체에 각 배경지도의 레이어를 추가합니다.
모든 레이어를 시각화 필요가 없기 때문에
'visible: false'를 설정하여 보이지 안도록 합니다.
<html> <head> <!-- jquery --> <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <!-- openlayers --> <link rel="stylesheet" href="https://openlayers.org/en/v4.6.5/css/ol.css" type="text/css"> <script src="https://openlayers.org/en/v4.6.5/build/ol.js"></script> <!-- proj4js--> <script src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.6.2/proj4.js"></script> <style> body { margin: 0; } .map { width: 100%; height: 100%; } #baseLayer { position: absolute; right: 10px; top: 10px; z-index: 1; } </style> <script> // dom ready $(document).ready(function() { init(); }); function init() { // 좌표계 설정 initProj(); // map 생성 var map = new ol.Map({ target: 'map', // Map 생성할 div id view: new ol.View({ center: [54300000, 4300000], // 초기 지도 위치 좌표 zoom: 8 // 초기 지도 위치 줌레벨 }), logo: false, controls: ol.control.defaults({ attribution: false }), }); // 배경지도 레이어 추가 addBaseLayer(map); // 배경지도 선택 select initBaseLayerSelect(map); } function initProj() { // google 좌표계 proj4.defs('EPSG:3857', '+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs'); // UTM-K 좌표계 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'); // 중부원점(GRS80) [200,000 500,000] proj4.defs('EPSG:5181', '+proj=tmerc +lat_0=38 +lon_0=127 +k=1 +x_0=200000 +y_0=500000 +ellps=GRS80 +units=m +no_defs'); } function addBaseLayer(map) { // ------------------------------ // google layers // ------------------------------ // google road var googleRoadLayer = new ol.layer.Tile({ source: new ol.source.XYZ({ projection : 'EPSG:3857', url : 'http://mt0.google.com/vt/lyrs=m&hl=en&x={x}&y={y}&z={z}', crossOrigin: 'anonymous' }), id: 'google_road', visible: false }); map.addLayer(googleRoadLayer); // google terrain var googleTerrainLayer = new ol.layer.Tile({ source: new ol.source.XYZ({ projection : 'EPSG:3857', url : 'http://mt0.google.com/vt/lyrs=p&hl=en&x={x}&y={y}&z={z}', crossOrigin: 'anonymous' }), id: 'google_terrain', visible: false }); map.addLayer(googleTerrainLayer); // google altered road var googleAlteredRoadLayer = new ol.layer.Tile({ source: new ol.source.XYZ({ projection : 'EPSG:3857', url : 'http://mt0.google.com/vt/lyrs=r&hl=en&x={x}&y={y}&z={z}', crossOrigin: 'anonymous' }), id: 'google_altered_road', visible: false }); map.addLayer(googleAlteredRoadLayer); // google satellite var googleSatelliteLayer = new ol.layer.Tile({ source: new ol.source.XYZ({ projection : 'EPSG:3857', url : 'http://mt0.google.com/vt/lyrs=s&hl=en&x={x}&y={y}&z={z}', crossOrigin: 'anonymous' }), id: 'google_satellite', visible: false }); map.addLayer(googleSatelliteLayer); // google terrain only var googleTerrainOnlyLayer = new ol.layer.Tile({ source: new ol.source.XYZ({ projection : 'EPSG:3857', url : 'http://mt0.google.com/vt/lyrs=t&hl=en&x={x}&y={y}&z={z}', crossOrigin: 'anonymous' }), id: 'google_terrain_only', visible: false }); map.addLayer(googleTerrainOnlyLayer); // google hybrid var googleHybridLayer = new ol.layer.Tile({ source: new ol.source.XYZ({ projection : 'EPSG:3857', url : 'http://mt0.google.com/vt/lyrs=y&hl=en&x={x}&y={y}&z={z}', crossOrigin: 'anonymous' }), id: 'google_hybrid', visible: false }); map.addLayer(googleHybridLayer); // ------------------------------ // OSM(OpenStreetMap) // ------------------------------ // osm standard // var osmStandardLayer = new ol.layer.Tile({ // source: new ol.source.OSM() // }); // map.addLayer(osmStandardLayer); var osmStandardLayer = new ol.layer.Tile({ source: new ol.source.XYZ({ projection : 'EPSG:3857', url : 'http://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png', crossOrigin: 'anonymous' }), id: 'osm_standard', visible: false }); map.addLayer(osmStandardLayer); // osm cyclosm var osmCyclosmLayer = new ol.layer.Tile({ source: new ol.source.XYZ({ projection : 'EPSG:3857', url : 'https://a.tile-cyclosm.openstreetmap.fr/cyclosm/{z}/{x}/{y}.png', crossOrigin: 'anonymous' }), id: 'osm_cyclosm', visible: false }); map.addLayer(osmCyclosmLayer); // osm humanitarian var osmHumanitarianLayer = new ol.layer.Tile({ source: new ol.source.XYZ({ projection : 'EPSG:3857', url : 'http://tile-{a-c}.openstreetmap.fr/hot/{z}/{x}/{y}.png', crossOrigin: 'anonymous' }), id: 'osm_humanitarian', visible: false }); map.addLayer(osmHumanitarianLayer); // ------------------------------ // vworld layers // ------------------------------ // vworld base var vworldBaseLayer = new ol.layer.Tile({ source: new ol.source.XYZ({ projection : 'EPSG:3857', url : 'https://xdworld.vworld.kr/2d/Base/service/{z}/{x}/{y}.png', crossOrigin: 'anonymous' }), id: 'vworld_base', visible: false }); map.addLayer(vworldBaseLayer); // vworld satellite var vworldSatelliteLayer = new ol.layer.Tile({ source: new ol.source.XYZ({ projection : 'EPSG:3857', url : 'https://xdworld.vworld.kr/2d/Satellite/service/{z}/{x}/{y}.jpeg', crossOrigin: 'anonymous' }), id: 'vworld_satellite', visible: false }); map.addLayer(vworldSatelliteLayer); // vworld hybrid var vworldHybridLayer = new ol.layer.Tile({ source: new ol.source.XYZ({ projection : 'EPSG:3857', url : 'https://xdworld.vworld.kr/2d/Hybrid/service/{z}/{x}/{y}.png', crossOrigin: 'anonymous' }), id: 'vworld_hybrid', visible: false }); map.addLayer(vworldHybridLayer); // vworld gray var vworldGrayLayer = new ol.layer.Tile({ source: new ol.source.XYZ({ projection : 'EPSG:3857', url : 'https://xdworld.vworld.kr/2d/gray/service/{z}/{x}/{y}.png', crossOrigin: 'anonymous' }), id: 'vworld_gray', visible: false }); map.addLayer(vworldGrayLayer); // vworld_midnight var vworldMidnightLayer = new ol.layer.Tile({ source: new ol.source.XYZ({ projection : 'EPSG:3857', url : 'https://xdworld.vworld.kr/2d/midnight/service/{z}/{x}/{y}.png', crossOrigin: 'anonymous' }), id: 'vworld_midnight', visible: false }); map.addLayer(vworldMidnightLayer); // ------------------------------ // naver layers // ------------------------------ // naver base var naverBaseLayer = new ol.layer.Tile({ source: new ol.source.XYZ({ projection : 'EPSG:3857', url : 'https://map.pstatic.net/nrb/styles/basic/1646972073/{z}/{x}/{y}@2x.png', tilePixelRatio: 2, // 타일사이즈 512일때 해상도 비율 crossOrigin: 'anonymous' }), id: 'naver_base', visible: false }); map.addLayer(naverBaseLayer); // naver satellite var naverSatelliteLayer = new ol.layer.Tile({ source: new ol.source.XYZ({ projection : 'EPSG:3857', url : 'https://map.pstatic.net/nrb/styles/satellite/1646972073/{z}/{x}/{y}@2x.png', tilePixelRatio: 2, // 타일사이즈 512일때 해상도 비율 crossOrigin: 'anonymous' }), id: 'naver_satellite', visible: false }); map.addLayer(naverSatelliteLayer); // naver terrain var naverTerrainLayer = new ol.layer.Tile({ source: new ol.source.XYZ({ projection : 'EPSG:3857', url : 'https://map.pstatic.net/nrb/styles/terrain/1646972073/{z}/{x}/{y}@2x.png', tilePixelRatio: 2, // 타일사이즈 512일때 해상도 비율 crossOrigin: 'anonymous' }), id: 'naver_terrain', visible: false }); map.addLayer(naverTerrainLayer); // ------------------------------ // daum(kakao) layers // ------------------------------ var daumTileGrid = new ol.tilegrid.TileGrid({ extent : [(-30000-524288), (-60000-524288), (494288+524288), (988576+524288)], tileSize : 256, resolutions : [4096, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, 0.5, 0.25], minZoom : 1 }); function getDaumTileUrlFunction(type) { var tileUrlFunction = function(tileCoord, pixelRatio, projection) { var res = this.getTileGrid().getResolutions(); var sVal = res[tileCoord[0]]; var yLength = 988576 - (-60000) + 524288 + 524288; var yTile = yLength / (sVal * this.getTileGrid().getTileSize()); var tileGap = Math.pow(2, (tileCoord[0] -1)); yTile = yTile - tileGap; var xTile = tileCoord[1] - tileGap; if (type == 'base') { return 'http://map' + Math.floor( (Math.random() * (4 - 1 + 1)) + 1 ) + '.daumcdn.net/map_2d_hd/2111ydg/L' + (15 - tileCoord[0]) + '/' + (yTile + tileCoord[2]) + '/' + xTile + '.png'; } else if (type == 'satellite') { return 'https://map' + Math.floor( (Math.random() * (4 - 1 + 1)) + 1 ) + '.daumcdn.net/map_skyview_hd/L' + (15 - tileCoord[0]) + '/' + (yTile + tileCoord[2]) + '/' + xTile + '.jpg'; } else if (type == 'hybrid') { return 'http://map' + Math.floor( (Math.random() * (4 - 1 + 1)) + 1 ) + '.daumcdn.net/map_hybrid_hd/2111ydg/L' + (15 - tileCoord[0]) + '/' + (yTile + tileCoord[2]) + '/' + xTile + '.png'; } }; return tileUrlFunction; } // daum base var daumBaseLayer = new ol.layer.Tile({ source: new ol.source.XYZ({ projection : 'EPSG:5181', tileGrid: daumTileGrid, tileUrlFunction: getDaumTileUrlFunction('base'), tilePixelRatio: 2, // 타일사이즈 512일때 해상도 비율 }), id: 'daum_base', visible: false }); map.addLayer(daumBaseLayer); // daum satellite var daumSatelliteLayer = new ol.layer.Tile({ source: new ol.source.XYZ({ projection : 'EPSG:5181', tileGrid: daumTileGrid, tileUrlFunction: getDaumTileUrlFunction('satellite'), tilePixelRatio: 2, // 타일사이즈 512일때 해상도 비율 }), id: 'daum_satellite', visible: false }); map.addLayer(daumSatelliteLayer); // daum hybrid var daumHybridLayer = new ol.layer.Tile({ source: new ol.source.XYZ({ projection : 'EPSG:5181', tileGrid: daumTileGrid, tileUrlFunction: getDaumTileUrlFunction('hybrid'), tilePixelRatio: 2, // 타일사이즈 512일때 해상도 비율 }), id: 'daum_hybrid', visible: false }); map.addLayer(daumHybridLayer); } function initBaseLayerSelect(map) { // add select option var html = ''; $.each(map.getLayers().getArray(), function(i, v) { html += '<option value="' + v.get('id') + '">' + v.get('id') + '</option>'; }); $('#baseLayer').append(html); // select event $('#baseLayer').change(function() { var layerId = $(this).val(); $.each(map.getLayers().getArray(), function(i, v) { if (layerId == v.get('id')) { v.setVisible(true); } else { v.setVisible(false); } }); }); // 초기값 $('#baseLayer').val('naver_base').trigger('change'); } </script> </head> <body> <div id="map" class="map"> <select id="baseLayer"></select> </div> </body> </html> |
지도 데이터를 가져올때 스크립트에 발급받은 api를 사용하여 로드해야되지않나요?
답글삭제