업무를 진행하면서 새로운 지도 API를 다루어보게 되었다. 검색시 본인이 활용하고 싶은 부분에 대한 자료가 부족하다고 느껴서 어려움을 느꼈다. API에 관한 설명 또한 영어라서...
후에 또 다시 활용하게 되었을때 코딩 시간을 단축하기 위해 새로이 알게 된 부분을 정리할 목적으로 게시글을 작성한다.
참고로 해당 게시글은 교재와 같이 정확한 개념, 설명이 아니라 그저 본인의 쉬운 이해를 위한 정리본으로 100% 정확한 개념을 파악하고 싶다면 다른 게시글이나 아래에 첨부하게 될 링크에서 직접 읽고 파악하는 것이 더 도움이 될 것이라고 생각한다.
목차는 아래와 같다.
1. 지도 표출
1) view 객체
2) control 객체
3) Layer 객체
4) map객체
2. 지도 위 도형삽입
3. 지도 위 마커표출
4. geojson활용 : 지역테두리, 도형
해당 링크에서 OpenLayers에 대한 예제와 API설명 등을 확인할 수 있다.
1. 지도 표출
지도 표출에 앞서 필요한 필요한 객체들과, 각 객체들이 무엇을 수행할 수 있는지를 먼저 생각하고 작업하게 되면 조금 더 구체적인 조건으로 지도를 표출할 수 있을것이라고 생각된다.
우선 본격적인 사용에 앞서, 좌표변환을 위한 proj4의 소스와 openLayers활용을 위한 ol의 소스를 파일로 첨부하였다.
위 소스의 활용을 위해 지도를 그리기 위해 작성되는 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
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);
사용된 마커 이미지를 첨부하였다.
마커에 text를 추가하고 싶다면 style객체에 text를 추가하면 될 것이다.
4. geojson활용 : 지역 테두리
행정구역에 테두리를 추가하기 위해서는 미리 geojson을 확보하고, 해당 소스를 통해 레이어를 생성하는 방법이 있다.
아래 링크를 통해 원하는 범위의 geojson을 확보하고, 작업을 준비하면 된다.
https://neurowhai.tistory.com/350
본인의 경우 특정 행정동의 좌표만이 필요했는데, 위의 방법으로 확보한 geojson의 경우 좌표는 보이지만 특정 행정구역을 판단하기가 어려웠다. 검색을 진행하다 행정동의 좌표를 판단하기 수월한 소스를 확보하였다.
https://github.com/vuski/admdongkor
사진과 같이 표시되는 가장 큰 범위의 geojson파일은 별도로 첨부하였다.
아래는 세계지도 geojson을 확인할 수 있는 깃허브 링크이다.
https://github.com/johan/world.geo.json/blob/master/countries.geo.json?short_path=afdfc39
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 |