wiki:oid/WorkLog/09-02-04

2009-02-04

感想與結論

  • 追了一天的"赤壁" Mapplet 原始碼,得到兩個啟示:
    1. 要實現不同的連結點選,呈現不同的圖層,赤壁這個 Mapplet 是靠 Hash 來存資料,並且每個動作前面都把 Hash 連結到的 Overlayer 清除掉。
    2. 用 jQuery 可以比較簡單地在 Run-Time 為每個連結設定 click 事件的處理方式。
  • [補遺] 其實還有其他啟示:
    1. 赤壁的 Mapplet 擺在 code.google.com 上,所以"程式跟資料"全部都存在 Google File System 上,調閱的速度也相對快許多。流量全部吃 Google 對外的頻寬。這招狠~好在是 Google 自家員工這樣搞~
    2. 從赤壁的 Mapplet 學到一點,事先規劃資料來源的 Data Model 是很重要的。在寫應用程式之前,應該先思考資料的 Model 然後加入操作流程的思考。

原始碼追蹤紀錄

  • 原本 waue 發表的Google Map的網址模組轉換,在官方的名稱為 Google Mapplets API
  • Google Mapplet API 跟 Google Map API 最主要的差別在於 Mapplet 是在官方 Google Map 上呈現,而 Google Map API 則可以用在自己的網站上。
    The main difference is that Mapplets run on Google Maps, 
    while the traditional Maps API is used to create maps on other websites.
    
  • "赤壁"原始碼 - http://code.google.com/p/redcliff/source/checkout
    svn checkout http://redcliff.googlecode.com/svn/trunk/ redcliff-read-only
    
  • 赤壁的 Mapplet

  • 在原始碼中,people.json 是用來顯示"主要人物"這個 Tag 的資料來源

  • 在原始碼中,big_event.json 是用來顯示"歷史事件"這個 Tag 的資料來源

  • 在原始碼中,event.json 是用來顯示點選"歷史事件"其中一個事件後,顯示各事件的關連資料來源

  • 在原始碼中,location.json 是用來把歷史古城的位置用貼圖方式顯示的經緯度資料來源

  • 在原始碼中,element.json 是用在點選特定古城位置時,顯示關聯事件的資料來源

  • 赤壁 Mapplet 原始碼 XML 解析
    <?xml version="1.0" encoding="UTF-8"?>
    <Module>
    
    <ModulePrefs title="赤壁之戰"
                 description="赤壁之戰的歷史地圖"
                 author="Google Redcliff Team"
                 author_email="chibi.ditu@gmail.com">
    # 參考 http://code.google.com/intl/zh-TW/apis/maps/documentation/mapplets/basics.html#Loading_the_Mapplets_API
    # 必須加入 sharedmap  feature 才能讓 mapplet 載入定義在 Content 中的 javascript 程式
       <Require feature="sharedmap"/>
       <Require feature="dynamic-height" />
       <Require feature="analytics" />
    </ModulePrefs>
    <Content type="html"><![CDATA[
    <style>@CHARSET "UTF-8";
    ### 以下略過 CSS 定義 ###
    </style>
    <!-- Show this gif when loading -->
    # 初始化的時候顯示"正在讀取..."的圖示跟字樣
    <div id="loading" style="color:#AAA;text-align:center;margin-top:40px;font-size:12px;"><img src="http://www.google.cn/staticcn/chibi/pie_32.gif"><br><br>正在讀取...</div>
    
  • 底下先定義 DOM 元件
    # 初始之後要顯示的 DIV 元件
    <!-- Hide first when loading -->
    <div id="main" style="z-index:10;display:none;">
       <div class="top-div">
         <span>選擇地圖: </span>
         <select class="dropdown-box" id="select_tiles">
           <option value="1.0">歷史地圖</option>
           <option value="0.5">混合地圖</option>
           <option value="0.0">現代地圖</option>
         </select>
       </div>
    
  • 上面這段就是畫面上的下拉式選單

   <div class="tab-content" id="tabContent">
     <div class="tab-head">
           <div class="tab-inactive"><div id="events_tab">歷史事件</div></div>
           <div class="tab-active"><div id="characters_tab">主要人物</div></div>
           <div class="tab-inactive"><div id="vote_tab">投票</div></div>
     </div>
  • 分頁 -
         <div id="events_cnt" style="display:none;">
           <div id="unused_bar"><!-- TODO may need to add some text in this bar --></div>
           <div id="big_event_list" ></div>
         </div>
    
  • 歷史事件 (events_cnt) 預設隱藏,裡面包含 big_event_list 元件
         <div id="characters_cnt">
           <div id="kingdom_checkbox">
             <label for="checkbox_wei">曹操軍</label><input id="checkbox_wei" type="checkbox" checked>
             <label for="checkbox_wu">孫權軍</label><input id="checkbox_wu" type="checkbox" checked>
             <label for="checkbox_shu">劉備軍</label><input id="checkbox_shu" type="checkbox" checked>
           </div>
           <div id="character_list"></div>
         </div>
    
  • 上方三個 checkbox ,底下是 character_list 用來顯示內容
         <div id="vote_cnt" style="display:none;">
           <div id="unused_bar"></div>
           <iframe frameborder=0 class="vote-ifr" src="http://redcliffvotetw.appspot.com/?locale=zh_tw"></iframe>
         </div>
       </div>
    
  • 投票 vote_cnt 預設隱藏,用 iframe 帶入 http://redcliffvotetw.appspot.com/?locale=zh_tw 這個 Google App Engine 的內容
       <div class="bottom-button-div">
         <a href='#' id="clear_button">清除地圖上的標誌</a>
         <span id="share_button"></span>
       </div>
       <div class="bottom-button-div2">
         <a href="#" id="disclaimer_show">聲明</a>
         <div id="disclaimer_box" style="display:none;"><div>
              本地圖為Google Inc.製作。赤壁之戰地圖中所使用的各種數據,為參考《後漢書》、《三國志》、《資治通鑑》、《三國郡縣表》等書籍資料,以及<a target="_blank" href= "http://zh.wikipedia.org/w/index.php?title=%E9%A6%96%E9%A1%B5&variant=zh-tw/">維基百科</a>等網站,整理獲得。
              人物肖像,事件相片等,為<a target="_blank" href="http://www.foxmovies.com.tw/">美商二十世紀福斯影片公司</a>及<a target="_blank" href="http://www.meiah.com/">美亞娛樂資訊集團有限公司</a>授權使用之電影《赤壁》劇照。
               <br><br>
              聯繫我們: <a href="mailto:chibi.ditu@gmail.com">chibi.ditu@gmail.com</a>
               <br>
               <span id="disclaimer_close">關閉</span>
             </div></div>
       </div>
    </div>
    
  • 主要顯示三個元件,包括"分享給朋友"、"清除地圖上的標誌"、"聲明"
  • 點選"聲明"才會顯示 disclaimer_box 的畫面
    <div style="height:2em;"></div>
    <script src="http://www.google.com/jsapi" type="text/javascript"></script>
    <script type="text/javascript">
             google.load("jquery", "1.2.6");
    </script>
    
  • 上面這一段是宣告要載入 Hosting 在 Google 的 jQuery API 1.2.6 版
    <script type="text/javascript">
    window.serverBase="http://www.google.com";
    ### 略過 - 這段看不太懂因為中文字轉碼過了應該是在用來做定義 "分享給朋友" 的寄信行為!!
    share.SharingButton=share.SharingWidget;
     })();
    </script>
    
  • [註] 底下開始會稍微變動一下原始碼的順序,我們先來看 jQuery 的 main 進入點
      $(function(){
        G_MAP = new RedcliffMap(); # 呼叫 RedcliffMap() 產生 GMap2 物件
        LoadLocation();            # 呼叫 LoadLocation()  location.json  讀檔並把資料存進 LOCATION   Hash 物件中
                                   # - 呼叫 LoadElement()   element.json   讀檔並把資料存進 ELEMENT    Hash 物件中LOAD_STATES=1
                                   # - 呼叫 LoadEvent()     event.json     讀檔並把資料存進 EVENT      Hash 物件中
                                   #   - 呼叫 LoadBigEvent()  big_event.json 讀檔並把資料存進 BIG_EVENT  Hash 物件中LOAD_STATES=2
                                   #   - 呼叫 LoadPeople()    people.json    讀檔並把資料存進 PEOPLE     Hash 物件中LOAD_STATES=3
        new TilesSelect();         # 
        new TabManager(['events', 'characters', 'vote'], 'characters');
        new Disclaimer();
        $('#clear_button').click(function(){
          G_MAP.clearOverlays();
        });
        new CharacterFilter();
        _IG_Analytics(UAACCT, "/view/load");
      });
    
  • 關於 G_MAP = new RedcliffMap(); 這行程式
      ### 首先要看的是 RedcliffMap 這個類別物件的建構子(Constructor)
      ### 以下省略類別中的 method 函數定義,從這裡可以看到 RedcliffMap 定義了 9 個 method
      ###     changeTiles(opacity_val),
      ###     addOverlay(overlay),
      ###     removeOverlay(overlay),
      ###     openInfoWindow(type, id, latlng),
      ###     highLightOverlay(element_ids),
      ###     deHighLightOverlay(),
      ###     setCenter(center, level),
      ###     clearOverlays(),
      ###     updateOverlay(type, id)
    
      RedcliffMap.prototype = {
        changeTiles: function(opacity_val),
        addOverlay: function(overlay),
        removeOverlay: function(overlay),
        openInfoWindow: function(type, id, latlng),
        highLightOverlay: function(element_ids),
        deHighLightOverlay: function(),
        setCenter: function(center, level),
        clearOverlays: function(),
        updateOverlay: function(type, id)
      };
    
      function RedcliffMap(node) {
        var me = this;
    
        # 參考 http://code.google.com/intl/zh-TW/apis/maps/documentation/mapplets/basics.html#GMap2
        # GMap2 代表 Google Map 的 map 根元件
        this.gmap = new GMap2();
    
        # 設定初始地圖中心經緯度位置
        this.gmap.setCenter(new GLatLng(29.833, 113.618), 7, G_PHYSICAL_MAP);
    
        # 用 GTileLayerOverlay 來取代原始的地圖底圖
        # 參考 http://code.google.com/intl/zh-TW/apis/maps/documentation/overlays.html#Tile_Overlays
        # 參考 http://code.google.com/intl/zh-TW/apis/maps/documentation/reference.html#GTileLayerOverlay
        # 建構子定義 GTileLayerOverlay(tileLayer:GTileLayer, opts?:GTileLayerOverlayOptions) 
    
        this.tileLayerOverlay = new GTileLayerOverlay(
    
        # 參考 http://code.google.com/intl/zh-TW/apis/maps/documentation/reference.html#GTileLayer
        # 建構子定義 GTileLayer(copyrights:GCopyrightCollection, minResolution:Number, 
        #                     maxResolution:Number, options?:GTileLayerOptions) 
        # 參考 http://code.google.com/intl/zh-TW/apis/maps/documentation/reference.html#GTileLayerOptions
        # 這裡設定 tileUrlTemplate: URL.tile_url = http://mt.google.cn/mt?v=cnsg1.2&hl=zh-CN&x={X}&y={Y}&z={Z}
        # 根據 API 文件 Templates 必須是這樣: http://host/tile?x={X}&y={Y}&z={Z}.png 
    
          new GTileLayer(null, null, null, {
            tileUrlTemplate: URL.tile_url,
            isPng:true,
            opacity:1.0
          })
        );
        this.gmap.addOverlay(this.tileLayerOverlay); 
      };
    
  • 關於 LoadLocation(); 這行程式
      function LoadLocation() {
    
        ### 參考 http://code.google.com/intl/zh-TW/apis/gadgets/docs/legacy/remote-content.html#Fetch_text
        ### _IG_FetchContent(url, func) 是一個 Mapplet 的 callback 函數,用來定義擷取 url 之後該執行哪個 func 函數
    
        ### 這裡定義要去擷取 URL.location_url ,
        ### 也就是 http://redcliff.googlecode.com/svn/trunk/data_tc/location.json?bpc=12191314
        ### [備註] 加上 bpc= 是為了清除 google code 的 cache ,這點在程式碼裡面也有寫上註解
        ### <!-- NOTE: Add "?bpc=<radnom>" to by pass the cache for the css file. -->
    
        _IG_FetchContent(URL.location_url, function(data) {
    
        ### 宣告 json 變數等於 callback 函數回傳回來的 data
        ### 參考 http://www.w3schools.com/jsref/jsref_eval.asp
    
        ### location.json 裡的內容
        ### [ {"name" : "成都" , "lat" : 30.670992 , "lng" : 104.067993 }, ... ]
    
          var json = eval(data);
    
        ### 依序把 location.json 裡的 name 跟 location (lat,lng) 設定上去
    
          $.each(json, function(index, location) {
    
        ### var LOCATION = new Hash(); 這裡的 LOCATION 物件是一個 Hash (湊雜)
        ### Hash 類別必須參考原始碼中 Hash.prototype 定義了 5 個 method
        ### removeItem(in_key), getItem(in_key), setItem(in_key, in_value), hasItem(in_key), getLength()
        ### 還有 length 跟 item 兩個 field.
        ### 照 setItem(in_key, in_value) 語法看起來應該會產生一個 二維陣列 (Array)
    
        ### 這裡還呼叫了 Location 建構子
        ### function Location(raw_location) {
        ###   var me = this;
        ###   this.location = raw_location;
        ###   this.name = location.name;
        ###   this.point = new GLatLng(raw_location.lat, raw_location.lng);
        ### };
    
        ### 因此這一行的最後結果應該是類似
        ### LOCATION.item["成都"].name="成都"
        ### LOCATION.item["成都"].point=GLatLng(30.670992,104.067993))
    
            LOCATION.setItem(location.name, new Location(location));
          });
        ### 呼叫 LoadElement() 跟 LoadEvent()
          LoadElement();
          LoadEvent();
        });
      };
    
  • 從 Element 的 prototype 跟建構子看來,Element 類別包含 id, element, type, event 四個標準 field,如果 JSON 型態是 Point 會兒外多出 point 跟 marker 兩個 field,如果 JSON 的型態是 line 則會多出 hidden_polyline 跟 arrow 兩個 field,而 getHiddenPolylineOverlay(points, weigth, id)、getArrowGroundOverlay(arrow_url, sw, ne)、getMarker(icon_url, point, id) 三個暫時的 inner function 是用來產生 marker, hidden_polyline, arraw 的,drawOnMap()、removeFromMap()兩個 method (其他被註解掉了)
      function Element(raw_element) {
        var me = this;
        this.id = raw_element.id
        this.element = raw_element;
        this.type = raw_element.type;
        
        var getHiddenPolylineOverlay = function(points, weigth, id) {
          var latlngs = new Array();
          $.each(points, function(index, point){
            latlngs.push(new GLatLng(point.lat, point.lng));
          });
          var polyline = new GPolygon(latlngs, "#000000", 10, 0.0);
          GEvent.addListener(polyline, 'click', function(latlng) {
            G_MAP.openInfoWindow("ELEMENT", id, latlng);
          });
          return polyline;
        };
        
        var getArrowGroundOverlay = function(arrow_url, sw, ne) {
          var bound = new GLatLngBounds(new GLatLng(ne.lat, ne.lng), new GLatLng(sw.lat, sw.lng));
          var arrow = new GGroundOverlay(CN_BASE + 'arrow/'  + arrow_url + '.png', bound);
          return arrow;
        }
        
        var getMarker = function(icon_url, point, id) {
          var image = CN_BASE + 'icon/' + icon_url + '.png';
          var icon = new GIcon(G_DEFAULT_ICON, image);
          if (icon_url.length == 2)
            icon.iconSize = new GSize(45,32);
          else
            icon.iconSize = new GSize(25,32);
          var marker = new GMarker(point, {icon:icon});
          GEvent.addListener(marker, 'click', function() {
            G_MAP.openInfoWindow("ELEMENT", id, point);
          });
          return marker;
        }
        if (this.type == 'point') {
          this.point = new GLatLng(raw_element.lat, raw_element.lng);
          this.marker = getMarker(raw_element.pic, this.point, this.id);
        } else {
          this.hidden_polyline = getHiddenPolylineOverlay(raw_element.hot_points, C_POLYLINE_WEIGHT, this.id);
          this.arrow = getArrowGroundOverlay(raw_element.arrow, raw_element.arrow_points[0], raw_element.arrow_points[1]);
          
        } 
        this.events = raw_element.event_ids;
      };
      
      Element.prototype = {
        drawOnMap: function() {
          if (this.type == 'line') {
            G_MAP.addOverlay(this.hidden_polyline);
            G_MAP.addOverlay(this.arrow);
          } else {
            G_MAP.addOverlay(this.marker);
          }
        },
        
        removeFromMap: function() {
          if (this.type == 'line') {
            G_MAP.removeOverlay(this.hidden_polyline);
            G_MAP.removeOverlay(this.arrow);
          } else {
            G_MAP.removeOverlay(this.marker);
          }
        }
        
        /*
        highLight: function() {
          G_MAP.removeOverlay(this.current_overlay);
          G_MAP.addOverlay(this.highlight_overlay);
          this.current_overlay = this.highlight_overlay;
        },
        
        deHighLight: function() {
          G_MAP.removeOverlay(this.current_overlay);
          G_MAP.addOverlay(this.overlay);
          this.current_overlay = this.overlay;
        },
        
        adjustZoomLevel: function() {
        }
        */
      };
    
  • 先看過 Element 類別的定義,之後我們回過頭來看 LoadElement 做些什麼
      function LoadElement() {
    
        ### 擷取 http://redcliff.googlecode.com/svn/trunk/data_tc/element.json?bpc=12191328
        ### element.json 的兩種型態
    
        ### type="point"
    
        ### {"id" : 0 , "type" : "point" , "event_ids" : [0 , 2] , "people" : ["劉備" , "諸葛亮"] , 
        ###  "pic" : "G" , "lat" : 32.009524 , "lng" : 111.939524 },
    
        ### type="line"
    
        ### {"id" : 3 , "type" : "line" , "event_ids" : [4] , "people" : ["曹操"] , 
        ###  "arrow" : "B_yx_xy" , "arrow_points" : [{"lat" : 36.115129 , "lng" : 114.326413} , 
        ###  {"lat" : 32.640746 , "lng" : 112.407843}] , "thickness" : 0.12 , 
        ###  "hot_points" : [{"lat" : 36.093 , "lng" : 114.304} , {"lat" : 35.219 , "lng" : 114.069} , 
        ###                  {"lat" : 34.113 , "lng" : 113.563} , {"lat" : 33.149 , "lng" : 112.932} , 
        ###                  {"lat" : 32.667 , "lng" : 112.431}] , 
        ###  "center" : {"lat" : 33.468 , "lng" : 113.167}},
    
        _IG_FetchContent(URL.element_url, function(data) {
          var json = eval(data);
          $.each(json, function(index, element) {
    
        ### 呼叫 setItem 產生二維陣列 
        ### 結果應該是 
        ### ELEMENT.item[0].id     = 0
        ### ELEMENT.item[0].type   = point
        ### ELEMENT.item[0].point  = GLatLng(32.009524,111.939524);
        ### ELEMENT.item[0].marker = GMarker( GLatLng(32.009524,111.939524), 
        ###                                   GIcon(G_DEFAULT_ICON, http://www.google.cn/staticcn/chibi/icon/G.png)
        ### 這個 marker 還註冊了 Click 的事件處理函式是去呼叫 G_MAP.openInfoWindow("ELEMENT", 0, GLatLng(32.009524,111.939524)); 
    
            ELEMENT.setItem(element.id, new Element(element));
          });
          ## 把 LOAD_STATES 加 1 - 此時 LOAD_STATES = 1
          LoadDone();
        })
      };
      
      function LoadEvent() {
    
        ### event.json 的範例
        ### {"id" : 0 , "name" : "諸葛亮寓居隆中" , "people" : ["諸葛亮"] , "element_ids" : [0] , 
        ###  "search" : ["諸葛亮" , "梁父吟" , "隆中"] , "time" : "建安十二年" , "ad" : "207年" , 
        ###  "desc" : "諸葛亮早年與弟弟諸葛均在南陽隆中躬耕隴畝。...略..." , 
        ###  "popup" : {"lat" : 32.009524 , "lng" : 111.939524}},
    
        _IG_FetchContent(URL.event_url, function(data) {
          var json = eval(data);
          $.each(json, function(index, event) {
    
        ### 呼叫 setItem 產生二維陣列 
        ### 結果應該是 
        ### EVENT.item[0].id          = 0
        ### EVENT.item[0].name        = "諸葛亮寓居隆中"
        ### EVENT.item[0].element_ids = [0]
        ### EVENT.item[0].people      = ["諸葛亮"]
        ### EVENT.item[0].search      = ["諸葛亮" , "梁父吟" , "隆中"]
        ### EVENT.item[0].time        = "建安十二年"
        ### EVENT.item[0].time_ad     = "207年"
        ### EVENT.item[0].desc        = "諸葛亮早年與弟弟諸葛均在南陽隆中躬耕隴畝。...略..."
        ### EVENT.item[0].point       = GLatLng(32.009524,111.939524)
    
            EVENT.setItem(event.id, new Event(event));
          });
          LoadBigEvent();
          LoadPeople();
        });    
      };
    
      function LoadBigEvent() {
    
        ### event.json 的範例
        ### {"id" : 0 , "name" : "三顧茅蘆" , "event_ids" : [0 , 1 , 2] , "element_ids" : [0 , 1] , 
        ###  "desc" : "諸葛亮在隆中躬耕,...略" , "time" : "建安十二年" , "ad" : "207年" , 
        ###  "center" : {"lat" : 32.010 , "lng" : 111.939} ,"pic" : "G" , "images" : [] },
    
        _IG_FetchContent(URL.big_event_url, function(data) {
          var json = eval(data);
          $.each(json, function(index, big_event) {
    
        ### 呼叫 setItem 產生二維陣列 
        ### 結果應該是 
        ### BIG_EVENT.item[0].id          = 0
        ### BIG_EVENT.item[0].name        = "三顧茅蘆"
        ### BIG_EVENT.item[0].element_ids = [0 , 1]
        ### BIG_EVENT.item[0].event_ids   = [0 , 1 , 2]
        ### BIG_EVENT.item[0].time        = "建安十二年"
        ### BIG_EVENT.item[0].time_ad     = "207年"
        ### BIG_EVENT.item[0].desc        = "諸葛亮在隆中躬耕,...略"
        ### BIG_EVENT.item[0].pic         = "G"
        ### BIG_EVENT.item[0].is_details_shown = false;
        ### BIG_EVENT.item[0].details     = null;
        ### BIG_EVENT.item[0].images      = []
        ### BIG_EVENT.item[0].center      = GLatLng(32.010, 111.939)
        ### BIG_EVENT.item[0].node        = <div class="big-event-item"><table><tbody><tr><td class="big-event-item-time" title="207年">建安十二年</td><td class="big-event-item-link"><a href="#">三顧茅蘆</a></td><td class="big-event-item-pic"><img src="http://www.google.cn/staticcn/chibi/icon/G.gif"></td></tr></tbody></table><div class="big-event-detail" style=""><p>諸葛亮在隆中躬耕,自比管仲樂毅。劉備求賢若渴,得司馬徽、徐庶推薦,三顧茅廬,終於見到諸葛亮。諸葛亮分析天下大勢,定下三分天下之計。</p><div class="big-event-imgs"></div><table class="events-div"><tbody><tr><td class="events-item-time" title="207年">建安十二年</td><td class="events-item-link"><a href="#">諸葛亮寓居隆中</a></td></tr><tr><td class="events-item-time" title="207年">建安十二年</td><td class="events-item-link"><a href="#">劉備訪名士</a></td></tr><tr><td class="events-item-time" title="207年">建安十二年</td><td class="events-item-link"><a href="#">劉備三顧茅廬</a></td></tr></tbody></table></div></div>
        ### BIG_EVENT.item[0].is_shown    = true;
    
            BIG_EVENT.setItem(big_event.id, new BigEvent(big_event));
          });
          ## 把 LOAD_STATES 加 1 - 此時 LOAD_STATES = 2
          LoadDone();
        });
      };
    
  • 這裡補記一下 BigEvent 裡面一段神奇的 Code ,從這段程式碼可以感受到 jQuery 可以在 Runtime 把 click 事件註冊上去,這真是一個神奇的事情啊!!
          var event_link = $('<a href=#>' + me.name + '</a>');
    
          ### 這裡其實只是產生了 DOM 裡面的一段如 <a href="#">三顧茅蘆</a> 的程式碼
          ### 透過 Firebug 去觀察 DOM 也只看到這樣的結果
          ### 但是因為 DOM 是由 jQuery 產生的,因此底下這幾行所定義的 click 事件處理函式
          ### 會因為不同的連結而有所不同
    
          event_link.click(function(){
            if (me.is_details_shown) {
              me.hideDetails();
            } else {
              me.showDetails();
            }
    
            ### 呼叫 Redcliff.updateOverlay(type, id)
            ### 一開始會先用 Redcliff.clearOverlays() 把目前的 Overlay 清掉
            ### 如果 type = 'E' , 從 BIG_EVENT 讀出對應的 event_id 跟 element_id
            ### 如果 type = 'P' , 從 PEOPLE 讀出對應的 event_id 跟 element_id
    
            G_MAP.updateOverlay('E', me.id);
    
            ### 呼叫 Redcliff.setCenter(center, level)
            ### 也就是把目前 Google Map 的中心位置設到 GLatLng(32.010, 111.939),比例尺設為 8
    
            G_MAP.setCenter(me.center, 8);
    
            ### 參考 http://www.google.com.tw/intl/zh-TW/apis/gadgets/tools.html#Analytics_Gadgets
            ### 這是為了作 Google Analytics 網址點選統計分析用的
    
            _IG_Analytics(UAACCT, '/click/eventLink/' + me.name);
            return false;
          });
          link_cell.append(event_link);
    
  • 繼續看 LoadPeople 在做什麼
      function LoadPeople() {
    
        ### people.json 的範例
        ### {"name" : "曹操" , "zi" : "孟德" , "hao" : null , 
        ###  "event_ids" : [3 , 4 , 9 , 10 , 13 , 17 , 19 , 21 , 22 , 23 , 24 ] , 
        ###  "element_ids" : [2 , 3 , 9 , 10 , 11 , 14 , 23 , 25 , 29 , 30 , 32 , 34] , 
        ###  "birth" : 155 , "death" : 220 , "birthplace" : "沛國譙縣" , "desc" : "曹操生於官宦世家...略" , 
        ###  "kindom" : "魏" , "wiki" : "http://zh.wikipedia.org/w/index.php?title=%E6%9B%B9%E6%93%8D&variant=zh-tw" , 
        ###  "pic" : "http://laiba.tianya.cn/laiba/images/274/12295005301924842653/A/1/o.png" , 
        ###  "center" : {"lat" : 31.224 , "lng" : 112.818}},
    
        _IG_FetchContent(URL.people_url, function(data) {
          var json = eval(data);
          $.each(json, function(index, raw_people) {
            var people = new People(raw_people)
    
        ### 呼叫 setItem 產生二維陣列 
        ### 結果應該是 
        ### PEOPLE.item["曹操"].id          = "曹操"
        ### PEOPLE.item["曹操"].name        = "曹操"
        ### PEOPLE.item["曹操"].nick        = "孟德"
        ### PEOPLE.item["曹操"].birth       = 155
        ### PEOPLE.item["曹操"].death       = 220
        ### PEOPLE.item["曹操"].birthplace  = "沛國譙縣"
        ### PEOPLE.item["曹操"].desc        = "曹操生於官宦世家,..略..."
        ### PEOPLE.item["曹操"].kingdom     = "魏"
        ### PEOPLE.item["曹操"].event_ids   = [3 , 4 , 9 , 10 , 13 , 17 , 19 , 21 , 22 , 23 , 24 ]
        ### PEOPLE.item["曹操"].element_ids = [2 , 3 , 9 , 10 , 11 , 14 , 23 , 25 , 29 , 30 , 32 , 34]
        ### PEOPLE.item["曹操"].pic         = "http://laiba.tianya.cn/laiba/images/274/12295005301924842653/A/1/o.png"
        ### PEOPLE.item["曹操"].digest      = null
        ### PEOPLE.item["曹操"].event       = null;
        ### PEOPLE.item["曹操"].center      = GLatLng(31.224 , 112.818)
        ### PEOPLE.item["曹操"].node        = PeopleNode($('#character_list'), this); ## 在 character_list 底下加入 DOM
        ### PEOPLE.item["曹操"].is_shown    = true;
    
            PEOPLE.setItem(people.name, people);
            PEOPLE_ARRAY.push(people);
          });
    
          ## 把 LOAD_STATES 加 1 - 此時 LOAD_STATES = 3
          LoadDone(); 
        });
      };
    

Last modified 15 years ago Last modified on Mar 4, 2009, 3:03:52 PM

Attachments (14)

Download all attachments as: .zip