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
- GeoRaptor 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