- 프로젝트에서 사용자에게 경로를 보여줄 때, 각 경로를 이어서 보여주려 했다.
또한, 해당 프로젝트에서는 활성화가 된 마커와 비활성화 마커의 이미지가 다르게 적용되었는데 진행한 방법을 기록해 보고자 한다.
먼저, 구현 완료된 화면은 다음과 같다.
| 마커 비활성화 + 첫 화면 | 마커 활성화 + 지도 확대 |
|---|---|
![]() | ![]() |
const TripRoutePage = () => {
const [routeData, setRouteData] = useState([]);
const mapRef = useRef(null);
const markersRef = useRef([]);
const { naver } = window;
useEffect(() => {
if (mapRef.current && naver) {
const location = new naver.maps.LatLng(33.4008, 126.5601);
mapRef.current = new naver.maps.Map("map", {
center: location,
zoom: 9,
mapDataControl: false,
scaleControl: false,
logoControlOptions: { position: 3 },
});
}
// data 요청 (temp data)
setRouteData([
{ title: "제주 국제 공항", subtitle: "제주 시내", lat: 33.4995, lng: 126.5388 },
{ title: "제주 국제 공항", subtitle: "제주 시내", lat: 33.4521, lng: 126.4076 },
{ title: "제주 국제 공항", subtitle: "제주 시내", lat: 33.3893, lng: 126.4104 },
{ title: "제주 국제 공항", subtitle: "제주 시내", lat: 33.3058, lng: 126.5161 },
]);
}, []);
return (
<TripRouteMapContainer ref={mapRef} id="map"></TripRouteMapContainer>
);
};
가독성을 위해 Map API 관련 코드를 제외하고 삭제했다.
여기에서 TripRouteMapContainer는, styled-components를 사용해 스타일링을 했다. 사용한 태그는 <div>태그!
naver.maps.Map 객체를 참조하기 위해 mapRef를 작성했다.
지도 객체는 다시 렌더링 할 필요가 없었기 때문에, useRef를 사용해 렌더링에 영향을 미치지 않으면서도 참조할 수 있도록 했다.
const location = new naver.maps.LatLng(33.4008, 126.5601);
mapRef.current = new naver.maps.Map("map", {
center: location,
zoom: 9,
mapDataControl: false,
scaleControl: false,
logoControlOptions: { position: 3 },
});
mapDataControl 클래스는 지도 데이터 저작권 컨트롤을 정의한다.scaleControl 클래스는 지도 축척 컨트롤을 정의한다.LogoControl 클래스는 NAVER 로고 컨트롤을 정의한다.| 아무런 설정 X (기본) | mapDataControl = false |
|---|---|
![]() | ![]() |
scaleControl: false | logoControlOptions: { position: 3 } |
|---|---|
![]() | ![]() |
디자인과 기능에서 필요하지 않은 부분은 false 처리를 해줬다.
디자인 구현을 위해 네이버 로고를 하단 시트 z-index로 가리려고 했었다.
이전에는, LogoControl을 false 처리해 네이버 로고를 안 보이도록 변경 가능했으나 검색한 결과 다음과 같은 내용을 찾을 수 있었다.
LogoControl 질문 답변 페이지

로고의 위치 조정 질문 답변 페이지

이 내용을 보고, z-index로 UI를 올려 로고를 가리면 안 되겠다!!! 생각해서 LogoControl로 상단에 위치하도록 변경했다.
setRouteData : 아직 백엔드와 연결 작업을 진행하지 않았기 때문에, 임시 데이터를 설정했다.
해당 부분은 백엔드에 API 요청을 받아 데이터를 넣어줄 예정이다.
const TripRoutePage = () => {
const [activeRoute, setActiveRoute] = useState(null);
const [routeData, setRouteData] = useState([]);
const mapRef = useRef(null);
const markersRef = useRef([]);
const { naver } = window;
useEffect(() => {
if (mapRef.current) {
markersRef.current.forEach((marker) => marker.setMap(null));
markersRef.current = [];
if (routeData.length > 0) {
routeData.forEach((route, index) => {
const marker = new naver.maps.Marker({
position: new naver.maps.LatLng(route.lat, route.lng),
map: mapRef.current,
icon: {
url: `/images/Map/Markers/marker${index + 1}_${activeRoute === index ? "on" : "off"}.svg`,
anchor: activeRoute === index ? new naver.maps.Point(26, 55) : new naver.maps.Point(15, 20),
},
});
naver.maps.Event.addListener(marker, "click", () => {
getClickMarker(index);
});
markersRef.current.push(marker);
});
// polyline
const path = routeData.map((route) => new naver.maps.LatLng(route.lat, route.lng));
const polyline = new naver.maps.Polyline({
map: mapRef.current,
path: path,
strokeColor: theme.color.primary,
strokeStyle: "shortdash",
strokeWeight: 2,
});
}
}
}, [routeData, activeRoute]);
const getClickMarker = (index) => {
setActiveRoute(index);
};
return (
<TripRouteMapContainer ref={mapRef} id="map"></TripRouteMapContainer>
);
};
useEffect에서 경로를 표시해주는 Marker와 이를 이어주는 PolyLine을 설정했다.markersRef는 지도에 표시되는 마커 관리를 위해 사용했다.routeData.forEach((route, index) => {
const marker = new naver.maps.Marker({
position: new naver.maps.LatLng(route.lat, route.lng),
map: mapRef.current,
icon: {
url: `/images/Map/Markers/marker${index + 1}_${activeRoute === index ? "on" : "off"}.svg`,
anchor: activeRoute === index ? new naver.maps.Point(26, 55) : new naver.maps.Point(15, 20),
},
});
naver.maps.Event.addListener(marker, "click", () => {
getClickMarker(index);
});
markersRef.current.push(marker);
});
anchor에 Point 클래스로 2차원 평면의 좌표를 정의했다.// polyline
const path = routeData.map((route) => new naver.maps.LatLng(route.lat, route.lng));
const polyline = new naver.maps.Polyline({
map: mapRef.current,
path: path,
strokeColor: theme.color.primary,
strokeStyle: "shortdash",
strokeWeight: 2,
});
strokeColor는 theme 파일에서 관리하는 color로 설정했다.strokeStyle는 다양한 스타일 중, 디자인과 가장 유사한 shortdash로 설정했다.
사용한 옵션 외에도 다양한 옵션이 있다!!! Polyline 옵션 예제 문서