Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

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.

share|improve this question
add comment

2 Answers 2

up vote 8 down vote accepted

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
     }
  }
);
share|improve this answer
2  
I like number 2, and feel like this might be the solution. –  Michael Markieta Jan 22 '12 at 23:04
    
You again! Unicoletti you're fast becoming my OpenLayers guru. I was actually thinking this one through overnight and option 2 came to me as a good workaround. I stepped through all of the hit-detection logic and identifying the selected feature should be very fast, but the redraw (which is less obvious without image icons) is what drags performance down across lots of features. I just have to tell OpenLayers to not bother highlighting (i.e. redrawing) on selection and use the workaround to 'highlight' the feature. –  tomfumb Jan 22 '12 at 23:28
1  
@unicoletti Could you edit your answer slightly for the benefit of others? The SelectFeature.onSelect event is fired after the feature is highlighted (selected), and so isn't much use for improving performance. However, the undocumented onBeforeSelect event gives near-immediate access to the clicked feature, and returning false in this handler cancels the feature highlight / select. –  tomfumb Jan 23 '12 at 0:12
    
For those looking how to 'add code to add feature to highlight layer' I've posted a working fiddle which adds a label, adds a shadow and adds an overlay graphic. –  ca0v Feb 24 '12 at 17:39
add comment

OpenLayers doesn't have knowledge of what features might have interactions with other features on redraw. As a result, when selecting a feature, it is very likely that OpenLayers redraws all of the features. (For example, if you have multiple features stacked up, and redrew only one of them, you could get weird side effects where the drawing isn't the same as you would get with a complete redraw.)

It's possible this has improved since I helped work on the code originally, since I know some work has been done in this regard, but this behavior wouldn't surprise me.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.