기능 | 지도를 활용한 위치 - ssseok/wedding.invitation GitHub Wiki
- 지도를 활용하여 정확한 위치를 시각적으로 보여줍니다.
bunx --bun shadcn@latest add separator
- https://ui.shadcn.com/docs/components/separator
- shadcn UI Separator를 사용하였습니다.
bunx --bun shadcn@latest add dropdown-menu
- https://ui.shadcn.com/docs/components/dropdown-menu
- shadcn UI Dropdown Menu를 사용하였습니다.
API KEY 설정하는 방법 API KEY를 설정하셨다면 NAVER MAP에 대한 설정을 알려드리겠습니다.
<script
type="text/javascript"
src="https://oapi.map.naver.com/openapi/v3/maps.js?ncpClientId=%VITE_NAVER_MAP_CLIENT_ID%"
></script>
- 최상위 루트에 있는 index.html에
script
를 넣어줍니다. html에 변수를 넣을 때는%%
기호를 사용하여 넣어줍니다. - Vite를 사용하면 .env에 변수 설정을
VITE_
으로 시작하여야 합니다.(저는 .env에 변수이름을VITE_NAVER_MAP_CLIENT_ID
이라고 했습니다.)
import {
WEDDING_ADDRESS,
WEDDING_MAP_LAT,
WEDDING_MAP_LOT,
} from '../../config';
import { useEffect, useRef } from 'react';
export default function MapNaver() {
const mapRef = useRef<HTMLDivElement>(null);
const lot = WEDDING_MAP_LOT;
const lat = WEDDING_MAP_LAT;
useEffect(() => {
if (!mapRef.current) return;
const position = new window.naver.maps.LatLng(lot, lat);
// 지도 생성
const map = new window.naver.maps.Map(mapRef.current, {
center: position,
zoom: 15,
// zoomControl: true,
// zoomControlOptions: {
// position: window.naver.maps.Position.TOP_RIGHT,
// },
});
// 마커 생성 (기본 디자인)
const marker = new window.naver.maps.Marker({
position: position,
map: map,
});
// 정보창 생성
const infoWindow = new window.naver.maps.InfoWindow({
content: `
<div class="p-4 bg-white shadow-lg text-center">
<h3 class="font-bold text-lg">결혼식장</h3>
<p class="text-gray-600">${WEDDING_ADDRESS}</p>
</div>
`,
borderColor: 'transparent',
});
// 마커 클릭 시 정보창 표시
window.naver.maps.Event.addListener(marker, 'click', () => {
if (infoWindow.getMap()) {
infoWindow.close();
} else {
infoWindow.open(map, marker);
}
});
return () => {
map.destroy();
};
}, []);
return (
<div className='w-full'>
<div ref={mapRef} className='w-full h-[400px] shadow-md' />
</div>
);
}
- Naver 지도를 택한 이유?
- 사실 Kakao 지도 API는 한번 사용해봤기에 사용안해본 Naver 지도를 택했습니다.
- 위도(lat), 경도(lot) 좌표 찾는 법
- 지도 주소로 위도 경도 찾는 사이트를 이용하시면 쉽게 좌표를 얻으실 수 있습니다.
- 마커 정보창
- Naver map에 InfoWindow 함수를 이용하여 정보창을 커스텀 가능합니다.
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from '@/common/components/ui/dropdown-menu';
import { Separator } from '@/common/components/ui/separator';
import { copy } from '@/lib/copy';
import {
WEDDING_ADDRESS,
WEDDING_LOCATION_BUS,
WEDDING_LOCATION_NAME,
WEDDING_LOCATION_SUBWAY,
WEDDING_LOCATION_TEL,
WEDDING_PARKING,
} from '../../config';
import { Map, MoveUpRight } from 'lucide-react';
export default function MapInfo() {
return (
<div className='mt-10 mx-8'>
<div className='flex justify-between items-center'>
<p>
{WEDDING_ADDRESS}
<br />
<strong>{WEDDING_LOCATION_NAME}</strong>
</p>
<DropdownMenu>
<DropdownMenuTrigger>
<Map className='w-5 h-5' />
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem onSelect={() => copy(WEDDING_ADDRESS)}>
주소복사하기
</DropdownMenuItem>
<DropdownMenuItem
onSelect={() => {
window.open(
`https://map.naver.com/p/search/${WEDDING_ADDRESS}`,
'_blank',
);
}}
className='flex justify-between'
>
네이버 지도 <MoveUpRight className='w-4 h-4' />
</DropdownMenuItem>
<DropdownMenuItem
onSelect={() => {
window.open(
`https://map.kakao.com/?q=${WEDDING_ADDRESS}`,
'_blank',
);
}}
className='flex justify-between'
>
카카오 지도 <MoveUpRight className='w-4 h-4' />
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
<p className='text-xs mt-2 text-gray-500 dark:text-foreground'>
{WEDDING_LOCATION_TEL}
</p>
<div className='mt-10 space-y-8 text-gray-500 dark:text-foreground'>
<div className='flex items-center'>
<span className='w-14 text-foreground'>지하철</span>
<Separator orientation='vertical' className='bg-foreground' />
<div className='text-xs space-y-1'>
<p>{WEDDING_LOCATION_SUBWAY}</p>
</div>
</div>
<div className='flex items-center'>
<span className=' w-14 text-foreground'>버스</span>
<Separator orientation='vertical' className='bg-foreground' />
<div className='text-xs space-y-1'>
{WEDDING_LOCATION_BUS.map((bus, index) => (
<p key={index}>{bus}</p>
))}
</div>
</div>
<div className='flex items-center'>
<span className='w-14 text-foreground'>주차</span>
<Separator orientation='vertical' className='bg-foreground' />
<div className='text-xs space-y-1'>
<p>{WEDDING_PARKING}</p>
<div className='flex gap-0.5'>
*
<span>
주차장 이용이 혼잡하오니 불편하시더라도 대중교통 이용을 권장
드립니다.
</span>
</div>
</div>
</div>
</div>
</div>
);
}