Go to content Go to navigation and search

Home

Current Oracle Spatial Blogs

Search

RSS / Atom

Email me

textpattern

Implementing a Scale/ST_Scale function for Oracle Spatial

· Feb 3, 07:20 pm by Simon Greener

The tools in Locator and Spatial do not include translate, rotate and scale functions. I have developed the first two of these and have written about them in the referenced articles. In this article I show how to use the last of these, a Scale function, which I have just developed.

Here is the function’s descriptive header and the public function declarations from my GEOM package.

  /* ----------------------------------------------------------------------------------------
  * function   : SCALE
  * precis     : Function which updates all coordinates in a shape by applying an x/y/z factor.
  * version    : 1.0
  * description: As against, move, which adds a supplied delta to existing coords, Scale multiplies
  *               existing coordinates by the supplied factors. Rounding is applied to the result using
  *               the supplied tolerances.
  * usage      : Function Scale( p_geometry IN MDSYS.SDO_GEOMETRY,
  *                               p_diminfo  IN MDSYS.SDO_DIM_ARRAY,
  *                               p_deltaX   IN number,
  *                               p_deltaY   IN number,
  *                               p_deltaY   IN number,
  *                             ) 
  *                 Return MDSYS.SDO_GEOMETRY DETERMINISTIC;
  *               eg fixedShape := CODESYS.geom.tolerance(shape,diminfo);
  * param      : p_geometry    : The shape to move.
  * paramtype  : p_geomery     : MDSYS.SDO_GEOMETRY
  * param      : p_diminfo     : Tolerance used to round x/y/z values after scaling 
  * param      : p_diminfo     : SDO_DIM_ARRAY 
  * param      : p_XFactor     : Factor to be applied to the X coordinate.
  * paramtype  : p_XFactor     : number
  * param      : p_YFactor     : Factor to be applied to the Y coordinate.
  * paramtype  : p_YFactor     : number
  * param      : p_ZFactor     : Factpr to be applied to the Z coordinate.
  * paramtype  : p_ZFactor     : number
  * requires   : CODESYS.GEOM.isMeasure and CODESYS.GEOM.ADD_Coordinate
  * return     : newShape      : Shape whose coordinates have been scaled.
  * rtnType    : newShape      : MDSYS.SDO_GEOMETRY
  * history    : Simon Greener - Jan 2008 - Original coding.
  * copyright  : Licensed under a Creative Commons Attribution-Share Alike 2.5 Australia License. (http://creativecommons.org/licenses/by-sa/2.5/au/) 
  **/
  FUNCTION Scale( p_geometry    IN MDSYS.SDO_GEOMETRY,
                  p_diminfo     IN MDSYS.SDO_DIM_ARRAY,
                  p_XFactor     IN NUMBER,
                  p_YFactor     IN NUMBER,
                  p_ZFactor     IN NUMBER  := NULL
                ) 
    Return MDSYS.SDO_GEOMETRY Deterministic;

  /* Wrapper functions */
  FUNCTION Scale( p_geometry    IN MDSYS.SDO_GEOMETRY,
                  p_tolerance   IN NUMBER,
                  p_XFactor     IN NUMBER,
                  p_YFactor     IN NUMBER,
                  p_ZFactor     IN NUMBER  := NULL
                ) 
    Return MDSYS.SDO_GEOMETRY Deterministic;

  FUNCTION ST_Scale( p_geometry    IN MDSYS.ST_GEOMETRY,
                     p_tolerance   IN NUMBER,
                     p_XFactor     IN NUMBER,
                     p_YFactor     IN NUMBER,
                     p_ZFactor     IN NUMBER  := NULL )
    Return MDSYS.ST_GEOMETRY DETERMINISTIC;

First, let’s scale a 2D ST_LINESTRING using one of the wrapper functions:

SELECT GEOM.ST_Scale(MDSYS.ST_GEOMETRY.FROM_WKT('LINESTRING(1 2, 1 1)'), 0.005, 0.5, 0.75).Get_WKT() as GEOM
  FROM DUAL;

GEOM
------------------------------
LINESTRING (0.5 1.5, 0.5 0.75)

1 rows selected

The result is as follows.

Scale simple, vertical, line.

Now, let’s test it using the two 2.5D test cases from the PostGIS online help for its ST_Scale function.

First, scale all three ordinates.

-- Scale X, Y, Z
SELECT GEOM.AsEWKT(GEOM.Scale(SDO_GEOMETRY(3002,null,null,sdo_elem_info_array(1,2,1),sdo_ordinate_array(1,2,3,1,1,1)), 0.005, 0.5, 0.75, 0.8)) as Geom
  FROM DUAL;

GEOM
---------------------------------------------------------------------------------------
LINESTRING XYZ ( LINESTRING(0.5 1.5 2.3999999999999999, 0.5 0.75 0.80000000000000004) )

1 rows selected

Then scale only the X,Y coords of a 2.5D geometry.

-- Scale X Y for a 2.5D geometry
SELECT GEOM.AsEWKT(GEOM.Scale(SDO_GEOMETRY(3002,null,null,sdo_elem_info_array(1,2,1),sdo_ordinate_array(1,2,3,1,1,1)), 0.005, 0.5, 0.75)) as GEOM
  FROM DUAL;

GEOM
--------------------------------------------------------
LINESTRING XYZ ( LINESTRING(0.5 1.5 3.0, 0.5 0.75 1.0) )

1 rows selected

The result, graphically, in both cases is the same as in the 2D graphic above.

Finally, let’s scale a simple polygon’s X and Y coordinates by 2.

SELECT GEOM.AsEWKT(GEOM.Scale(MDSYS.SDO_GEOMETRY(2003,null,null,sdo_elem_info_array(1,1003,4),sdo_ordinate_array(1,1,2,2,3,1)), 0.005, 2, 2)) as Geom 
  FROM DUAL;

GEOM
------------------------------------------------------
POLYGON XY ( CURVEPOLYGON(2.0 2.0, 4.0 4.0, 6.0 2.0) )

1 rows selected

The result is as shown.

Scale simple 2D polygon by 2

The Scale/ST_Scale functions are a useful, final, complement to the Translate/ST_Translate and Rotate/ST_Rotate functions I have written previous.

All functions are available in my free GEOM PL/SQL package.
I hope this is of use to someone.

post this at del.icio.uspost this at Diggpost this at Technoratipost this at Newsvinepost this at Ma.gnoliapost this at Furlpost this at Blinklistpost this at Spurlpost this at Wistspost this at Simpypost this at Redditpost this at Farkpost this at Blogmarkspost this at Yahoo! my webpost this at Mr. Wongpost this at Windows Livepost this at Google Bookmarkspost this to Twitter
  Textile Help