最近在處理 POIBank 搜尋的時候,難搞的 @willie 又來了一個新需求,他想要在搜尋嘉義市的時候也可以搜尋到嘉義縣的景點,簡單舉個例子。「故宮南院」的地址為「嘉義縣太保市故宮大道888號」,所以他希望使用者在搜尋時,無論城市是選擇嘉義縣、太保市或嘉義市的時候,都可以找到「故宮南院」。
對系統來說,沒有什麼需求是做不到的,但不能把需求客製化,所以想了一下這需求要如何開發才會比較有系統性。
我們先來整理一下中華民國的行政區劃:
- 省、直轄市
- 縣、市
- 鄉、鎮、縣轄市、直轄市山地原住民區、區
- 村、里
- 鄰
嘉義縣與嘉義市
嘉義市是「第二級市」,與嘉義縣無關。而嘉義縣是「第二級縣」,與嘉義市無關,兩者是平行位階。另外嘉義縣的縣治是太保市,為「第三級縣轄市」,但就算當地人也不見得搞的懂從屬關係。
以行政區邊界來看,嘉義縣與嘉義市雖然是平行位階,但嘉義縣卻將嘉義市包圍起來 (嘉義市是嘉義縣的內飛地),就跟新北市及台北市雖然都是「一級直轄市」,但新北市卻將台北市包圍起來一樣的意思。
宜蘭縣與宜蘭市
宜蘭縣是「第二級縣」,而宜蘭市是「第三級縣轄市」,另外宜蘭縣的縣治正好為宜蘭市。
以行政區邊界來看,因為宜蘭縣的縣治為宜蘭市,所以宜蘭縣將宜蘭市包圍起來也是很正常的事。
系統化需求
了解了行政區劃以及自己在 Google 上的搜尋經驗來講,使用者真的很難知道所搜尋的關鍵字,到底是屬於哪個行政區的位階,能打出「嘉義」或「宜蘭」就已經很厲害了。所以使用者在宜蘭市搜尋「羅東夜市」,或者是嘉義市搜尋「故宮南院」的時候,都應該要能搜的到正確的結果。
回到開頭所講的,這裡就可以從這裡把原始需求系統化,其實就是需要一個 similar city 的功能。把 schema 整理出來之後,也就是下面這樣而已:
city | similar |
---|---|
嘉義市 | 嘉義縣 |
宜蘭市 | 宜蘭縣 |
所以在嘉義市搜尋的時候,必須要將嘉義縣也加進來,在 PostGIS 就是用 ST_Union
將兩個 bounding box 合併起來再丟去 Elasticsearch 用 geo_polygon
做搜尋。
關於生活圈
上面的這個功能雖然已經上線了,但這世界真的沒有這麼簡單。其實 similar city 不只是單純的地名相似而已,應該也要包括相似的地理位置、生活習性、交通便利度…等。以下舉幾個例子大家應該就懂意思了。
- 九份:應該算基隆、新北、台北哪個城市呢?
- 淡水老街:應該算新北、台北哪個城市呢?
- 長庚醫院:應該算林口、桃園、龜山、新莊、蘆竹、迴龍哪個城市呢?
從上面這些例子就知道了,其實還有很多可以改善的空間,最重要的是要把生活圈也加到 similar city 才行,還有很大的進步空間啊!