6

I have this small SpatiaLite database and it looks like the following:

enter image description here

It's made of polygons and I'd like to find a way of excluding all polygons that look more like a line. Something like excluding the following ones:

enter image description here

Is there any PostGIS function that I can use to make a query and filter polygons according to their shape (not filtering by area size)? In a way that the ones that look more like a line are excluded?

I understand that the result may not be perfect but I'd like to know if there's any way of differentiating the shape of polygons with SpatiaLite/PostGIS...

5
  • This is likely to get closed as "too broad" since you're asking two questions, the same one, but for both spatialite and for PostGIS Jun 27, 2021 at 23:00
  • 1
    @alphabetasoup Actually, the close vote was before my editing because I was asking about QGIS too... I've already fixed that and now it's focusing only on the query solution. One curiosity though is: in my view, SpatiaLite can use most of PostGIS functions. Why do you still think it's too broad since probably the same solution that works on SpatiaLite may work on PostGIS as well? I can limit it only to SpatiaLite and there's no problem on that... But my feeling is that you were influenced by the first vote for closing it and you haven't checked that the "too broad" problem is already fixed..
    – raylight
    Jun 27, 2021 at 23:05
  • The set of functions are similar and both depend on GEOS, but they are different. Jun 27, 2021 at 23:07
  • @alphabetasoup Even if you consider that for me it's completely transparent if I'm working with PostGIS or SpatiaLite? I chose SpatiaLite since it's easy to share the data together with the question. But in my case, I can work with both PostGIS or SpatiaLite, leaving the PostGIS tag could lead me to learn the differences between them. But again, I can completely erase the PostGIS alternative from my question if you think that it'd be better... Do you stil consider it too broad even after reading my last point?
    – raylight
    Jun 27, 2021 at 23:14
  • 1
    To be honest, I'm not bothered and I've retracted my close vote Jun 27, 2021 at 23:24

5 Answers 5

6

Spatialite 5.0 has a function "Circularity" http://www.gaia-gis.it/gaia-sins/spatialite-sql-latest.html.

computes the Circularity Index from the given Geometry by applying the following formula:

index = ( 4 * PI * Sum(area) ) / ( Sum(perimeter) * Sum(perimeter) )

it only applies to Polygons or MultiPolygons with the following
interpretation:
    1.0 corresponds to a perfectly circular shape.
    very low values (near zero) correspond to a threadlike shape.
    intermediate values correspond to a more or less flattened
    shape; lower index values means a stronger flattening effect.
if the given Geometry does not contains any Polygon but contains
at least a Linestring the index will always assume a 0.0 value.
if the given Geometry only contains one or more Points the index
will always assume a NULL value.

SQL for your dataset:

select circularity(geometry) as shapeindex,*
from dataset
order by shapeindex asc;

The first selected feature in the BLOB explorer

enter image description here

5

You could use ST_MaximumInscribedCircle to find polygons which are "narrower" than a given distance. This will also find small polygons which are not elongated, so to filter those out you could use ST_Perimeter.

4

You can use a compactness measure to determine the "circularity" of a polygon. See this question.

2

How about using a QGIS function to create an "Oriented minimum bounding box"? The process creates a field called height and another width for each feature. You could then calculate the ratio of the two fields and set a threshold to what you consider elongated or not.

1

A very simple approach: calculate the length of the boundary as well as the area of the polygon, than use this to get the boundary/area ratio. Long boundary divided by small area results in a high value: thus you could define a threshold above which your polygons tend to be more or less like a line.

You could directly use Select by expression with an expression like the following. Replace x by a certain threshold that fits your needs. Start e.g. with 0.02 and than increase the value until you're staisfied with the result:

length (boundary($geometry)) / area($geometry) > x

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.