SpatialDB Advisor
This reflection has come about because of the many times I have gone to sites running Oracle Standard Edition (SE or SE1) that are, accidently, using some of the “geoprocessing” functions in the SDO_GEOM package that are licensed only for use with Enterprise Edition (EE). Oracle XE adds to this confusion as it is shipped with the complete SDO_GEOM package. And, finally, the recent release of Oracle 11g continues the restricted use of certain SDO_GEOM package “geoprocessing” functions and their use in the related ST_* functions of the SQL3/MM (or OGC) type library.
Oracle Locator is a cut down version of Oracle Spatial Standard Edition (SE/SE1) database installations.
From Appendix B of the Spatial User Guide we see:
Oracle Locator (also referred to as Locator) is a feature of Oracle Database 10g Standard Edition. Locator provides core features and services available in Oracle Spatial. It provides significant capabilities typically required to support Internet and wireless service-based applications and partner-based GIS solutions. Locator is not designed to be a solution for geographic information system (GIS) applications requiring complex spatial data management. If you need capabilities such as linear referencing, spatial functions, or coordinate system transformations, use Oracle Spatial instead of Locator.
Locator is available with both the Standard and Enterprise Editions of Oracle Database 10g. Spatial is a priced option available only with Oracle Database 10g Enterprise Edition. Spatial includes all Locator features as well as other features that are not available with Locator.
The installation of Locator depends on the successful and proper installation of Oracle interMedia. interMedia is installed and configured with Oracle Database 10g, although you can install interMedia manually if necessary, as documented in Oracle interMedia User’s Guide. During the installation of interMedia, Locator is installed.
In general, Locator includes the data types, operators, and indexing capabilities of Oracle Spatial, along with a limited set of the functions and procedures of Spatial. The Locator features include the following:
Much confusion exists about what is licensed and what is not wrt Locator. What is actually licensed is clearly documented in Appendix B of the Spatial User guide. Because, this article concentrates on the SDO_GEOM package functions and procedures, we note that only those functions listed in Table B-1 are licensed. These are:
SDO_GEOM.SDO_DISTANCE()
SDO_GEOM.VALIDATE_GEOMETRY_WITH_CONTEXT()
SDO_GEOM.VALIDATE_LAYER_WITH_CONTEXT()
There is no confusion about the other, self-contained, packages as these are only installed for Enterprise Edition. These packages are:
Why is there such confusion about the user of the SDO_GEOM function other than the three mentioned above in Standard Edition databases?
Simply put, when an SE database is created using Oracle’s DataBase Configuration Assistant (DBCA), all the functions and procedures in SDO_GEOM are installed: not just the actual three that are licensed for SE (see above). (The installer should be fixed to ensure that these are not installed.)
Coupled to this is the fact that very few day-to-day practitioners read the documentation and most certainly do not read or are a party to the license agreements negotiated and signed by management. Users simply connect to the installed software and start using it. When one of these users describes the SDO_GEOM package in SqlPlus (DESCRIBE MDSYS.SDO_GEOM) all SDO_GEOM functions are displayed: they therefore assume that use of these must be allowed. Finally, much/most commercial software used in the GIS world is keycoded to stop use of unlicensed components: that Oracle doesn’t do this is not widely known and contributes to the unintentional breaking of the license agreement.
Is there a way out of this problem?
Well, certainly, users should try and familiarise themselves with the license and try and conform to it. After all, Oracle owns the software and has the right to set whatever terms they want with respect to the licensing and use of their software.
I personally have a view that some of the “geoprocessing” functions in the SDO_GEOM package are not “geoprocessing” functions at all but properties of a spatial object and should be free of license restrictions. Specifically:
MDSYS.SDO_GEOM.SDO_AREA()
MDSYS.SDO_GEOM.SDO_LENGTH()
MDSYS.SDO_GEOM.SDO_MBR()
MDSYS.SDO_GEOM.SDO_MIN_MBR_ORDINATE()
MDSYS.SDO_GEOM.SDO_MAX_MBR_ORDINATE()
With respect to the other functions, eg SDO_UNION, SDO_INTERSECTION etc, while these are “geoprocessing” functions they are a necessary part of the OGC and SQL3/MM standard for an implementation of a spatial type that that Oracle should allow their use within Locator for no additional charge. However, they have decided otherwise and I respect that decision: perhaps they could consider licensing these functions independently of other Enterprise Edition Spatial features (eg LRS etc)? Certainly, most of the Locator users I know would happily part with $1,000 per cpu to be able to use these functions.
However, until such a thing happens, I will now outline some of the common SDO_GEOM functions that are illegally used in Locator installations demonstrating how they can be replaced by SQL or functions that are licensed for use.
The SDO_GEOM package contains the following functions:
MDSYS.SDO_GEOM.SDO_MBR
MDSYS.SDO_GEOM.SDO_MIN_MBR_ORDINATE
MDSYS.SDO_GEOM.SDO_MAX_MBR_ORDINATE
The SDO_MBR SDO_MBR function returns an optimized rectangle SDO_GEOMETRY object:
gis@XE>SELECT sdo_geom.sdo_mbr(geom) as MBR_Geometry
2 FROM transport
3 WHERE oid = 100000
4 /
MBR_GEOMETRY(SDO_GTYPE, SDO_SRID, SDO_POINT(X, Y, Z), SDO_ELEM_INFO, SDO_ORDINATES)
----------------------------------------------------------------------------------------------------------------------------------
SDO_GEOMETRY(2003, 82468, NULL, SDO_ELEM_INFO_ARRAY(1, 1003, 3), SDO_ORDINATE_ARRAY(489588.734, 5442823.66, 489666.972, 5442858.68))
To access the actual optimized rectangle ordinates one can do this:
gis@XE>SELECT o.*
2 FROM transport t,
3 TABLE(sdo_geom.sdo_mbr(t.geom).sdo_ordinates) o
4 WHERE t.oid = 100000
5 /
COLUMN_VALUE
------------
489588.734
5442823.66
489666.972
5442858.68
To “flatten” this into a single row, one could use the Locator licensed SDO_UTIL package’s GetVertices function as follows:
gis@XE>SELECT min(o.x) as minx,
2 max(o.x) as maxx,
3 min(o.y) as miny,
4 max(o.y) as maxy
5 FROM TRANSPORT t,
6 TABLE(sdo_util.GetVertices(sdo_geom.sdo_mbr(t.geom))) o
7* WHERE t.oid = 100000
gis@XE> /
MINX MAXX MINY MAXY
---------- ---------- ---------- ----------
503265.593 503361.836 5206993.37 5207088.18
Sensibly, however, most people simplify the SQL to access the lower left and upper right ordinates of the MBR optimized rectangle by using the provided MIN/MAX MBR functions as follows:
gis@XE>SELECT sdo_geom.sdo_min_mbr_ordinate(geom,1) as MINX,
2 sdo_geom.sdo_max_mbr_ordinate(geom,1) as MAXX,
3 sdo_geom.sdo_min_mbr_ordinate(geom,2) as MINY,
4 sdo_geom.sdo_max_mbr_ordinate(geom,2) as MAXY
5 FROM transport
6 WHERE oid = 100000
7 /
MINX MAXX MINY MAXY
---------- ---------- ---------- ----------
489588.734 489666.972 5442823.66 5442858.68
So how do we avoid the use of these licensed functions in Locator installations?
Firstly, one should note that the SDO_AGGR_MBR aggregate operator is licensed for use in Locator. The MBR functions in SDO_GEOM can be replaced with something that would conform to Oracle licensing in a trivial amount of time.
For example, the above SQL could be replaced by (a slightly different form of the SDO_MBR example above):
gis@XE>SELECT *
1 FROM TABLE(SELECT sdo_aggr_mbr(geom).sdo_ordinates
2 FROM transport
3 WHERE oid = 100000)
4 /
COLUMN_VALUE
------------
489588.734
5442823.66
489666.972
5442858.68
To return a single row we could do this:
gis@XE>SELECT min(case when rownum = 1 then column_value else NULL end) as minx,
1 min(case when rownum = 3 then column_value else NULL end) as maxx,
2 max(case when rownum = 2 then column_value else NULL end) as miny,
3 max(case when rownum = 4 then column_value else NULL end) as maxy
4 FROM TABLE(SELECT sdo_aggr_mbr(geom).sdo_ordinates
5 FROM transport
6 WHERE oid = 100000)
7 /
MINX MAXX MINY MAXY
---------- ---------- ---------- ----------
489588.734 489666.972 5442823.66 5442858.68
Or we could do this:
gis@XE>SELECT min(c.x) as minx,
1 max(c.x) as maxx,
2 min(c.y) as miny,
3 max(c.y) as maxy
4 FROM (SELECT sdo_aggr_mbr(t.geom) as mbr
5 FROM transport t
6 WHERE oid = 100000) g,
7 TABLE(mdsys.sdo_util.getvertices(g.mbr)) c;
8 /
MINX MAXX MINY MAXY
---------- ---------- ---------- ----------
489588.734 489666.972 5442823.66 5442858.68
(Note: there are many ways, in SQL, to “skin the cat”. I have deliberately done this in this article.)
Locator also includes the SDO_3GL package which is not mentioned in any of the licensing documents. One can conclude from this that the SDO_3GL package is not constrained by Locator license restrictions.
Investigating SDO_3GL we find that the package contains the following MBR procedure.
PROCEDURE EXTENT_OF_OBJECT
Argument Name Type In/Out Default?
------------------------------ ----------------------- ------ --------
DIMOBJ SDO_DIM_ARRAY IN
GEOMOBJ SDO_GEOMETRY IN
MIN_X NUMBER OUT
MAX_X NUMBER OUT
MIN_Y NUMBER OUT
MAX_Y NUMBER OUT
Note that this is a procedure not a function: it cannot be used in SQL SELECT statements. The only way we could use this would be via creating a set of functions that encapsulate this procedure and return the relevant elements. I will not do this here as these functions are relatively simple to write and I have already encapsulated them in an MBR object which is included in my free PL/SQL packages: I will demonstrate their use in Section 2.3.3 below.
The SDO_3GL package also contains the MBR_GEOMETRY function whose signature is:
FUNCTION MBR_GEOMETRY RETURNS SDO_GEOMETRY
Argument Name Type In/Out Default?
——————————————————————————-——————— GEOM SDO_GEOMETRY IN
DIM SDO_DIM_ARRAY IN
This can be used to return the extent of a feature as follows:
gis@XE>SELECT min(c.x) as minx,
2 max(c.x) as maxx,
3 min(c.y) as miny,
4 max(c.y) as maxy
5 FROM user_sdo_geom_metadata usgm,
6 transport t,
7 TABLE(mdsys.sdo_util.getvertices(mdsys.sdo_3gl.mbr_geometry(t.geom,usgm.diminfo))) c
8 WHERE usgm.table_name = 'TRANSPORT'
9 AND t.oid = 100000
10 /
MINX MAXX MINY MAXY
---------- ---------- ---------- ----------
489588.734 489666.972 5442823.66 5442858.68
The above query using my MBR package would be:
gis@XE>SELECT codesys.mbr(t.geom,usgm.diminfo).minx as minx,
2 codesys.mbr(t.geom,usgm.diminfo).miny as miny,
3 codesys.mbr(t.geom,usgm.diminfo).maxx as maxx,
4 codesys.mbr(t.geom,usgm.diminfo).maxy as maxy
5 FROM user_sdo_geom_metadata usgm,
6 transport t
7 WHERE usgm.table_name = 'TRANSPORT'
8 AND oid = 100000
9 /
MINX MINX MINY MAXY
---------- ---------- ---------- ----------
489588.734 5442823.66 489666.972 5442858.68
The MBR package only uses SDO_3GL.EXTENT_OF_OBJECT procedure and so does not break Standard Edition license restrictions. The MDSYS dependencies of the MBR package can be ascertained as follows:
gis@XE>SELECT referenced_owner,
2 referenced_name
3 FROM dba_dependencies
4 WHERE owner = 'CODESYS'
5 AND name = 'MBR'
6 AND referenced_owner = 'MDSYS'
7 /
REFERENCED_OWNER REFERENCED_NAME
------------------------------ ----------------
MDSYS SDO_GEOMETRY
MDSYS SDO_GEOMETRY
MDSYS SDO_DIM_ELEMENT
MDSYS SDO_DIM_ARRAY
MDSYS SDO_DIM_ARRAY
MDSYS SDO_3GL
6 rows selected.
In more detail (connected as CODESYS):
codesys@XE>SELECT text
2 FROM user_source
3 WHERE name = 'MBR'
4 AND INSTR(UPPER(text),'SDO_3GL') > 1
5 /
TEXT
------------------------------------
MDSYS.SDO_3GL.EXTENT_OF_OBJECT(
MDSYS.SDO_3GL.EXTENT_OF_OBJECT(
But what about SDO_GEOM? Using:
codesys@XE>SELECT text
2 FROM user_source
3 WHERE name = 'MBR'
4 AND INSTR(UPPER(text),'SDO_GEOM') > 1
5 /
TEXT
--------------------------------------------------------------------------------
Constructor Function MBR( p_geometry IN MDSYS.SDO_GEOMETRY,
Constructor Function MBR( p_geometry IN MDSYS.SDO_GEOMETRY,
Member Procedure SetLargestPart( p_geometry IN MDSYS.SDO_GEOMETRY,
Constructor Function MBR( p_geometry IN MDSYS.SDO_GEOMETRY,
Constructor Function MBR( p_geometry IN MDSYS.SDO_GEOMETRY,
-- @usage : FUNCTION SetLargestPart ( p_geometry IN MDSYS.SDO_GEOMETRY, p_dimarray IN MDSYS.SDO_DIM_ARRAY );
-- @paramtype : p_geomery : MDSYS.SDO_GEOMETRY
Member Procedure SetLargestPart( p_geometry IN MDSYS.SDO_GEOMETRY,
8 rows selected.
No SDO_GEOM package functions are being used by my MBR package.
Now, the SDO_GEOM.SDO_CENTROID function is an Enterprise feature. The SDO_GEOM.SDO_CENTROID function computes a mathematically weighted centroid that does not necessarily fall within a polygon as in the following example:

This function is called as follows:
gis@XE>SELECT mdsys.sdo_geom.sdo_centroid(a.geom,usgm.diminfo)
2 FROM user_sdo_geom_metadata usgm,
3 admin a
4 WHERE usgm.table_name = 'ADMIN'
5 AND a.oid = 46953
6 /
MDSYS.SDO_GEOM.SDO_CENTROID(A.GEOM,USGM.DIMINFO)(SDO_GTYPE, SDO_SRID, SDO_POINT(X, Y, Z), SDO_ELEM_INFO, SDO_ORDINATES)
-----------------------------------------------------------------------------------------------------------------------
SDO_GEOMETRY(2001, 82468, SDO_POINT_TYPE(327753.624, 5486215.53, NULL), NULL, NULL)
Elapsed: 00:00:00.01
But what if you don’t have an Enterprise license?
You have two other options for generating a centroid from geometry data using Standard Edition functions.
Firstly, you could use my GEOM package’s sdo_centroid function. This is a powerful function that is different from Oracle’s SDO_GEOM.SDO_CENTROID function in that it guarantees that a centroid will fall within a polygon and not outside it (a “para-centroid”). It will also place the centroid in the largest of all parts of a multi-part polygon and will not place a centroid inside any hole in any of the parts.
We call this function as follows:
gis@XE>SELECT codesys.geom.sdo_centroid(a.geom,usgm.diminfo)
2 FROM user_sdo_geom_metadata usgm,
3 admin a
4 WHERE usgm.table_name = 'ADMIN'
5 AND a.oid = 46953
6 /
CODESYS.GEOM.SDO_CENTROID(A.GEOM,USGM.DIMINFO)(SDO_GTYPE, SDO_SRID, SDO_POINT(X, Y, Z), SDO_ELEM_INFO, SDO_ORDINATES)
---------------------------------------------------------------------------------------------------------------------
SDO_GEOMETRY(2001, NULL, SDO_POINT_TYPE(327741.04, 5486221.36, NULL), NULL, NULL)
Secondly, you can use the CENTROID function in the SDO_3GL package. This will return exactly the same result as the SDO_GEOM.SDO_CENTROID function. You use it as follows:
gis@XE>SELECT mdsys.sdo_3gl.centroid(usgm.diminfo,a.geom)
2 FROM user_sdo_geom_metadata usgm,
3 admin a
4 WHERE usgm.table_name = 'ADMIN'
5 AND a.oid = 46953
6 /
MDSYS.SDO_3GL.CENTROID(USGM.DIMINFO,A.GEOM)(SDO_GTYPE, SDO_SRID, SDO_POINT(X, Y, Z), SDO_ELEM_INFO, SDO_ORDINATES)
------------------------------------------------------------------------------------------------------------------
SDO_GEOMETRY(2001, 82468, SDO_POINT_TYPE(327753.624, 5486215.53, NULL), NULL, NULL)
The SDO_GEOM.SDO_BUFFER function is also licensed only for use in Enterprise Edition.
We use this function as follows:
gis@XE>SELECT mdsys.sdo_geom.sdo_buffer(a.geom,usgm.diminfo,10)
2 FROM user_sdo_geom_metadata usgm,
3 admin a
4 WHERE usgm.table_name = 'ADMIN'
5 AND a.oid = 46953
6 /
-- resulting data not shown --
But how can we generate a buffer in Standard Edition?
Again, we can look to the SDO_3GL package.
FUNCTION GENERATE_BUFFER RETURNS SDO_GEOMETRY
Argument Name Type In/Out Default?
------------------------------ ----------------------- ------ --------
DIMOBJ SDO_DIM_ARRAY IN
GEOMOBJ SDO_GEOMETRY IN
DIST NUMBER IN
Which we use as follows:
gis@XE>SELECT mdsys.sdo_3gl.generate_buffer(usgm.diminfo,a.geom,10)
2 FROM user_sdo_geom_metadata usgm,
3 admin a
4 WHERE usgm.table_name = 'ADMIN'
5 AND a.oid = 46953
6 /
-- Resulting data not shown --
Are the buffers generated by the sdo_geom and sdo_3gl functions the same?
gis@XE>SELECt MDSYS.SDO_GEOM.RELATE(
2 MDSYS.SDO_3GL.GENERATE_BUFFER(usgm.diminfo,a.geom,10),
3 usgm.diminfo,
4 'mask=determine',
5 MDSYS.SDO_GEOM.SDO_BUFFER(a.geom,usgm.diminfo,10),
6 usgm.diminfo) As Relationship
7 FROM user_sdo_geom_metadata usgm,
8 admin a
9 WHERE usgm.table_name = 'ADMIN'
10 AND a.oid = 46953
11 /
RELATIONSHIP
------------
EQUAL
However, we now meet another problem: SDO_GEOM.RELATE is an Enterprise function! How can we check the relationship between two object with Locator?
Can we find a solution in the SDO_3GL RELATE functions?
gis@XE>SELECT MDSYS.SDO_3GL.RELATE(
2 usgm.diminfo,
3 MDSYS.SDO_3GL.GENERATE_BUFFER(usgm.diminfo,a.geom,10),
4 'mask=determine',
5 usgm.diminfo,
6 MDSYS.SDO_GEOM.SDO_BUFFER(a.geom,usgm.diminfo,10)) as Relationship
7 FROM user_sdo_geom_metadata usgm,
8 admin a
9 WHERE usgm.table_name = 'ADMIN'
10 AND a.oid = 46953
11 /
RELATIONSHIP
------------
111111111
What does this mean?
Well, if we do this:
gis@XE>SELECT MDSYS.SDO_3GL.RELATE(
2 usgm.diminfo,
3 a.geom,
4 'mask=determine',
5 usgm.diminfo,
6 MDSYS.SDO_GEOM.SDO_BUFFER(a.geom,usgm.diminfo,10)) as Relationship
7 FROM user_sdo_geom_metadata usgm,
8 admin a
9 WHERE usgm.table_name = 'ADMIN'
10 AND a.oid = 46953
11 /
RELATIONSHIP
------------
111111111
So, a bit mask of all 1s cannot mean EQUAL. I will investigate these masks and functions further to see what else I can discover and report back on them in an edited version of this article.
It has always amazed me that these two functions:
MDSYS.SDO_GEOM.SDO_AREA()
MDSYS.SDO_GEOM.SDO_LENGTH()
...are considered geoprocessing as these are properties of a geometric object and not something that results from the interaction of two objects. Still, it is Oracle’s right to license their technology as they see fit. But, given that these two functions are used an enormous amount in Locator installations we need a way out of the licensing dilemma.
There are two approaches. One is to see what is in the MDSYS.SDO_3GL package; the other is Java Topology Suite. I will only cover the first here and leave the latter for another blog article.
The MDSYS.SDO_3GL package contains two procedures (not functions):
PROCEDURE LENGTH_AREA
Argument Name Type In/Out Default?
------------------------------ ----------------------- ------ --------
DIMOBJ SDO_DIM_ARRAY IN
GEOMOBJ SDO_GEOMETRY IN
FLAG BINARY_INTEGER IN
LENGTH NUMBER OUT
AREA NUMBER OUT
PROCEDURE LENGTH_AREA
Argument Name Type In/Out Default?
------------------------------ ----------------------- ------ --------
DIMOBJ SDO_DIM_ARRAY IN
GEOMOBJ SDO_GEOMETRY IN
FLAG BINARY_INTEGER IN
UNIT VARCHAR2 IN
LENGTH NUMBER OUT
AREA NUMBER OUT
Note that the two procedures implement both the area and length processing. Both take a flag that indicates which property is required: length or area. The latter includes a UNIT field in case the caller wants the result in different units from the default: to use the units the SDO_SRID property of the SDO_GEOMETRY object must be non-NULL and the value must exist in the MDSYS.SDO_UNITS_OF_MEASURE table.
SELECT uom_id,
SUBSTR(unit_of_meas_name,1,50) as measure
FROM SDO_UNITS_OF_MEASURE
ORDER BY 2;
Experimenting with the FLAG argument shows that:
1 computes the Area of the geometry object
2 computes the lenght/boundary of a geometry object
(Note: This is counter-intuitive as the our parameters in the SDO_3GL.LENGTH_AREA procedures are the revers of this.)
In my GEOM package I have created four “wrapper” functions that provide a drop-in replacement for the SDO_GEOM.SDO_AREA and SDO_GEOM.SDO_LENGTH functions. Here is the definition of the GEOM.AREA implementations.
Function Length( p_geometry in sdo_geometry,
p_diminfo in sdo_dim_array,
p_units in varchar2 := 'Meter' )
Return number deterministic
Is
v_length number;
v_area number;
v_units varchar2(20) := p_units;
Begin
If ( p_geometry.sdo_srid is null ) Then
v_units := NULL;
End If;
mdsys.sdo_3gl.length_area(p_diminfo,p_geometry,2,v_units,v_area,v_length);
return v_length;
End Length;
Function Length( p_geometry in sdo_geometry,
p_tolerance in number,
p_units in varchar2 := 'Meter' )
Begin
Return &&defaultSchema.geom.Length(
p_geometry,
MDSYS.SDO_DIM_ARRAY(
MDSYS.SDO_DIM_ELEMENT('X',
&&defaultSchema..Constants.c_MaxVal,
&&defaultSchema..Constants.c_MaxVal,
p_tolerance),
MDSYS.SDO_DIM_ELEMENT('Y',
&&defaultSchema..Constants.c_MaxVal,
&&defaultSchema..Constants.c_MaxVal,
p_tolerance)),
p_units);
End Length;
Finally, an example to show that these functions return the correct results.
gis@XE> SELECT substr(PolyType,1,26) as polygon_Name,
2 mdsys.sdo_geom.sdo_length(a.geom,b.diminfo)
3 as sdo_length,
4 codesys.geom.length(a.geom,b.diminfo)
5 as geom_length,
6 mdsys.sdo_geom.sdo_area(a.geom,b.diminfo)
7 as sdo_area,
8 codesys.geom.area(a.geom,b.diminfo)
9 as geom_area
10 FROM ProjPoly2D a,
11 (select MDSYS.SDO_DIM_ARRAY(
12 MDSYS.SDO_DIM_ELEMENT('X',190000, 640000, .005),
13 MDSYS.SDO_DIM_ELEMENT('Y',120000, 630000, .005))
14 as diminfo
15 from dual) b;
16 /
POLYGON_NAME SDO_LENGTH GEOM_LENGTH SDO_AREA GEOM_AREA
-------------------------- ---------- ----------- ---------- ----------
VERTEXWITHHOLE 2450.63204 172538.909 172538.909 2450.63204
VERTEXNOHOLE 10904.004 1878660.14 1878660.14 10904.004
VERTEXNOHOLE 1355.00349 74901.4188 74901.4188 1355.00349
COMPOUNDOUTERSHELL 28.7626555 40.675415 40.675415 28.7626555
VERTEXNOHOLE 1888.23609 189833.345 189833.345 1888.23609
VERTEXWITHARCNOHOLE 28.7626555 40.675415 40.675415 28.7626555
NORMALISEDRECTANGLENOHOLE 1920000 2.2950E+11 2.2950E+11 1920000
CURVEPOLYWITHHOLE 5331.45953 1507964.47 1507964.47 5331.45953
8 rows selected.
The Java Topology Suite is a free API for spatial data that is capable of being deployed into the JVM that is shipped with Oracle 10gR2 and 11g. JTS has a complete set of “geoprocessing” functions that could be used as “drop in” replacements for the Enterprise Edition licensed functions in the SDO_GEOM package. I will leave a demonstration on how this can be done for another article.

Hello,
In 3.2 GEOM.SDO_CENTROID, you mention your GEOM package’s sdo_centroid function. I need to be able to calculate what you call the “para-centroid”. How can I obtain this package? Can you please give pricing information?
Thanks,
Hugo
Hugo,
The PL/SQL packages are free and can be downloaded from here
regards
Simon
Simon. First, my thanks and compliments on your blog. I will be a regular visitor. I have some confusion on the PL/SQL packages. On this page you reference vb_library.zip in the link above, but on the downloads page there is a file spatialdbadvisor_oracle_spatial_types_and_packages.zip
Is there some dependence one on the other?
Thanks.
Bill,
I have corrected the link: thanks for pointing it out.
There is no dependence between the vb and pl/sql libraries.
regards
Simon
Hi Simon. I’ve been looking into Locator on 11g and it looks like they are claiming compliance with SQL/MM Spatial except for Relate, Intersection, Union and ST_SYMMETRICDIFFERENCE. This seems like it goes a long way toward un-crippling Locator. I’d love your perspective.
Cheers,
Bill
Bill,
The SQL/MM Spatial type library at 11g remains the same as the one at 10gR2 except that now the ST_* objects can be indexed (not just the internal sdo_geometry object) which means search functions such as ST_Within() now use the spatial index if it is defined eg
SELECT count(*)
FROM quad q,
my_points p
WHERE q.quad_id = 43
AND p.geometry.ST_Within(q.geometry) = 1;
select mdsys.SDO_Geom.SDO_Centroid(geom,0.5) as geom,
mdsys.SDO_Geom.SDO_Area(geom,0.5) as area,
mdsys.SDO_Geom.SDO_Length(geom,0.5) as length,
mdsys.SDO_Geom.SDO_ConvexHull(geom,0.5) as chull
from projpoly2d
where rownum = 1
/
select mdsys.st_polygon(geom).ST_Centroid() as geom,
mdsys.st_polygon(geom).ST_Area() as area,
mdsys.st_polygon(geom).ST_ExteriorRing().ST_Length() as length,
mdsys.st_polygon(geom).ST_ConvexHull() as chull
from projpoly2d
where rownum = 1;
Good stuff Simon, thank you. I agree that SQL Server 2008 and PostGIS should (hopefully) push Oracle to re-visit.
Simon, First of all thank you for maintaining this great site. I am trying to use codesys sdo_centroid function in Oracle 11g(11.1.0.6). But I am getting ORA-4030 process out of memory errors when I tried the following query. It works fine in 10.2.0.3.
Here is the query.
select codesys.geom.sdo_centroid(SDO_GEOMETRY(2003, 4326, NULL, SDO_ELEM_INFO_ARRAY(1, 1003, 1), SDO_ORDINATE_ARRAY(-98.188095, 31.467118, -98.18846, 31.468043, -98.195101, 31.466029, -98.195631, 31.466992, -98.200194, 31.465637, -98.198701, 31.462233, -98.198678, 31.462179, -98.198454, 31.461669, -98.198437, 31.461631, -98.197313, 31.459068, -98.196229, 31.459431, -98.196131, 31.459465, -98.196118, 31.459469, -98.194407, 31.460043, -98.194698, 31.460734, -98.196271, 31.464479, -98.188095, 31.467118)),0.000001) from dual
Is geom package tested in 11g? Also does codesys package accept tolerance in meters or decimal degrees? I know Oracle spatial accepts in meters.
Thanks for your help.
-Bala
Bala,
This response is for anyone else out there who may follow this thread as Bala and I have resolved the issue via private communication.
Firstly, the answer. It appears that Bala solved the problem as follows:
“Before compiling the GEOM package I have to set the following parameter.”
alter session set plsql_optimize_level=1;
Thanks Bala, I have added this to the compilation script for my packages and uploaded them to my website.
Bala came to this workaround after trying a slightly modified version of the sdo_centroid function. (I inspected my original code and, even though it works on all versions up to 11g, modified it so that the core procedure uses pipelining to cut down on memory use and improve performance).
“Even with modified code it’s still leaking the memory and throwing ORA-04030 errors. Like you said it might be a bug in 11g. I will open a TAR with Oracle.”
Thanks for the great feedback, Bala.
regards
Simon
<<Tip #5: FAST REFRESHing of Oracle Materialized Views containing Sdo_Geometry columns >>Trick #2: Object Tables of Sdo_Geometry