2014-07-02 73 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

非常感谢! –

相关问题