Top 5 Recent Articles
ARTICLES CATEGORIES
- Algorithms (22)
- All (399)
- Biography (1)
- Blog (44)
- Business Requirements (1)
- Commentary (1)
- Conversion (2)
- Customers (2)
- Data Models (1)
- Education (2)
- GeoRaptor (13)
- GPS (1)
- Image Processing (2)
- Import Export (8)
- Licensing (2)
- LiDAR (1)
- Linear Referencing (4)
- Manifold GIS (3)
- Mapping (1)
- MySQL Spatial (7)
- Networking and Routing (including Optimization) (5)
- Open Source (18)
- Oracle Spatial and Locator (194)
- Partitioning (1)
- PostGIS (36)
- Projections (1)
- Published Articles (1)
- qGIS (1)
- Recommendations (1)
- Services (1)
- Software Change Log (1)
- Source Code (37)
- Space Curves (9)
- Spatial Database Functions (109)
- Spatial DB comparison (1)
- Spatial XML Processing (11)
- SQL Server Spatial (92)
- Standards (3)
- Stored Procedure (17)
- Tessellation or Gridding (10)
- Tools (2)
- Topological Relationships (1)
- Training (2)
- Triangulation (2)
Implementing a Scale/ST_Scale function for Oracle Spatial
The tools in Locator and Spatial do not include translate (move), 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.
!http://www.spatialdbadvisor.com/images/41.png (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.
!http://www.spatialdbadvisor.com/images/42.png (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.
Documentation
- MySQL Spatial General Functions
- Oracle LRS Objects
- Oracle Spatial Exporter (Java + pl/SQL)
- Oracle Spatial Object Functions
- Oracle Spatial Object Functions (Multi Page)
- PostGIS pl/pgSQL Functions
- SC4O Oracle Java Topology Suite (Java + pl/SQL)
- SQL Server Spatial General TSQL Functions
- SQL Server Spatial LRS TSQL Functions