본문 바로가기
JavaScript

[지도 API] OpenLayers_1

by amoomar 2022. 7. 6.
반응형

 

 

업무를 진행하면서 새로운 지도 API를 다루어보게 되었다. 검색시 본인이 활용하고 싶은 부분에 대한 자료가 부족하다고 느껴서 어려움을 느꼈다. API에 관한 설명 또한 영어라서...

후에 또 다시 활용하게 되었을때 코딩 시간을 단축하기 위해 새로이 알게 된 부분을 정리할 목적으로 게시글을 작성한다.

 

 

참고로 해당 게시글은 교재와 같이 정확한 개념, 설명이 아니라 그저 본인의 쉬운 이해를 위한 정리본으로 100% 정확한 개념을 파악하고 싶다면 다른 게시글이나 아래에 첨부하게 될 링크에서 직접 읽고 파악하는 것이 더 도움이 될 것이라고 생각한다.

 

 

목차는 아래와 같다.

1. 지도 표출
   1) view 객체
   2) control 객체
   3) Layer 객체
   4) map객체
2. 지도 위 도형삽입
3. 지도 위 마커표출
4. geojson활용 : 지역테두리, 도형

 

 

 

해당 링크에서 OpenLayers에 대한 예제와 API설명 등을 확인할 수 있다.

 

https://openlayers.org/

 

OpenLayers - Welcome

A high-performance, feature-packed library for all your mapping needs.

openlayers.org

 

 

 


 

 

 

1. 지도 표출

지도 표출에 앞서 필요한 필요한 객체들과, 각 객체들이 무엇을 수행할 수 있는지를 먼저 생각하고 작업하게 되면 조금 더 구체적인 조건으로 지도를 표출할 수 있을것이라고 생각된다.

 

우선 본격적인 사용에 앞서, 좌표변환을 위한 proj4의 소스와 openLayers활용을 위한 ol의 소스를 파일로 첨부하였다.

proj4.js
0.08MB
ol.js
0.95MB
ol.css
0.00MB

 

 

 

위 소스의 활용을 위해 지도를 그리기 위해 작성되는 javascript코드 최상단에 아래의 코드를 작성하였다.

proj4.defs('EPSG:980201', '+proj=lcc +lat_1=30 +lat_2=60 +lat_0=0 +lon_0=126 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs');
proj4.defs('EPSG:5179', '+proj=tmerc +lat_0=38 +lon_0=127.5 +k=0.9996 +x_0=1000000 +y_0=2000000 +ellps=GRS80 +units=m +no_defs');
ol.proj.proj4.register(proj4);

 

 

지도를 표출할 jsp에서는 css, js에 대한 경로를 작성한다.

<link rel="stylesheet" type="text/css" href="${contextPath}/informant/css/ol.css">

<script src="${contextPath}/informant/js/proj4/proj4.js"></script>
<script src="${contextPath}/informant/js/ol/ol.js"></script>

 

 

 

1) view 객체

 

해당 객체는 지도 생성시 중심이 될 좌표, 최소 죽소 Zoom레벨, zoom사용시의 해상도, 기본 해상도, 처음 지도 생성시의 Zoom 레벨 등의 설정에 대한 내용 등을 정의할 수 있다. (일부는 선택사항)

 

const baseCenter = ol.proj.transform([128.250000, 35.90000], 'EPSG:4326', 'EPSG:980201');
const baseZoom = 7;

const mapView = new ol.View({ 
	center: baseCenter, //중심좌표
	extent: ol.proj.transformExtent([122.5, 32, 135, 42.55], 'EPSG:4326', 'EPSG:980201'),
	minZoom: 7, //최소 Zoom레벨
	projection: 'EPSG:980201', //줌 사용시 해상도
	resolutions: resolutions, //기본 해상도
	zoom: baseZoom //초기 지도 Zoom레벨
});

 

 

 

 

* 좌표 변환 *

