OpenLayers – Issues Displaying Polygon (or Line) with Zero Size: How to Fix

openlayerspolygon

Using OpenLayers 6, my app will not display anything for a Polygon (or line) where all the vertices have the same coordinates.

Being that the style being used has a non-zero line thickness, I would like these zero-sized features to still be displayed (eg, as a dot with a diameter the same as the line thickness). Is this possible?

Eg, Attempting to display a polygon based on the following GeoJSON with 3 identical coordinate pairs displays nothing:

{ "type": "Polygon", "coordinates": [ [ [ -122.035835228206764, 37.336042860605609 ], [ -122.035835228206764, 37.336042860605609 ], [ -122.035835228206764, 37.336042860605609 ] ] ] }

Whereas, this one, with the first and last pair identical and the middle coordinate different displays as a straight line:

{ "type": "Polygon", "coordinates": [ [ [ -122.035835228206764, 37.336042860605609, 0.0 ], [ -122.029211830581957, 37.330858755040133, 0.0 ], [ -122.035835228206764, 37.336042860605609, 0.0 ] ] ] }

In both cases, the area of the polygon is zero. If a zero-area polygon with only 1 dimension can be displayed, why can a zero size polygon or a zero-length line not be displayed?

Or is there some other way that I could get these objects to appear?

It seems inconsistent that a polygon with zero-width displays when a line with zero length does not.

Best Answer

One possible solution would be to have a style function where geometry of a feature is checked. If it's polygon with three points with equal coordinates, circle style is returned with point geometry which has this coordinates, otherwise some default style is returned.

Code could then look something like this (tested):

var defaultStyle = new ol.layer.Vector().getStyleFunction()();

function pointStyle(coord) {
  var style = new ol.style.Style({
    image: new ol.style.Circle({
      radius: 2,
      fill: new ol.style.Fill({
        color: 'orange',
      }),
    }),
    geometry: new ol.geom.Point(coord)
  });
  
  return(style);
}

function myStyle(feature, resolution) {
  if (feature.getGeometry().getType() != 'Polygon') {
    return(defaultStyle);
  }

  const coordinates = feature.getGeometry().getCoordinates()[0];        
  if (coordinates.length == 3) {
    var isEqual = true;
    for (var i = 1; i < 3; i++) {
      if ((coordinates[0][0] != coordinates[i][0]) || (coordinates[0][1] != coordinates[i][1])) {
        isEqual = false;
        break;
      }
    }
    if (isEqual) {
      return(pointStyle(coordinates[0]));
    }
  }
  
  return(defaultStyle);
}