|
Implementing a Scale/ST_Scale function for Oracle Spatial
Tuesday February 03 2009 at 19:20
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.

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.

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.
       
|
Comment