728x90
커피숍, 편의점, 음식점 을 카테고리로 분류하여 클릭시 마커 생성 및 infowindow 생성 하는 기능 구현
참고한 Sample :
https://apis.map.kakao.com/web/sample/categoryMarker/
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>다양한 이미지 마커 표시하기</title>
<style>
.info-box {
padding: 10px;
margin: 5px;
width: 250px;
height: 150px;
font-size: 12px;
}
.ininfo {
background-color: white;
padding: 10px;
margin: 5px;
width: 250px;
height: 150px;
font-size: 12px;
}
#mapwrap{position:relative;overflow:hidden;}
.category, .category *{margin:0;padding:0;color:#000;}
.category {position:absolute;overflow:hidden;top:10px;left:10px;width:150px;height:50px;z-index:10;border:1px solid black;font-family:'Malgun Gothic','맑은 고딕',sans-serif;font-size:12px;text-align:center;background-color:#fff;}
.category .menu_selected {background:#FF5F4A;color:#fff;border-left:1px solid #915B2F;border-right:1px solid #915B2F;margin:0 -1px;}
.category li{list-style:none;float:left;width:50px;height:45px;padding-top:5px;cursor:pointer;}
.category .ico_comm {display:block;margin:0 auto 2px;width:22px;height:26px;background:url('https://t1.daumcdn.net/localimg/localimages/07/mapapidoc/category.png') no-repeat;}
.category .ico_coffee {background-position:-10px 0;}
.category .ico_store {background-position:-10px -36px;}
.category .ico_carpark {background-position:-10px -72px;}
</style>
</head>
<body>
<div id="mapwrap">
<!-- 지도가 표시될 div -->
<div id="map" style="width:100%;height:350px;"></div>
<!-- 지도 위에 표시될 마커 카테고리 -->
<div class="category">
<ul>
<li id="coffeeMenu" onclick="changeMarker('coffee')">
<span class="ico_comm ico_coffee"></span>
커피숍
</li>
<li id="storeMenu" onclick="changeMarker('store')">
<span class="ico_comm ico_store"></span>
편의점
</li>
<li id="carparkMenu" onclick="changeMarker('carpark')">
<span class="ico_comm ico_carpark"></span>
음식점
</li>
</ul>
</div>
</div>
<script type="text/javascript" src="//dapi.kakao.com/v2/maps/sdk.js?appkey=f6654953f7f2de9be8090793a3c14e09"></script>
<script>
var coffeePositions=[];
var storePositions=[];
var carparkPositions=[];
var infowindow;
navigator.geolocation.getCurrentPosition(function (position) {
const lat = position.coords.latitude;
const lng = position.coords.longitude;
createMap(lat, lng);
});
function createMap(lat, lng) {
const container = document.getElementById('map');
const options = {
center: new kakao.maps.LatLng(lat, lng),
level: 4
};
map = new kakao.maps.Map(container, options);
}
function getData(){
fetch('/coffee/data')
.then(response => response.json())
.then(data => {
data.forEach(v => {
const lat = v.latitude;
const lng = v.longitude;
var content = `<div class="info-box"> 상호명: ${v.coffeestore} <br> 주소: ${v.address} <br> </div>`;
coffeePositions.push(new kakao.maps.LatLng(lat,lng)) ;
createCoffeeMarkers(lat,lng,content);
})
})
}
function getData2(){
fetch('/store/data')
.then(response => response.json())
.then(data => {
data.forEach(v => {
const lat = v.latitude;
const lng = v.longitude;
storePositions.push(new kakao.maps.LatLng(lat,lng)) ;
console.log(storePositions);
createStoreMarkers();
})
})
}
function getData3(){
fetch('/restaurant/data')
.then(response => response.json())
.then(data => {
data.forEach(v => {
const lat = v.latitude;
const lng = v.longitude;
carparkPositions.push(new kakao.maps.LatLng(lat,lng)) ;
console.log(carparkPositions);
createCarparkMarkers();
})
})
}
// 커피숍 마커를 생성하고 커피숍 마커 배열에 추가하는 함수입니다
function createCoffeeMarkers(lat,lng,content) {
for (var i = 0; i < coffeePositions.length; i++) {
var imageSize = new kakao.maps.Size(22, 26),
imageOptions = {
spriteOrigin: new kakao.maps.Point(10, 0),
spriteSize: new kakao.maps.Size(36, 98)
};
// 마커이미지와 마커를 생성합니다
var markerImage = createMarkerImage(markerImageSrc, imageSize, imageOptions),
marker = createMarker(coffeePositions[i], markerImage);
infowindow = new kakao.maps.InfoWindow({
content: content,
removable: true
});
kakao.maps.event.addListener(marker, 'click', function () {
infowindow.setContent(content);
infowindow.open(map, marker);
map.panTo(coffeePositions);
// updateInfoBox(city);
});
// 생성된 마커를 커피숍 마커 배열에 추가합니다
coffeeMarkers.push(marker);
}
}
// 커피숍 마커들의 지도 표시 여부를 설정하는 함수입니다
function setCoffeeMarkers(map) {
for (var i = 0; i < coffeeMarkers.length; i++) {
coffeeMarkers[i].setMap(map);
}
}
var markerImageSrc = 'https://t1.daumcdn.net/localimg/localimages/07/mapapidoc/category.png'; // 마커이미지의 주소입니다. 스프라이트 이미지 입니다
coffeeMarkers = [], // 커피숍 마커 객체를 가지고 있을 배열입니다
storeMarkers = [], // 편의점 마커 객체를 가지고 있을 배열입니다
carparkMarkers = []; // 주차장 마커 객체를 가지고 있을 배열입니다
setCoffeeMarkers();
changeMarker('coffee'); // 지도에 커피숍 마커가 보이도록 설정합니다
// 마커이미지의 주소와, 크기, 옵션으로 마커 이미지를 생성하여 리턴하는 함수입니다
function createMarkerImage(src, size, options) {
var markerImage = new kakao.maps.MarkerImage(src, size, options);
return markerImage;
}
// 좌표와 마커이미지를 받아 마커를 생성하여 리턴하는 함수입니다
function createMarker(position, image) {
var marker = new kakao.maps.Marker({
position: position,
image: image
});
return marker;
}
// 편의점 마커를 생성하고 편의점 마커 배열에 추가하는 함수입니다
function createStoreMarkers() {
for (var i = 0; i < storePositions.length; i++) {
var imageSize = new kakao.maps.Size(22, 26),
imageOptions = {
spriteOrigin: new kakao.maps.Point(10, 36),
spriteSize: new kakao.maps.Size(36, 98)
};
// 마커이미지와 마커를 생성합니다
var markerImage = createMarkerImage(markerImageSrc, imageSize, imageOptions),
marker = createMarker(storePositions[i], markerImage);
// 생성된 마커를 편의점 마커 배열에 추가합니다
storeMarkers.push(marker);
}
}
// 편의점 마커들의 지도 표시 여부를 설정하는 함수입니다
function setStoreMarkers(map) {
for (var i = 0; i < storeMarkers.length; i++) {
storeMarkers[i].setMap(map);
}
}
// 주차장 마커를 생성하고 주차장 마커 배열에 추가하는 함수입니다
function createCarparkMarkers() {
for (var i = 0; i < carparkPositions.length; i++) {
var imageSize = new kakao.maps.Size(22, 26),
imageOptions = {
spriteOrigin: new kakao.maps.Point(10, 72),
spriteSize: new kakao.maps.Size(36, 98)
};
// 마커이미지와 마커를 생성합니다
var markerImage = createMarkerImage(markerImageSrc, imageSize, imageOptions),
marker = createMarker(carparkPositions[i], markerImage);
// 생성된 마커를 주차장 마커 배열에 추가합니다
carparkMarkers.push(marker);
}
}
// 주차장 마커들의 지도 표시 여부를 설정하는 함수입니다
function setCarparkMarkers(map) {
for (var i = 0; i < carparkMarkers.length; i++) {
carparkMarkers[i].setMap(map);
}
}
// 카테고리를 클릭했을 때 type에 따라 카테고리의 스타일과 지도에 표시되는 마커를 변경합니다
function changeMarker(type){
var coffeeMenu = document.getElementById('coffeeMenu');
var storeMenu = document.getElementById('storeMenu');
var carparkMenu = document.getElementById('carparkMenu');
// 커피숍 카테고리가 클릭됐을 때
if (type === 'coffee') {
getData();
// 커피숍 카테고리를 선택된 스타일로 변경하고
coffeeMenu.className = 'menu_selected';
// 편의점과 주차장 카테고리는 선택되지 않은 스타일로 바꿉니다
storeMenu.className = '';
carparkMenu.className = '';
// 커피숍 마커들만 지도에 표시하도록 설정합니다
setCoffeeMarkers(map);
setStoreMarkers(null);
setCarparkMarkers(null);
} else if (type === 'store') { // 편의점 카테고리가 클릭됐을 때
getData2();
// 편의점 카테고리를 선택된 스타일로 변경하고
coffeeMenu.className = '';
storeMenu.className = 'menu_selected';
carparkMenu.className = '';
// 편의점 마커들만 지도에 표시하도록 설정합니다
setCoffeeMarkers(null);
setStoreMarkers(map);
setCarparkMarkers(null);
} else if (type === 'carpark') { // 주차장 카테고리가 클릭됐을 때
getData3();
// 주차장 카테고리를 선택된 스타일로 변경하고
coffeeMenu.className = '';
storeMenu.className = '';
carparkMenu.className = 'menu_selected';
// 주차장 마커들만 지도에 표시하도록 설정합니다
setCoffeeMarkers(null);
setStoreMarkers(null);
setCarparkMarkers(map);
}
}
</script>
</body>
</html>
마커 위에 infowindow는 잘 생성되는데 내용이 바뀌지 않았다.
// 커피숍 마커를 생성하고 커피숍 마커 배열에 추가하는 함수입니다
function createCoffeeMarkers(lat,lng,content) {
for (var i = 0; i < coffeePositions.length; i++) {
var imageSize = new kakao.maps.Size(22, 26),
imageOptions = {
spriteOrigin: new kakao.maps.Point(10, 0),
spriteSize: new kakao.maps.Size(36, 98)
};
// 마커이미지와 마커를 생성합니다
var markerImage = createMarkerImage(markerImageSrc, imageSize, imageOptions),
marker = createMarker(coffeePositions[i], markerImage);
infowindow = new kakao.maps.InfoWindow({
content: content,
removable: true
});
console.log(content);
(function (marker,infowindow){
kakao.maps.event.addListener(marker, 'click', function () {
infowindow.setContent(content);
infowindow.open(map, marker);
map.panTo(coffeePositions);
});
})(marker,infowindow);
// 생성된 마커를 커피숍 마커 배열에 추가합니다
coffeeMarkers.push(marker);
}
}
위 코드로 실행하다보니 content에 제일 마지막 데이터만 들어가는 것을 확인하였다.
3시간 동안 이것저것 실행하고 chat GPT한테도 물어봤지만 제대로된 해답을 주지 않았다..ㅠ
결국 for 문의 범위를 변경하고 infowindow 관련 코드는 for 문 밖으로 꺼내주었더니 제대로 실행이 됐다~!
// 커피숍 마커를 생성하고 커피숍 마커 배열에 추가하는 함수입니다
function createCoffeeMarkers(lat,lng,content) {
var imageSize = new kakao.maps.Size(22, 26),
imageOptions = {
spriteOrigin: new kakao.maps.Point(10, 0),
spriteSize: new kakao.maps.Size(36, 98)
};
// 마커이미지와 마커를 생성합니다
for (var i = 0; i < coffeePositions.length; i++) {
var markerImage = createMarkerImage(markerImageSrc, imageSize, imageOptions),
marker = createMarker(coffeePositions[i], markerImage);
}
infowindow = new kakao.maps.InfoWindow({
content: content,
removable: true
});
console.log(content);
(function (marker,infowindow){
kakao.maps.event.addListener(marker, 'click', function () {
infowindow.setContent(content);
infowindow.open(map, marker);
map.panTo(coffeePositions);
});
})(marker,infowindow);
// 생성된 마커를 커피숍 마커 배열에 추가합니다
coffeeMarkers.push(marker);
}
infowindow 제거하는 removeinfo를 만들다가 결국 배열형식으로 position을 넣어 for문으로 꺼내올 필요가 없다는 것을 알게되었고 전체적으로 수정을 하였다.
수정한 코드
<script type="text/javascript"
src="//dapi.kakao.com/v2/maps/sdk.js?appkey=f6654953f7f2de9be8090793a3c14e09"></script>
<script>
var coffeePositions = [];
var storePositions = [];
var carparkPositions = [];
var infowindow;
navigator.geolocation.getCurrentPosition(function (position) {
const lat = position.coords.latitude;
const lng = position.coords.longitude;
createMap(lat, lng);
});
function createMap(lat, lng) {
const container = document.getElementById('map');
const options = {
center: new kakao.maps.LatLng(lat, lng),
level: 4
};
map = new kakao.maps.Map(container, options);
}
function getData() {
fetch('/coffee/data')
.then(response => response.json())
.then(data => {
data.forEach(v => {
const lat = v.latitude;
const lng = v.longitude;
const id = v.id;
const content = `<div class="info-box"> 상호명: ${v.coffestore} <br> 주소: ${v.address} <br> </div>`;
coffeePositions.push();
createCoffeeMarkers(lat, lng, content);
})
})
}
function getData2() {
fetch('/store/data')
.then(response => response.json())
.then(data => {
data.forEach(v => {
const lat = v.latitude;
const lng = v.longitude;
const content = `<div class="info-box"> 상호명: ${v.store} <br> 주소: ${v.address} <br> </div>`;
storePositions.push();
createStoreMarkers(lat, lng, content);
})
})
}
function getData3() {
fetch('/restaurant/data')
.then(response => response.json())
.then(data => {
data.forEach(v => {
const lat = v.latitude;
const lng = v.longitude;
const content = `<div class="info-box"> 상호명: ${v.restaurant} <br> 주소: ${v.address} <br> </div>`;
carparkPositions.push();
createCarparkMarkers(lat, lng, content);
})
})
}
// 커피숍 마커를 생성하고 커피숍 마커 배열에 추가하는 함수입니다
function createCoffeeMarkers(lat, lng, content) {
// 마커이미지와 마커를 생성합니다
const latlng = new kakao.maps.LatLng(lat, lng);
// console.log(content);
var imageSize = new kakao.maps.Size(22, 26),
imageOptions = {
spriteOrigin: new kakao.maps.Point(10, 0),
spriteSize: new kakao.maps.Size(36, 98)
};
var markerImage = createMarkerImage(markerImageSrc, imageSize, imageOptions);
const marker = createMarker(latlng, markerImage);
infowindow = new kakao.maps.InfoWindow({
removable: true
});
kakao.maps.event.addListener(marker, 'click', function () {
infowindow.setContent(content);
infowindow.open(map, marker);
map.panTo(latlng);
});
coffeeMarkers.push(marker);
}
// 커피숍 마커들의 지도 표시 여부를 설정하는 함수입니다
function setCoffeeMarkers(map) {
for (var i = 0; i < coffeeMarkers.length; i++) {
coffeeMarkers[i].setMap(map);
}
}
function removeInfo() {
if (infowindow) {
console.log(infowindow);
infowindow.close();
}
}
function getData(){
fetch('/coffee/data')
.then(response => response.json())
.then(data => {
data.forEach(v => {
const lat = v.latitude;
const lng = v.longitude;
const id = v.id;
const content = `<div class="info-box"> 상호명: ${v.coffeestore} <br> 주소: ${v.address} <br> </div>`;
coffeePositions.push() ;
createCoffeeMarkers(lat,lng,content);
})
})
}
function getData2(){
fetch('/store/data')
.then(response => response.json())
.then(data => {
data.forEach(v => {
const lat = v.latitude;
const lng = v.longitude;
const content = `<div class="info-box"> 상호명: ${v.store} <br> 주소: ${v.address} <br> </div>`;
storePositions.push() ;
createStoreMarkers(lat,lng,content);
})
})
}
function getData3(){
fetch('/restaurant/data')
.then(response => response.json())
.then(data => {
data.forEach(v => {
const lat = v.latitude;
const lng = v.longitude;
const content = `<div class="info-box"> 상호명: ${v.restaurant} <br> 주소: ${v.address} <br> </div>`;
carparkPositions.push() ;
createCarparkMarkers(lat,lng,content);
})
})
}
var markerImageSrc = 'https://t1.daumcdn.net/localimg/localimages/07/mapapidoc/category.png'; // 마커이미지의 주소입니다. 스프라이트 이미지 입니다
coffeeMarkers = [], // 커피숍 마커 객체를 가지고 있을 배열입니다
storeMarkers = [], // 편의점 마커 객체를 가지고 있을 배열입니다
carparkMarkers = []; // 주차장 마커 객체를 가지고 있을 배열입니다
setCoffeeMarkers();
changeMarker('coffee'); // 지도에 커피숍 마커가 보이도록 설정합니다
// 마커이미지의 주소와, 크기, 옵션으로 마커 이미지를 생성하여 리턴하는 함수입니다
function createMarkerImage(src, size, options) {
var markerImage = new kakao.maps.MarkerImage(src, size, options);
return markerImage;
}
// 좌표와 마커이미지를 받아 마커를 생성하여 리턴하는 함수입니다
function createMarker(position, image) {
var marker = new kakao.maps.Marker({
position: position,
image: image
});
return marker;
}
// 편의점 마커를 생성하고 편의점 마커 배열에 추가하는 함수입니다
function createStoreMarkers(lat, lng, content) {
const latlng = new kakao.maps.LatLng(lat, lng);
var imageSize = new kakao.maps.Size(22, 26),
imageOptions = {
spriteOrigin: new kakao.maps.Point(10, 36),
spriteSize: new kakao.maps.Size(36, 98)
};
// 마커이미지와 마커를 생성합니다
var markerImage = createMarkerImage(markerImageSrc, imageSize, imageOptions)
const marker = createMarker(latlng, markerImage);
infowindow = new kakao.maps.InfoWindow({
removable: true
});
kakao.maps.event.addListener(marker, 'click', function () {
infowindow.setContent(content);
infowindow.open(map, marker);
map.panTo(latlng);
});
// 생성된 마커를 편의점 마커 배열에 추가합니다
storeMarkers.push(marker);
}
// 편의점 마커들의 지도 표시 여부를 설정하는 함수입니다
function setStoreMarkers(map) {
for (var i = 0; i < storeMarkers.length; i++) {
storeMarkers[i].setMap(map);
}
}
// 주차장 마커를 생성하고 주차장 마커 배열에 추가하는 함수입니다
function createCarparkMarkers(lat, lng, content) {
const latlng = new kakao.maps.LatLng(lat, lng);
var imageSize = new kakao.maps.Size(22, 26),
imageOptions = {
spriteOrigin: new kakao.maps.Point(10, 72),
spriteSize: new kakao.maps.Size(36, 98)
};
// 마커이미지와 마커를 생성합니다
var markerImage = createMarkerImage(markerImageSrc, imageSize, imageOptions);
const marker = createMarker(latlng, markerImage);
infowindow = new kakao.maps.InfoWindow({
removable: true
});
kakao.maps.event.addListener(marker, 'click', function () {
infowindow.setContent(content);
infowindow.open(map, marker);
map.panTo(latlng);
});
// 생성된 마커를 주차장 마커 배열에 추가합니다
carparkMarkers.push(marker);
}
// 주차장 마커들의 지도 표시 여부를 설정하는 함수입니다
function setCarparkMarkers(map) {
for (var i = 0; i < carparkMarkers.length; i++) {
carparkMarkers[i].setMap(map);
}
}
// 카테고리를 클릭했을 때 type에 따라 카테고리의 스타일과 지도에 표시되는 마커를 변경합니다
function changeMarker(type) {
var coffeeMenu = document.getElementById('coffeeMenu');
var storeMenu = document.getElementById('storeMenu');
var carparkMenu = document.getElementById('carparkMenu');
// 커피숍 카테고리가 클릭됐을 때
if (type === 'coffee') {
getData();
// 커피숍 카테고리를 선택된 스타일로 변경하고
coffeeMenu.className = 'menu_selected';
// 편의점과 주차장 카테고리는 선택되지 않은 스타일로 바꿉니다
storeMenu.className = '';
carparkMenu.className = '';
//infowindow 제거
removeInfo();
// 커피숍 마커들만 지도에 표시하도록 설정합니다
setCoffeeMarkers(map);
setStoreMarkers(null);
setCarparkMarkers(null);
} else if (type === 'store') { // 편의점 카테고리가 클릭됐을 때
getData2();
// 편의점 카테고리를 선택된 스타일로 변경하고
coffeeMenu.className = '';
storeMenu.className = 'menu_selected';
carparkMenu.className = '';
//infowindow 제거
removeInfo();
// 편의점 마커들만 지도에 표시하도록 설정합니다
setCoffeeMarkers(null);
setStoreMarkers(map);
setCarparkMarkers(null);
} else if (type === 'carpark') { // 주차장 카테고리가 클릭됐을 때
getData3();
// 주차장 카테고리를 선택된 스타일로 변경하고
coffeeMenu.className = '';
storeMenu.className = '';
carparkMenu.className = 'menu_selected';
//infowindow 제거
removeInfo();
// 주차장 마커들만 지도에 표시하도록 설정합니다
setCoffeeMarkers(null);
setStoreMarkers(null);
setCarparkMarkers(map);
}
}
</script>
728x90
'웹 개발' 카테고리의 다른 글
Modal 창 구현 (1) | 2023.10.24 |
---|---|
Excel 데이터를 h2 데이터베이스에 저장하기 (0) | 2023.10.24 |
카카오 지도 api 활용 - 주소를 통해 위도경도 알아내기 (1) | 2023.10.23 |
카카오 지도 api 활용 - 다양한 이미지 마커 표시하기 (1) | 2023.10.23 |
카카오 지도 api 활용 - 현재 위치 기준 반경 데이터만 마커 생성 (1) | 2023.10.23 |