๐Ÿ“š Google Map Platform ์‚ฌ์šฉํ•˜๊ธฐ + ํ˜„์žฌ ์œ„์น˜๊ฐ’(์ขŒํ‘œ)๋ฐ›์•„ ์—ฐ๊ฒฐํ•˜๊ธฐ

๋ฐ•์˜์€ยท2023๋…„ 3์›” 16์ผ
0

๐Ÿ‘‰ ์ดˆ๊ธฐ ๊ธฐ๋ณธ ๊ณ„์ • ์„ธํŒ…

  1. ๊ณ„์ • ์ƒ์„ฑ ๋ฐ api key ๋ฐœ๊ธ‰
    Google Developers Platform์„ ์ฒ˜์Œ ์“ฐ๋ฉด ๋‹ค ๋“ฑ๋กํ•ด์•ผ ํ•œ๋‹ค.
  2. http ์›น ๋ฆฌํผ๋Ÿฌ api ํ‚ค ๋ณดํ˜ธ ์„ค์ •
    • ๊ตฌ๊ธ€ Maps API๋Š” ์‚ฌ์šฉํ•œ ๋งŒํผ ๊ณผ๊ธˆ์ด ๋˜๋Š” ์œ ๋ฃŒ API์ด์ง€๋งŒ, ๊ณ„์ • ์„ค์ • ํ›„ ํ•œ ๋‹ฌ์— 28,500๋ฒˆ ์ •๋„๋Š” ๋ฌด๋ฃŒ๋กœ ํ˜ธ์ถœ์ด ๊ฐ€๋Šฅ. ์ดํ›„๋ถ€ํ„ฐ ์œ ๋ฃŒ๋กœ ์ „ํ™˜๋œ๋‹ค. (๊ณ„์ • ์ดˆ๊ธฐ ์„ค์ • ์‹œ ๊ฒฐ์ œ ์นด๋“œ ๋“ฑ๋กํ•จ)
    • api ํ‚ค ์ƒ์„ฑ ์‹œ ๊ธฐ๋ณธ์œผ๋กœ ๋ณดํ˜ธ์„ค์ •์ด ๋˜์–ด์žˆ์ง€ ์•Š์€ ์ƒํƒœ์ž„.
    • _(๐Ÿ˜Ÿ ๊ทธ๋Ÿด..์ผ์€.. ์—†๊ฒƒ์ง€๋งŒ...) ์•…์˜์ ์ธ ์˜๋„๋กœ๋ฅผ ๊ฐ–๊ณ  ๋‚ด API ํ‚ค๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ตฌ๊ธ€ Maps API๋ฅผ ์—„์ฒญ๋‚˜๊ฒŒ ํ˜ธ์ถœํ•˜๋ฉด ๊ณผ๊ธˆ ๋Œ€๋ฐ•์ž„..
      - ์œ„์™€ ๊ฐ™์€ ์ƒํ™ฉ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด api ๋ณดํ˜ธ ์„ค์ • ํ•จ
      • !! ๊ฒฐ์ œ ํƒญ์˜ ์˜ˆ์‚ฐ ๋ฐ ์•Œ๋ฆผ์—์„œ ์—ฌ๋Ÿฌ ๋น„์šฉ์— ๋”ฐ๋ผ ๋ฉ”์ผ๋กœ ์•Œ๋žŒ์„ ๋ฐ›๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ์Œ.
      • ๊ทธ๋ƒฅ ํ•„์š”ํ•œ ๊ธฐ๊ฐ„๋™์•ˆ๋งŒ ์‚ฌ์šฉํ•˜๊ณ  api key ์‚ญ์ œํ•˜๋Š”๊ฒŒ ๋ง˜ํŽธํ˜€ใ…‹ใ…‹
      • ๊ตฌ๊ธ€ ๋งต api๋ฅผ ์‚ฌ์šฉํ•  ๋„๋ฉ”์ธ์„ ์ž…๋ ฅํ•˜๋ฉด ๋จ

๐Ÿ‘‰ ์„ค์น˜

1-1. Google Maps์˜ Docs์ด์šฉ

  • ์ซŒ ๋ถˆ์นœ์ ˆ

1-2-1. react-google-maps ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ด์šฉ

  • ์‚ฌ์šฉ์ด ๋” ์‰ฝ๊ณ  ๊ฐ€๋ฒผ์›€.

