Day04 簡介
昨天我們已經成功搜尋到附近的咖啡廳了,今天我們就來喘口氣,先不探討新的功能,先想想我們可以怎麼做
設定搜尋類型
我們知道在使用 nearbySearch
API 時,可以設定搜尋類型,在 Day03 的時候我們使用咖啡廳當我們的範例:
// Day03
const findCafeLocation = () => {
if(mapApiLoaded) {
const service = new mapApi.places.PlacesService(mapInstance)
const request = {
location: myPosition,
radius: 1000,
type: ['cafe'] // 咖啡廳
};
service.nearbySearch(request, (results, status) => {
if(status === mapApi.places.PlacesServiceStatus.OK) {
setPlaces(results)
}
})
}
}
那我們還能搜尋哪幾種類型的地標呢?
一樣搜尋 Google Maps API 文件,可以看到可以搜尋的類型多達下面好幾種:
accounting
airport
amusement_park
aquarium
art_gallery
atm
bakery
bank
bar
beauty_salon
bicycle_store
book_store
bowling_alley
bus_station
cafe
campground
car_dealer
car_rental
car_repair
car_wash
casino
cemetery
church
city_hall
clothing_store
convenience_store
courthouse
dentist
department_store
doctor
drugstore
... 下略
這就代表我們可以做一些按鈕或者表單,用來更新我們的搜尋類型:
// 上略
// 創建一個 state
const [searchType, setSearchType] = useState('cafe')
// 搜尋
const findLocation = () => {
if(mapApiLoaded) {
const service = new mapApi.places.PlacesService(mapInstance)
const request = {
location: myPosition,
radius: 4000,
type: searchType // 改為 state
};
service.nearbySearch(request, (results, status) => {
if(status === mapApi.places.PlacesServiceStatus.OK) {
setPlaces(results)
}
})
}
}
// 做一個 Function 可以改變搜尋類型
const handleSearchType = e => {
setSearchType(e.target.name)
}
// render
return (
<div style={{ height: '100vh', width: '100%' }}>
<input type="button" value="開始搜尋" onClick={findLocation} />
<input type="button" value="找餐廳" onClick={handleSearchType} name="restaurant"/>
<input type="button" value="找牙醫" onClick={handleSearchType} name="dentist"/>
<input type="button" value="找咖啡廳" onClick={handleSearchType} name="cafe"/>
<GoogleMapReact
bootstrapURLKeys={{
key: Key,
libraries:['places']
}}
options={{ mapTypeId: mapType }}
onBoundsChange={handleCenterChange}
defaultCenter={props.center}
defaultZoom={props.zoom}
yesIWantToUseGoogleMapApiInternals
onGoogleApiLoaded={({ map, maps }) => apiHasLoaded(map, maps)}
>
用這樣的作法,我們就可以改變搜尋類型了
input
這邊應該是要包成 Component 比較美觀,所以我們可以簡單包一下:
// 切換搜尋類型按鈕
const SearchType = ({ text, type }) => {
return <input type="button" value={text} name={type} />
}
const SimplaMap = () => {
// 略
//render
return (
<div style={{ height: '100vh', width: '100%' }}>
<input type="button" value="開始搜尋" onClick={ findLocation } />
<div onClick={ handleSearchType }>
<SearchType text="找餐廳" type="restaurant" />
<SearchType text="找牙醫" type="dentist" />
<SearchType text="找健身房" type="gym" />
</div>
<GoogleMapReact
bootstrapURLKeys={{
key: Key,
libraries: ['places']
}}
...
現在讓我們來測試看看,點選搜尋類型按鈕,是否會改變搜尋地標 :
這樣就沒問題了,接下來我們看看還有什麼功能可以讓我們採用:
地圖種類
現在我們可以製作一個挺酷的功能,那就是切換路面圖與衛星圖
實作方法也相當簡單,我們可以在 <GoogleMapReact>
加入一個屬性,叫做 option
,並在內中放一個物件,給一個 key 為 mapTypeId
,試試看值 hybrid
<GoogleMapReact
bootstrapURLKeys={{
key: Key,
libraries:['places']
}}
options={{ mapTypeId: 'hybrid' }}
onBoundsChange={handleCenterChange}
defaultCenter={props.center}
defaultZoom={props.zoom}
yesIWantToUseGoogleMapApiInternals
onGoogleApiLoaded={({ map, maps }) => apiHasLoaded(map, maps)}
>
可以看到變成衛星圖了!
這也代表我們可以做一組切換按鍵,來切換衛星圖與路線圖:
// 上略
// 創建一個 state
const [mapType, setMapType] = useState('roadmap')
// 改變地圖樣式
const handleMapTypeId = e => {
setMapType(e.target.name)
}
const SimplaMap = () => {
// 略..
//render
return (
<div style={{ height: '100vh', width: '100%' }}>
<input type="button" value="開始搜尋" onClick={ findLocation } />
<div onClick={ handleSearchType }>
<SearchType text="找餐廳" type="restaurant" />
<SearchType text="找牙醫" type="dentist" />
<SearchType text="找健身房" type="gym" />
<input type="button" value="衛星" onClick={ handleMapTypeId } name="hybrid" />
<input type="button" value="路線" onClick={ handleMapTypeId } name="roadmap" />
</div>
<GoogleMapReact
bootstrapURLKeys={{
key: Key,
libraries:['places']
}}
...
一樣,我們可以把它包得美觀一點,但這邊就不另行製作了,我們留到下次再優化
順帶一提,如果我們沒有放入 option
,它的預設 mapTypeId 就會是 roadmap
來看看會如何切換吧!
另外關於 Map Types,這邊列出四種,包括我們已知的兩種:
Map Type | |
---|---|
roadmap | 路線圖,也是默認類型 |
satellite | 即 Google Earth 的衛星圖像 |
hybrid | 普通視圖與衛星圖像的混合 |
tettain | 地形物理地圖 |
後記
今天的內容不多,主要是在思考這個系列的成品要做成什麼樣子
原本打算只做簡單一點就好,但後來覺得好像太簡單了
我覺得主要的問題在於最初花了很多時間在看文件,才會有那種我花好多時間做了地圖應用的假象
預計明天的內容是關於更便利的搜尋功能與解決一些 setState 的非同步問題