관리 메뉴

웹개발자의 기지개

[Javascript,PHP] 카카오지도 에서 화살표 표시하기1 (DB에 GPS 좌표값 저장하기) 본문

javascript

[Javascript,PHP] 카카오지도 에서 화살표 표시하기1 (DB에 GPS 좌표값 저장하기)

http://portfolio.wonpaper.net 2024. 3. 26. 01:45

 

카카오 지도 API 가 잘 나와 있었다.

하지만 화살표만 꼭 집어서 좌표값을 땡껴 올 수 있는 방안이 찾아보니 없었다.

구글링해봐도 필자와 같이 답답한 마음을 토로하는 개발자 분들 글을 볼 수 있었다.

부족하지만 다른 동료 개발자 분들도 이 소스로 좌표값을 받아서 쉽게 DB에 저장하고 활용할 수 있도록 나름 정리해 보았다.

 

카카오지도상의 화살표는 Polygon 형태 다각형으로 위의 사진과 같이 그리면 만들 수 있다.

Polyline 이라는 선이 있기는한데, 이는 일반 선을 그릴때 쓴다.

 

위의 이미지를 보면 위쪽 이미지(화살표 그리는 지도) , 아래쪽 이미지(위쪽 지도에 그려진 화살표를 옮겨와서 DB에 저장하는 지도) 로 나뉘는데, 아쉽지만, 화살표를 다각형으로 찍어서 그리면 하나의 다각형만 찍어서 백엔드 처리가 된다.

 

 

[ 카카오API Drawing Libraray에서 데이터 얻기 ]

https://apis.map.kakao.com/web/sample/drawingGetData/

 

 

[ location.php]

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Drawing Library에서 데이터 얻기</title>
    <style>
.map_wrap {width: 100%;position: relative;}
.modes {position: absolute;top: 10px;left: 10px;z-index: 1;}
.getdata{position: absolute;top: 440px;left: 10px;z-index: 1;}
.getdata2{position: absolute;top: 820px;left: 10px;z-index: 1;}
#drawingMap, #map {width: 100%;height: 400px;}
#map {margin-top: 10px;}
</style>
 
  <script src="https://code.jquery.com/jquery-3.6.0.js"></script>
</head>
<body>
<div class="map_wrap">
    <div id="drawingMap"></div>
    <div id="map"></div> 
    <p class="modes">
<!--
        <button onclick="selectOverlay('MARKER')">마커</button>
        <button onclick="selectOverlay('POLYLINE')">선</button>
        <button onclick="selectOverlay('CIRCLE')">원</button>
        <button onclick="selectOverlay('RECTANGLE')">사각형</button>
-->
        <button onclick="selectOverlay('POLYGON')">다각형 (화살표) 그리기</button>
    </p>
 
 
    <p class="getdata">
        <button onclick="getDataFromDrawingMap()">좌표값 모두 가져오기</button>
    </p>
 
    <p class="getdata2">
        <button onclick="dbUpdate()">DB저장하기</button>
    </p>
 
</div>
 
<script type="text/javascript" src="//dapi.kakao.com/v2/maps/sdk.js?appkey=키값&libraries=services,clusterer,drawing"></script>
<script>
// Drawing Manager로 도형을 그릴 지도 div
var drawingMapContainer = document.getElementById('drawingMap'),
    drawingMap = { 
        center: new kakao.maps.LatLng(35.8715665189534128.601258980014), // 지도의 중심좌표
        level: 3 // 지도의 확대 레벨
    };
 
// 지도를 표시할 div와  지도 옵션으로  지도를 생성합니다
var drawingMap = new kakao.maps.Map(drawingMapContainer, drawingMap); 
 
