google maps api的敗筆 GClientGeocoder地址轉譯有誤
日前,一位客戶問說為什麼我給它寫的google地圖api連結程式,有些地址查出來的位置會和google官網的不一樣?我聽到時當然覺得不大可能,試了一下對方給我的地址…啊咧,還真的不一樣!
我想了想,可能是google maps api連接的資料庫,和google maps直接查詢的資料庫有差異。
搜搜google,我們在使用地址轉地圖位置時,都會用到GClientGeocoder這個函式,它會把輸入的地址先去google資料庫查詢座標,再拿這座標去查詢地址。
var map = new GMap2(document.getElementById("map_canvas")); var geocoder = new GClientGeocoder(); function showAddress(address) { geocoder.getLatLng( address, function(point) { if (!point) { alert(address + " not found"); } else { map.setCenter(point, 13); var marker = new GMarker(point); map.addOverlay(marker); marker.openInfoWindowHtml(address); } } ); }
既然GClientGeocoder查出的座標有問題,就換個連結通道試試,找到Geocoding via HTTP,它是透過位址 http://maps.google.com/maps/geo 再帶參數查詢座標。
參考了此篇將中文地址寫入資料庫時透過 google maps 取得作標的作法,取出座標,再帶入google maps api來查詢:
1. 用php取出座標:
$address = $_POST['address']; $map_api_key = 'ABQIAAAATEOf9wLppH9P5Zgz_mbvGhTQKjgTyenlgzz_Jmf84ElUIhrNPBTph578IhrUkgnO7SFaO9P03-E0pQ'; $csv_url = "http://maps.google.com/maps/geo?q=".urlencode($address)."&output=csv&key=".$map_api_key; $ch = curl_init($csv_url); curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1); $get_contents = curl_exec($ch); curl_close($ch); $string = explode(',', $get_contents); $longitude = $string[2]; // 經度 $latitude = $string[3]; // 緯度
2. 用javascript至google查詢:
function initialize() { if (GBrowserIsCompatible()) { var map = new GMap2(document.getElementById("map_canvas")); map.setCenter(new GLatLng(<?=$longitude?>,<?=$latitude?>), 13); map.setUIToDefault(); } }
結果…查出來的位置還是不對T_T
最後,跟客戶確認狀況,他希望地址位置對比較重要,那麼就用iframe去嵌 http://maps.google.com.tw/maps 的位址,再帶入參數:
更多參數,可瀏覽此文Google Map Parameters
搞到最後,還是用iframe,不是用google maps api,讓人覺得有xxx
註1:此文範例略掉一些東西,不談基本,所以比較適合有用過google maps api的朋友瀏覽
註2:有用google maps api(GClientGeocoder)做地址轉譯的人,可以試試這個地址(宜蘭縣壯圍鄉美城村大福路3段53巷9號),會和google maps網站查出來的位置不一樣
註3:基礎文章(Google Maps API 實作範例 | 使用google map api來做地址定位 | Google Maps API 輸入地址轉經緯度,並產生地圖程式分享!! | I love Google Map II)
註4:最近api出v3版本,有空再玩看看
並非 Google 的錯,這是因為 load 錯 Maps API.
官網的範例使用的是 maps.google.com 的 domain, 你應該要使用 maps.google.com.tw.
如:
<script type=”text/javascript” src=”http://maps.google.com.tw/maps?file=api&v=2&key=abcdefg&hl=zh-TW”
詳情請看
http://code.google.com/apis/maps/documentation/#Localization
Maps API V3 有些更變,可直接改 language/country
http://code.google.com/apis/maps/documentation/v3/reference.html#Geocoder
謝謝您的指點,我已嚐試改為maps.google.com.tw做為連結位址,但依然回應錯誤的位置,如果您也有在用google maps api的話,可以試試查詢這個地址(宜蘭縣壯圍鄉美城村大福路3段53巷9號),它標出來的位置會和google maps官網直接查詢的不一樣…
至於V3版本,也許已經有修正這個問題,但我還沒時間去試…
一般來說 load 錯 API 是最常犯的錯,不過看來這次是另一個問題。
很不幸的 Google Maps 對『幾段』的地址只支援國字,而不支援阿拉伯數字。
試試看”宜蘭縣壯圍鄉大福路三段53巷9號” (注意3換成了三)
在 Google 修好這個問題之前,可以用 Javascript 偵測並修正。
至於要如何看出問題呢?當你在 Google Maps 搜尋時,你會發現它找的是『美城村, 263宜蘭縣壯圍鄉 *附近的* 大福路3段53巷9號』
注意,傳回的結果是『美城村』而非搜尋的地址。
而地圖上的標記『普羅旺斯』及『儷雯整体工作室』為附近景點的結果(剛好是查詢地址)。
另外從 API 回傳的結果其實也就是『美城村, 263台灣宜蘭縣壯圍鄉』真正的經緯度,這點和 Google Maps 網站回傳的是一致的,只是少了附近景點的資料。
我想我遇到的問題和你說的國字段無關…因為不管是數字還是國字,查詢出來的結果還是一樣
但您第二點提出的,我想可以為google maps和api查詢出來的位置為何不同做出一個解釋…
到google maps查詢地址時,它會同時搜尋同遭登錄的景點,增加準確性…
但api卻不會做這樣的事情,找不到全部地址,就以它能辨識的為主…
很高興您願意和我交流,並提供意見讓我了解,謝謝^^
你回傳的地址和這個一樣嗎?
[宜蘭縣壯圍鄉大福路三段53巷9號]
http://0rz.tw/iQnPN
我的 API (v3)和 地圖都是一致的。
這結果和 Google Simple Geocoder example (v2) 也是一樣。
http://code.google.com/apis/maps/documentation/examples/geocoding-simple.html
p.s. 之前貼的好像一直沒出來,可能是地圖的連結太長了
http://0rz.tw/iQnPN
我看不到地圖
另外,問題可能初步解決了吧…你給我的網址做查詢的確是一樣,我重新檢查資料後發現,其實那位客戶填入的資料是全形的3段而不是半形的3段,所以我程式replace掉半形做嚐試當然也沒用…(當初copy他給我的地址做測試,太大意了),換成三段後就正常
宜蘭縣壯圍鄉大福路3段53巷9號
http://code.google.com/apis/maps/documentation/examples/geocoding-simple.html
它的結果和google maps的位置並不一樣,也和我使用的api查詢結果不一樣(換言之,我看到三種不同的位置,第一是google maps,第二是example裡的geocoding-simple.html查詢,第三是我自己用v2 api的查詢)
如果您在V3版本測試的結果一樣,那也只能說google maps和api V3使用的函式或資料庫是一致的吧…
再次謝謝您的提點^^
宜蘭縣壯圍鄉大福路3段53巷9號<–出來的結果不對
請問版主知道web google map url 的 geocode 參數可以用什麼方式或api換算出來嗎?
geocode format example:
&geocode=FdisfgEdbv4-BynrhSfOb6xCNDGhNVcYFyLTXQ%3BFfU_fgEdDps-BykPhKLo3atCNDH3YCAWVVFU6g
目前我只發現geocode使用”%3B”來分隔value
謝謝!