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)
STMove: Function to Move a geometry object in SQL Server Spatial
If you have need for a TSQL based function for moving geometry objects in SQL Server Spatial (Denali is required), here is a function you might find useful.
USE [GISDB] -- Change this to your database GO -- Function: Move -- -- Delete if Exists -- IF EXISTS (SELECT * FROM sysobjects WHERE id = object_id (N'[dbo].[STMove]') AND xtype IN (N'FN', N'IF', N'TF') ) BEGIN DROP FUNCTION [dbo].[STMove]; PRINT 'Dropped [dbo].[STMove] ...'; END; GO -- Create -- CREATE FUNCTION [dbo].[STMove] ( @p_geometry geometry, @p_dX FLOAT, @p_dY FLOAT, @p_dZ FLOAT, @p_dM FLOAT, @p_round_xy INT = 3, @p_round_zm INT = 2 ) RETURNS geometry BEGIN DECLARE @v_coord INT = 0, @v_rows 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_dX IS NULL AND @p_dY IS NULL AND @p_dZ IS NULL AND @p_dM IS NULL ) RETURN CAST('One of deltas X,Y,Z and M must not be NULL.' AS VARCHAR(MAX)); -- geometry); SET @v_coord = 0; SET @v_rows = 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 + @p_dX, @p_round_x),24,@p_round_x)) + ' ' + LTRIM(STR(round(@v_y + @p_dY, @p_round_y),24,@p_round_y)) + CASE WHEN @v_z IS NULL THEN '' ELSE ' ' + LTRIM(STR(round(@v_z + @p_dZ, @p_round_z),24,@p_round_z)) END + CASE WHEN @v_m IS NULL THEN '' ELSE ' ' + LTRIM(STR(round(@v_m + @p_dM, @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 for some tests
Point
SELECT geometry::STGeomFromText('POINT(0 0 0)',0).STBuffer(0.5) AS geom UNION ALL SELECT dbo.STMove(geometry::STGeomFromText('POINT(0 0 0)',0),a.IntValue,b.IntValue,0,NULL,3,3,2,2).STBuffer(0.2) AS geom FROM dbo.generate_series(0,10,1) a CROSS apply dbo.generate_series(1,9,1) b;
The result looks like this:
Linestring
SELECT dbo.STMove(geometry::STGeomFromText('LINESTRING(0 0, 10 0)',0),5,a.IntValue,NULL,NULL,3,3,2,2).STBuffer(0.05) AS geom FROM dbo.generate_series(0,10,1) a;
The result looks like this:
Move rectangle 10,10
SELECT '' AS name, geometry::STGeomFromText('POLYGON((1 1, 1 6, 11 6, 11 1, 1 1))',0) AS geom UNION ALL SELECT 'Move 10,10' AS name, dbo.STMove(geometry::STGeomFromText('POLYGON((1 1, 1 6, 11 6, 11 1, 1 1))',0),10.0,10.0,NULL,NULL,3,3,2,2) AS geom;
The result looks like this:
Curved polygon
SELECT geometry::STGeomFromText('CURVEPOLYGON(COMPOUNDCURVE(CIRCULARSTRING(9.962 -0.872,10.1 0,9.962 0.872),(9.962 0.872,0 0,9.962 -0.872)))',0).STCurveToLine() AS geom UNION ALL SELECT dbo.STMove(geometry::STGeomFromText('CURVEPOLYGON(COMPOUNDCURVE(CIRCULARSTRING(9.962 -0.872,10.1 0,9.962 0.872),(9.962 0.872,0 0,9.962 -0.872)))',0),3,3,NULL,NULL,3,3,2,2).STCurveToLine() AS geom;
The result looks like this:
I hope this is of use to someone.If you have need for a TSQL based function for moving geometry objects in SQL Server Spatial (Denali is required), here is a function you might find useful.
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