var options = { // Drawing Manager를 생성할 때 사용할 옵션입니다
    map: drawingMap, // Drawing Manager로 그리기 요소를 그릴 map 객체입니다
    drawingMode: [ // Drawing Manager로 제공할 그리기 요소 모드입니다
        kakao.maps.drawing.OverlayType.MARKER,
        kakao.maps.drawing.OverlayType.POLYLINE,
        kakao.maps.drawing.OverlayType.RECTANGLE,
        kakao.maps.drawing.OverlayType.CIRCLE,
        kakao.maps.drawing.OverlayType.POLYGON
    ],
    // 사용자에게 제공할 그리기 가이드 툴팁입니다
    // 사용자에게 도형을 그릴때, 드래그할때, 수정할때 가이드 툴팁을 표시하도록 설정합니다
    guideTooltip: ['draw''drag''edit'], 
    markerOptions: { // 마커 옵션입니다 
        draggable: true// 마커를 그리고 나서 드래그 가능하게 합니다 
        removable: true // 마커를 삭제 할 수 있도록 x 버튼이 표시됩니다  
    },
    polylineOptions: { // 선 옵션입니다
        draggable: true// 그린 후 드래그가 가능하도록 설정합니다
        removable: true// 그린 후 삭제 할 수 있도록 x 버튼이 표시됩니다
        editable: true// 그린 후 수정할 수 있도록 설정합니다 
        strokeColor: '#39f'// 선 색
        hintStrokeStyle: 'dash'// 그리중 마우스를 따라다니는 보조선의 선 스타일
        hintStrokeOpacity: 0.5  // 그리중 마우스를 따라다니는 보조선의 투명도
    },
    rectangleOptions: {
        draggable: true,
        removable: true,
        editable: true,
        strokeColor: '#39f'// 외곽선 색
        fillColor: '#39f'// 채우기 색
        fillOpacity: 0.5 // 채우기색 투명도
    },
    circleOptions: {
        draggable: true,
        removable: true,
        editable: true,
        strokeColor: '#39f',
        fillColor: '#39f',
        fillOpacity: 0.5
    },
    polygonOptions: {
        draggable: true,
        removable: true,
        editable: true,
        strokeColor: '#39f',
        fillColor: '#39f',
        fillOpacity: 0.5,
        hintStrokeStyle: 'dash',
        hintStrokeOpacity: 0.5
    }
};
 
// 위에 작성한 옵션으로 Drawing Manager를 생성합니다
var manager = new kakao.maps.drawing.DrawingManager(options);
 
// 버튼 클릭 시 호출되는 핸들러 입니다
function selectOverlay(type) {
    // 그리기 중이면 그리기를 취소합니다
    manager.cancel();
 
    // 클릭한 그리기 요소 타입을 선택합니다
    manager.select(kakao.maps.drawing.OverlayType[type]);
}
 
// Drawing Manager에서 데이터를 가져와 도형을 표시할 아래쪽 지도 div
var mapContainer = document.getElementById('map'),
    mapOptions = { 
        center: new kakao.maps.LatLng(35.8715665189534128.601258980014), // 지도의 중심좌표
        level: 3 // 지도의 확대 레벨
    };
 
// 지도 div와 지도 옵션으로 지도를 생성합니다
var map = new kakao.maps.Map(mapContainer, mapOptions),
    overlays = []; // 지도에 그려진 도형을 담을 배열
 
// 가져오기 버튼을 클릭하면 호출되는 핸들러 함수입니다
// Drawing Manager로 그려진 객체 데이터를 가져와 아래 지도에 표시합니다
function getDataFromDrawingMap() {
    // Drawing Manager에서 그려진 데이터 정보를 가져옵니다 
    var data = manager.getData();
 
    // 아래 지도에 그려진 도형이 있다면 모두 지웁니다
    removeOverlays();
 
    // 지도에 가져온 데이터로 도형들을 그립니다
    drawMarker(data[kakao.maps.drawing.OverlayType.MARKER]);
    drawPolyline(data[kakao.maps.drawing.OverlayType.POLYLINE]);
    drawRectangle(data[kakao.maps.drawing.OverlayType.RECTANGLE]);
    drawCircle(data[kakao.maps.drawing.OverlayType.CIRCLE]);
    drawPolygon(data[kakao.maps.drawing.OverlayType.POLYGON]);
}
 
// 아래 지도에 그려진 도형이 있다면 모두 지웁니다
function removeOverlays() {
    var len = overlays.length, i = 0;
 
    for (; i < len; i++) {
        overlays[i].setMap(null);
    }
 
    overlays = [];
}
 
// Drawing Manager에서 가져온 데이터 중 마커를 아래 지도에 표시하는 함수입니다
function drawMarker(markers) {
    var len = markers.length, i = 0;
 
    for (; i < len; i++) {
        var marker = new kakao.maps.Marker({
            map: map, 
            position: new kakao.maps.LatLng(markers[i].y, markers[i].x), 
            zIndex: markers[i].zIndex
        });
 
        overlays.push(marker);
    }
}
 
// Drawing Manager에서 가져온 데이터 중 선을 아래 지도에 표시하는 함수입니다
function drawPolyline(lines) {
    var len = lines.length, i = 0;
 
    for (; i < len; i++) {
        var path = pointsToPath(lines[i].points);
        var style = lines[i].options;
        var polyline = new kakao.maps.Polyline({
            map: map,
            path: path,
            strokeColor: style.strokeColor,
            strokeOpacity: style.strokeOpacity,
            strokeStyle: style.strokeStyle,
            strokeWeight: style.strokeWeight
        });
 
        overlays.push(polyline);
    }
}
 
