简体   繁体   中英

openlayers: redraw vector layer without downloading data again

What I need is a way to modify a vector layer representation without downloading the data again. I have defined a GLM vector layer and a function called build_style to colorize their geometries according to some feature. I have an HTML form that calls the function UpdateGlmLayer which is defined in this way:

function UpdateGlmLayer(info_str) {
    var v = info_str.split("|");
    var filter_column = v[0];
    var values = [parseFloat(v[1]), parseFloat(v[2]), parseFloat(v[3])];
    glm.styleMap = build_style(filter_column, values);
    glm.redraw();
};

the GLM layer is defined in this way:

gml_protocol = new OpenLayers.Protocol.HTTP({
    url: "http://localhost:8080/geoserver/ows?service=WFS&version=1.0.0&request=GetFeature&typeName="+info["layer_featurePrefix"]+":"+info["layer_featureType"],
    format: new OpenLayers.Format.GML()
})

glm = new OpenLayers.Layer.Vector(info["layer_name"], {
    strategies: [new OpenLayers.Strategy.BBOX({ratio: 3, resFactor: 1})],
    protocol: gml_protocol,
    styleMap: build_style(info["filter_property"], info["filter_values"]), 
    srsName: info["layer_srsName"],
    projection: new OpenLayers.Projection("EPSG:4326"),
    visibility: true
});

When UpdateGlmLayer is triggered the colors seem to change immediately but after that the system stops for approximately the same time it took to downloaded the data on the initial page load. Nothing can be done during this time. Is there something wrong?

The problem is with you setting of the resFactor. I have created two demo maps, one loading some GeoServer GML vectors and restyling them without the resFactor 1 setting and another with the resFactor 1 setting and the second is definitely sending multiple requests. If you set the resfactor to anything above 1 this will not happen.

No resFactor setting + clicking restyle 3 times gives this result:

3个Restyle Clicks,1个数据请求

Only 1 data request.

However, a resFactor setting of 3 + clicking restyle 3 times gives this result: 3个Restyle点击,4个数据请求

4 data requests.

This I believe is the behavior you are seeing. This looks like a bug to me as the documentation says what you have done is valid. Looking at the code in the BBOX strategy js file the problem seems to be in the code:

var ratio = this.resolution / this.layer.map.getResolution();
invalid = (ratio >= this.resFactor || ratio <= (1 / this.resFactor));

This is running on the .redraw() function to calculate whether it needs to reload the data. Because ratio will always be set to 1 in when you redraw the map (the resolution has not changed so this.resolution === this.layer.map.getResolution() ) then invalid will always be equal to true and therefore the layer reloads.

resFactor

{Float} Optional factor used to determine when previously requested features are invalid. If set, the resFactor will be compared to the resolution of the previous request to the current map resolution. If resFactor > (old / new) and 1/resFactor < (old / new). If you set a resFactor of 1, data will be requested every time the resolution changes. If you set a resFactor of 3, data will be requested if the old resolution is 3 times the new, or if the new is 3 times the old. If the old bounds do not contain the new bounds new data will always be requested (with or without considering resFactor).

I am doing the restyles in the following manner:

var style1, style2;


style1 = new OpenLayers.Style({
                strokeColor: "yellow",
                strokeWidth: 10 });


style2 = new OpenLayers.Style({
                strokeColor: "blue",
                strokeWidth: 5 });

function restyle1()
{
    layer.styleMap = style1;
    layer.redraw();

}

function restyle2()
{
    layer.styleMap = style2;
    layer.redraw();

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM