如何在Google Static Map上顯示超長路徑?

July 24, 2010 · Posted in Google Maps 

PrintMyMap-Google Static Map API+CSS3
為了讓PrintMyMap的使用者可以感受地圖折好之後的樣子,我利用了Google Static Maps API畫出地圖,再利用CSS3 2d transform把地圖稍作變形,套在預先畫好的背景上。雖然Google Static Maps API解決了我需要將地圖變形的需求,但是有一些限制卻隨之而來。如果有用過Google Static Maps API,就應該會知道它其實只是一張利用URL傳送參數而產生的圖片。雖然Google Static Maps API的文件裡面沒有限制參數的長度,不過既然是使用URL傳送參數就會因為瀏覽器和伺服器端的實作而產生長度限制。

URL長度限制
如果URL長度過長,Google就會吐一個Request-URI Too Large的訊息回來。我用Google Chrome實際測試的結果,長度上限約在1800字元左右。
414 Request-URI Too Large


而這種情況在要顯示超長路徑(如:GPS Tracker紀錄或是路徑規劃產生的路徑)時很容易發生,因為每一個點的經緯度要精確到小數點以下六位,所以每一個點就要將近20個字元,一百個點不到就會超過長度限制。
以下面的這個路徑為例:
path=rgb:0x0000ff,weight:5|40.737102,-73.990318|40.749825,-73.987963|40.752946,-73.987384|40.755823,-73.986397
只有兩個點就已經用掉了110個字元。

比如下面這個路徑規劃的結果,有兩百多個點,在Google Maps API v3上可以正常顯示。
路徑規劃產生的超長路徑

在Google Static Maps API上,我為了不讓URL長度爆掉,只好限制只顯示80個點,就產生了路線不完整的現象。
超長路徑畫不完

所以唯一的解法就是簡化路徑,把一些點去除掉,並盡可能保持形狀。簡化路徑最普遍使用的演算法就是道格拉斯-派克爾法(Ramer–Douglas–Peucker algorithm)。

道格拉斯-派克爾法

credit: 維基百科
道格拉斯-派克爾法的做法就是保留頭尾兩點。將頭尾用一條直線連接,接著找出中間每個點距離這個最大的值b,接著保留這個距離頭尾連接起來的直線最遠的點c。然後設定一個容許值,這個容許值必須小於b。再檢查中間每個點到直線的距離,如果距離大於容許值,就保留這個點。然後用c點,把這條路徑分為兩部分,再依照前面的方法一直做下去。

GDouglasPeuker.js
如果要在Google Maps API或Google Static Maps API上使用道格拉斯-派克爾法,我們可以直接用Bill Chadwick寫好的GDouglasPeuker.js。GDouglasPeuker.js是可以免費使用的,不過如果你覺得它很有用,不妨到Bill Chadwick的網站上去donate一下。

GDouglasPeuker.js內只包含了GDouglasPeucker(source, kink)這個function。
source是LatLng組成的陣列,而kink是容許值(以公尺為單位)。

容許值的設定要特別注意,因為設定得太小,資料量還是很大,不一定能夠顯示。太大的話資料又壓縮過度,無法呈現細節。
以下以成田機場到汐留的開車路線為例,測試容許值。

GDouglasPeucker(route, 10)
壓縮不足,所以還未到終點就已經達到URL長度上限。

GDouglasPeucker(route, 50)
壓縮足夠,已經能夠在URL長度限制內顯示路徑。

GDouglasPeucker(route, 125)
看起來和容許值50時一樣,但資料量更少,因此此容許值比50更好。

GDouglasPeucker(route, 1000)
壓縮更多,路徑稍稍失真。

GDouglasPeucker(route, 2000)
繼續壓縮,路徑失真更嚴重。

GDouglasPeucker(route, 5000)
繼續壓縮,畫出來的路徑幾乎沒有意義。

從以上的測試可以發現容許值125的設定最佳,壓縮程度夠,也能夠忠實呈現原始路徑。
而這個值是怎麼算出來的呢?
我的想法是當兩個座標點被繪製在地圖上並沒有意義,因為地圖上根本會被當成同一個點,因此如果要呈現和未壓縮的路徑完全相同的地圖,最大的容許值就應該是一個像素所代表的實際長度,即地面解析度。

而依照這篇文章對於地面解析度的所推導出來的地面解析度公式為:
ground resolution = (cos(latitude * pi/180) * 2 * pi * 6378137 meters) / (256 * 2level pixels)

換成javascript語法就變成:
Math.cos(map.getCenter().lat() * Math.PI/180) * 2 * Math.PI * 6378137 / (256 * Math.pow(2,map.getZoom()));

套用上面的數值所計算出來的結果為124.13320927642286,這就可以解釋為什麼上面幾個容許值以125最佳了。

Comments