// Drawing Manager에서 가져온 데이터 중 사각형을 아래 지도에 표시하는 함수입니다
function drawRectangle(rects) {
    var len = rects.length, i = 0;
 
    for (; i < len; i++) {
        var style = rects[i].options;
        var rect = new kakao.maps.Rectangle({
            map: map, 
            bounds: new kakao.maps.LatLngBounds(
                new kakao.maps.LatLng(rects[i].sPoint.y, rects[i].sPoint.x),
                new kakao.maps.LatLng(rects[i].ePoint.y, rects[i].ePoint.x)
            ), 
            strokeColor: style.strokeColor,
            strokeOpacity: style.strokeOpacity,
            strokeStyle: style.strokeStyle,
            strokeWeight: style.strokeWeight,
            fillColor: style.fillColor,
            fillOpacity: style.fillOpacity
        });
 
        overlays.push(rect);
    }
}
 
// Drawing Manager에서 가져온 데이터 중 원을 아래 지도에 표시하는 함수입니다
function drawCircle(circles) {
    var len = circles.length, i = 0;
 
    for (; i < len; i++) {
        var style = circles[i].options;
        var circle = new kakao.maps.Circle({
            map: map, 
            center: new kakao.maps.LatLng(circles[i].center.y, circles[i].center.x), 
            radius: circles[i].radius,
            strokeColor: style.strokeColor,
            strokeOpacity: style.strokeOpacity,
            strokeStyle: style.strokeStyle,
            strokeWeight: style.strokeWeight,
            fillColor: style.fillColor,
            fillOpacity: style.fillOpacity
        });
 
        overlays.push(circle);
    }
}
 
// Drawing Manager에서 가져온 데이터 중 다각형을 아래 지도에 표시하는 함수입니다
function drawPolygon(polygons) {
    var len = polygons.length, i = 0;
 
    for (; i < len; i++) {
        var path = pointsToPath(polygons[i].points);
        var style = polygons[i].options;
        var polygon = new kakao.maps.Polygon({
            map: map,
            path: path,
            strokeColor: style.strokeColor,
            strokeOpacity: style.strokeOpacity,
            strokeStyle: style.strokeStyle,
            strokeWeight: style.strokeWeight,
            fillColor: style.fillColor,
            fillOpacity: style.fillOpacity
        });
 
        overlays.push(polygon);
    }
}
 
// Drawing Manager에서 가져온 데이터 중 
// 선과 다각형의 꼭지점 정보를 kakao.maps.LatLng객체로 생성하고 배열로 반환하는 함수입니다 
function pointsToPath(points) {
    var len = points.length
        path = [], 
        i = 0;
 
    for (; i < len; i++) { 
        var latlng = new kakao.maps.LatLng(points[i].y, points[i].x);
        path.push(latlng); 
 
        fnAddElement("f1","aX" + i,points[i].y);
        fnAddElement("f1","aY" + i,points[i].x);
    }
    
    fnAddElement("f1","aNum",len);
    return path;
}
 
 
// input hidden 태그만들기
function fnAddElement(fNm, nm, value) {
    var theForm = document.forms[fNm];
    if (theForm.elements[name]==null)
    {
        var input = document.createElement('input');
        input.type = 'hidden';
        input.name = nm;
        input.id = nm;
        input.value = value;
        theForm.appendChild(input);
    } else {
        $("#" + nm).val(value);
    }
}
 
// fnAddElement("f1","sample","1000");
 
function dbUpdate() {
    var form = document.f1;
    if (confirm("현재 상태대로 DB로 업데이트 하시겠습니까?"))
    {
        form.action = "location_ok.php";
        form.submit();
    }
}
</script>
 
<form name="f1" method="post">
</form>
 
</body>
</html>
cs

 

소스가 다소 길어서 어려울 수 있는데, 280라인에 fnAddElement 함수를

267 라인에서

fnAddElement("f1","aX" + i,points[i].y); 

fnAddElement("f1","aY" + i,points[i].x);

좌표점 개수만큼 for 문을 돌려서 input hidden 태그를 만드는게 핵심이다.

 

[ location_ok.php ] - 좌표값 넘기고 DB에 넣기 (필자는 간단히 PHP로 백엔드 처리를 하였다.)

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?
$aNum = $_POST['aNum'];
 
echo $aNum"개";
echo "<br><br>";
 
for ($i=0;$i<$aNum;$i++) {
    
    $aX = $_POST['aX'.$i];
    $aY = $_POST['aY'.$i];
 
    echo " aX".$i." : "$aX . " / aY" . $i . " : " . $aY . "<br>";
}
 
?>
cs

 

 

 

참고 : https://apis.map.kakao.com/web/sample/drawingToolbox/

참고 : https://apis.map.kakao.com/web/sample/drawingGetData/

참고 : https://doozzuri.tistory.com/entry/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EB%A1%9C-form%EC%97%90-input-%EC%B6%94%EA%B0%80%ED%95%98%EA%B8%B0

 

Comments