[[PageOutline]] = Step by Step building Your Own Google Map Application = == 申請 Gooogle Map API Key == * http://code.google.com/apis/maps/signup.html * 勾選同意使用規範,輸入網址,點選『Generate API Key』 [[Image(GoogleMapKey.jpg)]] * 產生 API Key 完畢就會得到第一個 HTML 範例 [[Image(GoogleMapSample.jpg)]] * 把 HTML 範例貼到 goglemap.html 檔案放置在 www 目錄(Ex. /var/www)中,就可以看到[http://trac.nchc.org.tw/googlemap.html 第一個成果]囉 :) == 解析網站原始碼 == * 參考 http://deepsea.biodiv.tw/locamapd.asp (PART 1) {{{ #!java function load() { PassValue(); // 解析 URL 中帶的參數 if (GBrowserIsCompatible()) { var map = new GMap2(document.getElementById("map")); // 取得 DOM 中,名稱為 map 的元件 map.addControl(new GLargeMapControl()); // 加入左上角比例尺規控制列 map.addControl(new GMapTypeControl()); // 加入右上角"地圖","衛星","混合地圖"按鈕 map.setCenter(new GLatLng(23.8,121), 7); // 設定預設經緯度北緯 23.8, 東經 121, 預設比例尺 100 公里(7) map.setMapType(G_SATELLITE_MAP); // 設定預設底圖為"衛星" } }}} * 我們把 function load() 裡面的程式加進 HTML 範例中, 就可以得到[http://trac.nchc.org.tw/googlemap1.html 第二個成果]囉 :)[[BR]] 這裡我額外加了 [http://code.google.com/apis/maps/documentation/controls.html GScaleControl] 元件, 來得知目前比例尺是多大. 這樣就可以知道數值 7 是對應比例尺 100 公里, 數值 8 是對應 50 公里. {{{ #!java map.addControl(new GScaleControl()); // 加入左下角比例尺狀態列 }}} * 繼續解析 http://deepsea.biodiv.tw/locamapd.asp (PART 2) {{{ #!java var request = GXmlHttp.create(); // 產生一個非同步的 AJAX XMLHttp 物件 (Jazz: 好簡單的一行 AJAX 啊!!) if (queryPair[0]=='R1') { // 這段是用在對應"物種統計"與"科別統計"的 URL 解析上 var GetDataXml="getdeepstaxml.asp?" + queryPair[0] + "=" + valuePair[0] + "&" + queryPair[1] + "=" + valuePair[1]; } else { var GetDataXml="getdeepstaxml.asp"; // 預設因為 queryPair[0] 是空的, 所以資料來源來自 getdeepstaxml.asp } request.open("GET",GetDataXml, true); // 用 XMLHttp 物件去開啟 http://deepsea.biodiv.tw/getdeepstaxml.asp }}} * 我們首先來看 http://deepsea.biodiv.tw/getdeepstaxml.asp 所回傳的 XML 資料 {{{ 這是一筆 XML 紀錄 依格式看來 (lat1, lng1) 是起點, (lat2, lng2) 是終點, id 是測站代號, depth 是魚網打撈的水深範圍 }}} [[Image(biodiv_xml.jpg)]] * 繼續解析 http://deepsea.biodiv.tw/locamapd.asp (PART 3) {{{ #!java request.onreadystatechange = function() { // 定義 XMLHttp 有狀態改變的事件處理函數 callback function if (request.readyState == 4) { // XMLHttp 的狀態是 Ready (4) 繼續處理 Server 傳回的 XML 資料 var xmlDoc = request.responseXML; // xmlDoc = 回傳的 XML 資料 var markers = xmlDoc.documentElement.getElementsByTagName("marker"); // 取出名稱為 marker 的 xml 元件, 結果是陣列 for (var i = 0; i < markers.length; i++) { var points2 = []; // 宣告一個空的陣列 point2 來存起始與結束座標點 // 把 lat1 跟 lng1 塞進起始座標點 GLatLng 物件 points2.push(new GLatLng(parseFloat(markers[i].getAttribute("lat1")),parseFloat(markers[i].getAttribute("lng1")))) // 把 lat2 跟 lng2 塞進起始座標點 GLatLng 物件 points2.push(new GLatLng(parseFloat(markers[i].getAttribute("lat2")),parseFloat(markers[i].getAttribute("lng2")))) // 用 point2 產生 GPolyline 物件,畫從 point2[2] 到 point2[1] 的線條 // - 參考 http://code.google.com/apis/maps/documentation/reference.html#GPolyline // - GPolyline(座標點, 顏色, 線條粗細(pixel), 透明度(0: 反鋸齒, 1: 半透明)) // 然後用 addOverlay 函數把線條疊到地圖上 map.addOverlay(new GPolyline(points2,'#FF0000',2,1)); // 計算起始與結束的中心位置座標點 var lat=(parseFloat(markers[i].getAttribute("lat1"))+parseFloat(markers[i].getAttribute("lat2")))/2 var lng=(parseFloat(markers[i].getAttribute("lng1"))+parseFloat(markers[i].getAttribute("lng2")))/2 // 產生中點 GLatLng 座標物件 var point = new GLatLng(lat,lng); // 取得 XML 資料中的測站名稱(id)與打撈深度(depth) var id=markers[i].getAttribute("id") var depth=markers[i].getAttribute("depth") // 呼叫自訂的 createMarkerWithLnk() 來產生一個具有連結的 Marker 物件 // createMarkerWithLnk(中點座標位置,測站代號,自訂圖示,測站打撈深度) var marker = createMarkerWithLnk(point,id,icon,depth); // 把 Marker 物件貼上地圖 map.addOverlay(marker); } } } request.send(null); // 送出 XMLHttp 物件的要求 } }}} * 繼續解析 http://deepsea.biodiv.tw/locamapd.asp (PART 4) - 自訂的 createMarkerWithLnk() 函數 {{{ #!java // 自訂的 createMarkerWithLnk() 來產生一個具有連結的 Marker 物件 // createMarkerWithLnk(中點座標位置,測站代號,自訂圖示,測站打撈深度) function createMarkerWithLnk(point,id,icon,depth) { var urlstr= id + " Depth:" + depth; // 提示字串="測站代號 Depth:打撈深度" var url="species.asp?id=" + id; // 連結網址=http://deepsea.biodiv.tw/species.asp?id=測站代號 // 產生一個 GMarker 物件 // - 參考1 http://code.google.com/apis/maps/documentation/reference.html#GMarker // - 參考2 http://code.google.com/apis/maps/documentation/reference.html#GMarkerOptions // - GMarker(座標位置, GMarkerOptions) // - GMarkerOptions={icon:自訂圖示 GIcon 物件, clickable: 可點選(true), title: 顯示提示字串} var marker = new GMarker(point,{icon:icon, clickable:true, title:urlstr}); // 用 GEvent.addListener 設定 GMarker 被點選時的事件處理函數 // 這裡定義的是遇到 click 事件時把 URL 導向到 url 變數設定之連結網址 GEvent.addListener(marker, "click", function() {location.href=url}); // 回傳 GMarker 物件 return marker; } }}} == 實驗跨站取得 XML 資料 == * 首先把 !GetDataXml 設定成 "http://deepsea.biodiv.tw/getdeepstaxml.asp", 把 HTML 範例改寫成 {{{ #!java Google Maps JavaScript API Example
}}} * 結果發現並不會正常畫出紅線, 因此用 wget 先把 XML 抓下來 {{{ #!sh jazz@trac:/var/www$ wget http://deepsea.biodiv.tw/getdeepstaxml.asp jazz@trac:/var/www$ mv getdeepstaxml.asp getdeepstaxml.xml }}} * 再把 XMLHttp 物件要去 GET 的 URL 改為 getdeepstaxml.xml , 就可以正常看到紅線了~[[BR]]請看[http://trac.nchc.org.tw/googlemap2.html 第三個成果] {{{ #!diff --- googlemap2.html 2008-09-19 15:34:37.000000000 +0800 +++ googlemap2.html 2008-09-19 15:35:30.000000000 +0800 @@ -20,7 +20,7 @@ - var GetDataXml="http://deepsea.biodiv.tw/getdeepstaxml.asp"; + var GetDataXml="getdeepstaxml.xml"; }}} * [猜測] 或許為了安全性, Google Map API 所產生的 XMLHttp 物件不允許連結外部 URL == Add iframe to Drupal == * 目前還在熟悉 Drupal 的管理介面邏輯,不過發表文章還算蠻簡單的。這裡實驗加 iframe 語法來呈現 Google Map 實驗成果到 Drupal 中;要注意的是『輸入格式』必須選『Full HTML』。 * [[Image(Drupal_iframe_1.jpg)]] * [[Image(Drupal_iframe_2.jpg)]]