SQL Server 2008 újdonságok 16. - térbeli adattípusok 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
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))
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))
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.
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.
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)
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];
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
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.








January 22nd, 2008 at 7:19 pm
Ertem. De mi a fenere jo mindez?
January 22nd, 2008 at 7:55 pm
Na jó. Ez mind síkbeli példa volt. Milyen a térbeli?
January 22nd, 2008 at 8:42 pm
Mire jók ezek? Térképeken objektumok között keresgélni, navigálni. Előbb-utóbb oda is eljutok. :)
January 22nd, 2008 at 8:43 pm
Kurbli: eddigi tudásom alapján nincs valódi térbeli típus, csak derékszögű és elliptikus. Lehet, hogy rosszul fordítottam a spatial szót a címben. :)
January 22nd, 2008 at 8:45 pm
Szindbad: http://www.directionsmag.com/editorials.php?article_id=2477&trv=1
Egy étteremkereső lekérdezés a fenti cikkből:
-Return Census Block regions with the count of restaurants
-contained in each region for each block group in the zipcode the user clicked on
DECLARE @clickedPoint dbo.Geometry;
SET @clickedPoint = dbo.Geometry::STPoint(@lat, @lon, 0);
SELECT c.id,
c.shape,
c.pop as [Population],
c.shape.STArea() as [Area],
(select count(*) from dbo.business b where c.shape.STIntersects(b.shape)=1
AND substring(sic,1,2)=’58′) as [Restaurant Count]
FROM dbo.census c, dbo.zipcodes z
WHERE c.shape.STIntersects(z.shape)=1 and z.shape.STIntersects(@clickedPoint)=1;
January 23rd, 2008 at 10:55 am
Es ennek mennyi relevanciaja van? Megeri igyelbonyolitani az SQL szervert? Vagy verszemet kaptak, es a C++ mintajara minden letezo featurrel teletomik, hogy aztan evek mulva visszaterjenek az “egyparadigmas” SQL nyelvhez?
January 23rd, 2008 at 11:50 am
Nem sokat bonyolít ez, egyszerűen egy új típust adtak hozzá, jó, az optimizer pár metódus esetén segít, meg indexet is írtak hozzá.
Oracle-ösödik az SQL Server, gondolom ott már rég van ilyen.
January 24th, 2008 at 12:03 pm
[...] Geometry metódusok folytatás, előzmények itt. [...]