【轉】OpenLayers專案分析(五) 資料解析以GML為例
前面也提到過,OpenLayers設計是符合標準的,有良好的框架結構和實現機制,非常值得學習。OpenLayers支援的格式比較多,有XML、GML、GeoJSON、GeoRSS、JSON、KML、WFS等。這回主要以GML為例來看OpenLayers 資料的解析過程。
先來了解一下GML:
GML (Geography Markup Language)即地理標識語言,它由OGC(開放式地理資訊系統協會)於1999年提出,目前版本是3.0。GML是XML在地理空間資訊領域的應用。利用GML可以儲存和釋出各種特徵的地理資訊,並控制地理資訊在Web瀏覽器中的顯示。地理空間網際網路絡作為全球資訊基礎架構的一部分,已成為Internet上技術追蹤的熱點。許多公司和相關研究機構通過Web將眾多的地理資訊源整合在一起,向用戶提供各種層次的應用服務,同時支援本地資料的開發和管理。GML可以在地理空間Web領域完成了同樣的任務。GML技術的出現是地理空間資料管理方法的一次飛躍。
介紹一篇文章:
我們從總體上來把握一下OpenLayers對於GML資料的解析,首先通過呼叫得到GML文字資料,然後通過Formate.GML類的read方法來解析這個文字,解析得到Geometry物件,然後Geometry物件用相應的渲染器畫出來。其實解析得到還是那些基本的Point呀、LineString呀之類的Geometry物件,就是我們在地圖上看到的那些內容。
下面看其實現過程:
//read()函式讀取資料,獲取特徵列
[程式碼]js程式碼:
01 |
read: function (data) { |
02 |
if ( typeof data == "string" ) { |
03 |
data = OpenLayers.Format.XML.prototype.read.apply( this , [data]); |
04 |
} |
05 |
var featureNodes = this .getElementsByTagNameNS (data.documentElement, this .gmlns, this .featureName); |
06 |
var features = []; |
07 |
for ( var i=0; i<featureNodes.length; i++) { |
08 |
var feature = this .parseFeature(featureNodes[i]); |
09 |
if (feature) { |
10 |
features.push(feature); |
11 |
} |
12 |
} |
13 |
return features; |
14 |
} |
//函式parseFeature()是OpenLayers中GML資料格式解析的核心,就是它建立地理物件
//和其屬性。
//實際上,每一個Foramt 子類都實現了這個成員函式,完成類似的功能。
[程式碼]js程式碼:
01 |
parseFeature: function (node) { |
02 |
// only accept on geometry per feature - look for highest "order" |
03 |
var order = [ "MultiPolygon" , "Polygon" , |
04 |
"MultiLineString" , "LineString" , |
05 |
"MultiPoint" , "Point" ]; |
06 |
var type, nodeList, geometry, parser; |
07 |
for ( var i=0; i<order.length; ++i) { |
08 |
type = order[i]; |
09 |
nodeList = this .getElementsByTagNameNS(node, this .gmlns, type); |
10 |
if (nodeList.length > 0) { |
11 |
// only deal with first geometry of this type |
12 |
var parser = this .parseGeometry[type.toLowerCase()]; |
13 |
if (parser) { |
14 |
geometry = parser.apply( this , [nodeList[0]]); |
15 |
} else { |
16 |
OpenLayers.Console.error( "Unsupported geometry type: " + |
17 |
type); |
18 |
} |
19 |
// stop looking for different geometry types |
20 |
break ; |
21 |
} |
22 |
} |
23 |
// construct feature (optionally with attributes) |
24 |
var attributes; |
25 |
if ( this .extractAttributes) { |
26 |
attributes = this .parseAttributes(node); |
27 |
} |
28 |
var feature = new OpenLayers.Feature.Vector(geometry, attributes); |
29 |
// assign fid - this can come from a "fid" or "id" attribute |
30 |
var childNode = node.firstChild; |
31 |
var fid; |
32 |
while (childNode) { |
33 |
if (childNode.nodeType == 1) { |
34 |
fid = childNode.getAttribute( "fid" ) || |
35 |
childNode.getAttribute( "id" ); |
36 |
if (fid) { |
37 |
break ; |
38 |
} |
39 |
} |
40 |
childNode = childNode.nextSibling; |
41 |
} |
42 |
feature.fid = fid; |
43 |
return feature; |
44 |
} |
剩下就是由具體的函式parse and bulid基本的地理物件(還有Attribute),包括point、multipoint、linestring、multilinestring、polygon、multipolygon等,然後在write出來。
結合前面的“OpenLayers空間資料的組織”,我們可以看到OpenLayers在解析獲取GML資料的時候,比如涉及到面、線的時候,總是以點為基礎構建的。有的朋友做過測試,說這時候,直接用SVG畫出來,效能上會好很多(具體沒測試過,不想多說什麼)。