1-2-2. @react-google-maps/api ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ด์šฉ

  • ๋‹ค์šด๋กœ๋“œ ์ˆ˜๊ฐ€ 1-2-1๋ณด๋‹ค ๋” ๋งŽ์Œ! ์‹ ๋ขฐ๋„ up ใ…‹ใ…‹
  • ๊ตฌ๊ธ€๋งต API์˜ ๋ณต์žกํ•˜๊ณ  ์ž์„ธํ•œ ๊ธฐ๋Šฅ๊นŒ์ง€ ๊ตฌํ˜„
  • ์—…๋ฐ์ดํŠธ ์ตœ๊ทผ๊นŒ์ง€ ๊ตฟ
    (์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ์‚ฌ์šฉํ• ๊ฑฐ์ž„.)

๐Ÿ‘‰ ์‚ฌ์šฉ ๋ฐฉ๋ฒ•

1. ์œ„ ์„ค์น˜ ์ฐธ๊ณ ํ•˜์—ฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋‹ค์šด๋กœ๋“œ

2. .envํŒŒ์ผ์— ๋ฐœ๊ธ‰๋ฐ›์€ Google API Key ์ถ”๊ฐ€

3. ์ฝ”๋“œ ์ž‘์„ฑ


      <div className="h-40 border border-blue-500">
        <LoadScript googleMapsApiKey="๋ฐœ๊ธ‰๋ฐ›์€ key">
          <GoogleMap
            mapContainerStyle={containerStyle}
            center={center}
            zoom={10}
          >
            {/* Child components, such as markers, info windows, etc. */}
            <></>
          </GoogleMap>
        </LoadScript>
        )
      </div>

4. ์ถœ๋ ฅ ํ™•์ธ

  • ์—ฌ๊ธฐ๊นŒ์ง€ ํ•˜๋ฉด ์•„๋ž˜ ์‚ฌ์ง„์ฒ˜๋Ÿผ ๋œฌ๋‹ค~~~! ๋‚˜์ด์‘ค!!!

5. ๊ธฐ๋ณธ ์š”์†Œ ์ถ”๊ฐ€ ๋ฐ ์‚ญ์ œ

5-1-1. ๊ธฐ๋ณธ ui์š”์†Œ ์ง€์šฐ๊ธฐ

  • ์œ„ ์ถœ๋ ฅ๋œ ์บก์ณ๋ฅผ ๋ณด๋ฉด ๊ธฐ๋ณธ ์š”์†Œ๋กœ ํ™•๋Œ€, ์ถ•์†Œ, ์ „์ฒด๋ณด๊ธฐ, ์œ„์„ฑ๋ชจ๋“œ ๋“ฑ์˜ ๊ธฐ๋ณธ ui๋ฒ„ํŠผ๋“ค์ด ์žˆ๋‹ค.
    disableDefaultUI: true : ๊ธฐ๋ณธ ui ์ „์ฒด๋ฅผ ์—†์• ์ค€๋‹ค.
ex)
	<GoogleMap 
		...
 	   options={{disableDefaultUI: true}}
 	   ...
 	   >
	</GoogleMap>

5-1-2. ์ง€๋„์— ์ปจํŠธ๋กค ์š”์†Œ ์ถ”๊ฐ€ํ•˜๊ธฐ

  zoomControl: boolean,
  mapTypeControl: boolean,
  scaleControl: boolean,
  streetViewControl: boolean,
  rotateControl: boolean,
  fullscreenControl: boolean ๋“ฑ....
  
  ex) 
  
  ...
  	<GoogleMap 
		...
    	options={{ streetViewControl: true, styles: myStyles }}
        			// ๋‚˜๋Š” ์œ„์„ฑ๋ทฐ๋„ ์‚ฌ์šฉํ•ด์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์— 
        			// streetViewControl์„ true๋กœ ์„ค์ •ํ•จ.
   	 	...
   	 >	
	</GoogleMap>
...

5-2. ๊ธฐ๋ณธ ์„ค์ • ๋งˆ์ปค๋“ค ์ง€์šฐ๊ธฐ

๊ธฐ๋ณธ์ ์œผ๋กœ ์Œ์‹์ , ๋ช…์†Œ ๋“ฑ ๋งˆ์ปค๊ฐ€ ๋‹ค ๋œธ. => option์˜ styles๋ฅผ ์ง€์ •ํ•˜์—ฌ ์ง€์ €๋ถ„ํ•œ ๋งˆ์ปค๋“ค์„ ๋‹ค ์ง€์šธ ์ˆ˜ ์žˆ์Œ.

ex)
	const myStyles = [
  	{
  	  featureType: "poi",
  	  elementType: "labels",
  	  stylers: [{ visibility: "off" }],
  	},
	];  
	     // featureType, elementType๋กœ 
		 // styler๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ์„ ํƒํ•œ ์ง€ํ˜•์ง€๋ฌผ๊ณผ ์š”์†Œ์— ์ ์šฉํ•  ๊ทœ์น™์„ ์ •ํ•  ์ˆ˜์žˆ์Œ.
	...
	<GoogleMap 
		...
    	options={{ disableDefaultUI: true, styles: myStyles }}
   	 	...
   	 >	
	</GoogleMap>

