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)
STScale: Function to Scale a geometry object
Here is a simple scaling function for use with SQL Server Spatial’s geometry data type.
USE [GISDB] -- Change this to your database GO -- Drop function if exists -- IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id (N'[dbo].[STScale]')) DROP FUNCTION [dbo].[STScale] GO -- Now create the function -- CREATE FUNCTION [dbo].[STScale]( @p_geometry geometry, @p_xFactor FLOAT, @p_yFactor FLOAT, @p_zFactor FLOAT, @p_mFactor FLOAT, @p_round_x INT = 3, @p_round_y INT = 3, @p_round_z INT = 2, @p_round_m INT = 2 ) RETURNS geometry BEGIN DECLARE @v_xFactor FLOAT = CASE WHEN @p_xFactor IS NULL THEN 1.0 ELSE @p_xFactor END, @v_yFactor FLOAT = CASE WHEN @p_yFactor IS NULL THEN 1.0 ELSE @p_yFactor END, @v_zFactor FLOAT = CASE WHEN @p_zFactor IS NULL THEN 1.0 ELSE @p_zFactor END, @v_mFactor FLOAT = CASE WHEN @p_mFactor IS NULL THEN 1.0 ELSE @p_mFactor END, @v_coord INT = 0, @v_wkt VARCHAR(MAX) = '', @v_token VARCHAR(MAX), @v_delim VARCHAR(MAX), @v_geometry geometry, @v_x FLOAT = 0.0, @v_y FLOAT = 0.0, @v_z FLOAT = NULL, @v_m FLOAT = NULL; BEGIN IF ( @p_geometry IS NULL ) RETURN NULL; IF ( @p_xFactor IS NULL AND @p_yFactor IS NULL AND @p_zFactor IS NULL AND @p_mFactor IS NULL ) RETURN CAST('One of scale factors X,Y,Z and M must not be NULL.' AS VARCHAR(MAX)); -- geometry); SET @v_coord = 0; DECLARE Tokens CURSOR FAST_FORWARD FOR SELECT t.token, t.separator FROM dbo.Tokenizer(@p_geometry.AsTextZM(),' ,()') AS t; OPEN Tokens; FETCH NEXT FROM Tokens INTO @v_token, @v_delim; WHILE @@FETCH_STATUS = 0 BEGIN IF ( @v_token IS NULL ) -- double delimiter BEGIN SET @v_wkt = @v_wkt + @v_delim END ELSE BEGIN IF ( @v_token NOT LIKE '[-0-9]%' ) BEGIN SET @v_wkt = @v_wkt + @v_token + LTRIM(@v_delim) END ELSE -- @v_token LIKE '[0-9]%' ) BEGIN SET @v_coord = @v_coord + 1; IF ( @v_coord = 1 ) SET @v_x = CAST(@v_token AS FLOAT) IF ( @v_coord = 2 ) SET @v_y = CAST(@v_token AS FLOAT) IF ( @v_coord = 3 ) SET @v_z = CAST(@v_token AS FLOAT) IF ( @v_coord = 4 ) SET @v_m = CAST(@v_token AS FLOAT) IF ( @v_delim IN (',',')') ) BEGIN SET @v_wkt = @v_wkt + LTRIM(STR(round(@v_x * @v_xFactor, @p_round_x),24,@p_round_x)) + ' ' + LTRIM(STR(round(@v_y * @v_yFactor, @p_round_y),24,@p_round_y)) + CASE WHEN @v_z IS NULL THEN '' ELSE ' ' + LTRIM(STR(round(@v_z * @v_zFactor, @p_round_z),24,@p_round_z)) END + CASE WHEN @v_m IS NULL THEN '' ELSE ' ' + LTRIM(STR(round(@v_m * @v_mFactor, @p_round_m),24,@p_round_m)) END + @v_delim; SET @v_coord = 0; END; END; END; FETCH NEXT FROM Tokens INTO @v_token, @v_delim; END; CLOSE Tokens DEALLOCATE Tokens SET @v_geometry = geometry::STGeomFromText(@v_wkt,@p_geometry.STSrid); RETURN @v_geometry; END END GO
Now some tests.
SELECT a.stype, a.geom.AsTextZM() AS geomWKT FROM (SELECT 'Scaled2D' AS stype, dbo.STScale(geometry::STGeomFromText('LINESTRING (1 2 3, 1 1 1)',0), 0.5,0.75,NULL,NULL, 2,2,2,2) AS geom UNION ALL SELECT 'Original' AS stype, geometry::STGeomFromText('LINESTRING (1 2 3, 1 1 1)',0) AS geom ) a;
Results
sType | geomWKT |
---|---|
Scaled2D | LINESTRING (0.5 1.5 3, 0.5 0.75 1) |
Original | LINESTRING (1 2 3, 1 1 1) |
SELECT a.stype, a.geom.AsTextZM() AS geomWKT FROM (SELECT 'Scaled3D' AS stype, dbo.STScale(geometry::STGeomFromText('LINESTRING (1 2 3, 1 1 1)',0), 0.5, 0.75, 0.8,NULL, 2,2,2,2) AS geom UNION ALL SELECT 'Original' AS stype, geometry::STGeomFromText('LINESTRING (1 2 3, 1 1 1)',0) AS geom ) a;
Results
sType | geomWKT |
---|---|
Scaled3D | LINESTRING (0.5 1.5 2.4, 0.5 0.75 0.8) |
Original | LINESTRING (1 2 3, 1 1 1) |
Finally, a polygon.
SELECT a.stype, a.geom.AsTextZM() AS geomWKT FROM (SELECT 'Original' AS stype, geometry::STGeomFromText('POLYGON ((1 1, 2 1, 2 2, 1 2, 1 1))',0) AS geom UNION ALL SELECT 'Scaled2D' AS stype, dbo.STScale(geometry::STGeomFromText('POLYGON ((1 1, 2 1, 2 2, 1 2, 1 1))',0), 2.0, 2.0, NULL,NULL, 2,2,2,2) AS geom UNION ALL SELECT 'ScaledYOnly' AS stype, dbo.STScale(geometry::STGeomFromText('POLYGON ((1 1, 2 1, 2 2, 1 2, 1 1))',0), NULL, 2.0, NULL,NULL, 2,2,2,2) AS geom ) a;
Results
sType | geomWKT |
---|---|
Original | POLYGON ((1 1, 2 1, 2 2, 1 2, 1 1)) |
Scaled2D | POLYGON ((2 2, 4 2, 4 4, 2 4, 2 2)) |
ScaledYOnly | POLYGON ((1 2, 2 2, 2 4, 1 4, 1 2)) |
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