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.

January 21, 2008 / by Zsolt Soczó

SQL Server 2008 újdonságok 15. – térbeli adattípusok 1.

Az új adattípusok tárgyalásának záró fázisához érkeztünk, már csak a két térbeli (spatial) típus maradt hátra: a geometry és a geography.
A geometry hagyományos, euklidészi, derékszögű, sík koordinátarendszerben dolgozik, míg a geograpy elliptikus, a Földön elhelyezkedő, földrajzi koordinátákat modellező típus (szélesség, hosszúság, stb.).
Koordinátákkal dolgozó emberkék most örülhetnek, végre natívan lehet a dolgaikat tárolni, és rengeteg műveletet (átfedik-e egymást alakzatok, milyen közel van, stb.) használhatnak rajtuk.

A típusok megértését eléggé megnehezíti, hogy a legtöbb átlagember számára ismeretlen szabványokra épülnek. Néhány fontosabbat felsorolok itt az elején. Open Geospatial Consortium (OGC)
Well-known text, WKT. Ez tulajdonképpen arról szól, hogyan lehet stringként leírni geometriai objektumokat.
Ennek párja a bináris leírás, Well-known binary, WKB. (Érdekes, a “jól ismert” fogalom mennyire relatív. :)
Pár WKT példa a korábbi wikis cikkből:

POINT(6 10)
LINESTRING(3 4,10 50,20 25)
POLYGON((1 1,5 1,5 5,1 5,1 1),(2 2, 3 2, 3 3, 2 3,2 2))
MULTIPOINT(3.5 5.6,4.8 10.5)
MULTILINESTRING((3 4,10 50,20 25),(-5 -8,-10 -8,-15 -4))
MULTIPOLYGON(((1 1,5 1,5 5,1 5,1 1),(2 2, 3 2, 3 3, 2 3,2 2)),((3 3,6 2,6 4,3 3)))
GEOMETRYCOLLECTION(POINT(4 6),LINESTRING(4 6,7 10))
POINT ZM (1 1 5 60)
POINT M (1 1 80)

A legtöbb alakzat persze könnyen kitalálható a neve alapján, de a paraméterként megadott számok értelmezése nem triviális. Egyrészt kérdés az, hogy milyen mértékegységben dolgoznak (pl. méter), másrészt, hogy milyen vonatkoztatási ponthoz képest értelmezzük azokat. Nekem kézenfekvő lett volna Greenwich mint egyik koordináta nullpont, másik irányból az egyenlítő, harmadikként pedig a tengerszint, de persze az élet sokkal színesebb ennél, hisz mindenki szereti az otthonában látni a nullpontot, nála legyen a világ közepe. Legyen pusztavacsi a koordináta rendszer. :)

No, a típusoknál olyan vonatkoztatási pontokat, referenciapontokat, spatial reference identifier-t, SRID-t használnak, amelyeket a European Petroleum Survey Group (EPSG) standard definiál. Európa egy amerikai termékben? Nofene.

Hogy ne lógjon a levegőben ez az infó, meg legyen már egy kis SQL is, mindjárt nézzük is meg, milyen vonatkoztatási rendszereket ismer a szerver:

select * from sys.spatial_reference_systems
spatial_reference_id authority_name authorized_spatial_reference_id well_known_text                                                                                                                                                                                                               unit_conversion_factor
-------------------- -------------- ------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------- ----------------------
4120                 EPSG           4120                            GEOGCS["Greek", DATUM["Greek", ELLIPSOID["Bessel 1841", 6377397.155, 299.1528128]], PRIMEM["Greenwich", 0], UNIT["Degree", 0.0174532925199433]]                                                          metre                1
4121                 EPSG           4121                            GEOGCS["GGRS87", DATUM["Greek Geodetic Reference System 1987", ELLIPSOID["GRS 1980", 6378137, 298.257222101]], PRIMEM["Greenwich", 0], UNIT["Degree", 0.0174532925199433]]                               metre                1
4122                 EPSG           4122                            GEOGCS["ATS77", DATUM["Average Terrestrial System 1977", ELLIPSOID["Average Terrestrial System 1977", 6378135, 298.257]], PRIMEM["Greenwich", 0], UNIT["Degree", 0.0174532925199433]]                    metre                1
4123                 EPSG           4123                            GEOGCS["KKJ", DATUM["Kartastokoordinaattijarjestelma (1966)", ELLIPSOID["International 1924", 6378388, 297]], PRIMEM["Greenwich", 0], UNIT["Degree", 0.0174532925199433]]                                metre                1
4124                 EPSG           4124                            GEOGCS["RT90", DATUM["Rikets koordinatsystem 1990", ELLIPSOID["Bessel 1841", 6377397.155, 299.1528128]], PRIMEM["Greenwich", 0], UNIT["Degree", 0.0174532925199433]]                                     metre                1
...
4326                 EPSG           4326                            GEOGCS["WGS 84", DATUM["World Geodetic System 1984", ELLIPSOID["WGS 84", 6378137, 298.257223563]], PRIMEM["Greenwich", 0], UNIT["Degree", 0.0174532925199433]]                                           metre                1
...
4237                 EPSG           4237                            GEOGCS["HD72", DATUM["Hungarian Datum 1972", ELLIPSOID["GRS 1967", 6378160, 298.247167427]], PRIMEM["Greenwich", 0], UNIT["Degree", 0.0174532925199433]]                                                 metre                1
...

