2014-07-02 108 views
0

我在Firefox中使用OpenLayers中的一個相當大的(加拿大)GML矢量圖層存在性能問題。我的網站使用JavaScript/PHP。創建該層這樣的:如何根據OpenLayers中的縮放來簡化GML矢量圖層?

map.addLayer(new OpenLayers.Layer.Vector(openlayers_gml_layer_canada_bv, { 
    strategies: [ new OpenLayers.Strategy.Fixed()], 
    protocol:  new OpenLayers.Protocol.HTTP({ 
     url: "./images/GML/BV - Canada.gml", 
     format: gml_format 
    }), 
    styleMap: RegionsStyles, 
    visibility: false 
})); 

我簽到處和給出的解決方案裏添加此行來選擇渲染:

OpenLayers.Layer.Vector.prototype.renderers = ["SVG2", "VML", "Canvas"]; 

它拖動時幫助拖放但是當我放開它,它會加載3-5秒(所以它在落後整個時間之後落後了一個大球,但仍然落後很多)。

另一個答案是要麼簡化矢量,要麼用GeoServers處理OpenLayers以外的圖塊。

我想盡可能簡化我的向量,但我不知道如何正確實現OpenLayers的簡化方法。你有關於如何簡化我的圖層的想法嗎?

我的代碼(map.addLayer ...)是一個函數,我添加了所有的矢量地圖。其他人並不落後,因爲他們更簡單。有沒有簡單的方法?我是否必須循環使用我的功能來簡化每個功能?如果是的話,我怎麼能改變我的功能之前實際上加載它們在地圖上(所以它不會滯後)?

這將是完美的,如果我可以根據縮放級別簡化地圖。因此,如果距離很遠(如果我看到加拿大全部),我希望圖層更加簡化,如果放大,我會減少圖層(因爲屏幕上的矢量更少,並且在某些時候完全停滯)。

非常感謝大家。我希望我的問題很清楚。

回答

1

基於Douglas Peucker算法,OpenLayers中內置了一個簡化函數,您可以在OpenLayer.Geometry.Linestring.js中看到源代碼,這裏是一個非常好的代碼 animated example.容差決定了多少簡化發生 - 您必須嘗試以供您使用案件。

這樣做的問題是您仍然需要加載整個GML文件,我懷疑這可能是您的大部分滯後來自(而不是實際呈現它)的地方。但是,如果您只是使用OpenLayers.Format.GML加載它,或者使用固定策略(如您所用)來簡化它,然後只顯示新的簡化版本,則在平移時不會出現這種延遲。由於您仍然可以加載原始文件,因此切換版本應該很簡單,在放大或縮小時可以選擇較高或較低的容差。請注意,簡化對線串而不是多邊形起作用,但您可以通過構成構成多邊形的點陣列構造線串來解決此問題。

var GML= <some gml file>; 

//convert gml to OpenLayers.Feature.Vector 
var reader=new OpenLayers.Format.GML(); 
var feat=reader.read(polygon); 

//get initial points from feature's geometry and set target points (eg, 2000 here). 
var num_points=feat.geometry.components[0].components.length; 
var target_points=2000; 

//set simplification tolerance to one meter initially 
var tolerance=1; 

//convert feature's geometry to linestring 
var linestring=new OpenLayers.Geometry.LineString(feat.geometry.components[0].components); 
var simplified_linestring; 

//simplify linestring until target points reached 
while(target_points<num_points){ 
    simplified_linestring=linestring.simplify(tolerance); 
    num_points=simplified_linestring.components.length; 
    tolerance+=1; 
} 


//create new geometry from simplified linestring  
var geom=new OpenLayers.Geometry.Polygon(new OpenLayers.Geometry.LinearRing(simplified_linestring.components)); 

如果你有你的GML中的許多多邊形,你就必須做的上限是feature.geometry.components.lengh循環。

另一種選擇是使用像Postgis這樣的東西來爲你做簡化,所以你不會傳輸這麼多的數據。但是,如果在某個縮放級別上實際需要完整的多邊形,這並不會真正起到幫助作用。

我不確定Geoserver在這種情況下會如何提供幫助,因爲它更適用於以各種柵格和矢量格式傳輸數據,除非您正在討論如何將GML渲染爲WMS,然後提供柵格表示。

+0

非常感謝! –

相關問題