空間數據的特徵、表達方式?
地理數據的模型(結構)?
在OpenLayers空間數據的實現主要存在OpenLayers. Geometry類及其子類中。我們先看下面的兩個圖片,表現了這些類的繼承關係。從圖上可以清楚的看出MultiPoint、Polygon和MultiLineString 這三個類實現了多重繼承,即直接繼承於Geometry類,又繼承於Collection類(爲什麼要這樣實現?)。
OpenLyers對於Geometry對象的組織是這樣的,其實最基礎的就是點,然後MultiPoint由點構成,繼承自Openlayers.Geometry.Collection,而LinearRing,LineString均由Point構成,
Polygon由OpenLayers.Geometry.LinearRing構成。OpenLyers在解析數據時候,將所有的面、線包含的點全部都對象化爲Openlayers.Geometry.Point。有人測試這裏面存在問題:解析矢量數據慢,甚至在點數多的情況下,會使瀏覽器“崩潰”掉。想想是有道理的:OpenLyers在解析數據時候,將所有的面、線包含的點全部都對象化爲點對象t,並首先將所有的對象讀取到內存,得到一個Feature的集合,然後將這個集合提交給渲染器進行渲染。這樣渲染起來當然慢了。至於爲什麼要這樣,可能是OpenLayers項目本身在標準上,在框架結構上做的比較好,更細部的東西還得優化呀。可話又說回來,OpenLayers作爲一個優秀的開源JS框架,學習借鑑的意義要比應用的意義大吧。
下面以Point和Collection爲例來說明其內部實現過程,先看Point。
我們知道一個點就是一個座標對(x,y)嘛,當然它得有兩個屬性x,y。在point類裏,提供了六個成員函數,分別是clone、distanceTo、equals、move、rotate和resize。看看計算兩點距離的函數是怎麼寫的:
[代碼]js代碼:
01 |
distanceTo: function (point)
{ |
02 |
var distance
= 0.0; |
03 |
if (
( this .x
!= null )
&& ( this .y
!= null )
&& |
04 |
(point
!= null )
&& (point.x != null )
&& (point.y != null )
) { |
05 |
var dx2
= Math.pow( this .x
- point.x, 2); |
06 |
var dy2
= Math.pow( this .y
- point.y, 2); |
07 |
distance
= Math.sqrt( dx2 + dy2 ); |
08 |
} |
09 |
return distance; |
10 |
} |
11 |
在collection集合對象中,可以存放同一類型的地理對象,也可以放不同的地理對象。定義了一個屬性component
,以數組對象的形式存儲組成collection對象的“組件”。別的不說了,看一個獲取集合大小的函數getLength: |
12 |
getLength: function ()
{ |
13 |
var length
= 0.0; |
14 |
for ( var i
= 0; i < this .components.length;
i++) { |
15 |
length
+= this .components[i].getLength(); |
16 |
} |
17 |
return length; |
18 |
} |
19 |
細心的朋友也許會發現,每一個基類都有一個destroy函數。它是OpenLayers實現的垃圾回收機制,以防止內存泄露,優化性能: |
20 |
/*
APIMethod: destroy |
21 |
*
Destroy this geometry. |
22 |
*/ |
23 |
destroy: function ()
{ |
24 |
this .components.length
= 0; |
25 |
this .components
= null ; |
26 |
}。 |