OpenLayers는 활용되는 위경도와 그 순서가 일반적으로 구글맵 등 우리가 보편적으로 사용하는 위경도와 조금 다르게 표출된다. 앞서 언급했다싶이 proj를 활용하게 되는데, 게시글 처음에 첨부했던 소스와 활용을 위한 코드를 작성했기 때문에 바로 사용할 수 있게 된다. 위에서도 활용 방법이 바로 나왔지만, 위좌표 변환을 위한 코드는 다음과 같다.

 

var center = ol.proj.transform([경도, 위도], '경도 변환의 기준값', '위도 변환의 기준값');

// 작성 예시 : 작성된 기준값을 통해 OpenLayers에서 활용되는 지도에서 사용 가능한 위경도로 변환이 가능하다.
var center = ol.proj.transform([127.825763, 36.916613], 'EPSG:4326','EPSG:3857');

 

 

 


 

 

 

2) control 객체

 

해당 객체를 통해 축적을 생성하거나, 마우스커서가 위치하는 좌표를 표시하거나 하는 등 다양한 조정을 시도할 수 있다. (일부는 선택사항)

// map객체 초기화시 사용할 변수
const extend = [
	new ol.control.ScaleLine({ units: 'metric' }), //축적 생성
	new ol.control.MousePosition({ //마우스가 위치한 좌표반환
		projection: 'EPSG:4326',
		coordinateFormat: function(coordinate) {
			return ol.coordinate.format(coordinate, '{y}, {x}', 6);
		}
	})
]

 

 

 

이때 MousePosition객체를 사용하지만, 웹상으로 표시가 되지 않게 하고싶다면 CSS스타일을 통해 해당 요구를 충족할 수 있다.

.ol-zoom { top: unset; left: unset; bottom: .5em; right: .5em; }
.ol-mouse-position { top: 10px; left: 50%; bottom: unset; right: unset; transform: translateX(-50%); display: none; }
.ol-attribution{display: none;}

 

 

 


 


3) Layer 객체

사용 범위가 다양한 만큼 사용 방법이 가장 복잡하게 느껴졌던 것 같다. 모든 내용을 이해하기엔 어려우니 필요한 것에 대해서만 언급할 예정이다. 

 

해당 객체를 통해 지도의 타입을 설정하거나,  지도 위에 표시될 모든 보여지는 것들(도형그리기, 선 그리기, 테두리 그리기, 마커 찍기 등)을 관할할 수 있다.

 

뒤에서 마커, 도형, 테두리에 대한 내용을 다룰 것이기에 이번 순서에서는 지도의 생성만을 위한 내용을 작성하였다.

 

// 그냥 지도
const layer01 = new ol.layer.Tile({
	source: new ol.source.OSM()
})

//타일 있는 지도
const layer02 = new ol.layer.Tile({
	source: new ol.source.XYZ({url: 'http://xdworld.vworld.kr:8080/2d/Base/202002/{z}/{x}/{y}.png'})
})

 

 

위에서 작성된 Tile들의 예시는 아래와 같다.

(좌)기본 레이어 / (우)타일 있는 지도 레이어

 

 

 

이외에도 위성지도 레이어 등 활용할 수 있는 레이어는 다양하며 마찬가지로  OpenLayers 공식 페이지의 예제 코드를 통해 내용을 파악할 수 있다.

 

 

 

 


 

 

 

4) map객체

 

위에서 언급된 모든 객체들을 포함하여 최종적으로 지도를 그릴 수 있게 해주는 객체이다. 본인과 같이 모든 내용들을 변수에 담지 않고 해당 객체를 초기화 하면서 포함하는 모든 객체들을 초기화하는 방법으로 작성해도 무관하나 유지보수에 용이하진 않을 것 같아 추천하는 방식은 아니다.

 