6. Marker ์ฐ๊ธฐ

  • React 18 ์ดํ›„ ๋ฒ„์ „์—์„œ๋Š” Marker ๋Œ€์‹  MarkerF ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.
...
 const center = useMemo(() => ({ lat: 12.345, lng: 678.91 }), []);
...
<GoogleMap ~~~>
     <MarkerF position={center} />
       	// ๋‚˜๋Š” ๊ธฐ๋ณธ ๋งˆ์ปค๋งŒ ์“ธ๊ฑฐ๋ผ์„œ ์˜ต์…˜ ์ „๋ถ€ ๋บŒ.
       	// ๐Ÿ‘‰ position (ํ•„์ˆ˜์˜ต์…˜!) = ๋งˆ์ปค์˜ ์œ„์น˜
        // ๐Ÿ‘‰ custom Marker์‚ฌ์šฉ์‹œ ๋งˆ์ปค ์ถ”๊ฐ€ ์„ ํƒ์˜ต์…˜
       	    // map = ๋งˆ์ปค๋ฅผ ๋ฐฐ์น˜ํ•  Map์„ ์ง€์ •   ex) map={myMap1}
       		//       ๋งˆ์ปค์˜ setMap() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋งˆ์ปค ์ถ”๊ฐ€ ๋ฐ ์‚ญ์ œ ๊ฐ€๋Šฅ.        
            // title = ๋งˆ์ปค์˜ ์„ค๋ช…   ex) title:"Hello World!"
       	    // icon, path, scale, anchor, rotaion, fillColor ๋“ฑ๋“ฑ..
</GoogleMap>
...

7. ๋งˆ์ปค์— ํ˜„์žฌ ์œ„์น˜๊ฐ’(์ขŒํ‘œ) ์—ฐ๊ฒฐํ•˜๊ธฐ

ํ˜„์žฌ ์œ„์น˜๊ฐ’์„ ๋ฐ›๊ธฐ ์œ„ํ•ด ๋Œ€๋ถ€๋ถ„
๋‚˜๋Š” ์ผ๋‹จ ๊ฐ„๋‹จํ•˜๊ฒŒ,,(์ด๊ฒŒ ๋งž๋‚˜ ์‹ถ๊ธดํ•จ.. ์•„๋ฌดํŠผ ์ขŒํ‘œ๊ฐ’์ด ์ž˜ ๋ถˆ๋Ÿฌ์™€์ง€๊ธด ํ•ด์„œ ์”€..)

๐Ÿ‘‰ ํฌ๋กฌ์—์„œ getCurrentPosition ๋ฉ”์„œ๋“œ๋Š” https์™€ localhost์—์„œ๋งŒ ๋™์ž‘ํ•จ.

  • ๊ธฐ๋ณธ์ ์œผ๋กœ ์œ„์น˜ ์ •๋ณด ์‚ฌ์šฉ ๋™์˜๊ฐ€ ๋˜์–ด์žˆ์–ด์•ผ ํ•จ.
  • ๋™์˜ ํ›„ position ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•จ.
  • console.log(position) : ์œ„์น˜, ์Šคํ”ผ๋“œ, ๊ณ ๋„ ๋“ฑ์˜ ๊ฐ’๋“ค ๋‹ด๊ฒจ์žˆ์Œ.
  • ๊ธฐํƒ€ ์˜ต์…˜๋“ค
    enableHighAccuracy(๋ฐฐํ„ฐ๋ฆฌ๋ฅผ ๋” ์†Œ๋ชจํ•ด์„œ ๋” ์ •ํ™•ํ•œ ์œ„์น˜๋ฅผ ์ฐพ์Œ)
    timeout(์ฃผ์–ด์ง„ ์ดˆ ์•ˆ์— ์ฐพ์ง€ ๋ชปํ•˜๋ฉด ์—๋Ÿฌ ๋ฐœ์ƒ)
    maximumAge(ํ•œ ๋ฒˆ ์ฐพ์€ ์œ„์น˜ ์ •๋ณด๋ฅผ ํ•ด๋‹น ์ดˆ๋งŒํผ ์บ์‹ฑ)
  const [lat, setLat] = React.useState(0);
  const [lng, setLng] = React.useState(0);
  const markerPosition = { lat, lng };


  const getLocation = () => {
    if (navigator.geolocation) {
      navigator.geolocation.getCurrentPosition(
        (position) => {
          console.log(`Position.Latitude ์œ„๋„ : ${position.coords.latitude}`);
          setLat(position.coords.latitude);
          console.log(`Position.longitude ๊ฒฝ๋„ : ${position.coords.longitude}`);
          setLng(position.coords.longitude);
        },
        (error) => {
          console.error(error);
        },
        {
          enableHighAccuracy: false,
          maximumAge: 0,
          timeout: Infinity,
        }
      );
    } else {
      alert("GPS๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์„ค์ •์„ ํ™•์ธํ•˜์„ธ์š”.");
    }
  };
  React.useEffect(() => {
    getLocation();
  }, []);
  • ์œ„์—์„œ ๋ฐ›์€ ์ขŒํ‘œ๋ฅผ markerPosition๋กœ ๋‹ด์•„์„œ ์•„๋ž˜ ๋งˆ์ปค ์˜ต์…˜์œผ๋กœ ๋„˜๊ฒจ์ฃผ๋ฉฐ๋…€ ๋จ.
    GoogleMap ์—์„œ์˜ center = ์ง€๋„์˜ ๋ณด์—ฌ์ง€๋Š” ๊ฐ€์šด๋ฐ ์ง€์ 
    GoogleMap ์—์„œ์˜ zoom = ์ดˆ๊ธฐ ๊ตฌ๊ธ€๋งต ํ™”๋ฉด์˜ ํ™•๋Œ€ ์ •๋„
    MarkerF์—์„œ์˜ position = ๋งˆ์ปค๊ฐ€ ์ฐํž ์ง€์ 
