Go to content Go to navigation and search


Software Documentation


SQL Server

Oracle Objects (New)

Oracle Packages (Original)

Spatial Companion For Oracle (SC4O)


    PL/SQL Objects from "Applying and Extending Oracle Spatial"
    TESSELATE and CENTROID package updates
    Applying and Extending Oracle Spatial: Source Code Problem
    CENTROID package use with ESRI's sde.st_geometry
    Changes to CENTROID and TESSELATE packages
    CENTROID Package now returns centroid of multi-linestring
    New versions of PL/SQL packages uploaded
    VB6 Oracle Spatial or Locator OO4O code
    Spatial PL/SQL Packages by Example
    Catalog Registry Tool
    Image Catalog Tool
    Oracle Spatial PL/SQL and VB6 Source Code



RSS / Atom

Email me


Creative Commons License
All Blog Articles, Data Models and Free Source Code by Simon Greener, The SpatialDB Advisor is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.

CENTROID Package now returns centroid of multi-linestring

Wednesday November 16 2011 at 06:34

My original CENTROID package’s sdo_centroid() functions, when supplied with a multilinestring sdo_geometry, would “explode” the multilinestring into its component linestrings and calculate the centroid (mid-point) of the largest linestring.

Some users have asked for the centroid package to return the centroid (midpoint) of the whole multilinestring. While the LINEAR package can do this, I have modified the CENTROID package so that it can return either via an option called p_line_explode.
If p_line_explode is set to 1 then the sdo_centroid() function will operate as it always has, but if set to 0, then the midpoint (at half-length) of the entire multipoint is returned.

  1.  /* ----------------------------------------------------------------------------------------
  2.   * @function   : SDO_Centroid
  3.   * @precis     : Generates centroid for a polygon.
  4.   * @version    : 1.0
  5.   * @description: The standard MDSYS.SDO_GEOM.SDO_GEOMETRY function does not guarantee
  6.   *               that the centroid it generates falls inside the polygon.   Nor does it
  7.   *               generate a centroid for a multi-part polygon shape.
  8.   *               This function ensures that the centroid of any arbitrary polygon
  9.   *               falls within the polygon.
  10.   * @usage      : Function Do_Centroid(
  11.   *                 p_geometry     IN MDSYS.SDO_GEOMETRY,
  12.   *                 p_dimarray     IN MDSYS.SDO_DIM_ARRAY,
  13.   *                 p_area         IN NUMBER,
  14.   *                 p_line_explode IN NUMBER)
  16.   * @param      : p_geometry  : MDSYS.SDO_GEOMETRY : The geometry object.
  17.   * @param      : p_tolerance    : Number : Tolerance used when processing vertices.
  18.   *                                         Expressed in dataset units eg decimal degrees if 8311.
  19.   *                                         See Convert_Distance for method of converting distance in meters to dataset units.
  20.   * @param      : p_area         : Number : Whether largest part in a multi-part polygon should be chosen as part with largest
  21.   *                                         area (1) or with largest MBR (not 1)
  22.   * @param      : p_line_explode : Number : Whether largest part in a multi-linestring should be used for centroid or chose
  23.   *                                         centroid based on 50% of length across all parts.
  24.   * @return     : centroid    : MDSYS.SDO_GEOMETRY : The centroid.
  25.   * @requires   : GetVector()
  26.   * @requires   : tolerance
  27.   * @note       : Does not check if passed shape is a polygon.
  28.   * @history    : Simon Greener - Mar 2008 - Total re-write of algorithm following on from cases the original algorithm didn't handle.
  29.   *                                          The new algorithm does everything in a single SQL statement which can be run outside of this function if needed.
  30.   *                                          The algorithm is based on a known method for filling a polygon which counts the type and number of crossings of a
  31.   *                                          "ray" (in this case a vertical line) across a polygon boundary. The new algorithm also has improved handling of
  32.   *                                          multi-part geometries and also generates a starting X ordinate for the vertical "ray" using vertex averaging
  33.   *                                          rather than the mid point of a part's MBR. This is to try and "weight" the centroid more towards where detail exists.
  34.   *               Simon Greener - Jul 2008 - Standalone version with no dependencies other than the need for external object types.
  35.   * @copyright  : Free for public use
  36.   **/
  37.   FUNCTION sdo_centroid (
  38.     p_geometry     IN MDSYS.SDO_Geometry,
  39.     p_tolerance    IN NUMBER,
  40.     p_area         IN NUMBER := 1,
  41.     p_line_explode IN NUMBER := 1)
  42.     RETURN MDSYS.SDO_Geometry deterministic;
  43.   /**
  44.   * Overload of main sdo_centroid function
  45.   **/
  46.   FUNCTION Do_Centroid(
  47.     p_geometry     IN MDSYS.SDO_GEOMETRY,
  48.     p_dimarray     IN MDSYS.SDO_DIM_ARRAY,
  49.     p_area         IN NUMBER := 1,
  50.     p_line_explode IN NUMBER := 1)
  51.     RETURN MDSYS.SDO_Geometry deterministic;


  1. SELECT CODESYS.centroid.sdo_centroid(MDSYS.SDO_GEOMETRY(2006, NULL, NULL, MDSYS.SDO_ELEM_INFO_ARRAY(1,2,1,5,2,1), MDSYS.SDO_ORDINATE_ARRAY(50.0, 15.0, 55.0, 15.0, 60.0, 15.0, 65.0, 15.0)),0.005,1,1) AS mcentroid,
  2.        CODESYS.centroid.sdo_centroid(MDSYS.SDO_GEOMETRY(2006, NULL, NULL, MDSYS.SDO_ELEM_INFO_ARRAY(1,2,1,5,2,1), MDSYS.SDO_ORDINATE_ARRAY(50.0, 15.0, 55.0, 15.0, 60.0, 15.0, 65.0, 15.0)),0.005,1,0) AS centroid
  3.   FROM dual;
  4. MCENTROID                                                                  CENTROID
  5. -------------------------------------------------------------------------- ------------------------------------------------------------------------


I hope this is of help to someone.

Creative Commons License

post this at del.icio.uspost this at Diggpost this at Technoratipost this at Redditpost this at Farkpost this at Yahoo! my webpost this at Windows Livepost this at Google Bookmarkspost this to Twitter