查詢 ・ Places

Places

給一句話,直接回傳一份地點清單。
「拉麵」、「台北的披薩店」、「忠孝東路的停車場」都可以直接丟進去,不必先拆成分類與座標。

單次回傳
20
可指定類型
1
請求
GET
「拉麵」在台北車站一帶的搜尋結果12345台北車站
「拉麵」在高雄車站一帶的搜尋結果12345高雄車站
拉麵

Location25.0478, 121.517022.6393, 120.3021

  1. 1一風堂 台北車站店
  2. 2明拉麵Ramen Bar
  3. 3太陽蕃茄拉麵 站前本店
  4. 4屯京拉麵 台北站前店
  5. 5花月嵐 台北凱撒店
  1. 1麵屋高 高雄火車站店
  2. 2麵屋田介
  3. 3好朋友拉麵館
  4. 4麵屋高 美麗島店
  5. 5拉麵橫山家 高雄七賢店
同一句「拉麵」,只換 Location —— 店名與落點都是實際查詢回來的。 台北的 3–5 座標相同(同一棟美食街),圖上散開才看得到。

「附近」是哪裡由你決定

查詢字串本身不帶地理資訊,「拉麵」在台北與在高雄應該回不同的店。Location 就是用來講清楚這件事的,同一句話換一組座標,整份清單就跟著換。

Radius 可以再給一個範圍,讓該範圍內的地點優先。 但它是優先而不是篩選 —— 下面這張圖的圈在脹縮,右邊的清單卻沒有動:

12345

Radius5020,000公尺

回傳的前五筆

  1. 1一風堂 台北車站店
  2. 2明拉麵Ramen Bar
  3. 3太陽蕃茄拉麵 站前本店
  4. 4屯京拉麵 台北站前店
  5. 5花月嵐 台北凱撒店

兩種半徑,結果完全相同

圈的大小為示意,未按比例。清單是實際回傳的前五筆 —— 半徑放大 400 倍也沒有變。

所以「只回這個範圍內的」做不到 —— 得自己拿回傳的geometry.location 算距離再過濾一次。 真正決定結果落在哪一區的是 Location,不是 Radius。

用類型收斂結果

查詢字太籠統時,結果會被最有名的那類地點佔滿。比如下面查的都是「台北」、位置都在台北車站,只換 Type,不指定時回的全是百貨公司,指定之後才拿得到你要的那一類。

請求

  • Query台北
  • Location25.0478, 121.5170
  • Type(不指定)restaurantparking

回應

  1. 京站百貨公司
  2. 誠品 台北車站捷運店百貨公司
  3. 誠品 站前店百貨公司
  4. 新光三越 台北站前店百貨公司
  5. 誠品 R79店百貨公司
  1. 台北餐旅總所複合式餐廳
  2. 小南門點心世界 北車店北方麵食點心
  3. 大戶屋 新光台北車站店日式簡餐/便當
  4. 台鐵便當本舖 2號店便當/自助餐
  5. 摩斯漢堡 台北車站店漢堡炸雞速食餐廳
  1. K區地下街停車場汽車地下停車場
  2. Times 台北地下街停車場汽車地下停車場
  3. 正好停停車場 台北車站西側地上站汽車平面停車場
  4. 正好停停車場 台北車站西區地下站汽車地下停車場
  5. 京站汽車停車場汽車地下停車場
三份清單都是實際查詢回來的,差別只有 Type 這一個參數。

TextSearch 的 Type 只能指定一種; 需要一次涵蓋多種類型的話,Autocomplete 的 Types 可以用| 串最多五種。完整類型清單見 Type List。

一筆結果長什麼樣

名稱、完整地址、座標與 types 陣列是每一筆都有的。 除此之外還有 kw_extra,這是勤崴自有圖資多給的部分。

  • name一風堂 台北車站店
  • formatted_address台北市中正區北平西路3號2樓
  • geometry.location25.047924, 121.517081
  • typesestablishment ・ point_of_interest ・ food ・ store ・ restaurant
  • kw_extra.category_name拉麵店
  • kw_extra.24hr_openfalse
實際回應的第一筆(查詢「拉麵」,位置在台北車站)。 標色的兩欄是 kw_extra —— 標準欄位之外,勤崴另外給的在地資訊。

types 是通用分類(restaurant、store)
kw_extra.category_name 則是中文細分類
比如同樣是 restaurant,使用 kw_extra.category_name 可再細分出「拉麵店」「北方麵食點心」「漢堡炸雞速食餐廳」等等。
想要在 UI 上直接顯示分類標籤時,後者比前者好用得多。

一次 20 筆,還要更多就用 PageToken

單次請求最多回 20 筆候選。需要更多時,把回應裡的 next_page_token 放進下一次請求的 PageToken 就能續抓 —— 沒有那個 token,第二批就開不了:

請求 ①

  • Query拉麵
  • PageToken(不帶)

回應 ①results ・ 20 筆

next_page_token<token>

請求 ②

  • Query拉麵
  • PageToken<token>

回應 ②results ・ 再 20 筆

next_page_token<token>

單次最多 20 筆為 API 定義;圖上只畫筆數與 token 的接法,不代表實際回傳內容。

20 筆通常已經夠一個搜尋結果頁用了。真的要窮舉某一區的地點, 比起一直翻頁,用 Type 加上不同的 Location 分區查 會更快也更完整。

跟 Autocomplete 的差別

兩支都是拿文字換地點,但用在不同時刻: 使用者還在打字時用 Autocomplete, 使用者已經送出時用 TextSearch。

  • Autocomplete:每按一個鍵就打一次,回的是「你可能想找的」預測,很短、很快。
  • TextSearch:是送出後打一次,回的是完整結果。帶座標、地址與 kw_extra,可以直接畫在圖上。
  • 兩者可以接起來:Autocomplete 拿到 place_id,再用 Place Details 取完整資料,比重打一次 TextSearch 精準。

詳細用法見 Autocomplete。

串接 API

REST 端點是 GET /maps/api/Place/TextSearch/json。Query 與 Key 是必填,其餘都可省略。

curl -sS -G "https://kwmap.localking.com.tw/maps/api/Place/TextSearch/json" \
  --data-urlencode "Query=拉麵" \
  --data-urlencode "Location=25.0478,121.5170" \
  --data-urlencode "Type=restaurant" \
  --data-urlencode "Key=<your-key>" \
  -H "Ocp-Apim-Subscription-Key: <subscription-key>"

圖台上則是 mapPlus.PlacesService 的 textSearch(request, callback), 參數名稱是小寫的 text / location / radius / type。完整參數與回應結構見 API 文件。