Topological vs Non-Topological Simplification/Generalization of Aggregated Area Geometies in Oracle

Oracle has a function, sdo_util.simplify that can simplify (generalize) the vertices describing a geometric object (that is, reduce the number in a way that maintains basic shape). However, that function only operates on a single geometry at a time. Using it on polygonal data that completely covers an area (planar enforced) can and will cause major deformation of the shapes destroying topological integrity. This article describes the problem and offers some solutions.

Here are some area shapes before simplification/generalisation. Note that the shared boundaries match with no gaps or overlaps.

Here are the same areas but after an unconstrained/non-topological simplification of each area independently of all others. Note that gaps and overlaps now occur.

Finally, here are the same areas but after a topologically constrained simplification/generalization. Note that boundaries still match with no overlaps and gaps.

Simplifying an aggregation without breaking the ordinate limit

Now, what would be nice is the ability to aggregate polygons and even if the result has more ordinates that Oracle can handle, simplify the resultant aggregate before returning it to Oracle. Now, this cannot be done as follows in the situation where the result of the SDO_AGGR_UNION breaks the SDO_ORDINATE_ARRAY limit:

 SELECT SDO_UTIL.SIMPLIFY(SDO_AGGR_UNION(SDOAGGRTYPE(a.GEOM,0.0005)),25,0.0005) AS aggrPoly

I have provided this capability via a new set of methods in my SC4O package. I will demonstrate one of those methods now.

These are the polygons displayed using GeoRaptor that we will aggregate.

The aggregation with simplification is done via this simple call:

 SELECT SC4O.ST_AggrUnionPolygons(CAST(COLLECT(a.GEOM) AS T_GeometrySet),3,25) AS aggrPoly
   FROM codesys.vegPolys a;

This uses a 3 decimal digit precision and a 25 meter simplification distance.

NOTE: The ST_AggrUnionPolygons function is designed to operate on projected data and not geographic (long/lat) data. If you have long/lat data (eg SRID = 8307) you can use the above function but the ordinate precision and the simplification distance must be specified in decimal degree units. If you can’t work out what something like 25m is in decimal degrees, I recommend you project your data into a suitable planar SRID to do the calculations and then project back. Assuming that vegPolys was geodetic, the new SQL would be:

 SELECT sdo_cs.transform(
           SC4O.ST_AggrUnionPolygons(CAST(COLLECT(sdo_cs.transform(a.GEOM,28355)) AS T_GeometrySet),3,25),
           8307) AS aggrPoly
   FROM codesys.vegPolys8307 a;

Either way, the following result should be produced:

Which, together with the original vegetation polygons looks like this: