建立屬於你的 Google Map 地圖標記(二) - 渲染自定參數的地圖元件


Posted by mumu892101 on 2022-08-08

地圖元件設置

在開發的一開始,首先需要先申請屬於你的 Google Maps API Key,接著我們必須建立一個指定長寬的父層,子層則是地圖元件,地圖元件會填充父層尺寸。這個設定在 google-map-react 中有提及,並且表示這個限制是來自於 Google-Map 所提供的。

<div className="w-full h-60 sm:h-96 mt-7 relative">
  <GoogleMapReact
    bootstrapURLKeys={{
      key: MAP_KEY,
      libraries: ['Maps javascript', 'places']
    }}
    center={coordsResult || initPosition || defaultCenter}
    defaultZoom={18}
    yesIWantToUseGoogleMapApiInternals={true}
    onGoogleApiLoaded={({ map, maps }) => apiHasLoaded(map, maps)}
    onChange={handleCenterChange}
  />
</div>


地圖元件參數設定

GoogleMapReact 這個 component 可以視為地圖本身,關於這個 component 的參數及用法,可以參考 google-map-react 的官方文件:https://www.npmjs.com/package/google-map-react ,以下介紹一下專案用到的參數有:

bootstrapURLKeys :
可以放置 Google Map Key 以及語言地區設定,另外 libraries 陣列中則是放置專案需要並且已啟用 Google Map API。

<GoogleMap
  bootstrapURLKeys={{
    key: API_KEY, // API Key
    language: 'ru', 
    region: 'ru',
    libraries:['places'], // 已啟用 Google Map API
    ...otherUrlParams,
  }}
>

center :
指打開地圖首先會呈現的地圖中心點,另外有 defaultCenter 這個參數,但更改會收到 warning。因為之後會用到定位的功能,當使用者同意定位時,中心點會以使用者所在位置呈現,如果不同意時則以自定義的固定中心點呈現,因此這邊使用 center 參數。

defaultZoom :
為打開地圖首先會呈現的地圖縮放比例。

yesIWantToUseGoogleMapApiInternals :
要使用這個套件載入 Google Map API 則需要設置為 true ,表示可以存取 google 地圖及物件。

onGoogleApiLoaded :
這個參數帶入一個 function 執行 Google Map API 初始載入後需要的行為。

onGoogleApiLoaded={({ map, maps }) => apiHasLoaded(map, maps)}

mapmaps 參數都是物件, map 就是地圖元件,maps 則是 Google Map API。當要在地圖元件上移動中心點或渲染標記,需要調用 map,而需要查詢座標、placeId 或自動提供地址選項等功能需要使用 API 時,則調用 maps。而這個 function 的內容,則是透過 react hooks 將 mapmaps 存於 state 中並調用。

onChange :
在這邊透過 onChange 帶入指定 function,該行為是當滑鼠點擊拖曳地圖時,調整地圖的中心點座標。



地圖元件細節設定

透過這個設定,已經可以呈現出地圖的元件,如果想要做一些其他設定,可以在 onGoogleApiLoaded 中的 function 去針對地圖載入後的元件設定其他參數:

  const apiHasLoaded = useCallback((map, maps) => {
    map.setOptions({
      gestureHandling: 'cooperative',
      maxZoom: 18
    })
    setMapInstance(map)
    setMapApi(maps)
    setMapApiLoaded(true)
  }, [])

因為專案需要同時符合桌機和移動裝置需求,因此在手勢的設定上有進行調整:
gestureHandling : 設定為 cooperative,是讓使用移動裝置的用戶在單指點擊地圖時,希望觸發的是放置地圖標記的功能,而不是縮放功能,在這個設定下,移動裝置用戶僅能使用雙指縮放地圖。
maxZoom : 最大可縮放比例,因應專案是放置地圖在表單中,尺寸範圍有限,因此只能縮小讓地圖移動時可以迅速轉換地區,透過 maxZoom 和 defaultZoom 設定相同數值,則不允許用戶進行地圖放大。



定位使用者位置

取得使用者當前位置的方式,並不是透過 Google Map API,而是透過 Web Geolocation API 取得當前裝備的位置,文件可以參考 https://developer.mozilla.org/zh-TW/docs/Web/API/Geolocation/getCurrentPosition
前兩個參數分別是 success 和 error 的 callback,如果成功拿到 position 則將回傳資料存於 state 中,讓 GoogleMapReact component 中的 center 參數可以取得該座標。

  useEffect(() => {
    navigator.geolocation.getCurrentPosition(
      (position) => {
        setInitPosition({
          lat: position.coords.latitude,
          lng: position.coords.longitude
        })
      },
      () => {
        console.log('無法顯示或拒絕定位')
        setInitPosition(defaultCenter)
      }
    )
  }, [])


地圖元件渲染

經過以上的基本設定,我們已經可以看到頁面上出現初始的地圖元件:

接下來的文章,將繼續紀錄透過地址的輸入,取得回傳結果後放置座標標記,並將座標與 placeId 存於 state 中,讓表單的資料物件能和地圖功能結合。


#React #GoogleMap #Google-Maps-APIs #React Hook #google-map-react







Related Posts

[Cellular Network  Study]

[Cellular Network Study]

ModernWeb'20 隨筆

ModernWeb'20 隨筆

原始型別(傳值By Value ) v.s 物件型別(傳參考By Reference)

原始型別(傳值By Value ) v.s 物件型別(傳參考By Reference)


Comments