Tuesday, July 06, 2004

JTS to Oracle Spatial

The only way to create MultipPolygons in oracle is to use the oracle.sdoapi.geom.GeometryFactory.createGeometryCollection() method. The javadoc states:

Creates a GeometryCollection. This method may return sub-type of GeometryCollection such as MultiPoint.


However, the return type expected is MultiPolygon, but the method is returning a GeometryCollection type. Inserting this into oracle results in a 2004 SRID instead of the needed 2007 SRID.

Well, at least I think it is needed. We (John C and I) figured that it would be better to convert all geometries to the same type of geometry. Instead of that, I am going to try and mix polygons and multi-polygons.

Ok, so I had a problem with the dimension out of range, oracle error ORA-13367. It seems that the geometry metadata table was populated by sdelayer register command. I must remember to populate the metadata table before I register it with sde.

Now, I have found a problem that the Geometry.buffer() object creates a polygon that is specified by coordinates in a clockwise manner. Oracle expects a counter clockwise polygon.

JTS Polygon outer rings can be oriented either clockwise or counter-clockwise.

The oracle database needs the outer rings to be oriented counter clockwise and the inner rings to be clockwise. I've been told they do this to determine what ring is an outer ring.

The java sdoapi does not seem to specify either. I would 'assume' that the orientation should not matter because the api has getExteriorRing and getInterierRings methods which allow one to determine which is the outer ring without relying on orientation.

The result is a polygon in JTS land with a clockwise oriented outer ring that uses AdapterJTS to convert into an sdoapi.Polygon which then gets converted into a JDBC prepared statement via the oracle GeometryAdapter and inserted into oracle. The polygon does not get converted so that the outer ring is counter clockwise. This results in an invalid sdo_geometry.

As a work around I have not used the buffer() method and have buffered things myself in a hackish way. I still plan on sending this as a bug report to Oracle and then maybe up the chain to geotools if oracle states that the outring ring in sdoapi java land is required to be counter clockwise.



Finally I ended my day trying to register the point centroid table with sde. It did not work. Probably because I was trying to get a point view from a polygon table. I think that the index did not jive properly. I'm not entirely sure. Tom suggested a hack registration that probably would work. I have decided to create two tables intead. One is the polygon table with a trigger to populate the other, a point table that is the centroid of the polygon.

1 comment:

Anonymous said...

Your blog keeps getting better and better! Your older articles are not as good as newer ones you have a lot more creativity and originality now keep it up!