Search code examples
stylesopenlayers-3

Customize vertex style when selecting features (point, line, polygon) in Openlayers 3?


I am trying to show the vertices on selected features in openlayers 3 by customizing their style. I have managed to do so for polygons, but need it dynamically on all feature types (point, line polygon)

The solution for polygons is using multiple styles, as shown below.

var styleFunction = function() {
        return [
          new ol.style.Style({
            image: new ol.style.Circle({
              radius: 5,
              fill: new ol.style.Fill({
                color: '#00aaff'
              }),
              stroke: new ol.style.Stroke({color: '#00aaff', width: 2})
            }),
            geometry: function(feature) {
              var coordinates = feature.getGeometry().getCoordinates()[0];
              return new ol.geom.MultiPoint(coordinates);
            }
          }),
          new ol.style.Style({
            stroke: new ol.style.Stroke({
              color: "#00aaff",
              width: 3
            }),
            fill: new ol.style.Fill({
              color: "rgba(255,255,255,0.4)"
            })
          })
        ]
      }

This solution works for polygons, but when selecting lines the vertices don't show, and when selecting points my styleFunction breaks completely.

I get the following error on points:

TypeError: e is undefined SimpleGeometry.js:196
    setLayout SimpleGeometry.js:196
    setCoordinates MultiPoint.js:158
    e MultiPoint.js:25
    geometry (index):128
    Ua vector.js:128
    Ua vector.js:127
    renderFeature VectorLayer.js:404
    E VectorLayer.js:353
    <anonymous> (index):975
    prepareFrame VectorLayer.js:370
    renderFrame Map.js:159
    renderFrame_ PluggableMap.js:1232
    animationDelay_ PluggableMap.js:191
    <anonymous> (index):975

Can anyone help me modify the styleFunction in a way that it supports all feature types?

Thanks for any leads


Solution

  • Handle each type of geometry differently as getCoordinates returns different object of coordinates depending on the type of geometry passed. Check this

    var styleFunction = function() {
            return [
              new ol.style.Style({
                image: new ol.style.Circle({
                  radius: 5,
                  fill: new ol.style.Fill({
                    color: '#00aaff'
                  }),
                  stroke: new ol.style.Stroke({color: '#00aaff', width: 2})
                }),
                geometry: function(feature) {
                  var coordinates;
                  if (feature.getGeometry().getType() == "LineString"){
                      coordinates = feature.getGeometry().getCoordinates();
                  } else if (feature.getGeometry().getType() == "Polygon"){
                      coordinates = feature.getGeometry().getCoordinates()[0];
                  } else if (feature.getGeometry().getType() == "Pont"){
                   //not 100% sure this would work!!!!
                      coordinates = [feature.getGeometry().getCoordinates()];
                   } else {
                      alert("maybe you need to handle also multi geometries");
                   }
                  return new ol.geom.MultiPoint(coordinates);
                }
              }),
              new ol.style.Style({
                stroke: new ol.style.Stroke({
                  color: "#00aaff",
                  width: 3
                }),
                fill: new ol.style.Fill({
                  color: "rgba(255,255,255,0.4)"
                })
              })
            ]
          }