不可否認openlayers的確是個好東西,尤其是他的事件封裝機制更是讓人愛不釋手,感謝致力於openlayers開發的指令碼愛好者們。但是作為乙個開源的指令碼框架,它也存在不少缺陷,gml解析的低效率就是乙個嚴重的問題。
對於乙個像美國states的gml檔案,大小約為300k左右,有95個面物件,所有面物件一共包含11000個左右的點,這麼乙個gml檔案,不算從wfs請求過來的時間,就是放在本地就用openlayers指令碼解析,耗時也在10s以上,雖然這裡機器不太好,屬於上個世紀的戴爾機器,記憶體256,cpu2.8g,但是這麼長的耗時實在是說不過去。
後來試用精簡了的武漢資料,大小大概400k,只有乙個面物件,不過這個面包含很多個點,16145左右,從wfs請求,結果在客戶端根本就畫不出來,ie死掉了。
後來檢視openlayers解析gml資料的**,很容易就可以發現問題。openlayers對於geometry物件的組織是這樣的,其實最基本的就是點,然後multipoint由點構成,繼承自openlayers.geometry.collection,而linearring,linestring均由point構成,polygon由openlayers.geometry.linearring構成。
openlayers在解析資料時候,將所有的面、線包含的點全部都物件化為openlayers.geometry.point,並首先將所有的物件讀取到記憶體,得到乙個feature的集合,然後將這個集合提交給渲染器進行渲染。本來這個思想就行不通,加入我們通過wfs收到的檔案有10m或者更大,要是把這些全部解析出來然後放到記憶體,那還不跑死啊,這個就像乙個100m的文字檔案要解析出來一樣,要是等全部解析完了再處理資料那是不行的,萬一資料再大呢,比如2g的資料,你還能這樣全部讀到記憶體麼??
而其實將所有的點都物件化才是它效率低下的根本原因,本人做過測試,將16145個openlayers.geometry.point在現有機器配置下例項化耗時6s(除了乙個qq外,機器不執行任何其他程式),這個解析效率顯然是不能滿足gis應用的。
那麼我認為,應該在gml資料解析得到相應geometry物件的時候就直接將其用vml或svg畫出來,而且構建polygon物件的時候不要涉及point物件,及不要像這樣構建
ring1 = new openlayers.geometry.linearring(p.points);
rings.push(ring1);
var poly = new openlayers.geometry.polygon(rings);
最好是直接傳入一系列座標對直接構建polygon。
筆者自己寫了個解析gml的簡單指令碼程式,然後用vml進行繪製,繪製本地的states資料連載入到顯示不要1s,繪製區域網wfs請求的武漢資料,連請求到顯示不要兩秒,效能有明顯改善。但是筆者這個簡單程式只能作為測試,資料組織方面肯定不能和openlayers相比。
附:vml和svg是以dom元素的形式存在與客戶端用於適量資料的顯示,因而二者都不能顯示大資料量,它們只能作為一種輔助的形式顯示少量的向量資料。要想獲得可以接受的效率,向量物件的個數最多在1000個左右。vml和svg的繪圖效率比較低下,假如向量物件比較多或者面物件的面積普遍較大,那麼重繪也是比較慢的。
openlayers學習記錄
openlayers.util.getelement 以陣列的形式返回所有引數在document中的dom元素 openlayers.util.getelement的別名 openlayers.util.extend 目標物件,原物件 將原物件中的所有非 undefined 屬性拷貝到目標物件 包括...
Openlayers結合TopoJson的簡單使用
openlayers 6 topojson 轉換topojson的 qgis postgresql 業務需求展示乙個地區社群等界線不同年份的變換。從資料庫呼叫資料太慢 一次查詢需要2s,時間耗損在 st asgeojson函式上。若有好的方法請指出 使用geoserver發布地圖年份多 單個shp資...
GML物件的層次結構
gml是乙個複雜的標準。本文的內容以ogc gml 3.1.0為參考標準。它包含的內容非常多,除常規的二維向量gis資訊以外,還包括複雜目標 拓撲資訊 三維目標 時態資訊 地理覆蓋 註記符號 空間參考 元資料 柵格資料等等資訊。和gml2版本不同,gml3.1.0中的feature並不總是幾何物件,...