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 have been pulling my hair out over this issue and am now wondering if it is a bug rather than something I am doing wrong.

The Problem: I have a vector layer that users can edit. Each feature on the vector layer has an attribute called "Status" and I am using a unique values renderer to style the features. The layer can contain point, line, and polygon geometries. I have successfully set the layer styling and features are styled according to their status attribute. However, when a user selects a feature to modify the geometry the editing handles are not displayed which means the user is unable to modify the geometry, but the style clearly changes to the edit style. Here are the relevant parts of my code to create the layer:

// Capture the styles for the default render intents of a Vector layer
var defaultSymboliser = OpenLayers.Util.applyDefaults({}, OpenLayers.Feature.Vector.style["default"]);
var selectSymboliser = OpenLayers.Util.applyDefaults({ strokeColor: "red", fillColor: "blue" }, OpenLayers.Feature.Vector.style["select"]);
var temporarySymboliser = OpenLayers.Util.applyDefaults({ strokeColor: "red", fillColor: "blue" }, OpenLayers.Feature.Vector.style["temporary"]);

var editLayerStyleMap = new OpenLayers.StyleMap(
    {
        'default': defaultSymboliser,
        'select': selectSymboliser,
        'temporary': temporarySymboliser
    }
);

// Create a symboliser lookup that will be used to stye features in their default intent
var symbolisersLookup = {
    'Draft': { fillColor: '#0000ff', fillOpacity: 0.4, strokeColor: '#0000ff', pointRadius: 6 },
    'Submitted': { fillColor: '#00ff00', fillOpacity: 0.4, strokeColor: '#00ff00', pointRadius: 6 },
    'Review': { fillColor: '#ff0000', fillOpacity: 0.4, strokeColor: '#ff0000', pointRadius: 6 },
    'Processed': { fillColor: '#9900ff', fillOpacity: 0.4, strokeColor: '#9900ff', pointRadius: 6 }
};

// Add the symboliser and lookup rules to the StyleMap object, using the default intent
editLayerStyleMap.addUniqueValueRules('default', 'Status', symbolisersLookup);

editLayerRefreshStrategy = new OpenLayers.Strategy.Refresh({force: true});
editLayer = new OpenLayers.Layer.Vector("User Submitted Information", {
    strategies: [new OpenLayers.Strategy.BBOX(), editLayerRefreshStrategy],
    protocol: new OpenLayers.Protocol.HTTP({
        url: "Services/UserSubmittedInformationHandler.ashx",
        format: new OpenLayers.Format.GeoJSON()
    }),
    styleMap: editLayerStyleMap
});
mainMap.addLayer(editLayer); 

If I comment out the line:

editLayerStyleMap.addUniqueValueRules('default', 'Status', symbolisersLookup);

Then the features are no longer styled according to their status value but the editing handles do now appear. So, is this an OpenLayers bug or have I not done something important that allows the select render intent to work correctly when a UniqueValueRules is applied?

share|improve this question

1 Answer 1

up vote 1 down vote accepted

I've tried everything I can think of but the behaviour of OpenLayers remains the same. I'm convinced this is a bug so will be logging an issue in the bug tracker.

In the meantime I have managed to implement a work-around, that whilst not ideal, will work until there is a fix for the issue. In the end the solution seems obvious but it took me some time to appreciate that fact! So, put simply I remove the StyleMap in the beforefeaturemodified event handler and then apply it again in the afterfeaturemodified event handler. The following is a very rough example of what I do:

editLayer.events.register("beforefeaturemodified", editLayer, function (event) {
    editLayer.styleMap.styles["default"].rules = [];

    // In addition it seems that virtual vertices are also not respected, their display property is set to "none"
    // so we need to override that here.
    modifyControl.virtualStyle.display = 'visible';
});

editLayer.events.register("afterfeaturemodified", editLayer, function(event) {
    // Put logic here to save edits, etc

    // Reapply the style map
    addEditLayerStyleMap();
});    

function addEditLayerStyleMap() {
   var defaultSymboliser = OpenLayers.Util.applyDefaults({}, OpenLayers.Feature.Vector.style["default"]);
   var selectSymboliser = OpenLayers.Util.applyDefaults({ strokeColor: "red", fillColor: "blue" }, OpenLayers.Feature.Vector.style["select"]);
   var temporarySymboliser = OpenLayers.Util.applyDefaults({ strokeColor: "red", fillColor: "blue" }, OpenLayers.Feature.Vector.style["temporary"]);

   var editLayerStyleMap = new OpenLayers.StyleMap(
     {
       'default': defaultSymboliser,
       'select': selectSymboliser,
       'temporary': temporarySymboliser
     },
     {
       extendDefault: false
     }
   );

   var symbolisersLookup = {
     'Draft': { fillColor: '#0000ff', fillOpacity: 0.4, strokeColor: '#0000ff', pointRadius: 6 },
     'Submitted': { fillColor: '#00ff00', fillOpacity: 0.4, strokeColor: '#00ff00', pointRadius: 6 },
     'Review': { fillColor: '#ff0000', fillOpacity: 0.4, strokeColor: '#ff0000', pointRadius: 6 },
     'Processed': { fillColor: '#9900ff', fillOpacity: 0.4, strokeColor: '#9900ff', pointRadius: 6 }
   };

   editLayerStyleMap.addUniqueValueRules('default', 'Status', symbolisersLookup);

   // Apply the style map to the edit layer
   editLayer.styleMap = editLayerStyleMap;
}

I'm going to have a look at the OpenLayers code to see if I can track down the bug and fix it.


BEGIN EDIT:

the line

modifyControl.virtualStyle.display = 'visible';

only gave me the virtual vertices at begin/end of each line segment, but no vertices in the middle (for inserting new vertices). I disabled the stylemap to find out the default values of the virtualStyle property and replaced the line above through:

modifyControl.virtualStyle = {
        cursor : "inherit",
        fillColor : "#ee9900",
        fillOpacity : 0.3,
        fontColor : "#000000",
        hoverFillColor : "white",
        hoverFillOpacity : 0.8,
        hoverPointRadius : 1,
        hoverPointUnit : "%",
        hoverStrokeColor : "red",
        hoverStrokeOpacity : 1,
        hoverStrokeWidth : 0.2,
        labelAlign : "cm",
        labelOutlineColor : "white",
        labelOutlineWidth : 3,
        pointRadius : 6,
        pointerEvents : "visiblePainted",
        strokeColor : "#ee9900",
        strokeDashstyle : "solid",
        strokeLinecap : "round",
        strokeOpacity : 0.3,
        strokeWidth : 1
    }
share|improve this answer
    
I have a similar problem, although I don't think the rules are the problem, because even though I add rules to the default/select/temporary styles, I've defined a separate style for vertices renderIntent with no rules, which is set to the vertices, but somehow the layer still seems to ignore the style. OK, the rules are the problem - I removed them and it finally worked!... –  Janis Oct 17 '13 at 17:27

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.