OpenLayer 介紹

來源:互聯網
上載者:User

(一)項目介紹

網址:http://www.openlayers.org/

  OpenLayers 是由MetaCarta公司開發的,用於WebGIS用戶端的JavaScript包,目前的最高版本是2.5 V,通過BSD License 發行。它實現訪問地理空間資料的方法都符合行業標準,比如OpenGIS的WMS和WFS規範, OpenLayers採用純物件導向的JavaScript方式開發,同時借用了Prototype架構和Rico庫的一些組件。

  採用OpenLayers作為用戶端不存在瀏覽器依賴性。由於OpenLayers採用JavaScript語言實現,而應用於Web瀏覽器中的DOM(文件物件模型)由JavaScript實現,同時,Web瀏覽器(比如IE,FF等)都支援DOM 。

  OpenLayers APIs採用動態類型指令碼語言JavaScript編寫,實現了類似與Ajax功能的無重新整理更新頁面,能夠帶給使用者豐富的桌面體驗(它本身就有一個Ajax類,用於實現Ajax功能)。

  目前,OpenLayers所能夠支援的Format有:XML、GML、GeoJSON、GeoRSS、JSON、KML、WFS、WKT(Well-Known Text)。在OPenlayers.Format名稱空間下的各個類裡,實現了具體讀/寫這些Format的解析器。

  OpenLayers所能夠利用的地圖資料資源“豐富多彩”,在這方面提供給擁護較多的選擇,比如WMS、WFS、GoogleMap、KaMap、MSVirtualEarth、WorldWind等等。當然,也可以用簡單的圖片作為源。

第一次使用OpenLayers:

  先到它的官方網站http://www.openlayers.org下載他的壓縮包,解壓後可以看到其中的一些目錄和檔案,拷貝目錄下的OpenLayer.js、根目錄下的lib目錄、根目錄下的img目錄到你網站的Scripts目錄下(當然,這個只是例子,您網站的目錄結構您自己說得算,只要保證OpenLayers.js,/lib,/img在同一目錄中即可)。 然後,建立一個index.html作為查看地圖的頁面,匯入OpenLayers.js和你將要建立的js。

  我們以載入WMS和GML檔案為例。 

    <script src="../lib/OpenLayers.js"></script>

  <script type="text/javascript">

        var lon = 5;    //x-axis coodinate in map units

        var lat = 40;   //y-axis coordinate in map units

        var zoom = 5;   //number of zoom levels

        var map, layer; 

    //聲明變數map、layer;等同於 var map = null; var layer = null;

        map = new OpenLayers.Map('map');

        //執行個體化一個地圖類OpenLayers.Map

        layer = new OpenLayers.Layer.WMS( "OpenLayers WMS", 

                    "http://labs.metacarta.com/wms/vmap0", {layers: 'basic'} );

        //以WMS的格式執行個體化圖層類OpenLayers.Layer

        map.addLayer(layer);

        map.zoomToExtent(newOpenLayers.Bounds(-3.922119,44.335327,

        4.866943,49.553833));

    //在Map對象上載入Layer對象,並用map.zoomToExtent函數使地圖合適地顯示

    map.addLayer(new OpenLayers.Layer.GML("GML", "gml/polygon.xml"));

    //再在剛載入的WMS檔案上,載入一GML檔案

  剩下的工作就是,加上一些控制項OpenLayers.Control之類的東西,比如LayerSwitcher等。它們會在地圖瀏覽的“視窗”上增加一些工具列或是“按鈕”,增加互動性和功能性。

  當然,Openlayers中的東西遠不止這些,至於它的架構分析、APIs實現機制,會在後續文章中說出。寫這個的過程,也是一個學習的過程,其中難免有不妥之處,熱烈歡迎大家批評指正,相互交流。

     (二)原始碼總體結構分析       

  通過前面的項目介紹,我們大概已經知道Openlayers是什麼,能夠做什麼,有什麼意義。接下來我們分析它怎麼樣,以及怎樣實現的等問題。

  這個圖是從它的文檔上截取的,旨在從感官上認識一下OpenLayers的類。下面分別介紹(文檔中的類是按字母順序排列的,也按這個順序說吧):

  我們看到在類的頂層“高高在上”的是OpenLayers,它為整個項目實現提供名稱空間(JavaScript語言沒有名稱空間一說,但是它確實有自己的機制實作類別似的功能,後面會說明),它直接擁有一常量 VERSION_NUMBER,以標識版本。

  Ajax:顧名思義,用於實現Ajax功能,只是OpenLayers的開發者們把它單獨寫到一個類裡了,其中用到了Prototype.js架構裡的一些東西。同時,設計的時候也考慮了跨瀏覽器的問題。

  BaseTypes:這裡定製了OpenLayers中用到的string,number 和 function。比如,OpenLayers. String. startsWith,用於測試一個字串是否一以另一個字串開頭;OpenLayers. Number. limitSigDigs,用於限制整數的有效數位;OpenLayers. Function.bind,用於把某一函數綁定於對象等等。

  Console:OpenLayers.Console,此名稱空間用於調試和把錯誤等輸出到“控制台”上,需要結合使用../Firebug/firebug.js。

  Control:我們通常所說的控制項類,它提供各種各樣的控制項,比如上節中說的圖層開關LayerSwitcher,編輯工具條EditingToolbar等等。載入控制項的例子:

        class = new OpenLayers.Map('map', { controls: [] });

    map.addControl(new OpenLayers.Control.PanZoomBar());

    map.addControl(new OpenLayers.Control.MouseToolbar());

  Events:用於實現OpenLayers的事件機制。具體來說,OpenLayers中的事件分為兩種,一種是瀏覽器事件,例如mouseup,mousedown之類的;另外一種是自訂的,如addLayer之類的。OpenLayers中的事件機制是非常值得我們學習的,後面將具體討論。

  Feature:我們知道:Feature是geography 和attributes的集合。在OpenLayers中,特別地OpenLayers.Feature 類由一個marker 和一個lonla組成。

