Friday 20 October 2017

performance - OpenLayers canvas renderer - redraws all features on selecting a single feature


I am currently trying to learn more about OpenLayers, and I'm coming up against performance / behaviour issues that I wouldn't expect to see. To elaborate...


I have combined this example for generating lots of random points with this example on highlighting / changing the icons of features on selection.



The result is available in this JSFiddle.


The (very basic) application prioritises the Canvas renderer, so that the points layer is defined like this:


var layer = new OpenLayers.Layer.Vector('points', {renderers: ['Canvas', 'SVG', 'VML'],
styleMap: new OpenLayers.StyleMap({
"default": new OpenLayers.Style(OpenLayers.Util.applyDefaults({
externalGraphic: "img/marker-green.png",
graphicOpacity: 1,
rotation: 0,
pointRadius: 10
}, OpenLayers.Feature.Vector.style["default"])),

"select": new OpenLayers.Style({
externalGraphic: "img/marker-blue.png"
})
})});

The Canvas renderer is nice because zooming and panning works well with thousands of points (unlike SVG) but clicking / feature selection is much slower than SVG. I was surprised to see that all feature icons are redrawn before the selected feature's icon changes (to marker-blue.png). This is especially apparent in Firefox, but less noticeable in Chrome and too fast to see in IE9.


This question on SO suggests that there could be an issue with how OpenLayers is interacting with the Canvas, but unfortunately I don't know enough about HTML5 or OpenLayers (yet) to be sure.


Does anyone have experience with OpenLayers / Canvas renderer? I am interested in any ways of speeding up feature selection when there are lots of features - whether it's the time taken to figure out which feature was selected, or simply changing the selected feature's icon.


Any help much appreciated.



Answer




I can confirm that OL Canvas renderer redraws the whole layer when even a single feature needs to be redrawn. The exact point of the sources where this is implemented is this one in drawFeature.


This has probably to do with the fact that the canvas is simply a bitmap so redrawing on top of it can produce artifacts if the new image is not perfectly placed on top of the old one (this could happen due to rounding and antialiasing, but this is just me speculating).


Workarounds:



  1. Use the SVG renderer which does not exhibit the redraw behavior on feature selection

  2. Or add another Vector layer on top just for the purpose of highlighting features. Hook into the SelectFeature control onSelect event so that the selected feature is added to this highlight layer


@tomfumb , as per your kind request here's the snippet:


var selectControl = new OpenLayers.Control.SelectFeature(
layer, {

clickout: true, multiple: false, hover: false, box: false,
onBeforeSelect: function(feat) {
// add code to add feature to highlight layer
return false;
},
onUnselect: function(feat) {
// add code to remove feature from highlight layer
}
}
);

No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...