[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