wiki:oid/WorkLog/08-09-19

Step by Step building Your Own Google Map Application

申請 Gooogle Map API Key

  • 產生 API Key 完畢就會得到第一個 HTML 範例

  • 把 HTML 範例貼到 goglemap.html 檔案放置在 www 目錄(Ex. /var/www)中,就可以看到第一個成果囉 :)

解析網站原始碼

  • 參考 http://deepsea.biodiv.tw/locamapd.asp (PART 1)
      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 範例中, 就可以得到第二個成果囉 :)
    這裡我額外加了 GScaleControl 元件, 來得知目前比例尺是多大. 這樣就可以知道數值 7 是對應比例尺 100 公里, 數值 8 是對應 50 公里.
          map.addControl(new GScaleControl());                  // 加入左下角比例尺狀態列
    
  • 繼續解析 http://deepsea.biodiv.tw/locamapd.asp (PART 2)
      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 紀錄
    <marker lat1="24.8078" lng1="122.04" lat2="24.86533" lng2="122.04067" id="CD121" depth="471-531 m"/>
    依格式看來 (lat1, lng1) 是起點, (lat2, lng2) 是終點, id 是測站代號, depth 是魚網打撈的水深範圍
    

  • 繼續解析 http://deepsea.biodiv.tw/locamapd.asp (PART 3)
      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() 函數
      // 自訂的 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 範例改寫成
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
      <head>
        <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
        <title>Google Maps JavaScript API Example</title>
        <script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=ABQIAAAAREq2HXjZzIdAyVORbKBYMhTGA1AmqT3f4EHIxhq9FLpYC-sN5RSNOiRjrKXraxSIlkXZKb9VzUKDWQ"
          type="text/javascript"></script>
        <script type="text/javascript">
        //<![CDATA[
        function load() {
          if (GBrowserIsCompatible()) {
            var map = new GMap2(document.getElementById("map"));  // 取得 DOM 中,名稱為 map 的元件
            map.addControl(new GLargeMapControl());               // 加入左上角比例尺規控制列
            map.addControl(new GScaleControl());                  // 加入左下角比例尺狀態列
            map.addControl(new GMapTypeControl());                // 加入右上角"地圖","衛星","混合地圖"按鈕
            map.setCenter(new GLatLng(23.8,121), 7);              // 設定預設經緯度北緯 23.8, 東經 121, 預設比例尺 100 公里(7)
            map.setMapType(G_SATELLITE_MAP);                      // 設定預設底圖為"衛星"
          }
          var request = GXmlHttp.create();                        // 產生一個非同步的 AJAX XMLHttp 物件
          var GetDataXml="http://deepsea.biodiv.tw/getdeepstaxml.asp";
          request.open("GET",GetDataXml, true);                   // 用 XMLHttp 物件去開啟 http://deepsea.biodiv.tw/getdeepstaxml.asp
          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));
              }
            }
          }
          request.send(null);                                      // 送出 XMLHttp 物件的要求
        }
        //]]>
        </script>
      </head>
      <body onload="load()" onunload="GUnload()">
        <div id="map" style="width: 800px; height: 600px"></div>
      </body>
    </html>
    
  • 結果發現並不會正常畫出紅線, 因此用 wget 先把 XML 抓下來
    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 , 就可以正常看到紅線了~
    請看第三個成果
    • googlemap2.html

       
      20       var GetDataXml="http://deepsea.biodiv.tw/getdeepstaxml.asp";
       20      var GetDataXml="getdeepstaxml.xml";
  • [猜測] 或許為了安全性, Google Map API 所產生的 XMLHttp 物件不允許連結外部 URL

用 iframe 將 Google Map 加入 Drupal 頁面

  • 目前還在熟悉 Drupal 的管理介面邏輯,不過發表文章還算蠻簡單的。這裡實驗加 iframe 語法來呈現 Google Map 實驗成果到 Drupal 中;要注意的是『輸入格式』必須選『Full HTML』。
  • 加入 Drupal 呈現效果
Last modified 15 years ago Last modified on Feb 18, 2009, 4:23:12 PM

Attachments (6)

Download all attachments as: .zip