모빌리티 도메인을 개발하는 회사를 다니며 구현했던 로직들 중 기억에 남는 것들을 정리하려한다.
내가 했던 삽질들을 다른 사람들은 하지 않기를 바라는 마음으로 공유한다.
Tmap API를 확인해보면 '폴리곤' 이라는 다각형을 그리는 API를 제공한다.
https://tmapapi.sktelecom.com/main.html#webv2/sample/webSample84
도대체 왜 이렇게 만드는건데
API는 아래의 링크를 참조하자
폴리곤을 그리는 API : Tmapv2.extension.Drawing
https://tmapapi.sktelecom.com/main.html#webv2/docs/WebDocs.extension_Drawing
폴리곤 내 좌표 포함여부 API : Tmapv2.Polygon
https://tmapapi.sktelecom.com/main.html#webv2/docs/WebDocs.Polygon
현재 만들고자 하는 기능은 우회하여 구현해야한다. 방법은 2가지가 있다.
Tmap은 레스터 형식의 맵(Tmapv2)과 벡터 형식의 맵(Tmapv3)을 제공한다. 하지만 이번 로직의 구현을 위해서는 레스터 형식의 맵을 사용해야 한다.
벡터 형식의 경우 폴리곤을 그리는 API를 제공하지 않기 때문이다.
index.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>simpleMap</title>
<script src="https://apis.openapi.sk.com/tmap/jsv2?version=1&appKey=생성한 AppKey"></script>
<script src="index.js"></script>
<link rel="stylesheet" href="index.css">
</head>
<body onload="initTmap()">
<div id="map_div">
<div class="map_act_btn_wrap clear_box" style="position: absolute;z-index: 1;padding-left: 10px;">
<button onClick="drawMeasure()">면적 그리기</button>
<button onClick="drawPolygon()">폴리곤 그리기</button>
</div>
</div>
</body>
</html>
index.js
let map = null;
let drawingObject = null;
let measureObject = null;
let markerArray = [];
function initTmap(){
// map 생성
map = new Tmapv2.Map("map_div", {
center : new Tmapv2.LatLng(37.57220450, 126.99532028), // 지도 초기 좌표
width : "100%", // 지도의 넓이
height : "100vh", // 지도의 높이
zoom : 16 // 지도의 줌레벨
});
// 더미 마커 생성
for(let i=0; i<10; i++){
for(let j=0; j<10; j++){
let lat = 37.56520450 + (0.002 * i);
let lon = 126.98602028 + (0.002 * j);
let marker = new Tmapv2.Marker({
position: new Tmapv2.LatLng(lat, lon),
iconHTML: '<div id="icon" style="background:black"></div>',
iconSize: new Tmapv2.Size(10, 10),
zIndex: 200,
map: map
});
// 마커 정보 저장
markerArray.push(marker);
}
}
// map 우클릭
map.addListener('contextmenu', ()=>{
if(true){
console.log('--- measureObject ---');
console.log(measureObject);
console.log(measureObject._data.pointArray);
console.log('--- polygonObject ---');
console.log(drawingObject);
console.log(drawingObject._data.shapeArray[0]);
setTimeout(()=>{
console.log(drawingObject._data.shapeArray[0]._shape_data.path);
}, 1);
}
});
};
// 면적 그리기
function drawMeasure(){
measureObject = new Tmapv2.extension.MeasureArea({
map: map
});
};
// 폴리곤 그리기
function drawPolygon(){
drawingObject = new Tmapv2.extension.Drawing(
{
map:map, // 지도 객체
strokeWeight: 4, // 테두리 두께
strokeColor:"blue", // 테두리 색상
strokeOpacity:1, // 테두리 투명도
fillColor:"red", // 도형 내부 색상
fillOpacity:0.2 // 도형 내부 투명도
}
);
drawingObject.drawPolygon();
};
위와 같이 해당 객체의 정보를 볼 수 있다. 각 객체 아래에 존재하는 정보는 LatLng 객체를 저장하는 곳을 찾아놓은 것이다.
polygonObject의 경우 바로 객체를 찍어볼 경우 값을 받아오지 못했다.
1ms를 기다렸다가 콘솔을 찍어보는 로직을 추가한 이유이다. 폴리곤을 그리는 API를 사용하여 꼭짓점의 정보를 가져오려면 위와 같이 동작시켜야 하는 것 같다.
polygon API에서는 꼭짓점의 정보를 Tmap에서 제공하는 LatLng 객체로 전달해야만 한다.
현재 콘솔로 나오는 객체는 LatLng 객체이므로 따로 객체를 생성할 필요는 없다.
LatLng 객체에 대한 API 정보는 아래 링크를 참조하자
https://tmapapi.sktelecom.com/main.html#webv2/docs/WebDocs.LatLng
이제 위와 같이 받아온 정보를 통해 새롭게 polygon을 그린 뒤 contains 메서드를 사용하면 마커가 해당 구역에 포함되는지 확인할 수 있다.
index.js 내 우클릭 이벤트
// map 우클릭
map.addListener('contextmenu', ()=>{
// 랜덤 색상
let randomColor = "#" + Math.round(Math.random() * 0xffffff).toString(16);
// 폴리곤 생성
let polygon = new Tmapv2.Polygon({
paths: [measureObject._data.pointArray], // 면적 객체의 꼭짓점 배열
fillColor: randomColor, // 랜덤 내부 색상
map: map // 지도 객체
});
// 폴리곤 내 마커 판별
for(let i=0; i<markerArray.length; i++){
if(polygon.contains(markerArray[i].getPosition())){
markerArray[i].setIconHTML('<div id="icon" style="background:'+randomColor+'"></div>');
}
}
});
구역 객체의 정보를 통해 랜덤한 배경색의 폴리곤을 생성한 뒤 마커가 포함되면 마커의 배경색을 폴리곤의 동일한 색상으로 변경하도록 동작한다.