[postgis-users] Centroid - More information on my package

Simon Greener simon at spatialdbadvisor.com
Tue Jun 19 14:53:27 PDT 2007


Regina and Rob,

> I must commend you on the very nice instructive site you have.  Now for a nit-pcik.  Your link to the PostGIS site is broken!

Oops... will fix: thanks.

> This might be a stupid question - but it wasn't obvious to me so I will ask it.
> I presume the function you have is embedded in your
> http://www.spatialdbadvisor.com/files/spatialdbadvisor_oracle_spatial_types_and_packages.zip

Correct.

> But wasn't quite clear what it would be named and what .sql file to find it in or if it depends on numerous files.

Fair question. It is called SDO_CENTROID (after Oracle's
sdo_geom.sdo_centroid function) and is in the GEOM package. There are
two files for the GEOM package:

GEOM_package.sql      -- the interface specification.
GEOM_package_body.sql -- the actual code

>From the GEOM_package.sql the interface declarations are:

************************************************************

  /*
----------------------------------------------------------------------------------------
  -- @function   : SDO_Centroid
  -- @precis     : Generates centroid for a polygon.
  -- @version    : 1.0
  -- @description: The standard MDSYS.SDO_GEOM.SDO_GEOMETRY function does
not guarantee
  --               that the centroid it generates falls inside the
polygon.   Nor does it
  --               generate a centroid for a multi-part polygon shape.
  --               This function ensures that the centroid of any
arbitrary polygon
  --               falls within the polygon.
  -- @usage      : Function Do_Centroid(
  --                 p_geometry IN MDSYS.SDO_GEOMETRY,
  --                 p_dimarray IN MDSYS.SDO_DIM_ARRAY )
  --                 RETURN MDSYS.SDO_GEOMETRY DETERMINISTIC;
  -- @param      : p_geometry : The polygon shape.
  -- @paramtype  : p_geomery  : MDSYS.SDO_GEOMETRY
  -- @return     : centroid   : The centroid.
  -- @rtnType    : centroid   : MDSYS.SDO_GEOMETRY
  -- @requires   : GetVector2D()
  -- @requires   : tolerance
  -- @note       : Does not check if passed shape is a polygon.
  -- @history    : Tino Delbourgo's Mum - Jun 2002 - Original algorithm!
  --             : Tino Delbourgo, Geometry Pty Ltd - Jun 2002 - Original
Java code.
  --               Simon Greener - Jun 2002 - Converted to PL/SQL
  --               Simon Greener - Apr 2003 - Fixed bug where Candidate
XY shared value with segment end-point x or y.
  --               Simon Greener - Apr 2003 - Applied tolerance to shape
before computing centroid.
  --               Simon Greener - Apr 2003 - Better support 2007
multi-part polygons.
  --               Simon Greener - Apr 2003 - Fixed divide by zero error.
  -- @copyright  : Free for public use
  */
  function sdo_centroid (
    p_geometry in MDSYS.SDO_Geometry,
    p_tolerance in number )
    return MDSYS.SDO_Geometry deterministic;

  function sdo_centroid (
    p_geometry in MDSYS.SDO_Geometry,
    p_dimarray in MDSYS.SDO_Dim_Array )
    return MDSYS.SDO_Geometry deterministic;

  /*
----------------------------------------------------------------------------------------
  -- @function   : Sdo_Multi_Centroid
  -- @precis     : Generates centroids for a all parts of a multi-polygon.
  -- @version    : 1.0
  -- @description: The standard MDSYS.SDO_GEOM.SDO_GEOMETRY function does
not guarantee
  --               that the centroid it generates falls inside the
polygon.   Nor does it
  --               generate a centroid for a multi-part polygon shape.
  --               This function generates a point for every part of a
2007 multi-part polygon..
  -- @usage      : Function SDO_Multi_Centroid(
  --                 p_geometry IN MDSYS.SDO_GEOMETRY,
  --                 p_dimarray IN MDSYS.SDO_DIM_ARRAY )
  --                 RETURN MDSYS.SDO_GEOMETRY DETERMINISTIC;
  -- @param      : p_geometry : The polygon shape.
  -- @paramtype  : p_geomery  : MDSYS.SDO_GEOMETRY
  -- @return     : centroid   : The centroids of the parts as a
multi-part shape.
  -- @rtnType    : centroid   : MDSYS.SDO_GEOMETRY
  -- @requires   : GetVector2D()
  -- @requires   : tolerance
  -- @note       : Does not check if passed shape is a polygon.
  -- @history    : Simon Greener - Jun 2006 - Original coding.
  -- @copyright  : Free for public use
  */
  function SDO_Multi_Centroid(
    p_geometry in MDSYS.SDO_Geometry,
    p_dimarray in MDSYS.SDO_Dim_Array )
    return MDSYS.SDO_Geometry deterministic;

  function sdo_multi_centroid(
    p_geometry in MDSYS.SDO_Geometry,
    p_tolerance in number)
    return MDSYS.SDO_Geometry deterministic;

************************************************************

In the GEOM_package_body.sql all the actual "heavy lifting" is done by
the following private function:

  Function Do_Centroid(
    p_geometry IN MDSYS.SDO_GEOMETRY,
    p_dimarray IN MDSYS.SDO_DIM_ARRAY )
    RETURN MDSYS.SDO_GEOMETRY DETERMINISTIC

as the interfaces included above are just "wrappers" (with overloading)
over this actual private function.

Finally, the Do_Centroid function calls another private function:

  Function GetVector2D (
    p_geometry in mdsys.sdo_geometry )
    return &&defaultSchema..Vector2DSetType

which "vectorizes" the polygon boundaries (shells). A vector (see
create_required_types.sql) is:

CREATE OR REPLACE TYPE &defaultSchema..VectorType AS OBJECT (
   startCoord &defaultSchema..ST_Point,
   endCoord   &defaultSchema..ST_Point );

There are other dependencies (eg the MBR package is used to get the MBR
of each outer shell to find the largest part of a multipart object) but
these would go in a PostGIS implementation.

Oh, YES, the PL/SQL implementation is much more complicated than the Java
version because of number of factors. I will dig out the Java version
(which I have not compiled and deployed in to Oracle's JVM recently so
it may not compile) and post it to this list.

------------------------------

From: Rob Agar <robagar at westnet.com.au>

> Out of curiosity, where would your function place the centroid of a (2D) doughnut?

It does not place it in any of the hole(s) no matter how many exist.

regards
Simon



More information about the postgis-users mailing list