https://kevinjuniors.github.io/my-project/webapp/index.html
카카오 지도 API를 이용하여 직접 약국 지도 웹 앱을 구현 해본 것입니다.
그 중 카카오 맵 API를 불러오는 JavaScript 파일의 코드들인데 그 중
진한 부분의 코드가 Uncaught ReferenceError: kakao is not defined 오류를 내 뱉는데 어디서 엃힌 것 일까요… 이 오류 때문에 기존에 잘 보이던 지도도 브라우저 상에서도 보이지 않고 있습니다 ㅠㅠ;;;;;;
// // 마커를 클릭했을 때 해당 장소의 상세정보를 보여 줄 커스텀 오버레이
/// var placeOverlay = new kakao.maps.CustomOverlay({zindex: 1}), ///
contentNode = document.createElement(‘div’),
markers = [],
currCategory = ‘’;
// 지도를 웹 브라우저 상에 표시할 DOM Element를 지정
const mapContainer = document.getElementById(“map”);
mapOption = {
center: new kakao.maps.LatLng(37.20993410884578, 127.05867025427891), // 지도의 중심좌표
level: 3 // 지도의 확대 레벨
};
// 지도를 생성하고 객체(Object)를 DOM에 반환하여 출력
const map = new kakao.maps.Map(mapContainer, mapOption);
// 장소 검색 객체를 생성
var ps = new kakao.maps.services.Places(map);
// 지도에 idle Event를 등록
kakao.maps.event.addListener(map, ‘idle’, searchPlaces);
// 커스텀 오버레이의 Contents Node에 css class를 추가
contentNode.className = ‘placeinfo_wrap’;
/* 커스텀 오버레이의 컨텐츠 노드에 mousedown, touchstart 이벤트가 발생했을때
지도 객체에 이벤트가 전달되지 않도록 이벤트 핸들러로 kakao.maps.event.preventMap 메소드를 등록 */
addEventHandle(contentNode, ‘mousedown’, kakao.maps.event.preventMap);
addEventHandle(contentNode, ‘touchstart’, kakao.maps.event.preventMap);
// 커스텀 오버레이 컨텐츠를 설정합니다
placeOverlay.setContent(contentNode);
addCategoryClickEvent();
// Element에 이벤트 핸들러를 추가시키는 함수
function addEventHandle(target, type, callback) {
if (target.addEventListener) {
target.addEventListener(type, callback);
} else {
target.attachEvent(‘on’ + type, callback);
}
}
// 카테고리 검색을 요청하는 함수입니다
function searchPlaces() {
if (!currCategory) {
return;
}
placeOverlay.setMap(null);
removeMarker();
ps.categorySearch(currCategory, placesSearchCB, {useMapBounds:true});
}
// 장소검색이 완료됐을 때 호출되는 콜백함수 입니다
function placesSearchCB(data, status, pagination) {
if (status === kakao.maps.services.Status.OK) {
// 정상적으로 검색이 완료됐으면 지도에 마커를 표출합니다
displayPlaces(data);
} else if (status === kakao.maps.services.Status.ZERO_RESULT) {
// 검색결과가 없는경우
alert("해당 지역의 약국 정보 조회 결과가 존재하지 않습니다.");
} else if (status === kakao.maps.services.Status.ERROR) {
// 에러로 인해 검색결과가 나오지 않은 경우
alert("예기지 않은 오류 발생으로 인해 약국 정보 조회 결과를 정상적으로 출력 하는데 실패 하였습니다.");
}
}
// 지도에 마커를 표출하는 함수
function displayPlaces(places) {
var order = document.getElementById(currCategory).getAttribute(‘data-order’);
for ( var i=0; i<places.length; i++ ) {
// 마커를 생성하고 지도에 표시
var marker = addMarker(new kakao.maps.LatLng(places[i].y, places[i].x), order);
/* 마커와 검색결과 항목을 클릭 했을 때
장소정보를 표출하도록 클릭 이벤트를 추가 */
(function(marker, place) {
kakao.maps.event.addListener(marker, 'click', function() {
displayPlaceInfo(place);
});
})(marker, places[i]);
}
}
// 마커를 생성하고 지도 위에 마커를 표시하는 함수
function addMarker(position, order) {
var imageSrc = ‘https://t1.daumcdn.net/localimg/localimages/07/mapapidoc/places_category.png’, // 마커 이미지 url, 스프라이트 이미지를 씁니다
imageSize = new kakao.maps.Size(27, 27), // 마커 이미지의 크기
imgOptions = {
spriteSize : new kakao.maps.Size(72, 206), // 스프라이트 이미지의 크기
spriteOrigin : new kakao.maps.Point(46, (order*36)), // 스프라이트 이미지 중 사용할 영역의 좌상단 좌표
offset: new kakao.maps.Point(11, 28) // 마커 좌표에 일치시킬 이미지 내에서의 좌표
},
markerImage = new kakao.maps.MarkerImage(imageSrc, imageSize, imgOptions),
marker = new kakao.maps.Marker({
position: position, // 마커의 위치
image: markerImage
});
marker.setMap(map);
markers.push(marker);
return marker;
}
// 지도 위에 표시되고 있는 마커를 모두 제거합니다
function removeMarker() {
for ( var i = 0; i < markers.length; i++ ) {
markers[i].setMap(null);
}
markers = [];
}
// 클릭한 마커에 대한 장소 상세정보를 커스텀 오버레이로 표시하는 함수
function displayPlaceInfo (place) {
var content = ‘
’ ’ + place.place_name + ‘’;
if (place.road_address_name) {
content += ' <span title="' + place.road_address_name + '">' + place.road_address_name + '</span>' +
' <span class="jibun" title="' + place.address_name + '">(지번 : ' + place.address_name + ')</span>';
} else {
content += ' <span title="' + place.address_name + '">' + place.address_name + '</span>';
}
content += ' <span class="tel">' + place.phone + '</span>' +
'</div>' +
'<div class="after"></div>';
contentNode.innerHTML = content;
placeOverlay.setPosition(new kakao.maps.LatLng(place.y, place.x));
placeOverlay.setMap(map);
}
// 각 카테고리에 클릭 이벤트를 등록
function addCategoryClickEvent() {
var category = document.getElementById(‘category’),
children = category.children;
for (var i=0; i<children.length; i++) {
children[i].onclick = onClickCategory;
}
}
// 카테고리를 클릭했을 때 호출되는 함수입
function onClickCategory() {
var id = this.id,
className = this.className;
placeOverlay.setMap(null);
if (className === 'on') {
currCategory = '';
changeCategoryClass();
removeMarker();
} else {
currCategory = id;
changeCategoryClass(this);
searchPlaces();
}
}
// 클릭된 카테고리만 클릭된 스타일을 적용하는 함수
function changeCategoryClass(el) {
var category = document.getElementById(‘category’),
children = category.children,
i;
for ( i=0; i<children.length; i++ ) {
children[i].className = '';
}
if (el) {
el.className = 'on';
}
}
/* 지도상 컨트롤 메뉴 삽입
일반 지도와 스카이 뷰 지도 타입으로 변경 할 수 있는 지도 타입 컨트롤 추가 */
const mapTypeControl = new kakao.maps.MapTypeControl();
// 컨트롤을 추가하고자 하는 지도를 지정
map.addControl(mapTypeControl, kakao.maps.ControlPosition.TOPRIGHT);
// 지도 Zoom-In, Zoom-Out 기능을 지원하는 Zoom 컨트롤 추가
const zoomControl = new kakao.maps.ZoomControl();
map.addControl(zoomControl, kakao.maps.ControlPosition.RIGHT);
// 좌표 정보를 주소로 변환
// 좌표 정보를 주소로 변환하는 객체를 생성
var geocoder = new kakao.maps.services.Geocoder();
var marker = new kakao.maps.Marker();
infowindow = new kakao.maps.InfoWindow({zindex: 2});
// 현재 지도 중심좌표로 주소를 검색해서 지도 좌측 상단에 표시
searchAddrFromCoords(map.getCenter(), displayCenterInfo);
/* 지도 클릭시 클릭한 지점의 위치 자표를 주소 정보롤 변환시켜
브라우저 상에 보여지도록 하는 이벤트를 추가 */
kakao.maps.event.addListener(map, ‘click’, function(mouseEvent) {
searchDetailAddrFromCoords(mouseEvent.latLng, function(result, status) {
if (status === kakao.maps.services.Status.OK) {
var detailAddr = !!result[0].road_address ? '
detailAddr += '
var content = '<div class="bAddr">' +
'<span class="title">법정동 주소정보</span>' +
detailAddr +
'</div>';
// 마커를 클릭한 위치에 표시합니다
marker.setPosition(mouseEvent.latLng);
marker.setMap(map);
// 인포윈도우에 클릭한 위치에 대한 법정동 상세 주소정보를 표시합니다
infowindow.setContent(content);
infowindow.open(map, marker);
}
});
});
// 중심 좌표나 확대 수준이 변경됐을 때 지도 중심 좌표에 대한 주소 정보를 표시하도록 이벤트를 등록합니다
kakao.maps.event.addListener(map, ‘idle’, function() {
searchAddrFromCoords(map.getCenter(), displayCenterInfo);
});
function searchAddrFromCoords(coords, callback) {
// 좌표로 행정동 주소 정보를 요청합니다
geocoder.coord2RegionCode(coords.getLng(), coords.getLat(), callback);
}
function searchDetailAddrFromCoords(coords, callback) {
// 좌표로 법정동 상세 주소 정보를 요청합니다
geocoder.coord2Address(coords.getLng(), coords.getLat(), callback);
}
// 지도 좌측상단에 지도 중심좌표에 대한 주소정보를 표출하는 함수입니다
function displayCenterInfo(result, status) {
if (status === kakao.maps.services.Status.OK) {
var infoDiv = document.getElementById(‘centerAddr’);
for(var i = 0; i < result.length; i++) {
// 행정동의 region_type 값은 'H' 이므로
if (result[i].region_type === 'H') {
infoDiv.innerHTML = result[i].address_name;
break;
}
}
}
}