var map01 = new ol.Map({
	
	controls: new ol.control.defaults({ zoom: false }).extend(extend), //지도의 제한
	
	layers: layer, //지도의 스타일
		
	view: view, //지도 초기 설정
    
	// 지도 사용의 제한들 (Default값이 존재하므로 생략해도 무관)
	interactions: new ol.interaction.defaults({ 
		altShiftDragRotate: false, //alt+shift+드래그 회전을 원하는지
		doubleClickZoom: false, // 더블클릭 줌이 필요한지
		dragPan: true, //드래그 팬(이동)이 필요한지
		mouseWheelZoom: false, //마우스 휠 줌이 필요한지
		pinchRotate: false, //핀치 회전이 필요한지
		pinchZoom: false, // 핀치 줌이 필요한지
		shiftDragZoom: false //shift+드래그 줌이 필요한지
	}),
    
	target: "risk_map", //지도를 그릴 대상이 되는 html요소의 id
    
});

 

 


 

 

2. 지도 위 도형삽입

 

언급했다싶이 Layer 객체를 통해 작업할 수 있다. 동그라미, 다각형, 선 등을 지도에 표시하거나 혹은 사용자가 직접 해당 도형들을 그릴 수 있게 할 수도 있다. 해당 게시글에서는 지도에 표출하는 내용만을 다룰 것이다.

 

 

사각형을 그리기 위한 함수를 생성하고, 꼭지점과 도형의 border(테두리 색), 도형의 fill(채울 색)을 인자로 전달해주면 앞서 생성했던 map객체에 도형 레이어를 추가할 수 있다. 다각형을 그리고 싶다면 feature에 꼭지점이 하나 더 들어가도록 좌표를 추가해주면 될 것이다.

 

function addPolygon(leftT, leftB, rightB, rightT, colorB, colorF){
		
	var feature = new ol.Feature({
		geometry: new ol.geom.Polygon(
			[
				[
					[leftT[0], leftT[1]],
					[leftB[0], leftB[1]],
					[rightB[0], rightB[1]],
					[rightT[0], rightT[1]]
				]
			]
		    ),
	    });
		
	feature.getGeometry().transform('EPSG:4326', 'EPSG:3857');
		
	var vectorSource = new ol.source.Vector({
		features: [feature] //feature의 집합
	});
		
	var polygonLayer = new ol.layer.Vector({
		source : vectorSource,
		style : [
			new ol.style.Style({
				stroke: new ol.style.Stroke({
					color: colorB,
					width: 2
				}),
				fill: new ol.style.Fill({
					color: colorF
				}),
				//도형 내부에 글씨도 넣을 수 있음
				/* text: new text({
					text: "넣을 글씨",
					textAlign: 'center',
					font: '15px roboto,sans-serif'    
				})*/
			})
		]
	});

	//지도에 레이어 추가
	map01.addLayer(polygonLayer);

};

var leftT=[126.873592, 37.200905];
var leftB=[126.873592, 34.987749];
var rightB=[126.231369, 34.987749];
var rightT=[126.231369, 37.200905];
addPolygon(leftT, leftB, rightB, rightT, 'rgb(0,204,255)', 'rgba(0,204,255,0.4)');

leftT=[129.954383, 38.338507];
leftB=[130.001047, 37.310572];
rightB=[131.769083, 37.372405];
rightT=[131.712050, 38.484764];
addPolygon(leftT, leftB, rightB, rightT, 'rgb(255,204,0)', 'rgba(255,204,0,0.6)');

 

 

 

 

설정한 각 좌표들을 꼭지점으로 하여 정상적으로 출력되는 모습을 확인할 수 있다.

 

 

 

* 원 그리는 예제 *

원의 경우는 feature객체의 값만을 다르게 하여 수월히 그릴 수 있다. 해당 예제는 링크를 첨부하였다.

https://lts0606.tistory.com/200

 

Openlayers draw circle (오픈레이어스 원 그리기, Openlayers 원 그리기)

