All articles

SQL Server 2008 újdonságok 16. – térbeli adattípusok 2.

Published 2008-01-22 - Last modified 2008-01-25

Original: https://soci.hu/blog/index.php/2008/01/22/sql-server-2008-ujdonsagok-15-terbeli-adattipusok-2/

Az előző rész végén volt egy kép, ami vizualizálta a geometriai alakzatokat. Ez a kis program a GeoQuery 2008, és rendkívül jó szolgálatot tesz megnézni, melyik függvény mire szolgál.

Ebben a részben bemutatok pár geometry metódust, szemérmetlenül ellopva a program beépített msdn példáit (köszönet a szerzőnek a feldolgozásért). Párat azért én is szültem. :)

A példákban a Thickness és a Color oszlopok csak a programnak szólnak, hogyan jelenítse meg az alakzatokat.

Területszámítás, STArea:

DECLARE @g geometry;
SET @g = geometry::STGeomFromText('POLYGON((0 0, 3 0, 3 3, 0 3, 0 0),(2 2, 2 1, 1 1, 1 2, 2 2))', 0);
SELECT @g, @g.STArea() as [AreaInUnits], 0.1 as [Thickness];
8

starea.png

Azaz van egy 3×3-as négyzetünk, amiben van egy 1×1-es luk. Így a területe 8, nem meglepő.

Határolóvonalak, STBoundary. Ez már nem teljesen triviális, a BOL sem segít egyelőre, csak a szabvány.

“-Point and MultiPoint instances do not have a boundary.
-LineString and MultiLineString boundaries are formed by the start points and end points, removing those that occur an even number of times.”
-The boundary of a Polygon consists of a set of LinearRings that make up its exterior and interior boundaries.”

DECLARE @g geometry;
SET @g = geometry::STPolyFromText('POLYGON((0 0, 0 3, 3 3, 3 0, 0 0), (1 1, 1 2, 2 1, 1 1))', 10);
SELECT 'Red' Color, 0.2 as [Thickness], @g
union all
select 'Yellow' Color, 0.1 as [Thickness], @g.STBoundary()
POLYGON((0 0, 0 3, 3 3, 3 0, 0 0), (1 1, 1 2, 2 1, 1 1))
MULTILINESTRING((1 1, 1 2, 2 1, 1 1), (0 0, 3 0, 0 3, 0 0))

stboundary1.png

A piros az alakzat, a sárga a határolóvonala. A kettő egybeesik, csak az irányuk más, ez a kimenetből látszik, illetve az egyik sokszög, a másik vonalak halmaza.

Ugyanez vonalakkal:

DECLARE @g geometry;
SET @g = geometry::STGeomFromText('LINESTRING(0 0, 2 2, 0 2, 2 0)', 0);
SELECT @g, @g.STBoundary(), 0.1 as [Thickness];
LINESTRING(0 0, 2 2, 0 2, 2 0)
MULTIPOINT((2,0), (0,0))

stboundary.png

Látszik, hogy a szabványnak megfelelő a kimenet.

STBuffer. Azokat a pontokat adja vissza, amelyek egy alakzattól a megadott távolságra, vagy annál közelebb fekszenek.
Egyszerű vonallal:

DECLARE @g geometry;
SET @g = geometry::STGeomFromText('LINESTRING(0 0, 4 0)', 0);
SELECT @g, @g.STBuffer(1), 0.1 as [Thickness];
Marha sok pontból álló POLYGON.

stbuffer1.png

Bonyolultabb sokszöggel:

DECLARE @g geometry;
SET @g = geometry::STGeomFromText('POLYGON((0 0, 0 3, 3 3, 3 0, 0 0), (1 1, 1 2, 2 1, 1 1))', 0);
SELECT @g, 0.1 as [Thickness], 'Red' as Color
union all 
select @g.STBuffer(1), 0.1 as [Thickness], 'Yellow' as Color;
Marha sok pontból álló POLYGON.

stbuffer2.png

A sárga vonal a számított Buffer.

Középpont számítás, STCentroid. Matekosok utánakereshetnek, hogy számolják (érdekelne a link).

DECLARE @g geometry;
SET @g = geometry::STGeomFromText('POLYGON((0 0, 3 0, 3 3, 0 3, 0 0),(2 2, 2 1, 1 1, 1 2, 2 2))', 0);
SELECT @g, @g.STCentroid(), 0.1 as [Thickness];
POINT(1.5 1.5)

stcentroid1.png

Ez könnyű volt. Bonyolultabb alakzatra meg majd kiszámolja a gép. :)

Tartalmazza-e az egyik alakzat a másikat (teljesen), STContains:

DECLARE @g geometry;
DECLARE @h geometry;
SET @g = geometry::STGeomFromText('POLYGON((0 0, 2 0, 2 2, 0 2, 0 0))', 0);
SET @h = geometry::STGeomFromText('POINT(1 1)', 0);
SELECT @g, @h, @g.STContains(@h), 0.1 as [Thickness];
1

Azt mondja, benne van, meglepő. Képet most nem mellékelek, láttunk már ilyen négyzetet.

Konkávból konvex, STConvexHull:

DECLARE @g geometry;
SET @g = geometry::STGeomFromText('POLYGON((0 0, 0 2, 1 1, 2 2, 2 0, 0 0))', 0);
SELECT @g, 'Original' AS [Display], 'Blue' as [Color], 0.2 as [Thickness]
UNION ALL
SELECT @g.STConvexHull(), 'Hull', 'Green' as [Color], 0.1 as [Thickness];

stconvexhull1.png

A kék az eredeti, az zöld a kiegyengetett, konvexesített.

Metszi-e egymást két alakzat? STCrosses.

DECLARE @g geometry;
DECLARE @h geometry;
SET @g = geometry::STGeomFromText('LINESTRING(0 2, 2 0)', 0);
SET @h = geometry::STGeomFromText('LINESTRING(0 0, 2 2)', 0);
SELECT @g, @h, @g.STCrosses(@h), 0.1 as [Thickness];
1

Különbségképzés, azok határolópontok által bekerített terület az egyik alakzatból, amelyek nincsenek benne egy másikban: STDifference.

DECLARE @g geometry;
DECLARE @h geometry;
SET @g = geometry::STGeomFromText('POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))', 0);
SET @h = geometry::STGeomFromText('POLYGON((1 1, 3 1, 3 3, 1 3, 1 1))', 0);
SELECT 'Original Polygons' as [Display], @g, @h, 'Green' as [Color],  0.2 as [Thickness]
UNION ALL
SELECT 'First minus second', null, @g.STDifference(@h), 'Blue' as [Color], 0.1 as [Thickness]
UNION ALL
SELECT 'Second minus first', null, @h.STDifference(@g), 'Orange' as [Color], 0.05 as [Thickness];
Original Polygons  POLYGON ((0 0, 0 2, 2 2, 2 0, 0 0))      POLYGON ((1 1, 3 1, 3 3, 1 3, 1 1))      Green  0.20
First minus second NULL                                     POLYGON ((0 0, 2 0, 2 1, 1 1, 1 2, 0 2,  Blue   0.10
Second minus first NULL                                     POLYGON ((2 1, 3 1, 3 3, 1 3, 1 2, 2 2,  Orange 0.05

stdifference.png

Jópofa. Az alsó zöld négyzet az egyik alakzatunk, a felső zöld a másik. A kék azt mutatja, ha az alsóból kivonjuk a felsőt, a sárga, ha a felsőből az alsót.

Folyt. köv.