Showing
3 changed files
with
391 additions
and
28 deletions
README.md
0 → 100644
1 | +## Subject | ||
2 | +Kakao 지도 API를 이용한 여행 경로 추천 서비스 | ||
3 | +출발지와 도착지를 설정하면 사이 경로의 유명 관광지/음식점/카페 등을 카테고리 별로 반환 | ||
4 | +원하는 장소를 경유지로 추가하여 경로를 재검색 | ||
5 | + | ||
6 | +## How to build | ||
7 | +### npm | ||
8 | + | ||
9 | + ~$ npm install | ||
10 | + | ||
11 | +### Kakao 지도 API | ||
12 | +<https://apis.map.kakao.com/web/> | ||
13 | +카카오계정을 통해 APP KEY를 발급받은 후 views/main.ejs, views/search.ejs의 아래 부분에 추가 | ||
14 | +src = "//dapi.kakao.com/v2/maps/sdk.js?appkey=APPKEY&libraries=services" | ||
15 | + | ||
16 | +## How to use | ||
17 | +- 메인 페이지 지도상에서 출발지와 도착지를 선택하고 검색버튼 클릭 | ||
18 | +- 검색된 페이지에서 이동 경로에 있는 카테고리 별 장소(관광명소, 숙박, 카페, 음식점)를 검색 가능 | ||
19 | +- 지도 상에 마커와 인포윈도우를 통해 결과를 출력 | ||
20 | +- 원하는 경유지를 선택하여 경로 재검색 가능 | ||
21 | + | ||
22 | +## License | ||
23 | +MIT License | ||
24 | + | ||
25 | +Copyright (c) 2020 Jiwoo Choi | ||
26 | +Permission is hereby granted, free of charge, to any person | ||
27 | +obtaining a copy of this software and associated documentation | ||
28 | +files (the "Software"), to deal in the Software without | ||
29 | +restriction, including without limitation the rights to use, | ||
30 | +copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
31 | +copies of the Software, and to permit persons to whom the | ||
32 | +Software is furnished to do so, subject to the following conditions: | ||
33 | + | ||
34 | +The above copyright notice and this permission notice shall be | ||
35 | +included in all copies or substantial portions of the Software. | ||
36 | + | ||
37 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
38 | +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | ||
39 | +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
40 | +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | ||
41 | +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | ||
42 | +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
43 | +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
44 | +OTHER DEALINGS IN THE SOFTWARE. | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
... | @@ -14,8 +14,8 @@ | ... | @@ -14,8 +14,8 @@ |
14 | <script> | 14 | <script> |
15 | var mapContainer = document.getElementById('map'), // 지도를 표시할 div | 15 | var mapContainer = document.getElementById('map'), // 지도를 표시할 div |
16 | mapOption = { | 16 | mapOption = { |
17 | - center: new kakao.maps.LatLng(33.450701, 126.570667), | 17 | + center: new kakao.maps.LatLng(37.564213, 127.001698), |
18 | - level: 3 // 지도의 확대 레벨 | 18 | + level: 10 // 지도의 확대 레벨 |
19 | }; | 19 | }; |
20 | 20 | ||
21 | var map = new kakao.maps.Map(mapContainer, mapOption); // 지도를 생성합니다 | 21 | var map = new kakao.maps.Map(mapContainer, mapOption); // 지도를 생성합니다 |
... | @@ -39,7 +39,7 @@ var startDragSrc = 'https://t1.daumcdn.net/localimg/localimages/07/mapapidoc/red | ... | @@ -39,7 +39,7 @@ var startDragSrc = 'https://t1.daumcdn.net/localimg/localimages/07/mapapidoc/red |
39 | var startDragImage = new kakao.maps.MarkerImage(startDragSrc, startDragSize, startDragOption); | 39 | var startDragImage = new kakao.maps.MarkerImage(startDragSrc, startDragSize, startDragOption); |
40 | 40 | ||
41 | // 출발 마커가 표시될 위치입니다 | 41 | // 출발 마커가 표시될 위치입니다 |
42 | -var startPosition = new kakao.maps.LatLng(33.450701, 126.570667); | 42 | +var startPosition = new kakao.maps.LatLng(37.564213, 127.001698); |
43 | 43 | ||
44 | 44 | ||
45 | // 출발 마커를 생성합니다 | 45 | // 출발 마커를 생성합니다 |
... | @@ -83,7 +83,7 @@ var arriveDragSrc = 'https://t1.daumcdn.net/localimg/localimages/07/mapapidoc/bl | ... | @@ -83,7 +83,7 @@ var arriveDragSrc = 'https://t1.daumcdn.net/localimg/localimages/07/mapapidoc/bl |
83 | var arriveDragImage = new kakao.maps.MarkerImage(arriveDragSrc, arriveDragSize, arriveDragOption); | 83 | var arriveDragImage = new kakao.maps.MarkerImage(arriveDragSrc, arriveDragSize, arriveDragOption); |
84 | 84 | ||
85 | // 도착 마커가 표시될 위치입니다 | 85 | // 도착 마커가 표시될 위치입니다 |
86 | -var arrivePosition = new kakao.maps.LatLng(33.450701, 126.572667); | 86 | +var arrivePosition = new kakao.maps.LatLng(37.564213, 127.011698); |
87 | 87 | ||
88 | // 도착 마커를 생성합니다 | 88 | // 도착 마커를 생성합니다 |
89 | var arriveMarker = new kakao.maps.Marker({ | 89 | var arriveMarker = new kakao.maps.Marker({ | ... | ... |
... | @@ -2,13 +2,96 @@ | ... | @@ -2,13 +2,96 @@ |
2 | <html> | 2 | <html> |
3 | <head> | 3 | <head> |
4 | <meta charset="utf-8"> | 4 | <meta charset="utf-8"> |
5 | - <title>카테고리로 장소 검색하기</title> | 5 | + <title>검색 결과</title> |
6 | + <style> | ||
7 | +.map_wrap, .map_wrap * {margin:0; padding:0;font-family:'Malgun Gothic',dotum,'돋움',sans-serif;font-size:12px;} | ||
8 | +.map_wrap {position:relative;width:100%;height:800px;} | ||
9 | +#category {position:absolute;top:10px;left:10px;border-radius: 5px; border:1px solid #909090;box-shadow: 0 1px 1px rgba(0, 0, 0, 0.4);background: #fff;overflow: hidden;z-index: 2;} | ||
10 | +#category li {float:left;list-style: none;width:50px;px;border-right:1px solid #acacac;padding:6px 0;text-align: center; cursor: pointer;} | ||
11 | +#category li.on {background: #eee;} | ||
12 | +#category li:hover {background: #ffe6e6;border-left:1px solid #acacac;margin-left: -1px;} | ||
13 | +#category li:last-child{margin-right:0;border-right:0;} | ||
14 | +#category li span {display: block;margin:0 auto 3px;width:27px;height: 28px;} | ||
15 | +#category li .category_bg {background:url(https://t1.daumcdn.net/localimg/localimages/07/mapapidoc/places_category.png) no-repeat;} | ||
16 | +#category li .bank {background-position: -10px 0;} | ||
17 | +#category li .mart {background-position: -10px -36px;} | ||
18 | +#category li .pharmacy {background-position: -10px -72px;} | ||
19 | +#category li .oil {background-position: -10px -108px;} | ||
20 | +#category li .cafe {background-position: -10px -144px;} | ||
21 | +#category li .store {background-position: -10px -180px;} | ||
22 | +#category li.on .category_bg {background-position-x:-46px;} | ||
23 | +.placeinfo_wrap {position:absolute;bottom:28px;left:-150px;width:300px;} | ||
24 | +.placeinfo {position:relative;width:100%;border-radius:6px;border: 1px solid #ccc;border-bottom:2px solid #ddd;padding-bottom: 10px;background: #fff;} | ||
25 | +.placeinfo:nth-of-type(n) {border:0; box-shadow:0px 1px 2px #888;} | ||
26 | +.placeinfo_wrap .after {content:'';position:relative;margin-left:-12px;left:50%;width:22px;height:12px;background:url('https://t1.daumcdn.net/localimg/localimages/07/mapapidoc/vertex_white.png')} | ||
27 | +.placeinfo a, .placeinfo a:hover, .placeinfo a:active{color:#fff;text-decoration: none;} | ||
28 | +.placeinfo a, .placeinfo span {display: block;text-overflow: ellipsis;overflow: hidden;white-space: nowrap;} | ||
29 | +.placeinfo span {margin:5px 5px 0 5px;cursor: default;font-size:13px;} | ||
30 | +.placeinfo .title {font-weight: bold; font-size:14px;border-radius: 6px 6px 0 0;margin: -1px -1px 0 -1px;padding:10px; color: #fff;background: #d95050;background: #d95050 url(https://t1.daumcdn.net/localimg/localimages/07/mapapidoc/arrow_white.png) no-repeat right 14px center;} | ||
31 | +.placeinfo .tel {color:#0f7833;} | ||
32 | +.placeinfo .jibun {color:#999;font-size:11px;margin-top:0;} | ||
6 | 33 | ||
34 | + | ||
35 | +.map_wrap a, .map_wrap a:hover, .map_wrap a:active{color:#000;text-decoration: none;} | ||
36 | +#menu_wrap {position:absolute;top:0;left:1600px;bottom:0;width:250px;margin:10px 0 30px 10px;padding:5px;overflow-y:auto;background:rgba(255, 255, 255, 0.7);z-index: 1;font-size:12px;border-radius: 10px;} | ||
37 | +.bg_white {background:#fff;} | ||
38 | +#placesList li {list-style: none;} | ||
39 | +#placesList .item {position:relative;border-bottom:1px solid #888;overflow: hidden;cursor: pointer;min-height: 65px;} | ||
40 | +#placesList .item span {display: block;margin-top:4px;} | ||
41 | +#placesList .item h5, #placesList .item .info {text-overflow: ellipsis;overflow: hidden;white-space: nowrap;} | ||
42 | +#placesList .item .info{padding:10px 0 10px 55px;} | ||
43 | +#placesList .info .gray {color:#8a8a8a;} | ||
44 | +#placesList .info .jibun {padding-left:26px;background:url(https://t1.daumcdn.net/localimg/localimages/07/mapapidoc/places_jibun.png) no-repeat;} | ||
45 | +#placesList .info .tel {color:#009900;} | ||
46 | +#placesList .item .markerbg {float:left;position:absolute;width:36px; height:37px;margin:10px 0 0 10px;background:url(https://t1.daumcdn.net/localimg/localimages/07/mapapidoc/marker_number_blue.png) no-repeat;} | ||
47 | +#placesList .item .marker_1 {background-position: 0 -10px;} | ||
48 | +#placesList .item .marker_2 {background-position: 0 -56px;} | ||
49 | +#placesList .item .marker_3 {background-position: 0 -102px} | ||
50 | +#placesList .item .marker_4 {background-position: 0 -148px;} | ||
51 | +#placesList .item .marker_5 {background-position: 0 -194px;} | ||
52 | +#placesList .item .marker_6 {background-position: 0 -240px;} | ||
53 | +#placesList .item .marker_7 {background-position: 0 -286px;} | ||
54 | +#placesList .item .marker_8 {background-position: 0 -332px;} | ||
55 | +#placesList .item .marker_9 {background-position: 0 -378px;} | ||
56 | +#placesList .item .marker_10 {background-position: 0 -423px;} | ||
57 | +#placesList .item .marker_11 {background-position: 0 -470px;} | ||
58 | +#placesList .item .marker_12 {background-position: 0 -516px;} | ||
59 | +#placesList .item .marker_13 {background-position: 0 -562px;} | ||
60 | +#placesList .item .marker_14 {background-position: 0 -608px;} | ||
61 | +#placesList .item .marker_15 {background-position: 0 -654px;} | ||
62 | +#pagination {margin:10px auto;text-align: center;} | ||
63 | +#pagination a {display:inline-block;margin-right:10px;} | ||
64 | +#pagination .on {font-weight: bold; cursor: default;color:#777;} | ||
65 | +</style> | ||
7 | </head> | 66 | </head> |
8 | <body> | 67 | <body> |
9 | 68 | ||
10 | -<div id="map" style="width:100%;height:800px;"></div> | 69 | +<div class="map_wrap"> |
11 | - | 70 | + <div id="map" style="width:100%;height:800px;position:relative;overflow:hidden;"></div> |
71 | + <ul id="category"> | ||
72 | + <li id="AT4" data-order="0"> | ||
73 | + <span class="category_bg oil"></span> | ||
74 | + 관광지 | ||
75 | + </li> | ||
76 | + <li id="AD5" data-order="1"> | ||
77 | + <span class="category_bg mart"></span> | ||
78 | + 숙박 | ||
79 | + </li> | ||
80 | + <li id="CE7" data-order="2"> | ||
81 | + <span class="category_bg cafe"></span> | ||
82 | + 카페 | ||
83 | + </li> | ||
84 | + <li id="FD6" data-order="3"> | ||
85 | + <span class="category_bg store"></span> | ||
86 | + 음식점 | ||
87 | + </li> | ||
88 | + </ul> | ||
89 | + <div id="menu_wrap" class="bg_white"> | ||
90 | + <hr> | ||
91 | + <ul id="placesList"></ul> | ||
92 | + <div id="pagination"></div> | ||
93 | + </div> | ||
94 | +</div> | ||
12 | <script type="text/javascript" src="//dapi.kakao.com/v2/maps/sdk.js?appkey=비밀&libraries=services"></script> | 95 | <script type="text/javascript" src="//dapi.kakao.com/v2/maps/sdk.js?appkey=비밀&libraries=services"></script> |
13 | <script> | 96 | <script> |
14 | var Request = function() { | 97 | var Request = function() { |
... | @@ -31,47 +114,283 @@ var startx = request.getParameter('startx'); | ... | @@ -31,47 +114,283 @@ var startx = request.getParameter('startx'); |
31 | var starty = request.getParameter('starty'); | 114 | var starty = request.getParameter('starty'); |
32 | var endx = request.getParameter('endx'); | 115 | var endx = request.getParameter('endx'); |
33 | var endy = request.getParameter('endy'); | 116 | var endy = request.getParameter('endy'); |
34 | -// 마커를 클릭하면 장소명을 표출할 인포윈도우 입니다 | 117 | + |
35 | -var infowindow = new kakao.maps.InfoWindow({zIndex:1}); | 118 | +var sw = new kakao.maps.LatLng(startx, endy), |
119 | + ne = new kakao.maps.LatLng(endx, starty); | ||
120 | + | ||
121 | +var bs = new kakao.maps.LatLngBounds(sw, ne); | ||
122 | + | ||
123 | +var placeOverlay = new kakao.maps.CustomOverlay({zIndex:1}), | ||
124 | + contentNode = document.createElement('div'), // 커스텀 오버레이의 컨텐츠 엘리먼트 입니다 | ||
125 | + markers = [], // 마커를 담을 배열입니다 | ||
126 | + currCategory = ''; // 현재 선택된 카테고리를 가지고 있을 변수입니다 | ||
36 | 127 | ||
37 | var mapContainer = document.getElementById('map'), // 지도를 표시할 div | 128 | var mapContainer = document.getElementById('map'), // 지도를 표시할 div |
38 | mapOption = { | 129 | mapOption = { |
39 | center: new kakao.maps.LatLng(endx, endy), // 지도의 중심좌표 | 130 | center: new kakao.maps.LatLng(endx, endy), // 지도의 중심좌표 |
40 | - level: 5 // 지도의 확대 레벨 | 131 | + level: 8 // 지도의 확대 레벨 |
41 | }; | 132 | }; |
42 | 133 | ||
43 | // 지도를 생성합니다 | 134 | // 지도를 생성합니다 |
44 | var map = new kakao.maps.Map(mapContainer, mapOption); | 135 | var map = new kakao.maps.Map(mapContainer, mapOption); |
45 | 136 | ||
46 | // 장소 검색 객체를 생성합니다 | 137 | // 장소 검색 객체를 생성합니다 |
47 | -var ps = new kakao.maps.services.Places(map); | 138 | +var ps = new kakao.maps.services.Places(); |
48 | 139 | ||
49 | -// 카테고리로 유명관광지를 검색합니다 | 140 | +// 지도에 idle 이벤트를 등록합니다 |
50 | -ps.categorySearch('AT4', placesSearchCB, {useMapBounds:true}); | 141 | +kakao.maps.event.addListener(map, 'idle', searchPlaces); |
51 | 142 | ||
52 | -// 키워드 검색 완료 시 호출되는 콜백함수 입니다 | 143 | +// 커스텀 오버레이의 컨텐츠 노드에 css class를 추가합니다 |
53 | -function placesSearchCB (data, status, pagination) { | 144 | +contentNode.className = 'placeinfo_wrap'; |
54 | - if (status === kakao.maps.services.Status.OK) { | 145 | + |
55 | - for (var i=0; i<data.length; i++) { | 146 | +// 커스텀 오버레이의 컨텐츠 노드에 mousedown, touchstart 이벤트가 발생했을때 |
56 | - displayMarker(data[i]); | 147 | +// 지도 객체에 이벤트가 전달되지 않도록 이벤트 핸들러로 kakao.maps.event.preventMap 메소드를 등록합니다 |
148 | +addEventHandle(contentNode, 'mousedown', kakao.maps.event.preventMap); | ||
149 | +addEventHandle(contentNode, 'touchstart', kakao.maps.event.preventMap); | ||
150 | + | ||
151 | +// 커스텀 오버레이 컨텐츠를 설정합니다 | ||
152 | +placeOverlay.setContent(contentNode); | ||
153 | + | ||
154 | +// 각 카테고리에 클릭 이벤트를 등록합니다 | ||
155 | +addCategoryClickEvent(); | ||
156 | + | ||
157 | +// 엘리먼트에 이벤트 핸들러를 등록하는 함수입니다 | ||
158 | +function addEventHandle(target, type, callback) { | ||
159 | + if (target.addEventListener) { | ||
160 | + target.addEventListener(type, callback); | ||
161 | + } else { | ||
162 | + target.attachEvent('on' + type, callback); | ||
57 | } | 163 | } |
164 | +} | ||
165 | + | ||
166 | +// 카테고리 검색을 요청하는 함수입니다 | ||
167 | +function searchPlaces() { | ||
168 | + if (!currCategory) { | ||
169 | + return; | ||
170 | + } | ||
171 | + | ||
172 | + // 커스텀 오버레이를 숨깁니다 | ||
173 | + placeOverlay.setMap(null); | ||
174 | + | ||
175 | + removeMarker(); | ||
176 | + // 지도에 표시되고 있는 마커를 제거합니다 | ||
177 | + | ||
178 | + ps.categorySearch(currCategory, placesSearchCB, {bounds : bs}); | ||
179 | +} | ||
180 | + | ||
181 | +// 장소검색이 완료됐을 때 호출되는 콜백함수 입니다 | ||
182 | +function placesSearchCB(data, status, pagination) { | ||
183 | + if (status === kakao.maps.services.Status.OK) { | ||
184 | + | ||
185 | + // 정상적으로 검색이 완료됐으면 지도에 마커를 표출합니다 | ||
186 | + displayPlaces(data); | ||
187 | + displayPagination(pagination); | ||
188 | + } else if (status === kakao.maps.services.Status.ZERO_RESULT) { | ||
189 | + // 검색결과가 없는경우 해야할 처리가 있다면 이곳에 작성해 주세요 | ||
190 | + alert('검색 결과가 존재하지 않습니다.'); | ||
191 | + return; | ||
192 | + | ||
193 | + } else if (status === kakao.maps.services.Status.ERROR) { | ||
194 | + // 에러로 인해 검색결과가 나오지 않은 경우 해야할 처리가 있다면 이곳에 작성해 주세요 | ||
195 | + alert('검색 결과 중 오류가 발생했습니다.'); | ||
196 | + return; | ||
58 | } | 197 | } |
59 | } | 198 | } |
60 | 199 | ||
61 | -// 지도에 마커를 표시하는 함수입니다 | 200 | +// 지도에 마커를 표출하는 함수입니다 |
62 | -function displayMarker(place) { | 201 | +function displayPlaces(places) { |
202 | + | ||
203 | + var listEl = document.getElementById('placesList'), | ||
204 | + menuEl = document.getElementById('menu_wrap'), | ||
205 | + fragment = document.createDocumentFragment(), | ||
206 | + listStr = ''; | ||
207 | + removeAllChildNods(listEl); | ||
208 | + removeMarker(); | ||
209 | + // 몇번째 카테고리가 선택되어 있는지 얻어옵니다 | ||
210 | + // 이 순서는 스프라이트 이미지에서의 위치를 계산하는데 사용됩니다 | ||
211 | + var order = document.getElementById(currCategory).getAttribute('data-order'); | ||
212 | + | ||
213 | + for ( var i=0; i<places.length; i++ ) { | ||
214 | + var placePosition = new kakao.maps.LatLng(places[i].y, places[i].x); | ||
215 | + | ||
63 | // 마커를 생성하고 지도에 표시합니다 | 216 | // 마커를 생성하고 지도에 표시합니다 |
64 | - var marker = new kakao.maps.Marker({ | 217 | + var marker = addMarker(placePosition, order); |
65 | - map: map, | 218 | + var itemEl = getListItem(i, places[i]); |
66 | - position: new kakao.maps.LatLng(place.y, place.x) | 219 | + // 마커와 검색결과 항목을 클릭 했을 때 |
220 | + // 장소정보를 표출하도록 클릭 이벤트를 등록합니다 | ||
221 | + (function(marker, place) { | ||
222 | + kakao.maps.event.addListener(marker, 'click', function() { | ||
223 | + displayPlaceInfo(place); | ||
67 | }); | 224 | }); |
225 | + })(marker, places[i]); | ||
226 | + fragment.appendChild(itemEl); | ||
227 | + } | ||
228 | + listEl.appendChild(fragment); | ||
229 | + menuEl.scrollTop = 0; | ||
230 | +} | ||
68 | 231 | ||
69 | - // 마커에 클릭이벤트를 등록합니다 | 232 | +function getListItem(index, places) { |
70 | - kakao.maps.event.addListener(marker, 'click', function() { | 233 | + |
71 | - // 마커를 클릭하면 장소명이 인포윈도우에 표출됩니다 | 234 | + var el = document.createElement('li'), |
72 | - infowindow.setContent('<div style="padding:5px;font-size:12px;">' + place.place_name + '</div>'); | 235 | + itemStr = '<span class="markerbg marker_' + (index+1) + '"></span>' + |
73 | - infowindow.open(map, marker); | 236 | + '<div class="info">' + |
237 | + ' <h5>' + places.place_name + '</h5>'; | ||
238 | + | ||
239 | + if (places.road_address_name) { | ||
240 | + itemStr += ' <span>' + places.road_address_name + '</span>' + | ||
241 | + ' <span class="jibun gray">' + places.address_name + '</span>'; | ||
242 | + } | ||
243 | + else { | ||
244 | + itemStr += ' <span>' + places.address_name + '</span>'; | ||
245 | + } | ||
246 | + | ||
247 | + itemStr += ' <span class="tel">' + places.phone + '</span>' + | ||
248 | + '</div>'; | ||
249 | + | ||
250 | + el.innerHTML = itemStr; | ||
251 | + el.className = 'item'; | ||
252 | + | ||
253 | + return el; | ||
254 | +} | ||
255 | + | ||
256 | +// 마커를 생성하고 지도 위에 마커를 표시하는 함수입니다 | ||
257 | +function addMarker(position, order) { | ||
258 | + var imageSrc = 'https://t1.daumcdn.net/localimg/localimages/07/mapapidoc/places_category.png', // 마커 이미지 url, 스프라이트 이미지를 씁니다 | ||
259 | + imageSize = new kakao.maps.Size(27, 28), // 마커 이미지의 크기 | ||
260 | + imgOptions = { | ||
261 | + spriteSize : new kakao.maps.Size(72, 208), // 스프라이트 이미지의 크기 | ||
262 | + spriteOrigin : new kakao.maps.Point(46, (order*36)), // 스프라이트 이미지 중 사용할 영역의 좌상단 좌표 | ||
263 | + offset: new kakao.maps.Point(11, 28) // 마커 좌표에 일치시킬 이미지 내에서의 좌표 | ||
264 | + }, | ||
265 | + markerImage = new kakao.maps.MarkerImage(imageSrc, imageSize, imgOptions), | ||
266 | + marker = new kakao.maps.Marker({ | ||
267 | + position: position, // 마커의 위치 | ||
268 | + image: markerImage | ||
74 | }); | 269 | }); |
270 | + | ||
271 | + marker.setMap(map); // 지도 위에 마커를 표출합니다 | ||
272 | + markers.push(marker); // 배열에 생성된 마커를 추가합니다 | ||
273 | + | ||
274 | + return marker; | ||
275 | +} | ||
276 | + | ||
277 | +// 지도 위에 표시되고 있는 마커를 모두 제거합니다 | ||
278 | +function removeMarker() { | ||
279 | + for ( var i = 0; i < markers.length; i++ ) { | ||
280 | + markers[i].setMap(null); | ||
281 | + } | ||
282 | + markers = []; | ||
283 | +} | ||
284 | + | ||
285 | +// 클릭한 마커에 대한 장소 상세정보를 커스텀 오버레이로 표시하는 함수입니다 | ||
286 | +function displayPlaceInfo (place) { | ||
287 | + var content = '<div class="placeinfo">' + | ||
288 | + ' <a class="title" href="' + place.place_url + '" target="_blank" title="' + place.place_name + '">' + place.place_name + '</a>'; | ||
289 | + | ||
290 | + if (place.road_address_name) { | ||
291 | + content += ' <span title="' + place.road_address_name + '">' + place.road_address_name + '</span>' + | ||
292 | + ' <span class="jibun" title="' + place.address_name + '">(지번 : ' + place.address_name + ')</span>'; | ||
293 | + } else { | ||
294 | + content += ' <span title="' + place.address_name + '">' + place.address_name + '</span>'; | ||
295 | + } | ||
296 | + | ||
297 | + content += ' <span class="tel">' + place.phone + '</span>' + | ||
298 | + '</div>' + | ||
299 | + '<div class="after"></div>'; | ||
300 | + | ||
301 | + contentNode.innerHTML = content; | ||
302 | + placeOverlay.setPosition(new kakao.maps.LatLng(place.y, place.x)); | ||
303 | + placeOverlay.setMap(map); | ||
304 | +} | ||
305 | + | ||
306 | +// 검색결과 목록 하단에 페이지번호를 표시는 함수입니다 | ||
307 | +function displayPagination(pagination) { | ||
308 | + var paginationEl = document.getElementById('pagination'), | ||
309 | + fragment = document.createDocumentFragment(), | ||
310 | + i; | ||
311 | + | ||
312 | + // 기존에 추가된 페이지번호를 삭제합니다 | ||
313 | + while (paginationEl.hasChildNodes()) { | ||
314 | + paginationEl.removeChild (paginationEl.lastChild); | ||
315 | + } | ||
316 | + | ||
317 | + for (i=1; i<=pagination.last; i++) { | ||
318 | + var el = document.createElement('a'); | ||
319 | + el.href = "#"; | ||
320 | + el.innerHTML = i; | ||
321 | + | ||
322 | + if (i===pagination.current) { | ||
323 | + el.className = 'on'; | ||
324 | + } else { | ||
325 | + el.onclick = (function(i) { | ||
326 | + return function() { | ||
327 | + pagination.gotoPage(i); | ||
328 | + } | ||
329 | + })(i); | ||
330 | + } | ||
331 | + | ||
332 | + fragment.appendChild(el); | ||
333 | + } | ||
334 | + paginationEl.appendChild(fragment); | ||
335 | +} | ||
336 | + | ||
337 | +// 검색결과 목록 또는 마커를 클릭했을 때 호출되는 함수입니다 | ||
338 | +// 인포윈도우에 장소명을 표시합니다 | ||
339 | +function displayInfowindow(marker, title) { | ||
340 | + var content = '<div style="padding:5px;z-index:1;">' + title + '</div>'; | ||
341 | + | ||
342 | + infowindow.setContent(content); | ||
343 | + infowindow.open(map, marker); | ||
344 | +} | ||
345 | + | ||
346 | + // 검색결과 목록의 자식 Element를 제거하는 함수입니다 | ||
347 | + function removeAllChildNods(el) { | ||
348 | + while (el.hasChildNodes()) { | ||
349 | + el.removeChild (el.lastChild); | ||
350 | + } | ||
351 | +} | ||
352 | + | ||
353 | +// 각 카테고리에 클릭 이벤트를 등록합니다 | ||
354 | +function addCategoryClickEvent() { | ||
355 | + var category = document.getElementById('category'), | ||
356 | + children = category.children; | ||
357 | + | ||
358 | + for (var i=0; i<children.length; i++) { | ||
359 | + children[i].onclick = onClickCategory; | ||
360 | + } | ||
361 | +} | ||
362 | + | ||
363 | +// 카테고리를 클릭했을 때 호출되는 함수입니다 | ||
364 | +function onClickCategory() { | ||
365 | + var id = this.id, | ||
366 | + className = this.className; | ||
367 | + | ||
368 | + placeOverlay.setMap(null); | ||
369 | + | ||
370 | + if (className === 'on') { | ||
371 | + currCategory = ''; | ||
372 | + changeCategoryClass(); | ||
373 | + removeMarker(); | ||
374 | + } else { | ||
375 | + currCategory = id; | ||
376 | + changeCategoryClass(this); | ||
377 | + searchPlaces(); | ||
378 | + } | ||
379 | +} | ||
380 | + | ||
381 | +// 클릭된 카테고리에만 클릭된 스타일을 적용하는 함수입니다 | ||
382 | +function changeCategoryClass(el) { | ||
383 | + var category = document.getElementById('category'), | ||
384 | + children = category.children, | ||
385 | + i; | ||
386 | + | ||
387 | + for ( i=0; i<children.length; i++ ) { | ||
388 | + children[i].className = ''; | ||
389 | + } | ||
390 | + | ||
391 | + if (el) { | ||
392 | + el.className = 'on'; | ||
393 | + } | ||
75 | } | 394 | } |
76 | </script> | 395 | </script> |
77 | </body> | 396 | </body> | ... | ... |
-
Please register or login to post a comment