将地址转换成地理座标的程序被称为地理编码 (Geocoding),Google Maps API亦支援地理编码服务(注意:有每天查询次数不可超过2,500次的限制,申请Google Maps API Premier可以提高到100,000次) ,呼叫方法很简单,使用URL "http:…
利用HTML5 Canvas动态产生文字图示
前几篇Google Map API文章,一直有用到Google地图加上Marker的做法。(即下图的红色大头针图案)

不过,若全部的标示点用一样的图示,会显得无趣且容易混淆(如下图所示),虽然将滑鼠移到标示图案上方会显示名称,在使用者体验上总觉得还有改善空间。

事实上,Google Maps API在新增地标时,是可以自订图示的。MarkerOptions提供icon参数可指定图档URL,另外有shadow参点可指定阴影图档的URL,以取代预设的黑点红色大头针图示。
只是有个小问题,在消防分队位置显示范例中,台北市共有44个消防分队,即使能自订图示,可能也只是用44台消防车换掉44根大头针,对于识别度并没有太多提升,除非我们能预先制作44个刻有消防分队名称的图档,再一一对应到44个Marker使用…
身为程式魔人,44个图档用手工做是不被允许的,当然要自动产生才不会被人耻笑。我第一个想到是用ASP.NET动态产生图档的技巧,不过再转念一想,何不用HTML5的Canvas来实做,完全在Client解决? (IE6/7/8:那我们怎么办?念你们曾纵横江湖多年,也算时代英雄,你们自尽吧!)
HTML5 Canvas要即时产生图档不是问题,再配合Canvas.toDataURL()就可取代图档案URL,作为MarkerOptions.icon参数的设定值,就能达到当场动态产生Marker图示的目的。
我试写了一个小函数,用Canvas作图,再用toDataURL()输出作为<img>的src来源:
<!DOCTYPE html> <html> <head runat="server"> <title>動態Canvas圖標</title> <script type='text/javascript' src='http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.1.js'></script> <style> body,input { font-size: 9pt; } img { margin: 5px } </style> <script> $(function () { //利用canvas產生一個內含文字的圖檔 function createMarkerIcon(text, opt) { //定義預設參數 var defaultOptions = { fontStyle: "normal", //normal, bold, italic fontName: "Arial", fontSize: 12, //以Pixel為單位 bgColor: "darkblue", fgColor: "white", padding: 4, arrowHeight: 6 //下方尖角高度 }; options = $.extend(defaultOptions, opt); //建立Canvas,開始幹活兒 var canvas = document.createElement("canvas"), context = canvas.getContext("2d"); //評估文字尺寸 var font = options.fontStyle + " " + options.fontSize + "px " + options.fontName; context.font = font; var metrics = context.measureText(text); //文字大小加上padding作為外部尺寸 var w = metrics.width + options.padding * 2; //高度以Font的大小為準 var h = options.fontSize + options.padding * 2 + options.arrowHeight; canvas.width = w; canvas.height = h; //邊框及背景 context.beginPath(); context.rect(0, 0, w, h - options.arrowHeight); context.fillStyle = options.bgColor; context.fill(); //畫出下方尖角 context.beginPath(); var x = w / 2, y = h, arwSz = options.arrowHeight; context.moveTo(x, y); context.lineTo(x - arwSz, y - arwSz); context.lineTo(x + arwSz, y - arwSz); context.lineTo(x, y); context.fill(); //印出文字 context.textAlign = "center"; context.fillStyle = options.fgColor; context.font = font; context.fillText(text, w / 2, (h - options.arrowHeight) / 2 + options.padding); //傳回DataURI字串 return canvas.toDataURL(); } $("<img />", { src: createMarkerIcon("Jeffrey") }) .appendTo("body"); $("<img />", { src: createMarkerIcon("黑暗執行緒", { //注意: fontName所指定字型,需使用者機器上有安裝才算數 fontName: "微軟正黑體", fontSize: 14, fontStyle: "bold", padding: 5, bgColor: "#6199DF", fgColor: "white" }) }).appendTo("body"); }); </script> </head> <body> </body> </html>
姜姜姜姜~~ 这样子只要输入文字,就可以当场产生图示啰!

简单修改程式,加入icon参数指向createMarkerIcon():
var marker = new google.maps.Marker({ position: latlng, //經緯度 title: "八角亭", //顯示文字 icon: createMarkerIcon("八角亭", { bgColor: "brown" }), map: map //指定要放置的地圖對象 });
原本黑头大头针就换成带文字的告示牌,是不是清楚多了呢?

到了该为HTML5欢呼的时刻,赞啦!!
原文:http://blog.darkthread.net/post-2012-06-16-canvas-dynamic-image.aspx