...
	<GoogleMap
    	...
        center={center}   
        zoom={16}
        ...
    >
    	<MarkerF position={markerPosition} />  ๐Ÿ‘ˆ!
    </GoogleMap>
...

8. ๋งˆ์ปค์˜ ์œ„์น˜๊ฐ’(์ขŒํ‘œ) ๋ฐ›๊ธฐ

-์ถ”๊ฐ€์˜ˆ์ •


๐Ÿ‘‰ ์ฐธ๊ณ 

  • ๊ตฌ๊ธ€๋งต ๋‚ด๋ถ€์—์„œ ์ฐ๋Š” Marker๋Š” GoogleMap ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์—์„œ ์„ ์–ธ
  • LoadScriptNext
    - Next์—์„œ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ ๋Œ€์‹  ๋ฅผ ์‚ฌ์šฉํ•ด์ค€๋‹ค.
    - ๋ฐœ๊ธ‰๋ฐ›์€ API ํ‚ค๋ฅผ googleMapsApiKey์— ๋„ฃ์–ด์ค€๋‹ค.
  • GoogleMap
    - ๊ธฐ๋ณธ zoom์ •๋„์™€ ๊ธฐ๋ณธ ์œ„์น˜(center)๋ฅผ ์„ค์ •ํ•ด์ฃผ๊ณ , mapContainerClassName๋ฅผ ์‚ฌ์šฉํ•ด className๊ฐ’์„ ์ „๋‹ฌํ•ด์ฃผ์—ˆ๋‹ค.(Wrapper ์ฐธ๊ณ )
  • MarkerF
    - React 18 ์ดํ›„๋กœ๋Š” ํƒœ๊ทธ ๋Œ€์‹  ๋ฅผ ์‚ฌ์šฉํ•ด์ค˜์•ผ ํ•œ๋‹ค.
    - custom Marker๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์„ ๊ฒฝ์šฐ icon๋‚ด์— img url๊ณผ scale ๊ฐ’์„ ์ง€์ •ํ•ด์ค€๋‹ค.
  • 18 ๋ฒ„์ „์—์„œ <Marker/> ๋Œ€์‹  <MarkerF/>๋ฅผ ์‚ฌ์šฉ

โ˜ ๏ธ RefererNotAllowedMapError ์—๋Ÿฌ

  • http ํŠน์ • ์›น์‚ฌ์ดํŠธ์—์„œ๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋„๋ก ์ œํ•œํ•ด๋’€๋”๋‹ˆ ์•„์ง ๋ฐฐํฌ๋ฅผ ์•ˆํ•ด์„œ๊ทธ๋Ÿฐ์ง€ ์ด๋Ÿฐ ์—๋Ÿฌ๊ฐ€ ๋–ด๋‹ค.
  • ์ผ๋‹จ ์ œํ•œ ์ „์ฒด ํ•ด์ œํ•˜์—ฌ ์—๋Ÿฌ๋ฅผ ์ฒ˜๋ฆฌํ–ˆ๋‹ค.ใ…‹ ใ…‹... ใ…Ž;;

์ฐธ๊ณ  : google maps platform
์ฐธ๊ณ 
์ฐธ๊ณ 
์ขŒํ‘œ ์ฐธ๊ณ 

0๊ฐœ์˜ ๋Œ“๊ธ€