I am doing a assignment in which I created spatial tables for 3 warehouse location. These 3 warehouses has polygon geometry. I want add query to show which gemetry is not rectangle. Below is table I created:
-
2If you check basic definition of "a rectangle" you may see "A rectangle is a quadrilateral with four right angles." So, probably you will need to [1] calculate interior angles if they all are 90° and [2] check if opposite sides are equal in their length.– Taras ♦Commented Oct 14, 2021 at 13:21
-
2What have you tried? Do you know how to tell if four lines (or four points) form a rectangle, and you just need to know how to implement that in SQL? eg check side lengths and diagonal lengths? onlinemath4all.com/…– SpacedmanCommented Oct 14, 2021 at 13:22
-
1What is a rectangle when dealing with unprojected data? Let's not forget that a degree of longitude does not have the same ground length at various latitudes, and that angles are a bit more complex over a sphere than over a flat surface..– JGHCommented Oct 14, 2021 at 14:31
-
Because the geodetic distances are very small, it's probably reasonable to compute as if the geometries were planar.– dr_jtsCommented Oct 14, 2021 at 18:02
3 Answers
If rectangles are required to have exactly 4 corners, then only polygons where ST_NPoints(geom) > 5
need to be considered.
To test quadrilaterals for rectangularity, compare the lengths of their diagonals. In a rectangle the diagonal lengths are (almost) equal. Since finite numerical precision means the lengths will rarely be exactly equal, a tolerance factor is needed To use a dimension-free tolerance the lengths can be normalized by the total length.
Here's a query computing the "rectangularity ratio" from your data and a perfect rectangle:
WITH data(id, geom) AS (VALUES
(1, 'POLYGON((144.78116 -37.824855, 144.780843 -37.826916, 144.782018 -37.827019, 144.78232 -37.82496, 144.78116 -37.824855))')
,(3, 'POLYGON((153.193238 -27.682795, 153.19302 -27.68375, 153.193568 -27.683843, 153.193795 -27.682894,153.193238 -27.682795))')
,(4, 'POLYGON ((153.1931 -27.6828, 153.1937 -27.6828, 153.19370000000004 -27.6838, 153.1931 -27.6838, 153.1931 -27.6828))')
)
SELECT id,
(ST_Distance( ST_PointN(ST_ExteriorRing(geom), 1), ST_PointN(ST_ExteriorRing(geom), 3))
- ST_Distance( ST_PointN(ST_ExteriorRing(geom), 2), ST_PointN(ST_ExteriorRing(geom), 4)))
/ (ST_Distance( ST_PointN(ST_ExteriorRing(geom), 1), ST_PointN(ST_ExteriorRing(geom), 3))
+ ST_Distance( ST_PointN(ST_ExteriorRing(geom), 2), ST_PointN(ST_ExteriorRing(geom), 4))) AS rect_ratio
FROM data;
which gives the result:
id | rect_ratio
----+-----------------------
1 | -0.025764420345746754
3 | -0.02484385683541937
4 | 6.269495874867416e-12
-
1This is really helpful. I'm so grateful. I used ST_NPoints(geom) > and it worked Commented Oct 14, 2021 at 18:58
-
As pointed out above, just checking the "diagonal" lengths does have a failure case (triangle with multiple vertices on one edge). So there needs to be an area check or an angle check as well to eliminate this.– dr_jtsCommented Oct 15, 2021 at 16:50
If you are using projected data, you can check if the minimum oriented bounding box of the geometry is the same as the original geometry. Since a bounding box is a rectangle, you can deduce that the input is also a rectangle.
with src (id, geom) as ( values
(1,'polygon((0 0, 0 1, 1 1,1 0, 0 0))'::geometry),
(2,'polygon((0 0, 0 1, 1 2,1 0, 0 0))'::geometry))
select id, ST_Equals(ST_OrientedEnvelope(geom),geom) is_rectangle
from src;
id | is_rectangle
----+--------------
1 | t
2 | f
(2 rows)
-
1This doesn't allow for slight inaccuracies in the input data. To handle this you could compute the Hausdorff distance between the rings of the input polygon and the oriented envelope and test if it is less than a desired amount (possibly a percentage of the perimeter or area?)– dr_jtsCommented Oct 14, 2021 at 17:57
-
1Or just
SELECT ..., ST_Area(geom) / ST_Area(ST_OrientedEnvelope(geom)) > 0.99
- no need to care for vertex count/order, simple and efficient.– geozelotCommented Oct 14, 2021 at 18:30 -
@geozelot yes, that's simpler, but won't detect narrow "gores".– dr_jtsCommented Oct 14, 2021 at 22:11
-
@dr_jts I mean, neither does comparing diagonals - obviously being unreliable for anything but
ST_NPoints = 5
(but those rectangular shapes do exist...); no chance to detect 2 diagonals (one, yes, e.g.ST_LongestLine
) and it's vulnerable to anomalies, e.g. with'POLYGON((0 0, 0.5 0, 1 0, 1.5 0, 0.75 1, 0 0))'
, which, I believe, is a triangle with a perfect ratio. Hausdorff is equally vulnerable to outliers, e.g.'POLYGON((0 0, 0.5 0.4, 1 0, 1 1, 0 1, 0 0))'
. The equality approach here leaves us with no tolerance at all, which is, as we know, not fitting for floating point precision.– geozelotCommented Oct 15, 2021 at 11:25 -
So, for all those cases which cannot hold that very strict set of requirements, i.e. "has 4 corners / 5 vertices" - and this one requirement is needed for both approaches, comparing diagonals and making the equality check more likely to succeed - one of the most reliable, general purpose 'rectangularity' checks is comparing Polygon area with the minimum oriented envelope. And it's equally precise for the 5 vertices case...– geozelotCommented Oct 15, 2021 at 11:32
The Cook County Assessor's Office has a set of SQL statements that, together, can be used to determine the regularity of a shape (in their case, it's applied to 1.8 million property parcels). https://github.com/ccao-data/data-architecture/pull/522
The six attributes they ascribe to each parcel were taken from a paper called "See how the land lies: Land valuation using spatial models" by Jacqueline Seufert, Geert Goeyvaerts & Sven Damen, published January 2023.
Read that GitHub pull request to see the SQL statements to ascribe these six attributes:
- The standard deviation of the interior angles of the parcel polygon
- The standard deviation of the parcel polygon edge length
- The standard deviation of the parcel vertices' distance to the parcel centroid
- The total number of vertices in the parcel polygon
- The ratio of the length of the sides of the minimum spanning rotated rectangle
- The ratio of the areas of the minimum spanning rotated rectangle and the parcel polygon itself