4

I have a style function for LineStrings which will place a circle at each vertex of a feature.

When I select the feature it reverts to using the default style even though I have replicated my style function with a minor (colour) change. The other minor bug is that the function has two params (start, end) but I would like to place the circle on every vertex. Is there a way to achieve this?

Specifically though, is there a reason why it might be unable to display a selected feature using a style function? I am replicating the code below:

var selectedStyle = function (feature, resolution) {
var geometry = feature.getGeometry();
var styles = [
  // linestring
  new ol.style.Style({
      stroke: new ol.style.Stroke({
          color: '#ffcc33',
          width: 6
      })
  })
];

geometry.forEachSegment(function (start, end) {
    var dx = end[0] - start[0];
    var dy = end[1] - start[1];
    var rotation = Math.atan2(dy, dx);
    // circles
    styles.push(new ol.style.Style({
        geometry: new ol.geom.Point(end),
        image: new ol.style.Circle({
            radius: 5,
            fill: new ol.style.Fill({
                color: 'rgb(0, 0, 255)'
            }),
            stroke: new ol.style.Stroke({ color: 'blue', width: 2 })
        })
    }));
});

return styles;
};
3

2 Answers 2

2

I ll give an example I use for a layer use to draw polygons and lines. So you may get the idea and adjust to fit your needs. The geometry function is collecting all the vertices exist on the feature passed, and then it returns a multipoint out of these coords.

pseudoEditstyles = [
  /* We are using two different styles for the polygons/lines:
   *  - The first style is for the polygons/lines themselves.
   *  - The second style is to draw the vertices of the polygons.
   *    In a custom `geometry` function the vertices of a polygon are
   *    returned as `MultiPoint` geometry, which will be used to render
   *    the style.
   */
  new ol.style.Style({
    stroke: new ol.style.Stroke({
      color: 'blue',
      width: 3
    }),
    fill: new ol.style.Fill({
      color: 'rgba(0, 0, 255, 0.1)'
    })
  }),
  new ol.style.Style({
    image: new ol.style.RegularShape({
      fill: new ol.style.Fill({
          color: 'rgba(255, 0, 0, 0.5)'
      }),
      stroke: new ol.style.Stroke({
          color: 'black', 
          width: 1
      }),
      points: 4,
      radius: 6,
      angle: Math.PI / 4
    }),
    geometry: function(feature) {

      var geometry  =  feature.getGeometry();
      var geomType = geometry.getType();

      if (geomType === 'Polygon'){
      var linerings = geometry.getLinearRings();
      var coordinates = linerings[0].getCoordinates();
        for (var i=1;i<linerings.length;i++){ 
            var coordsToAdd = linerings[i].getCoordinates();
            for (var f=0;f<coordsToAdd.length;f++){
             coordinates.push(coordsToAdd[f]);   
            }
        }
      return new ol.geom.MultiPoint(coordinates);
      }
      else if (geomType === 'LineString'){ 
      var coordinates = geometry.getCoordinates();
      return new ol.geom.MultiPoint(coordinates);    
      }
    }
  })
]
2
  • Thanks for your input @pavlos. The geometry function I have works on a linestring, but not when using the select interaction which is the reason for the question. I've utilised your function and it works fine. I don't quite understand the difference between a LineString and a MultiPoint geometry. Something to study there!
    – dvmac01
    Commented Oct 15, 2015 at 14:16
  • Again, thanks pavlos. I like your style function and otherwise would have rated your example as the answer but Jonatas addressed my specific question regarding the select interaction so I decided that his answer should be the correct one. I appreciate your help ;)
    – dvmac01
    Commented Oct 15, 2015 at 14:24
1

UPDATE:

When a function is used on ol.Feature#setStyle your feature is referenced with the this keyword. Like:

var selectedStyle = function () {
    console.info(this);
    var feature = this;
    var geometry = feature.getGeometry();
};

The reason that your features don't keep style is because they are (when selected) on a temporary ol.layer.Vector. So, to achieve what you want you can do:

select.on('select', function(evt){
    var selected = evt.selected;
    var deselected = evt.deselected;

    if (selected.length) {
        selected.forEach(function(feature){
            console.info(feature);
            feature.setStyle(style_modify);
        });
    } else {
        deselected.forEach(function(feature){
            console.info(feature);
            feature.setStyle(null);
        });
    }
});

http://jsfiddle.net/jonataswalker/eogk4r4b/

3
  • Thanks as ever Jonatas, however I get an Uncaught TypeError: feature.getGeometry is not a function when passing (selectedStyle) from above. I tried placing the function inside the collection.forEach but it made no difference.
    – dvmac01
    Commented Oct 15, 2015 at 11:26
  • I understand now, sorry I'm so wrapped in this project that sometimes I miss the obvious! Thanks again for your assistance Jonatas ;)
    – dvmac01
    Commented Oct 15, 2015 at 14:21
  • You're welcome, have a good day. Commented Oct 15, 2015 at 14:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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