오픈레이어스3 에서는 원, 점, 사각형 및 기타 이미지 그리기가 사실 참 쉬웠습니다. 그런데 버전이 4로 올라가면서 불러오는 스크립트의 레이어에 따라서 별칭을 주어야하는 필수 클래스가 존

lts0606.tistory.com

 

 

 

 


 

 

3. 지도 위 마커표출

 

인자로 경도, 위도를 담은 변수를 주면 해당 위치에 마커이미지를 추가하는 예제이다.

 

 //마커 등록하기 함수
function addMarker(point) {

    //Point 좌표 등록
    var point_feature = new ol.Feature({
        geometry: new ol.geom.Point([point[0], point[1]]).transform('EPSG:4326', 'EPSG:3857')
    });
    
    var markerSource = new ol.source.Vector();
    //markerSource에 등록한 point를 담는다. addFeature를 이용해서, 여러개의 point를 source에 담는다.
    markerSource.addFeature(point_feature);

    //style을 활용해서, point의 style을 변경한다.
    var markerStyle = new ol.style.Style({
	    image: new ol.style.Icon({ //마커 이미지
	        opacity: 1, //투명도 1=100% 
	        scale: 0.04, //크기 1=100%

	        //marker 이미지, 해당 point를 marker로 변경한다.
	        src: '../img/marker04.png'
	    }),
        //html의 css, z-index 기능이다.
	    zindex: 10
	});

    // 마커 레이어 생성
	markerLayer = new ol.layer.Vector({
	    source: markerSource, //마커 feacture들
	    style: markerStyle //마커 스타일
	});

	// 지도에 마커가 그려진 레이어 추가
	map01.addLayer(markerLayer);
}

var point=[125.396184, 35.603151]
addMarker(point);

 

 

 

사용된 마커 이미지를 첨부하였다.

marker04.png
0.01MB

 

 

 

마커에 text를 추가하고 싶다면 style객체에 text를 추가하면 될 것이다.

 

 

 

 


 

 

4. geojson활용 : 지역 테두리

 

 

행정구역에 테두리를 추가하기 위해서는 미리 geojson을 확보하고, 해당 소스를 통해 레이어를 생성하는 방법이 있다.

 

 

아래 링크를 통해 원하는 범위의 geojson을 확보하고, 작업을 준비하면 된다.

 

https://neurowhai.tistory.com/350

 

대한민국 행정구역(시도, 시군구) GeoJSON 파일 다운로드 및 SHP 파일 단순화 후 변환 방법 설명

원본 출처이자 해상도가 높은 파일(SHP)은 아래 링크에서 구하실 수 있습니다. http://www.gisdeveloper.co.kr/?p=2332 대한민국 최신 행정구역(SHP) 다운로드 – GIS Developer www.gisdeveloper.co.kr 위 데이터..

neurowhai.tistory.com

 

 

 

본인의 경우 특정 행정동의 좌표만이 필요했는데, 위의 방법으로 확보한 geojson의 경우 좌표는 보이지만 특정 행정구역을 판단하기가 어려웠다. 검색을 진행하다 행정동의 좌표를 판단하기 수월한 소스를 확보하였다.

 

https://github.com/vuski/admdongkor

 

GitHub - vuski/admdongkor: 대한민국 행정동 경계 파일

대한민국 행정동 경계 파일. Contribute to vuski/admdongkor development by creating an account on GitHub.

github.com

 

 

 

사진과 같이 표시되는 가장 큰 범위의 geojson파일은 별도로 첨부하였다.

korea.geojson
5.85MB

 

 

 


 

 

아래는 세계지도 geojson을 확인할 수 있는 깃허브 링크이다.

https://github.com/johan/world.geo.json/blob/master/countries.geo.json?short_path=afdfc39 

 

GitHub - johan/world.geo.json: Annotated geo-json geometry files for the world

Annotated geo-json geometry files for the world. Contribute to johan/world.geo.json development by creating an account on GitHub.