Az SQL Server 2008 alapértelmezett módon a 4326-os SRID-t használja, ami Greenwich-i kezőpontú, méterben és fokban dolgozik, és ez így van jól, szimpatikus választás. Laikusoknak WGS 84. (Megvan a poén a Dumb és Dumberből? Canis- laikusoknak kutya. :)

És egy utolsó szabványhivatkozás, aztán programolunk. A geometry típust az Open Geospatial Consortium (OGC) Simple Features for SQL Specification version 1.1.0-nak megfelelően implementálták, a standardot megnézve látszik, hogy a metódusok neve, stb. szépen illeszkedik a szabványhoz.

Ebben a részben kezdjünk az egyszerűbbel, a geometry típussal, mégiscsak egyszerűbb derékszögű rendszerben gondolkodni, mint egy elliptikus izén.

Hozzunk létre egy pontot reprezentáló változót:

DECLARE @g geometry;
SET @g = geometry::STGeomFromText('POINT (3 4)', 0);
select @g.ToString()

Kimenet:

POINT (3 4)

STGeomFromText a már hivatkozott WKT szövegből parsolja ki az alakzatot. Az SRID 0, azaz nem definiált lesz, geometrynél ez ok, geographynál viszont ez kötelező, csak kell egy kiindulópont, ha valami földi alakzatatot akarunk belőni. Használhattuk volna a specializáltabb STPointFromText metódust is.

Játszunk kicsit a pontokkal, rakjuk össze őket egy csapatba (STUnion):

declare @a geometry = geometry::STGeomFromText('POINT(0 0)', 0);
declare @b geometry = geometry::STGeomFromText('POINT(4 4)', 0);

select @a.STUnion(@b).ToString();
MULTIPOINT ((4 4), (0 0))

Csináljunk belőle vonalat:

select @a.STUnion(@b).STConvexHull().ToString();
LINESTRING (4 4, 0 0)

Mi az a Convex Hull, azaz konvex test?
“Az A halmazt konvexnek nevezzük, ha bármely két pontját összekötve az egyenes pontjai az halmazon belül maradnak.”

Szóval ez a metódus konvex testeket tud összerakni, ami most csak egy vonal lett, mivel 2 pontot adtunk meg. Adjunk meg 3-at, mit csinál belőle?

declare @c geometry = geometry::STGeomFromText('POINT(0 4)', 0);
select @a.STUnion(@b).STUnion(@c).STConvexHull().ToString();
POLYGON ((4 4, 0 4, 0 0, 4 4))

Ezt még elég könnyű elképzelni, ez egy csúcsán álló, derékszögű háromszög. Nem négyszög, mert az első és utolsó pontja is 4, 4.

Vizuálisok kedvéért a vonalunk és a háromszögünk:

Geometry lekérdezés kimenete vizualizálva

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

2 COMMENTS

  • Mancika November 13, 2013

    Ez csak engem zavar?

    select geography::Point(10,20,4326).ToString(),geography::Point(10,20,4326).STAsText()
    select geometry::Point(10,20,4326).ToString(),geometry::Point(10,20,4326).STAsText()

    POINT (20 10) POINT (20 10)
    POINT (10 20) POINT (10 20)

  • Soczó Zsolt December 10, 2013

    Mi a kérdés?