1

I have a cluster layer which I styled with a style function. I want to be able to have a color picker in my frame for each vector layer so that I could change the fill value of the style independently for each layer.

When I tried to set the initial value for the color picker to the actual fill color of the layer I noticed that if I use layer.getStyle() I don't get a Style object, but a function!

How could I retrieve the fill value from that? Moreover, how could I adjust that value with a color picker?

Edit: as dvmac01 suggested I am using the forEachFeature function to change the style.

function changeColor() {
    layer.getSource().forEachFeature(function(feature) {
        // this happens when the source is a cluster
        if(feature.get('features')) {
            var resolution = map.getView().getResolution();
            var style = clusterStyle(feature, resolution, this.value);
            feature.setStyle(style);
        } else {
            var style = new ol.style.Style({
                fill: new ol.style.Fill ({color: this.value})
            });
            feature.setStyle(style);
        }
    }, this);
}
colorPicker.addEventListener('input',changeColor);

I try to check whether the current layer is a cluster layer or a regular (polygon) layer. If I change the color of a polygon layer everything works fine. However, for my cluster layer, everything appears to be working fine when I check the styles on the developer console, but for some reason the points are not redrawn with the correct color.

If I type this in the console map.getLayers().item(2).getSource().getFeatures()[0].getStyle().getImage().getFill(); I can see that the value is the one that I selected with the color picker, yet the circles keep the original color.

0

Without seeing your code it's difficult to answer why layer.getStyle might return a function but the following code works for me. I have several inputs(either pickers or number steppers) and the result of my event listening on these triggers this function:

    var drawLayer, style, fillColPickerValue, strokeColPickerValue, strokeWidthValue; // Global variable declared upfront

    function setFillStroke(strokeColPickerValue, strokeWidthValue, fillColPickerValue) {
        drawLayer = session.activeRoute.Layers[0]; // identify the relevant layer

        drawLayer.getSource().forEachFeature(function (feature) {
            fillColPickerValue = $('body, html').find("#fillColPicker").data("kendoColorPicker").value();
            strokeColPickerValue = $('body, html').find("#strokeColPicker").data("kendoColorPicker").value();
            strokeWidthValue = $('body, html').find("#strokeWidth").data("kendoNumericTextBox").value();
            console.log(strokeWidthValue);

            style = new ol.style.Style({
                fill: new ol.style.Fill({
                    color: fillColPickerValue,
                    opacity: 1.0
                }),
                stroke: new ol.style.Stroke({
                    color: strokeColPickerValue,
                    width: strokeWidthValue
                })
            });
            feature.setStyle(style);
        });
    }
  • I have tried something similar to that using forEachFeature but somehow it is not working. I have edited my original question to show my current code. – Sofia Ontiveros May 11 '16 at 21:09
  • From what I can see, you aren't identifying the layer. In my example: drawLayer = session.activeRoute.Layers[0]; // identify the relevant layer Also, what is your If statement doing? if(feature.get('features')) ? Maybe insert a console.log to see if anything is identified and maybe comment out the If part to see if it's not matching your condition. – dvmac01 May 12 '16 at 7:06
0

I finally figured it out. Since the cluster layer changes dynamically as zoom changes, it is necessary to supply a style function, instead of a static style. What I ended up doing was having a global dictionary storing the fill color for each layer. The color picker modifies the relevant color for the selected layer, and the style function fetches the color from there.

var fill_colors = {};
var clusterStyle = function(feature, resolution) {
    var parentLayer = feature.get('features')[0].parentLayer;
    var fill = fill_colors[parentLayer.idCounter];
    var size = feature.get('features').length;

    style = new ol.style.Style({
        image: new ol.style.Circle({
            radius: size === 1 ? 7 : 10,
            stroke: new ol.style.Stroke({
                color: '#fff'
            }),
            fill: new ol.style.Fill({
                color: fill
            })
        }),
        text: new ol.style.Text({
            text: size === 1 ? '' : size.toString(),
            fill: new ol.style.Fill({
                color: '#fff'
            })
        })
    });
    return style;
};


function changeColor() {
    layer.getSource().forEachFeature(function(feature) {
        // this happens when the source is a cluster
        if(feature.get('features')) {
            fill_colors[layer.idCounter] = this.value;
        } else {
            var style = new ol.style.Style({
                stroke: new ol.style.Stroke ({color: this.value})
            });
            feature.setStyle(style);
        }
    }, this);
}
colorPicker.addEventListener('input',changeColor);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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