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.
Could you hire me? Contact me if you like what I’ve done in this article and think I can create value for your company with my skills.
LEAVE A COMMENT
8 COMMENTS
Ertem. De mi a fenere jo mindez?
Na jó. Ez mind síkbeli példa volt. Milyen a térbeli?
Mire jók ezek? Térképeken objektumok között keresgélni, navigálni. Előbb-utóbb oda is eljutok. :)
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. :)
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;
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?
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.