顯示具有 GoogleMap 標籤的文章。 顯示所有文章
顯示具有 GoogleMap 標籤的文章。 顯示所有文章

2012年2月23日 星期四

既然Flash版GoogleMap不再發新的key…



總覺得自己老是在走偏門…=_=。

自從GoogleMap Flash版停止再發送key值之後,GoogleMap的Flash版本等於正式走入歷史,也因此我們要在flash裡使用GoogleMap的話會變得很頭大。
雖然說以後全flash的網站「理論上」會越來越少,應該都會是flash搭配html一起邁向美好的未來,但是有時難免客戶(或設計師)為了整體視覺著想(或其它因素),一定要在flash使用GoogleMap的話,那就是我們要苦往肚子裡吞的時候了。
這兩天研究了一下,想說看有沒有辦法弄一個簡單的GoogleMap到flash裡,結果似乎是可行的。
說穿了,原理其實就是計算經緯度,然後跟Google「偷偷」的拿取該經緯度下的圖片,再呈現在flash裡而已。

GoogleMap的圖片區塊
可以先參考一下這一篇:
http://code.google.com/intl/zh-TW/apis/maps/documentation/javascript/v2/overlays.html#Google_Maps_Coordinates
要取得圖片的網址很簡單,瞄一下httpWatch的話就會知道,格式類似這樣:
http://mt0.googleapis.com/vt?lyrs=m@170000000&src=apiv3&hl=zh-TW&x=1&y=1&z=15&s=G&style=api|smartmaps
Google把地圖切分成很多區塊,每一個區塊(Tile)的圖片大小是256X256,在不同級數之下會有不同數量區塊,數量的增加是以2的次方在增加的。

也就是說,在縮放等級(zoom)是0的情況之下,世界地圖只有2的0次方=1張的圖片,zoom=2的時候,x軸及y軸各有2的2次方=4張圖,一共16張圖。
有了這個概念的時候,我們就可以依照zoom的大小,配上實際經緯度投射到平面座標上的點,來找出目前該經緯度所對應到的圖片,然後再從Google那邊把圖抓回來就對了,剛剛上面的圖片網址裡,x及y就是代表該區塊的index值,z則是縮放值。

經緯度的投射座標
既然已經知道地圖被切成多少區塊,就很方便取得了,但麻煩的在於經緯度。
GoogleMap使用的是「麥卡托投影法」來計算經緯度,請參考wiki:
http://zh.wikipedia.org/wiki/%E9%BA%A5%E5%8D%A1%E6%89%98%E6%8A%95%E5%BD%B1
這種投影法將地球投影成圓柱狀體,也因此,經度的部份是從最左邊的-180到最右邊的180度,平均均分地圖上的所有x軸距離。
於是我們可以很簡單的計算出某一個經度應該對應到實際像素裡的哪一個x值,因為經度是平均切割整個世界地圖的,所以純粹只是比例的換算而已。
麻煩的在於緯度。
緯度並不是平均切割地球的從南到北,越靠近極點,形變就越大。
感謝wiki,我們不用自己去導出投影的公式,wiki已經幫我們列出來了:

上半部是由經緯度計算出x及y的值,下半部是由x跟y的值反算出經緯度,由於我們要將經緯度用在GoogleMap圖片的像素值上,因此我們只要再加上一些參數做修正其實就可以了。

結果
我花了一點時間實作了一下,結果在這邊:

http://labs.medialand.com.tw/jason/flash/googlemap/
原始檔下載
輸入經緯度及放大級數,這flash就會把周邊的地圖載入進來。
其它的,例如:拖動地圖…等等的,我就沒時間再寫了,反正都已經能正確取得圖片及計算出座標值,其它的就是另外一種工作了。
比較需要注意的是
1. 這只是簡單的地圖,畢竟不能跟完整個GoogleMap相比(當然你要寫得超屌也可以)
2. 經過測試,無法去draw載進來的地圖,crossdomain的關係。
3. 一樣是crossdomain的關係,其它的GoogleMap api,像是地址反查這種功能,在web的flash裡也無法直接去做query,可能還是得透過js去做中繼。
4. 這是旁門左道,非必要的話還是請愛用GoogleMap v3。


2009年10月27日 星期二

Flash版GoogleMap使用街景


前一陣子(好大一陣子),GoogleMap的台北街景上線,順便的我發現GoogleMap api for flash也有多了一些東西,像是路徑規劃、3D地圖等等…。
3D地圖基本上只是把地圖變成可以旋轉改變角度而已,事實上仍然是平面的,「非常的」耗效能,國外是有人把建築物用pv3D直接疊在3D地圖上感覺像是Google Earth一樣,但是說真的我的電腦已經算不慢的了,跑起來還是慢到可怕…。

說起來比較讓人興奮的應該是路徑規劃了吧。
之前Flash版的GoogleMap少了這個總覺得少了什麼,現在有了就好多了。
不過這一篇不是要講路徑規劃的部份,而是要講街景。
之前因為台灣都沒有街景,所以一直沒去碰這個,現在台北有了,就很好奇的想把街景跟Flash的GoogleMap結合起來看看。
有把玩過GoogleMap街景的應該都會注意到,街景的介面是Flash的,我想這是因為Flash在處理圖片的移動及blur這些部份是比js來得方便的原因吧?但是目前為止雖然街景介面本身是個Flash,但是仍然無法直接被Flash版的GoogleMap直接載入使用,所以我只好用土法練鋼的方法 – 透過js溝通。

Google在文件上寫得還算清楚明白,大概看一下就知道怎麼叫出街景了,挺簡單的。
先從html開始,首先載入GoogleMap的js,要改變的只有key這個變數,key就是跟Google申請的api key。
然後在body上加入onload跟onunload的處理方法,我這邊是先分別指定initialize()跟unloadAll()兩個function來負責。onunload一定要處理,否則很有可能會造成記憶體沒有回收的狀況。


由於地圖是由Flash來處理,因此就不產生js的GoogleMap實體。
所以直接宣告廣域的街景物件(GStreetviewPanorama)及一個判別是否由flash版GoogleMap指定座標的flag。由於GStreetviewPanorama需要一個dom來放置,所以在html裡我們放一個div來裝GStreetviewPanorama。
然後就編寫initialize()及unloadAll()。


GStreetviewPanorama的error事件我們主要會用到的大概是兩個:
1. 錯誤代碼603:表示沒有Flash Player。
2. 錯誤代碼600:被指定的座標沒有街景。
基本上這兩個都要實作,以避免出問題。
而GStreetviewPanorama的initialized事件,則是當GStreetviewPanorama的座標位置改變的時候會被觸發,因此我們可以監聽這個事件來控管目前地圖跟街景之間座標的同步。
因此這兩個事件處理函式應該會很像是這樣子:


最後就很簡單了。
需要顯示哪邊的街景時,就直接從Flash版的GoogleMap用ExternalInterface去呼叫一個function來指定GStreetviewPanorama的座標就好。


在看文件時,其實js的GoogleMap有一個優點是可以把目前有支援街景的路線疊上一個overlay在地圖上,但是Flash版的沒有,所以如果要用Flash版的GoogleMap去結合街景,使用者只能用「試試看」的方式去點選某條路是否有街景,這是比較不方便的,也許也只能等Google下次更新Flash api時再期待會不會有這功能出現了。