Top 5 Recent Articles
ARTICLES CATEGORIES
- Algorithms (22)
- All (399)
- Biography (1)
- Blog (44)
- Business Requirements (1)
- Commentary (1)
- Conversion (2)
- Customers (2)
- Data Models (1)
- Education (2)
- GeoRaptor (13)
- GPS (1)
- Image Processing (2)
- Import Export (8)
- Licensing (2)
- LiDAR (1)
- Linear Referencing (4)
- Manifold GIS (3)
- Mapping (1)
- MySQL Spatial (7)
- Networking and Routing (including Optimization) (5)
- Open Source (18)
- Oracle Spatial and Locator (194)
- Partitioning (1)
- PostGIS (36)
- Projections (1)
- Published Articles (1)
- qGIS (1)
- Recommendations (1)
- Services (1)
- Software Change Log (1)
- Source Code (37)
- Space Curves (9)
- Spatial Database Functions (109)
- Spatial DB comparison (1)
- Spatial XML Processing (11)
- SQL Server Spatial (92)
- Standards (3)
- Stored Procedure (17)
- Tessellation or Gridding (10)
- Tools (2)
- Topological Relationships (1)
- Training (2)
- Triangulation (2)
ESRI ArcSDE Exverted and Inverted Polygons and Oracle Spatial
Anyone who has used an ESRI client software to edit data which is then stored in Oracle via ArcSDE has probably come across some peculiarly organised polygons that pass ArcSDE validation but not Oracle’s.
(Note: Both products are OGC Simple Features Specification compliant. So why is this? In the main this is because ESRI’s ArcSDE pre-existed the OGC and SQL/MM standards. It would seem to me that the standards compliance process only tests a product’s adherence to the declared aspects of the standard: they do not look at support for features or functions not declared as part of the standard. Nor do they demand that features not in the standard be removed. This could be construed as being a loop-hole allowing vendors to “embrace and extend” the standard, but in this situation it is simply a case of something historically pre-existing the standard.)
These peculiarly organised polygons are inverted or exverted polygons that have their genesis in the original programming of the Spatial DataBase Engine (SDBE) 1.0 by Geomatic Technologies Incorporated (GTI) based in Bellingham, Washington (a company owned by the brilliant Mike Butler) before its sale to ESRI.
(As side node: GTI produced SDBE only for Interbase. One of the main features of Interbase was an Array datatype which GTI used to store the coordinates of a spatial feature in the POINTS column of the Fnnn table. When ESRI bought SDBE and ported it to Oracle they decided to store the points in a LONG RAW column making it impossible for a non-ArcSDE client to access and understand without some effort at reverse engineering. PL/SQL has no functions that allow a programmer to see “inside” a LONG RAW based SDEBINARY geometry.)
I am sure inverted polygons exist in ArcSDE (and have double checked the original _”Introduction to ArcSDE”_ course notes I wrote for ESRI Inc back in 1995) but I cannot remember if exverted polygons were a part of ArcSDE. When I held the position of GIS Manager at my last employer, my team constantly had problems with ArcInfo creating bow tie (ie exverted) polygons which ArcSDE would pass and store in Oracle (we used SDO_GEOMETRY storage) yet would not pass our daily PL/SQL based DBMS_JOB that checked all spatial edits done that day. Because of this I have included discussion of exverted (eg bow tie ) polygons in this article.
OK, since a picture is worth a thousand words, let’s have a look at these polygons.
Firstly, let’s create a table to hold our data.
drop table inverted; delete from user_sdo_geom_metadata where table_name = 'INVERTED'; commit; create table inverted ( oid integer, geom_type varchar2(25), geom sdo_geometry ); insert into user_sdo_geom_metadata (table_name,column_name,diminfo,srid) values ('INVERTED','GEOM',MDSYS.SDO_DIM_ARRAY(MDSYS.SDO_DIM_ELEMENT(X,0,5000,0.05),MDSYS.SDO_DIM_ELEMENT(Y,0,5000,0.05)),NULL); commit;
Now, let’s create a singly inverted polygon.
insert into inverted values(1,'Singly inverted polygon', sdo_geometry(2003,null,null, sdo_elem_info_array(1,1003,1), sdo_ordinate_array(100,0,400,0,400,150,250,100,250,200,400,150,400,300,100,300,100,0)));
This polygon looks like this.
!http://www.spatialdbadvisor.com/images/44.png (Polygon with inverted outer shell)!
Now, let’s create a doubly inverted polygon.
insert into inverted values(2,'Doubly inverted polygon', sdo_geometry(2003,null,null, sdo_elem_info_array(1,1003,1), sdo_ordinate_array(450,0,800,0,800,150,725,100,650,150,575,100,500,150,575,200,650,150,725,200,800,150,800,300,450,300,450,0)));
This polygon looks like this.
!http://www.spatialdbadvisor.com/images/47.png (Polygon with doubly inverted outer shell)!
Now let’s create a simple, *exverted* polygon.
insert into inverted values(3,'Exverted Polygon', sdo_geometry(2003,null,null, sdo_elem_info_array(1,1003,1), sdo_ordinate_array(125,400,200,400,200,450,275,425,275,475,200,450,200,525,125,525,125,400)));
This polygon looks like this.
!http://www.spatialdbadvisor.com/images/45.png (Polygon with exverted outer shell)!
Finally, though unnecessary (as the previous exverted polygon is also a “bow tie”), let’s create a classic *Bow Tie* (exverted) polygon.
insert into inverted values(4,'Bow Tie', sdo_geometry(2003,null,null, sdo_elem_info_array(1,1003,1), sdo_ordinate_array(400,400,575,475,725,400,725,550,575,475,400,550,400,400))); commit;
This polygon looks like this.
!http://www.spatialdbadvisor.com/images/46.png (Polygon with exverted outer shell – A classic bow tie)!
Now let’s check the status of these geometries
select i.oid, i.geom_type, substr(sdo_geom.validate_geometry(i.geom,0.5),1,6) as valid, i.geom.sdo_elem_info from inverted i; OID GEOM_TYPE VALID GEOM.SDO_ELEM_INFO ---------------------- ------------------------- ------ ------------------ 1 Singly inverted polygon 13349 NUMBER(1,1003,1) 2 Doubly inverted polygon 13349 NUMBER(1,1003,1) 3 Exverted Polygon 13349 NUMBER(1,1003,1) 4 Bow Tie 13349 NUMBER(1,1003,1) 4 rows selected
Note that all of them are described in the SDO_ELEM_INFO array by a single outer shell (ie 1003). This is correct with respect to the organisation of inverted and exverted polygons. For those not used to Oracle, the error number 13349 is described as follows:
!http://www.spatialdbadvisor.com/images/48.png (Oracle Error 13349 produced by Sdo_Geom.Validate_Geometry)!
Of course, because they are not OGC/SFS or SQL/MM compliant polygons, they fail Oracle’s validation software.
Now, check what happens when they are passed through Oracle’s own, internal, Sdo_Util.Rectify_Geometry routine.
select geom_type, substr(sdo_geom.validate_geometry(geom,0.5),1,6) as ovalid, r.geom.sdo_elem_info as oelements, r.rectgeom.sdo_elem_info as relements, substr(sdo_geom.validate_geometry(r.rectgeom,0.5),1,10) as rvalid from (select i.geom_type, i.geom, sdo_util.rectify_geometry(i.geom,0.5) as rectgeom from inverted i )r; GEOM_TYPE OVALID OELEMENTS RELEMENTS RVALID ------------------------ ------ ------------------ ------------------------------------ ------ Singly inverted polygon 13349 NUMBER(1,1003,1) NUMBER(1,1003,1,13,2003,1) TRUE Doubly inverted polygon 13349 NUMBER(1,1003,1) NUMBER(1,1003,1,13,2003,1,23,2003,1) TRUE Exverted Polygon 13349 NUMBER(1,1003,1) NUMBER(1,1003,1,9,1003,1) TRUE Bow Tie 13349 NUMBER(1,1003,1) NUMBER(1,1003,1,9,1003,1) TRUE 4 rows selected
They are corrected. Normally one would correct these either in the client or in the database via a trigger or a DBMS_SCHEDULER task run at the end of each day to check the day’s edits. Fixing via interactive SQL executed in SQLPlus or SQL Developer would occur as follows:
update inverted i set i.geom = sdo_util.rectify_geometry(i.geom,0.5) where sdo_geom.validate_geometry(i.geom,0.5) <> 'TRUE';
Whilever these geometries exist in the database uncorrected, what is the effect on geoprocessing results?
Let’s check.
First, are buffers correctly formed?
select oid, geom_type, sdo_geom.validate_geometry(sdo_geom.sdo_buffer(i.geom,10,0.05),0.5) as bValie from inverted i; OID GEOM_TYPE BVALIE ---------------------- ------------------------- ------ 1 Singly inverted polygon TRUE 2 Doubly inverted polygon TRUE 3 Exverted Polygon TRUE 4 Bow Tie TRUE 4 rows selected
Yes they are. Secondly let’s create a test, overlay geometry.
insert into inverted values(5,'Overlay Geometry', sdo_geometry(2003,null,null, sdo_elem_info_array(1,1003,1), sdo_ordinate_array(423,-87,880,-98,867,119,429,158,423,-87))); commit;
Which looks like this (over oid = 2):
!http://www.spatialdbadvisor.com/images/50.png (Polygon overlaying Doubly Inverted Inverted Polygon)!
Firstly let’s union (SDO_GEOM.SDO_UNION) this geometry with the ‘Doubly Inverted Polygon’ (oid 2).
select i1.oid, sdo_geom.validate_geometry(sdo_geom.sdo_union(i1.geom,i2.geom,0.05),0.05) as uValid from inverted i1, inverted i2 where i1.oid = 2 and i2.oid = 5; OID UVALID ---------------------- ------ 2 TRUE 1 rows selected
Which (correctly) looks like:
!http://www.spatialdbadvisor.com/images/53.png (Union With Double Inverted Polygon)!
Now let’s intersect (SDO_GEOM.SDO_INTERSECTION) this geometry with the ‘Doubly Inverted Polygon’ (oid 2).
select il.oid, sdo_geom.validate_geometry(sdo_geom.sdo_intersection(i1.geom,i2.geom,0.05),0.05) as intValid from inverted i1, inverted i2 where i1.oid = 2 and i2.oid = 5; OID INTVALID ---------------------- -------- 2 TRUE 1 rows selected
Which (correctly) looks like:
!http://www.spatialdbadvisor.com/images/52.png (Intersection With Double Inverted Polygon)!
Of course, one should really only conduct geoprocessing on valid geometries, but if you have to do so on invalid geometries, please check the results oneself as Oracle, I believe, does not guarantee the results of processing when the geoemtry data is invalid.
I hope this article is of use to someone.
Documentation
- MySQL Spatial General Functions
- Oracle LRS Objects
- Oracle Spatial Exporter (Java + pl/SQL)
- Oracle Spatial Object Functions
- Oracle Spatial Object Functions (Multi Page)
- PostGIS pl/pgSQL Functions
- SC4O Oracle Java Topology Suite (Java + pl/SQL)
- SQL Server Spatial General TSQL Functions
- SQL Server Spatial LRS TSQL Functions