39 Responses to “如何在Google Static Map上顯示超長路徑?”

  1. [...] This post was mentioned on Twitter by MacTalks, bluesaturn. bluesaturn said: 分享 http://www.lis186.com/?p=1945 (如何在Google Static Map上顯示超長路徑?) http://plurk.com/p/6iyti6 [...]

  2. Nineteen on July 25th, 2010 12:59 am

    哈哈,很有趣,這篇很有意思!

  3. 菏泽生活网 on August 5th, 2010 8:27 am

    学习了,网上能人辈出,俺可是个菜鸟任务(>_<)

  4. 炽芒文学 on August 5th, 2010 12:08 pm

    这么远啊 画画就是简单~

  5. 91526 on August 5th, 2010 4:45 pm

    果然内涵。。。

  6. 清晨的欣赏。 on August 6th, 2010 11:39 am

    仔细看了看你的博客,觉得,还不错。如果有机会在外包领域合作。我很期待。

  7. 淘宝店铺推荐 on August 6th, 2010 1:52 pm

    文章不错,值得顶!!

  8. ieij on August 6th, 2010 2:42 pm
  9. дженерик виагра купить on August 6th, 2010 3:06 pm

    Достаточно интересная и познавательная тема

  10. 电脑e管家 on August 6th, 2010 7:05 pm

    这个超长路径地图是不是可以在电子导航仪上显示呢?

  11. 毛孔变粗怎么办 on August 6th, 2010 8:22 pm

    你好啊,我是璇璇,很高兴能在你这留言。想和你交个朋友!

  12. база cian on August 6th, 2010 9:28 pm

    Думаю, какую полезную информацию можно извлечь из этого материала

  13. 精美图片网 on August 7th, 2010 12:26 am

    云彩从天上飘过,我从这里踩过!

  14. 洞口电影网 on August 7th, 2010 12:31 am

    GOOD!很好!

  15. 济南网页制作 on August 7th, 2010 5:12 am

    最近如何。咋没回访哦

  16. 356688 on August 7th, 2010 4:15 pm

    我来也,看看您的博客,貌似不错,O(∩_∩)O

  17. 你会用成人用品吗? on August 8th, 2010 1:01 pm

    家好,我是做成人用品网店的,经营各类成人玩具,情趣内衣 、安全套,各类药物,保证 正品,价格公道,欢迎各位光临,淘宝店:http://chengren365.taobao.com 本店专用QQ:1342920373

  18. 淘宝店铺推荐 on August 8th, 2010 3:45 pm

    文章不错,受益匪浅,顶!!

  19. 高兴seo on August 8th, 2010 6:11 pm

    你好,文章写的不错!!

  20. cne on August 8th, 2010 10:13 pm
  21. 淘宝网 on August 8th, 2010 10:21 pm

    文章写的很不错。

  22. www.356688.com on August 9th, 2010 11:02 am

    貌似写的不错,嘿嘿,下次再来~走也~

  23. 淘宝 on August 9th, 2010 2:08 pm

    网站文章写的很不错,RSS已经被我订阅了!

  24. 易瑞沙 on August 9th, 2010 3:10 pm

    太详细了,谢谢了

  25. 毛孔变粗怎么办 on August 9th, 2010 9:58 pm

    文章写的真不错,我要好好向你学习~~~~~~

  26. coo on August 10th, 2010 12:06 pm

    似乎有点道理

  27. Распланировали свои майские праздники?

  28. 栅栏 on August 13th, 2010 8:14 am

    空虚的

  29. hbzegpcx on August 15th, 2010 2:42 am

    67T59I akoartfogagb, [url=http://tzlgbyprrlwt.com/]tzlgbyprrlwt[/url], [link=http://fkhhiifzfgmc.com/]fkhhiifzfgmc[/link], http://hijreipdqoxr.com/

  30. gleqpr on August 15th, 2010 6:07 am

    XONRHl bxnlhexvheon, [url=http://ssynkvvfrqtr.com/]ssynkvvfrqtr[/url], [link=http://lrfjsaouqasv.com/]lrfjsaouqasv[/link], http://pghapgpyaygr.com/

  31. ABC童装 on August 16th, 2010 4:04 pm

    谢谢分享,又学习了一招了

  32. 减肥饼干 on August 22nd, 2010 12:09 am

    呵呵,好玩!

  33. very on August 22nd, 2010 1:16 am

    低调的飞过

  34. ED Hardy,Shop EDHardys on August 23rd, 2010 12:56 pm

    写的很详细

  35. nike air max on August 23rd, 2010 4:45 pm

    详细,好玩!CUTE!

  36. 体会内衣 on August 25th, 2010 10:24 am

    学习了。。

  37. 欧秀芭莎 on August 25th, 2010 10:40 am

    写的很详细,支持下

  38. 润微 on August 25th, 2010 11:15 am

    很不错啊。。。。

  39. 名人瑞裳 on August 25th, 2010 11:34 am

    地板中。。。

Leave a Reply




  • Plurk

  • 我的位置

  • Events

  • My Flickr Photos

    www.flickr.com
  • Meta

  • Counter
    Technorati Profile