본문 바로가기
게임서버-스파르타코딩NodeJs_7기/CH6 최종 프로젝트

길찾기 지도

by GREEN나무 2025. 2. 28.
728x90

250228 - 마커 위치로 좌표 보여주기 가능, 좌표입력으로 출발,도착 마커 이동 실패

            <div id="map" style="flex: 2; height: 400px; border-radius: 10px;">
                <script>
                    let mapContainer = document.getElementById('map'),
                        mapOption = {
                            center: new kakao.maps.LatLng(0, 0),
                            level: 5,
                        };
                    let map = new kakao.maps.Map(mapContainer, mapOption);

                    // 현재 위치 표시
                    if (navigator.geolocation) {
                        navigator.geolocation.getCurrentPosition(function (position) {
                            let lat = position.coords.latitude,
                                lon = position.coords.longitude;
                            let locPosition = new kakao.maps.LatLng(lat, lon),
                                message = '<div style="padding:5px;">여기에 계신가요?!</div>';
                            displayMarker(locPosition, message);
                        });
                    } else {
                        let locPosition = new kakao.maps.LatLng(0, 0),
                            message = 'geolocation을 사용할 수 없어요..';
                        displayMarker(locPosition, message);
                    }
                    function displayMarker(locPosition, message) {
                        let marker = new kakao.maps.Marker({
                            map: map,
                            position: locPosition,
                        });
                        let infowindow = new kakao.maps.InfoWindow({
                            content: message,
                            removable: true,
                        });
                        infowindow.open(map, marker);
                        map.setCenter(locPosition);
                    }

                    let geocoder = new kakao.maps.services.Geocoder();

                    // 로컬 스토리지에서 저장된 좌표 정보 불러오기
                    let savedStart = JSON.parse(localStorage.getItem('startLocation'));
                    let savedEnd = JSON.parse(localStorage.getItem('endLocation'));

                    // 확대/축소 컨트롤 추가
                    let zoomControl = new kakao.maps.ZoomControl();
                    map.addControl(zoomControl, kakao.maps.ControlPosition.RIGHT);

                    // 마커 정보 배열 (출발지, 도착지)
                    let markers = [
                        {
                            key: 'start',
                            info: '출발지',
                            position: savedStart ? new kakao.maps.LatLng(savedStart.lat, savedStart.lng) : new kakao.maps.LatLng(36.3275, 127.4268),
                            imageUrl: 'https://t1.daumcdn.net/localimg/localimages/07/mapapidoc/red_b.png',
                            storageKey: 'startLocation',
                        },
                        {
                            key: 'end',
                            info: '도착지',
                            position: savedEnd ? new kakao.maps.LatLng(savedEnd.lat, savedEnd.lng) : new kakao.maps.LatLng(36.340309, 127.389999),
                            imageUrl: 'https://t1.daumcdn.net/localimg/localimages/07/mapapidoc/blue_b.png',
                            storageKey: 'endLocation',
                        },
                    ];

                    // 마커를 지도에 추가하고 드래그 이벤트 등록
                    markers.forEach(function (data) {
                        let markerImage = new kakao.maps.MarkerImage(
                            data.imageUrl,
                            new kakao.maps.Size(50, 50),
                        );
                        let marker = new kakao.maps.Marker({
                            position: data.position,
                            image: markerImage,
                            map: map,
                            draggable: true,
                        });

                        // 마커 위에 정보창 추가
                        let infowindow = new kakao.maps.InfoWindow({
                            content: `<div style="padding:5px;">${data.info}</div>`,
                        });
                        infowindow.open(map, marker);

                        // 드래그 종료 시 좌표 저장 (입력창 업데이트는 별도 이벤트에서 처리)
                        kakao.maps.event.addListener(marker, 'dragend', function () {
                            let position = marker.getPosition();
                            localStorage.setItem(
                                data.storageKey,
                                JSON.stringify({ lat: position.getLat(), lng: position.getLng() }),
                            );
                            console.log(`${data.info} 위치 저장됨:`, position.getLat(), position.getLng());
                        });

                        data.marker = marker;
                    });

                    // 전역 변수로 출발지, 도착지 마커 지정
                    let startMarker = markers.find(m => m.key === 'start').marker;
                    let endMarker = markers.find(m => m.key === 'end').marker;

                    // 길찾기 버튼 클릭 시 링크 새 창 열기
                    function openDirection() {
                        let startPos = startMarker.getPosition();
                        let endPos = endMarker.getPosition();
                        let url = `https://map.kakao.com/link/to/도착지,${endPos.getLat()},${endPos.getLng()}/from/출발지,${startPos.getLat()},${startPos.getLng()}`;
                        window.open(url, '_blank');
                    }

                    // 입력창의 주소를 검색하여 마커 이동 및 좌표 저장
                    function setMarkerPosition(marker, addressInputId) {
                        let inputElement = document.getElementById(addressInputId);
                        geocoder.addressSearch(inputElement.value, function (result, status) {
                            if (status === kakao.maps.services.Status.OK) {
                                let coords = new kakao.maps.LatLng(result[0].y, result[0].x);
                                marker.setPosition(coords);
                                map.setCenter(coords);
                                localStorage.setItem(
                                    addressInputId + 'Location',
                                    JSON.stringify({ lat: result[0].y, lng: result[0].x }),
                                );
                            } else {
                                alert('검색 결과가 없습니다.');
                            }
                        });
                    }

                    // 마커 이동 시 입력창에 좌표 업데이트
                    function updateInputValue(marker, addressInputId) {
                        let inputElement = document.getElementById(addressInputId);
                        let position = marker.getPosition();
                        inputElement.value = `${position.getLat()}, ${position.getLng()}`;
                    }

                    // 입력창 변경 시 해당 마커 이동
                    document.getElementById('start').addEventListener('change', function () {
                        setMarkerPosition(startMarker, 'start');
                    });

                    document.getElementById('end').addEventListener('change', function () {
                        setMarkerPosition(endMarker, 'end');
                    });

                    // 마커 드래그 후 입력창 값 업데이트
                    kakao.maps.event.addListener(startMarker, 'dragend', function () {
                        updateInputValue(startMarker, 'start');
                    });

                    kakao.maps.event.addListener(endMarker, 'dragend', function () {
                        updateInputValue(endMarker, 'end');
                    });


                    // 입력창의 주소를 기반으로 마커 위치를 이동시키는 함수
                    function setMarkerPosition(marker, addressInputId) {
                        let inputElement = document.getElementById(addressInputId);
                        geocoder.addressSearch(inputElement.value, function (result, status) {
                            if (status === kakao.maps.services.Status.OK) {
                                let coords = new kakao.maps.LatLng(result[0].y, result[0].x);
                                marker.setPosition(coords);
                                map.setCenter(coords);
                                // 변경된 좌표를 로컬 스토리지에 저장 (옵션)
                                localStorage.setItem(addressInputId + 'Location', JSON.stringify({ lat: result[0].y, lng: result[0].x }));
                            } else {
                                alert('검색 결과가 없습니다.');
                            }
                        });
                    }

                    // 출발지 입력창 값이 바뀌면 startMarker의 위치 업데이트
                    document.getElementById('start').addEventListener('change', function () {
                        setMarkerPosition(startMarker, 'start');
                    });
                    // 북마커 데이터 호출 및 지도에 추가
                    let markerData = [];

                    fetch('http://localhost:3000/direction/bookmarke')
                        .then((response) => {
                            if (!response.ok) {
                                throw new Error(`HTTP error! Status: ${response.status}`);
                            }
                            console.log('✅ 패치 성공');
                            return response.json();
                        })
                        .then((data) => {
                            console.log('북마커 데이터:', data);
                            if (data.bookmarksS && Array.isArray(data.bookmarksS)) {
                                data.bookmarksS.forEach((bookmarkeS) => {
                                    markerData.push({
                                        position: new kakao.maps.LatLng(bookmarkeS.latitude, bookmarkeS.longitude),
                                        imageUrl: bookmarkeS.sub_achievement_images,
                                        size: new kakao.maps.Size(20, 20),
                                        info: bookmarkeS.title,
                                        draggable: false,
                                    });
                                });
                            }
                            if (data.bookmarksP && Array.isArray(data.bookmarksP)) {
                                data.bookmarksP.forEach((bookmarkeP) => {
                                    markerData.push({
                                        position: new kakao.maps.LatLng(bookmarkeP.latitude, bookmarkeP.longitude),
                                        imageUrl: 'https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbnZWDr%2FbtsMxEa1tat%2Fd4s5w26JdYrq0b7Qp9wDt1%2Fimg.png',
                                        size: new kakao.maps.Size(20, 20),
                                        info: bookmarkeP.title,
                                        draggable: false,
                                    });
                                });
                            }
                            addMarkersToMap();
                        })
                        .catch((error) => console.error('Error fetching data:', error));

                    function addMarkersToMap() {
                        if (markerData.length === 0) {
                            console.warn('📢 북마커 데이터 없음');
                            return;
                        }
                        var bounds = new kakao.maps.LatLngBounds();
                        markerData.forEach(function (data) {
                            var markerImage = new kakao.maps.MarkerImage(data.imageUrl, data.size);
                            var marker = new kakao.maps.Marker({
                                position: data.position,
                                image: markerImage,
                                map: map,
                                draggable: data.draggable,
                            });
                            var infowindow = new kakao.maps.InfoWindow({
                                content: `<div style="padding:5px;">${data.info} <br>
                                  <a href="https://map.kakao.com/link/map/${data.info},${data.position.getLat()},${data.position.getLng()}" target="_blank" style="color:skyblue">큰지도보기</a> 
                                  <a href="https://map.kakao.com/link/to/${data.info},${data.position.getLat()},${data.position.getLng()}" target="_blank" style="color:blue">길찾기</a></div>`,
                            });
                            infowindow.open(map, marker);
                            bounds.extend(data.position);
                        });
                        map.setBounds(bounds);
                    }
                </script>

            </div>