OpenLayers. Feature.WFS與OpenLayers. Feature. Vector繼承於它。

  Format:此類用於讀/寫各種格式的資料,它的子類都分別建立了各個格式的解析器。這些格式有:XML、GML、GeoJSON、GeoRSS、JSON、KML、WFS、WKT(Well-Known Text)。

  Geometry:怎麼翻譯呢,幾何?是對地理對象的描述。它的子類有Collection、Curve、LinearRing、LineString、MultiLineString、MultiPoint、MultiPolygon、Point、Polygon、Rectangle、Surface,正是這些類的執行個體,構成了我們看到的地圖。需要說明的是,Surface 類暫時還沒有實現。

  Handler:這個類用於處理序列事件,可被啟用和取消。同時,它也有命名類似於瀏覽器事件的方法。當一個handler 被啟用,處理事件的方法就會被註冊到瀏覽器監聽器listener ,以響應相應的事件;當一個handler被取消,這些方法在事件監聽器中也會相應的被取消註冊。Handler通過控制項control被建立,而control通過icon表現。

  Icon:在電腦螢幕上以表徵圖的形式呈現,有url、尺寸size和位置position3個屬性。一般情況,它與 OpenLayers.Marker結合應用,表現為一個Marker。

  Layer:圖層。

  Map:網業中動態地圖。它就像容器,可向裡面添加圖層Layer和控制項Control。實際上,單個Map是毫無意義的,正是Layer和Control成就了它。

  Marker:它的執行個體是OpenLayers.LonLat 和OpenLayers.Icon的集合。通俗一點兒說,Icon附上一定的經緯度就是Marker。

它們的組合關係是:

  Popup:地圖上一個小巧的層,實現地圖“開關”功能。使用例子:

      Class = new OpenLayers.Popup("chicken",

                   new OpenLayers.LonLat(5,40),

                   new OpenLayers.Size(200,200),

                   "example popup",

                   true);

      map.addPopup(popup);

  Renderer:渲染類。在OpenLayers中,渲染功能是作為向量圖層的一個屬性存在的,我們稱之為渲染器,向量圖層就是通過這個渲染器提供的方法將向量資料顯示出來。以SVG和VML為例,繼承關係是這樣的:    

 

至於OpenLayers. Renderer. Elements為什麼要存在,以及它的渲染機制,後面會說。

  Tile:設計這個類用於指明單個“瓦片”Tile,或者更小的解析度。Tiles儲存它們自身的資訊,比如url和size等。它的類繼承關係如下:

     

  Util:“跑龍套”的類。

  寫到這裡,可以看到OpenLayers 的類纏繞的挺麻煩的,接下來的文章將從代碼部分分析更細部的東西。

 

(三)BaseTypes :定義底層類與定製JS內建類  

 

    先說基底類型BaseTypes下,OpenLyers構建的“自己”的類。它們分別是:OpenLayers. LonLat、OpenLayers. Pixel、OpenLayers.Size、OpenLayers. Element、OpenLayers. Bounds和OpenLayers. Class。下面分別介紹:

  OpenLayers. LonLat:經緯度類,其執行個體為地圖提供一經度、緯度對,即位置。有兩個屬性lon(x-axis coodinate )和lat(y-axis coordinate )。這裡說明一下,怎麼經緯度又與x軸座標、y軸座標糾纏在一起?是這樣:當地圖是在地理座標投影下,它就是經緯度;不然就是地圖上的x/y軸座標。除建構函式外,實現了五個函數:

