임승현

Enable to Search the Theater by Keyword

1 +const express = require("express");
2 +const app = express();
3 +const bodyParser = require('body-parser');
4 +const request = require("request");
5 +const router = express.Router();
6 +
7 +let kakaoOptions = {
8 + url : "https://dapi.kakao.com/v2/local/search/keyword",
9 + method : "GET",
10 + headers : {
11 + 'Authorization': 'KakaoAK 56e51abe725086bc9db03da986e47fed'
12 + },
13 + qs: {
14 + 'query': 'CGV 광명',
15 + //'category_group_code' : 'CT1',
16 + 'size' : 5
17 + },
18 + encoding : 'UTF-8'
19 +}
20 +
21 +request(kakaoOptions, function (err, res, body) {
22 + theater_list = JSON.parse(body).documents;
23 + if(!err && res.statusCode == 200){
24 + theater_list.forEach(info => {
25 + if(info.category_name.endsWith("CJCGV"))
26 + console.log(info.place_name + " : " + info.place_url);
27 + });
28 + }
29 +})
30 +
31 +module.exports = router;
...\ No newline at end of file ...\ No newline at end of file
1 +{
2 + "name": "test01",
3 + "version": "1.0.0",
4 + "description": "",
5 + "main": "index.js",
6 + "scripts": {
7 + "test": "echo \"Error: no test specified\" && exit 1"
8 + },
9 + "author": "",
10 + "license": "ISC",
11 + "dependencies": {
12 + "body-parser": "^1.17.1",
13 + "express": "^4.15.2",
14 + "express-session": "^1.15.2",
15 + "java": "^16.0.1",
16 + "request" : "^2.88.2"
17 + }
18 + }
...\ No newline at end of file ...\ No newline at end of file
1 +module.exports= {
2 + html: function(title,style,list,body,control){
3 + return `
4 + <!doctype html>
5 + <html>
6 + <head>
7 + <title>WEB - ${title}</title>
8 + <meta charset="utf-8">
9 + </head>
10 + <body>
11 + <h1><a href="/">WEB</a></h1>
12 + <div id="map" style=${style}></div>
13 + ${list}
14 + ${control}
15 + ${body}
16 + <p></p>
17 + </body>
18 + </html>
19 + `;
20 + }
21 +}
...\ No newline at end of file ...\ No newline at end of file
1 +<!DOCTYPE html>
2 +<html>
3 +<head>
4 + <meta charset="utf-8">
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 a, .map_wrap a:hover, .map_wrap a:active{color:#000;text-decoration: none;}
9 + .map_wrap {position:relative;width:100%;height:500px;}
10 + #menu_wrap {position:absolute;top:0;left:0;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;}
11 + .bg_white {background:#fff;}
12 + #menu_wrap hr {display: block; height: 1px;border: 0; border-top: 2px solid #5F5F5F;margin:3px 0;}
13 + #menu_wrap .option{text-align: center;}
14 + #menu_wrap .option p {margin:10px 0;}
15 + #menu_wrap .option button {margin-left:5px;}
16 + #placesList li {list-style: none;}
17 + #placesList .item {position:relative;border-bottom:1px solid #888;overflow: hidden;cursor: pointer;min-height: 65px;}
18 + #placesList .item span {display: block;margin-top:4px;}
19 + #placesList .item h5, #placesList .item .info {text-overflow: ellipsis;overflow: hidden;white-space: nowrap;}
20 + #placesList .item .info{padding:10px 0 10px 55px;}
21 + #placesList .info .gray {color:#8a8a8a;}
22 + #placesList .info .jibun {padding-left:26px;background:url(https://t1.daumcdn.net/localimg/localimages/07/mapapidoc/places_jibun.png) no-repeat;}
23 + #placesList .info .tel {color:#009900;}
24 + #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;}
25 + #placesList .item .marker_1 {background-position: 0 -10px;}
26 + #placesList .item .marker_2 {background-position: 0 -56px;}
27 + #placesList .item .marker_3 {background-position: 0 -102px}
28 + #placesList .item .marker_4 {background-position: 0 -148px;}
29 + #placesList .item .marker_5 {background-position: 0 -194px;}
30 + #placesList .item .marker_6 {background-position: 0 -240px;}
31 + #placesList .item .marker_7 {background-position: 0 -286px;}
32 + #placesList .item .marker_8 {background-position: 0 -332px;}
33 + #placesList .item .marker_9 {background-position: 0 -378px;}
34 + #placesList .item .marker_10 {background-position: 0 -423px;}
35 + #placesList .item .marker_11 {background-position: 0 -470px;}
36 + #placesList .item .marker_12 {background-position: 0 -516px;}
37 + #placesList .item .marker_13 {background-position: 0 -562px;}
38 + #placesList .item .marker_14 {background-position: 0 -608px;}
39 + #placesList .item .marker_15 {background-position: 0 -654px;}
40 + #pagination {margin:10px auto;text-align: center;}
41 + #pagination a {display:inline-block;margin-right:10px;}
42 + #pagination .on {font-weight: bold; cursor: default;color:#777;}
43 + </style>
44 +</head>
45 +<body>
46 +<div class="map_wrap">
47 + <div id="map" style="width:100%;height:100%;position:relative;overflow:hidden;"></div>
48 +
49 + <div id="menu_wrap" class="bg_white">
50 + <div class="option">
51 + <div>
52 + <form onsubmit="searchPlaces(); return false;">
53 + 키워드 : <input type="text" value="이태원 맛집" id="keyword" size="15">
54 + <button type="submit">검색하기</button>
55 + </form>
56 + </div>
57 + </div>
58 + <hr>
59 + <ul id="placesList"></ul>
60 + <div id="pagination"></div>
61 + </div>
62 +</div>
63 +
64 +<script type="text/javascript" src="//dapi.kakao.com/v2/maps/sdk.js?appkey= c48bde8b1f66c569193a37cbc58d1c87&libraries=services"></script>
65 +<script>
66 + // 마커를 담을 배열입니다
67 + var markers = [];
68 +
69 + var mapContainer = document.getElementById('map'), // 지도를 표시할 div
70 + mapOption = {
71 + center: new kakao.maps.LatLng(37.566826, 126.9786567), // 지도의 중심좌표
72 + level: 3 // 지도의 확대 레벨
73 + };
74 +
75 + // 지도를 생성합니다
76 + var map = new kakao.maps.Map(mapContainer, mapOption);
77 +
78 + // 장소 검색 객체를 생성합니다
79 + var ps = new kakao.maps.services.Places();
80 +
81 + // 검색 결과 목록이나 마커를 클릭했을 때 장소명을 표출할 인포윈도우를 생성합니다
82 + var infowindow = new kakao.maps.InfoWindow({zIndex:1});
83 +
84 + // 키워드로 장소를 검색합니다
85 + searchPlaces();
86 +
87 + // 키워드 검색을 요청하는 함수입니다
88 + function searchPlaces() {
89 +
90 + var keyword = document.getElementById('keyword').value;
91 +
92 + if (!keyword.replace(/^\s+|\s+$/g, '')) {
93 + alert('키워드를 입력해주세요!');
94 + return false;
95 + }
96 +
97 + // 장소검색 객체를 통해 키워드로 장소검색을 요청합니다
98 + ps.keywordSearch( keyword, placesSearchCB);
99 + }
100 +
101 + // 장소검색이 완료됐을 때 호출되는 콜백함수 입니다
102 + function placesSearchCB(data, status, pagination) {
103 + if (status === kakao.maps.services.Status.OK) {
104 +
105 + // 정상적으로 검색이 완료됐으면
106 + // 검색 목록과 마커를 표출합니다
107 + displayPlaces(data);
108 +
109 + // 페이지 번호를 표출합니다
110 + displayPagination(pagination);
111 +
112 + } else if (status === kakao.maps.services.Status.ZERO_RESULT) {
113 +
114 + alert('검색 결과가 존재하지 않습니다.');
115 + return;
116 +
117 + } else if (status === kakao.maps.services.Status.ERROR) {
118 +
119 + alert('검색 결과 중 오류가 발생했습니다.');
120 + return;
121 +
122 + }
123 + }
124 +
125 + // 검색 결과 목록과 마커를 표출하는 함수입니다
126 + function displayPlaces(places) {
127 +
128 + var listEl = document.getElementById('placesList'),
129 + menuEl = document.getElementById('menu_wrap'),
130 + fragment = document.createDocumentFragment(),
131 + bounds = new kakao.maps.LatLngBounds(),
132 + listStr = '';
133 +
134 + // 검색 결과 목록에 추가된 항목들을 제거합니다
135 + removeAllChildNods(listEl);
136 +
137 + // 지도에 표시되고 있는 마커를 제거합니다
138 + removeMarker();
139 +
140 + for ( var i=0; i<places.length; i++ ) {
141 +
142 + // 마커를 생성하고 지도에 표시합니다
143 + var placePosition = new kakao.maps.LatLng(places[i].y, places[i].x),
144 + marker = addMarker(placePosition, i),
145 + itemEl = getListItem(i, places[i]); // 검색 결과 항목 Element를 생성합니다
146 +
147 + // 검색된 장소 위치를 기준으로 지도 범위를 재설정하기위해
148 + // LatLngBounds 객체에 좌표를 추가합니다
149 + bounds.extend(placePosition);
150 +
151 + // 마커와 검색결과 항목에 mouseover 했을때
152 + // 해당 장소에 인포윈도우에 장소명을 표시합니다
153 + // mouseout 했을 때는 인포윈도우를 닫습니다
154 + (function(marker, title) {
155 + kakao.maps.event.addListener(marker, 'mouseover', function() {
156 + displayInfowindow(marker, title);
157 + });
158 +
159 + kakao.maps.event.addListener(marker, 'mouseout', function() {
160 + infowindow.close();
161 + });
162 +
163 + itemEl.onmouseover = function () {
164 + displayInfowindow(marker, title);
165 + };
166 +
167 + itemEl.onmouseout = function () {
168 + infowindow.close();
169 + };
170 + })(marker, places[i].place_name);
171 +
172 + fragment.appendChild(itemEl);
173 + }
174 +
175 + // 검색결과 항목들을 검색결과 목록 Element에 추가합니다
176 + listEl.appendChild(fragment);
177 + menuEl.scrollTop = 0;
178 +
179 + // 검색된 장소 위치를 기준으로 지도 범위를 재설정합니다
180 + map.setBounds(bounds);
181 + }
182 +
183 + // 검색결과 항목을 Element로 반환하는 함수입니다
184 + function getListItem(index, places) {
185 +
186 + var el = document.createElement('li'),
187 + itemStr = '<span class="markerbg marker_' + (index+1) + '"></span>' +
188 + '<div class="info">' +
189 + ' <h5>' + places.place_name + '</h5>';
190 +
191 + if (places.road_address_name) {
192 + itemStr += ' <span>' + places.road_address_name + '</span>' +
193 + ' <span class="jibun gray">' + places.address_name + '</span>';
194 + } else {
195 + itemStr += ' <span>' + places.address_name + '</span>';
196 + }
197 +
198 + itemStr += ' <span class="tel">' + places.phone + '</span>' +
199 + '</div>';
200 +
201 + el.innerHTML = itemStr;
202 + el.className = 'item';
203 +
204 + return el;
205 + }
206 +
207 + // 마커를 생성하고 지도 위에 마커를 표시하는 함수입니다
208 + function addMarker(position, idx, title) {
209 + var imageSrc = 'https://t1.daumcdn.net/localimg/localimages/07/mapapidoc/marker_number_blue.png', // 마커 이미지 url, 스프라이트 이미지를 씁니다
210 + imageSize = new kakao.maps.Size(36, 37), // 마커 이미지의 크기
211 + imgOptions = {
212 + spriteSize : new kakao.maps.Size(36, 691), // 스프라이트 이미지의 크기
213 + spriteOrigin : new kakao.maps.Point(0, (idx*46)+10), // 스프라이트 이미지 중 사용할 영역의 좌상단 좌표
214 + offset: new kakao.maps.Point(13, 37) // 마커 좌표에 일치시킬 이미지 내에서의 좌표
215 + },
216 + markerImage = new kakao.maps.MarkerImage(imageSrc, imageSize, imgOptions),
217 + marker = new kakao.maps.Marker({
218 + position: position, // 마커의 위치
219 + image: markerImage
220 + });
221 +
222 + marker.setMap(map); // 지도 위에 마커를 표출합니다
223 + markers.push(marker); // 배열에 생성된 마커를 추가합니다
224 +
225 + return marker;
226 + }
227 +
228 + // 지도 위에 표시되고 있는 마커를 모두 제거합니다
229 + function removeMarker() {
230 + for ( var i = 0; i < markers.length; i++ ) {
231 + markers[i].setMap(null);
232 + }
233 + markers = [];
234 + }
235 +
236 + // 검색결과 목록 하단에 페이지번호를 표시는 함수입니다
237 + function displayPagination(pagination) {
238 + var paginationEl = document.getElementById('pagination'),
239 + fragment = document.createDocumentFragment(),
240 + i;
241 +
242 + // 기존에 추가된 페이지번호를 삭제합니다
243 + while (paginationEl.hasChildNodes()) {
244 + paginationEl.removeChild (paginationEl.lastChild);
245 + }
246 +
247 + for (i=1; i<=pagination.last; i++) {
248 + var el = document.createElement('a');
249 + el.href = "#";
250 + el.innerHTML = i;
251 +
252 + if (i===pagination.current) {
253 + el.className = 'on';
254 + } else {
255 + el.onclick = (function(i) {
256 + return function() {
257 + pagination.gotoPage(i);
258 + }
259 + })(i);
260 + }
261 +
262 + fragment.appendChild(el);
263 + }
264 + paginationEl.appendChild(fragment);
265 + }
266 +
267 + // 검색결과 목록 또는 마커를 클릭했을 때 호출되는 함수입니다
268 + // 인포윈도우에 장소명을 표시합니다
269 + function displayInfowindow(marker, title) {
270 + var content = '<div style="padding:5px;z-index:1;">' + title + '</div>';
271 +
272 + infowindow.setContent(content);
273 + infowindow.open(map, marker);
274 + }
275 +
276 + // 검색결과 목록의 자식 Element를 제거하는 함수입니다
277 + function removeAllChildNods(el) {
278 + while (el.hasChildNodes()) {
279 + el.removeChild (el.lastChild);
280 + }
281 + }
282 +</script>
283 +</body>
284 +</html>
...\ No newline at end of file ...\ No newline at end of file
1 -<component name="libraryTable">
2 - <library name="jsoup-1.15.1">
3 - <CLASSES>
4 - <root url="jar://$PROJECT_DIR$/jsoup-1.15.1.jar!/" />
5 - </CLASSES>
6 - <JAVADOC />
7 - <SOURCES />
8 - </library>
9 -</component>
...\ No newline at end of file ...\ No newline at end of file