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;
};
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/

  • 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 Oct 15 '15 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 Oct 15 '15 at 14:21
  • You're welcome, have a good day. – Jonatas Walker Oct 15 '15 at 14:25
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);    
      }
    }
  })
]
  • 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 Oct 15 '15 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 Oct 15 '15 at 14:24

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.