toShortString:function() 把座標轉換為字串;

clone:function()  複製一個LonLat對象;

Add:function(lon,lat)  改變現有地圖的位置;

  return new OpenLayers.LonLat(this.lon + lon, this.lat + lat);

equals:function(ll)  判斷傳入的lon,lat對是否與當前的相等;

wrapDateLine:function(maxExtent)  複製下(lon,lat),指定為邊界的最大範圍。

 

  OpenLayers. Pixel:像素類,在顯示器上以(x,y)座標的的形式呈現像素位置。有兩個屬性x座標、y座標,提供四個成員函數:

clone:function() 拷貝像素;

equals:function(px)  判斷兩像素是否相等;

add:function(x,y)  改變(x,y)使其成為新像素;

return new OpenLayers.Pixel(this.x + x, this.y + y);

offset:function(px)  調用add()使像素位置發生位移。

  newPx = this.add(px.x, px.y);

 

  OpenLayers.Size:也有兩個屬性,寬度width、高度height。實現了兩個成員函數:clone:function()和equals:function(sz)不多說了。

 

  OpenLayers. Element:在這個名稱空間下,開發者寫了好多API,有visible、toggle、hide、show、remove、getHeight、getDimensions和getStyle,以實現元素的顯示、隱藏、刪除、取得高度,取得範圍等功能。以getHeight函數為例我們看看它的代碼:

  /**

     * APIFunction: getHeight

     *  

     * Parameters:

     * element - {DOMElement}

     * 

     * Returns:

     * {Integer} The offset height of the element passed in

     */

    getHeight: function(element) {

        element = OpenLayers.Util.getElement(element);

        return element.offsetHeight;

    }

這裡涉及到文件物件模型DOM的一些東西,函數本身很簡單,最後返回元素的高度。

 

  OpenLayers. Bounds:在這個類中,資料以四個浮點型數left, bottom, right, top 的格式儲存,它是一個像盒子一樣的範圍。它實現了三個描述一個Bound的函數:toString、toArray和toBBOX。其中,toString的代碼如下:

  /** 

     * APIMethod: toString

     * 

     * Returns:

     * {String} String representation of bounds object. 

     *          (ex.<i>"left-bottom=(5,42) right-top=(10,45)"</i>)

     */

    toString:function() {

        return ( "left-bottom=(" + this.left + "," + this.bottom + ")"

                 + " right-top=(" + this.right + "," + this.top + ")" );

    }

結果類似於"left-bottom=(5,42) right-top=(10,45)"

  三個Bound資料來源函數:fromString、fromArray和fromSize;

五個擷取對象屬性的函數:getWidth、getHeight、getSize、getCenterPixel、getCenterLonLat;

餘下還有:add:function(x,y),extend:function(object),containsLonLat,containsPixel,contains,intersectsBounds,containsBounds,determineQuadrant,wrapDateLine。以函數extend為例,看看源碼。

    extend:function(object) {

        var bounds = null;

        if (object) {

            switch(object.CLASS_NAME) {

                case "OpenLayers.LonLat":    

                    bounds = new OpenLayers.Bounds    (object.lon, object.lat, object.lon, object.lat);

                    break;

                case "OpenLayers.Geometry.Point":

                    bounds = new OpenLayers.Bounds(object.x, object.y,object.x, object.y);

                    break;                 

                case "OpenLayers.Bounds":   

                    bounds = object;

                    break;

            }

            if (bounds) {

                if ( (this.left == null) || (bounds.left < thi                     s.left)) {

                     this.left = bounds.left;}

                if ( (this.bottom == null) || (bounds.bottom <                     this.bottom) ) {

                    this.bottom = bounds.bottom;} 

                if ( (this.right == null) || (bounds.right > t                    his.right) ) {

                    this.right = bounds.right;}

                if ( (this.top == null) || (bounds.top > this.                    top) ) { 

                    this.top = bounds.top;}

            }

        }

    }

可以看出,對Bounds的擴充可以有三種形式:point, lonlat, 或者bounds,計算的條件是零座標是在螢幕的左上方。

 

  OpenLayers. Class:這個類是OpenLayers 中的“大紅人”,只要建立其他類就得用它,同時也實現了多重繼承。用法如下:

  單繼承建立:class = OpenLayers.Class(prototype);

  多繼承建立:class = OpenLayers.Class(Class1, Class2, prototype);

    淨說底層類了,對js內建類的擴充下回寫 

   

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.