github.com

 

 


 

 

 

1) 파일 배치 및 경로 파악

geojson을 적당한 프로젝트 내 위치에 추가하여두고, 경로를 변수화 해둔 후 layer 하위의 vector객체를 통해 geojson에 저장된 좌표들을 호출하여 구역화가 되도록 하였다.

 

const areaPath = 'jsonData/area/korea.geojson';

var areaLayer = new ol.layer.Vector({
	name: 'areaLayer1', opacity: 0.75,
    // geojson을 포맷
	source: new ol.source.Vector({ format: new ol.format.GeoJSON(), projection: 'EPSG:4326', url: areaPath }),
	// 스타일 적용(테두리 두께 및 색상 설정)
    style: new ol.style.Style({ stroke: new ol.style.Stroke({color: '#FE6000', width: 1 }) }), zIndex: 20
});

 

 

 

 


 

 

 

2) 레이어 추가

이렇게 생성한 레이어객체를 map객체 생성시 layers항목에 추가하거나 addLayer메서드를 통해 동작하도록 하면 정상 실행 되는 것을 확인할 수 있다.

// 방법 1
var map01 = new ol.Map({ 
	controls: new ol.control.defaults({ zoom: false }).extend(extend),
	layers : [layer, areaLayer],
	
	// https://openlayers.org/en/latest/apidoc/module-ol_interaction.html 참조
	interactions: new ol.interaction.defaults({ 
		altShiftDragRotate: false, //alt+shift+드래그 회전을 원하는지
		doubleClickZoom: false, // 더블클릭 줌이 필요한지
		dragPan: true, //드래그 팬(이동)이 필요한지
		mouseWheelZoom: true, //마우스 휠 줌이 필요한지
		pinchRotate: false, //핀치 회전이 필요한지
		pinchZoom: false, // 핀치 줌이 필요한지
		shiftDragZoom: false //shift+드래그 줌이 필요한지
	}),
	
	target: 'os_rwcw_map_1',
	view: mapView
});

// 방법 2
map01.addLayer(areaLayer);

 

 

 

* 레이어의 추가 및 삭제 메서드 *

// 특정 레이어 삭제메서드
map객체명.removeLayer(삭제할 레이어객체명)

// 특정 레이어 추가메서드
map객체명.addLayer(추가할 레이어객체명)

 


 

geojson을 활용하여 단순 테두리가 아니라, 해당 geojson의 좌표를 감싸는 polygon(다각형)을 생성하고 싶을때는, 아래의 예시와 같은 함수를 활용하여 도형을 출력할 수 있다.

function drawMap(map, color, path) {
	var polygonLayer = new ol.layer.Vector({
		name: path, //후에 이벤트 처리 등을 용이하게 하기 위해 name을 설정해주는 것도 좋다.
		opacity: 0.5, //도형의 불투명도를 설정하는 방법 1(택 1)
		source: new ol.source.Vector({ format: new ol.format.GeoJSON(), url: filePath + path + '.geojson' }),//url에 참조할 geojson의 경로를 입력할 것.
		style: [
			new ol.style.Style({
            		//단순 색상 채우기
				stroke: new ol.style.Stroke({
					color: color,
					width: 2
				}),
                	// 도형의 불투명도 설정하는 방법 2(택1)
				fill: new ol.style.Fill({
					color: color.replace(')', ', 0.6)')
				}),
			})
		]
	});
	map.addLayer(polygonLayer); //이때의 map은 ol.map객체이다.
}

 

 

 

 


 

반응형

'JavaScript' 카테고리의 다른 글

Object_value로 key 참조하기  (0) 2022.09.23
[그래프 API] HighCharts  (0) 2022.07.07
URL, API  (0) 2022.02.22
타이밍 이벤트 & 단원 총정리  (0) 2022.02.18
BOM & Form  (0) 2022.02.17