透過函數維護空間資料

透過 SQL Server 使用空間資訊最方便的地方是以資料集合套用強大的函數。

由於函數與屬性非常多,參考線上說明:ms-help://MS.SQLCC.v10/MS.SQLSVR.v10.en/s10de_1devconc/html/628262ee-a428-4b89-a966-b29ca5431159.htm

由於空間資料型態是以 SQLCLR UDT 的方式實做,透過 T-SQL 呼叫的慣例如下:

  • 使用 “." 來存取屬性,或是呼叫執行個體的函數
  • 使用 “::" 來呼叫類別提供的靜態函數
  • 函數、屬性名稱要區分大小寫

可依功用簡單將函數分類如下:

art42F3提供空間物件的資訊

  • STArea
  • STLength
  • STCentroid

art4323兩個空間物件間的關係

  • STIntersects
  • STDistance

art4324維護空間物件內容,如聯集(結合)、差集

  • STUnion
  • STSymDifference

art4325取得物件結構中的子物件集合,由於無法以集合(collection)方式存取,故改以函數呼叫,並傳遞索引參數以指定集合中的第幾個元素

  • STGeometryN
  • STPointN

各種函數呼叫範例如下:

以各種格式呈現

DECLARE @g GEOMETRY=’POINT(2 2 2 2)’
SELECT @g.STAsBinary() ‘WKB’,@g.STAsText() ‘WKT’,@g.AsTextZM() ‘WKT ZM’, @g.AsGml() ‘GML’

執行結果如下:
image

取出物件中各個點

DECLARE @g geometry = geometry::STGeomFromText(‘LINESTRING(0 0, 2 2, 1 0)’, 0);
DECLARE @i INT =1,@s NVARCHAR(100)="
WHILE @i<4
BEGIN
–透過 STPointN 取出各點資料,套用 T-SQL 新增的累加語法
SELECT @s+=@g.STPointN(@i).ToString() + ‘ ‘;
SET @i+=1
END
PRINT @s

執行結果如下:
POINT (0 0) POINT (2 2) POINT (1 0)

存取資料表內的資料

USE TempDB
GO
IF OBJECT_ID ( ‘dbo.SpatialTable’, ‘U’ ) IS NOT NULL
DROP TABLE dbo.SpatialTable;
GO

CREATE TABLE SpatialTable
( id int IDENTITY (1,1),
GeomCol1 geometry,
GeomCol2 AS GeomCol1.STAsText() );
GO
INSERT SpatialTable (GeomCol1)
VALUES (geometry::STGeomFromText(‘LINESTRING (100 100, 20 180, 180 180)’, 0));
go
INSERT SpatialTable (GeomCol1)
VALUES (geometry::STGeomFromText(‘POLYGON ((0 0, 150 0, 150 150, 0 150, 0 0))’, 0));

INSERT SPATIALtABLE (GeomCol1)
VALUES (geometry::STGeomFromText(‘POINT(100 10)’,0));
go

DECLARE @geom1 geometry;
DECLARE @geom2 geometry;
DECLARE @result geometry;

SELECT @geom1 = GeomCol1 FROM SpatialTable WHERE id = 1;
SELECT @geom2 = GeomCol1 FROM SpatialTable WHERE id = 2;
–取出兩筆空間資料交錯的部分
SELECT @result = @geom1.STIntersection(@geom2);
SELECT @result.STAsText();
/*
結果:
LINESTRING (50 150, 100 100)
*/

SELECT *,GeomCol1.STX,GeomCol1.STY FROM SpatialTable WHERE id=3
結果如下:

image

正確的空間資料執行個體(Valid Instance)

在建立多邊形資料時,可能在視覺上是正確的,但可能點的描述順序錯誤,或是邊界交錯,例如
POLYGON ((0 0, 100 0, 0 100, 100 100,0 0))
照點順序的視覺效果如下:

image

但運算時會發生錯誤,例如:

DECLARE @g GEOMETRY = ‘POLYGON ((0 0, 100 0, 0 100, 100 100,0 0))’
PRINT @g.STArea()  — 計算面積

得到錯誤訊息下:

Msg 6522, Level 16, State 1, Line 2
A .NET Framework error occurred during execution of user-defined routine or aggregate “geometry":
System.ArgumentException: 24144: This operation cannot be completed because the instance is not valid. Use MakeValid to convert the instance to a valid instance. Note that MakeValid may cause the points of a geometry instance to shift slightly.
System.ArgumentException:
at Microsoft.SqlServer.Types.SqlGeometry.ThrowIfInvalid()
at Microsoft.SqlServer.Types.SqlGeometry.STArea()

這時可以透過 MakeValid 函數將錯誤轉成正確

DECLARE @g GEOMETRY = ‘POLYGON ((0 0, 100 0, 0 100, 100 100,0 0))’
–透過 MakeValid 函數將不正確的內容轉成正確
DECLARE @gValid GEOMETRY = @g.MakeValid()
PRINT @gValid.ToString()
PRINT @gValid.STArea()

其執行結果如下:

MULTIPOLYGON (((50 50, 100 100, 0 100, 50 50)), ((0 0, 100 0, 50 50, 0 0)))
5000

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 變更 )

Twitter picture

You are commenting using your Twitter account. Log Out / 變更 )

Facebook照片

You are commenting using your Facebook account. Log Out / 變更 )

Google+ photo

You are commenting using your Google+ account. Log Out / 變更 )

連結到 %s

%d 位部落客按了讚: