Artur Finger 1.11.2016 70 min 1
Plán Motivace Prostorová data a geodata obecně SRID, projekce, 2D, 3D, WKT Standard opengis Datové typy, funkce Standard SF Část 3 standardu SQL/MM (2002) Datové typy, funkce Komerce MySQL spatial 2
Motivace Vzdálenost mezi dvěma body Vykresli povodňové zóny Na základě toho, kudy vede řeka zóny v dosahu zemětřesení zóny v dosahu erupce vulkánu Jedná se o polygony Najdi všechny sklady, kam doletí dron ze základny Když se špatně změří, dojde palivo a dron i s nákladem skončí v moři Jedná se o body uvnitř kruhu Najdi všechny sklady kam doletí dron, když může 1x použít stanici s palivem Najdi všechna města, kam doletí jaderné hlavice ze Severní Korei Vrať délku cesty na mapě Součet délek částí lomemé čářy 3
http://static.guim.co.uk 4
Proč to nejde udělat v klasickém SQL (bez prostorového rozšíření) Špatně se bude pracovat s tvary jak v SQL naimplementovat libovolně jemný polygon? problém Dotazy budou pomalé Např. Najdi všechna města do 100 km kolem Prahy Nelze využít klasické indexy (B-strom) problém Špatně se budou psát geografické funcke Vzdálenost mezi dvěma body na zeměkoli (Haversine distance) problém 5
Další motivace/využití Meteorologická data Deforestace (kácení lesů) Globální data o znečištění Globálním oteplování Ve všech těchto případech se nejedná jen o prostorová, ale i časová data Zajímá nás např. jak se deforestace vyvíjí v čase https://www.w3.org/tr/sdw-ucr/ 6
https://mongabay-images.s3.amazonaws.com/15/0427wwf_deforestation_threats.jpg 7
Úvod do prostorových a geografických dat 8
Kartézská data 2D https://www.math10.com/en/geometry/geogebra/geogebra.html 9
Kartézská data 3D http://a1.mzstatic.com 10
Use case 2D data Cancer research (TCGA image genomics) 2D data jsou pozice/tvary rakovinných jader Hledají tam nějakou podobnost https://www.w3.org/tr/sdw-ucr/ 11
Use case 3D data Dokonce by se jim hodila i 3D data/databáze, protože u rakoviny záleží také na tom, jak se vyvíjí v čase 3-tí dimenze je zde čas, nikoliv prostor 12
Geo data 13
SRID (Spatial Reference System Identifier) Identifikátor souřadného systému pro geografická data Zemský povrch Jako koule (aproximace reality) Promítnutá zeměkoule do roviny Cylindricky Merkátorova projekce Webová Merkátorova projekce Používá Google Maps a Google Maps API Mnoho dalších variant... Pseudocylindricky Planárně Kónicky Mnoho dalších... 14
Merkátorova projekce Něco dost podobného používá Google Maps https://media1.britannica.com/eb-media/47/2547-004-8428db64.jpg 15
Merkátorova projekce: problém 16
Merkátorova projekce: problém 2 JAm 17.5M km2 Antarktida - 14M km2 Nemá smysl zde počítat vzdálenost/úhly 17
Poučení Je nutné vědět, v jakém souřadném systému se pouhybuji Nejpoužívanější SRIDy SRID 4326 zeměkoule (GPS souřadnice) Google earth (lat-long souradnice) V úhlech (-180, 180)x(-90, 90) Např. Praha = 50.0833020, 14.4667000 Např. Rio, Brazilie = -43.9665070, -22.1894477 Na papírové mapě se jedná o 43.9665S, 22.1894W Zde se počítají přesné vzdálenosti na kouli SRID 3857 zeměkoule promítnutá do roviny Projekcí Web Merkator Google maps Používá se pro zobrazní mapy, tak jak jsme zvyklí V metrech! Např. Praha x=1609458.07, y= 6442724.24 Odpovídá x=14.4667000, y=50.0833020 http://twcc.fr/ - coordinated converter http://docs.openlayers.org/library/spherical_mercator.html 18
Měření vzdálenosti na kouli Haversine distance Souřadnice ve SRID 4326 Netriviální na implementaci Je potřeba mít k dispozici goniometrické funkce a arcsin na přesnost časově http://www.ryanduell.com/wp-content/uploads/2012/12/screenshot-12812-132-pm.png https://software.intel.com/sites/default/files/great%20circle.png 19
WKT (Well-Known Text) WKT umí popsat i 3D a 4D objekty Neříká, jaký SRID objekty mají Analogicky existuje i WKB (Well-Known Binary) 20
opengis (obecný geo standard) 21
OGC Open geospatial consortium Značka(trademark) opengis je zastaralá a dnes pod tím názvem nic nenajdete Sdružení více než 500 firem, univerizitních týmů a vládních orgánů/týmů Snaží se standardizovat vše ohledně GIS GIS = geografický informační systém Pracuje s prostorovými daty na zemského povrchu Města, státy, řeky, hory, sopky,... Standardy opengis, SF Standardy jsou zdarma Nejsou závazné 22
opengis standard pro geografická data Data na zeměkouli (pod nějakou projekcí viz SRID) Body, lomené čárky, polygony,... Specifikuje datové typy a funkce Určný pro libovolný programovací jayzk/libovolné prostředí, kde je potřeba práce s prostorovými daty SQL Java, C++, cokoliv Co se týče relačních databází, bude sloužit jako základ pro pokročilejší standardy 23
opengis - datové typy (aka geometrie) TODO foto = lomená úsečka = Diskrétní kružnice 24
opengis datové typy U geometrie se rozlišuje okraj a vnitřek Je zadaná krajními body 25
opengis standard - funkce SpatialReference vrací systém souřadnic dané geometrie SRID! Změna souřadného systému většinou nezmění výsledek prostorových funkcí Envelope vrací minimální obdélník představující okraje geometrie (aka MBR) Export vrací geometrii reprezentovanou jiným způsobem WKT, IsEmpty vrací TRUE, pokud je geometrie prázdná množina IsSimple vrací TRUE, pokud je geometrie jednoduchá (neprotínající sama sebe) Boundary vrací okraj geometrie 26
opengis funkce topologické Equal je okraj i vnitřní část dvou geometrií prostorově shodná Disjoint se okraj ani vnitřní část dvou geometrií neprotínají Intersect dvě geometrie nejsou disjunktní Touch se okraje dvou geometrií protínají, ale jejich vnitřní části ne Cross se vnitřní část povrchu protíná s křivkou Within se vnitřní část první geometrie neprotíná s oblastí ležící mimo druhou geometrii Contains jedna geometrie obsahuje druhou geometrii Overlap vnitřní části geometrií mají neprázdný průnik 27
opengis funkce 2 Distance vrací nejkratší vzdálenost dvou geometrií Buffer vrací geometrii, která obsahuje všechny body, které jsou vzdáleny od dané geometrie méně než daná hodnota ConvexHull vrací konvexní obal dané geometrie Intersection vrací geometrický průnik dvou geometrií Union vrací geometrické sjednocení dvou geometrií Difference vrací část geometrie, která se neprotíná s jinou danou geometií SymmDiff vrací části daných geometrií, které se navzájem neprotínaj 28
SF (Simple Features) aka SFA (Simple Feature Access) Krycí jméno pro Několik dokumentů opengis (OGC) Několik dokumentů ISO Ale je to známější pojem Mimo jiné definuje WKT (Well Known Text) https://en.wikipedia.org/wiki/simple_features 29
SQL/MM část 3 (prostorový a geo standard specificky pro SQL) 30
SQL/MM ISO a IEC standard (2002) Je to snaha o standardizaci multimédií v SQL Full-text, obrázky, prostorová data... SQL/MM Part 3: Spatial je mezinárodním standardem definujícím jak prostřednictvím SQL ukládat, načítat a zpracovávat prostorová data Vychází ze SF Hlavně z opengis 31
SQL/MM datové typy 32
33
34
SQL/MM typy jsou ekvivalentní typům WKT CIRCULARSTRING(1 5, 6 2, 7 3) Se zadává pomocí 3 bodů Polygon, může mít zadaný i vnitřní výřez. https://alastaira.wordpress.com/ 35
SQL/MM - funkce ST_distance, ST_intersects, ST_union, Začínají předponou ST_ Spatial, temporal (čas nakonec není součástí standardu, ale předpona ST_ se zachovala) 36
SQL/MM funkce definované na typu ST_Geometry a) a method ST_Dimension(), b) a method ST_CoordDim(), c) a method ST_GeometryType(), d) a method ST_SRID(), e) a method ST_SRID(INTEGER), f) a method ST_Transform(INTEGER), g) a method ST_IsEmpty(), h) a method ST_IsSimple(), i) a method ST_IsValid(), i.1) a method ST_Is3D(), i.2) a method ST_IsMeasured(), i.3) a method ST_LocateAlong(DOUBLE PRECISION), i.4) a method ST_LocateBetween(DOUBLE PRECISION, DOUBLE PRECISION), j) a method ST_Boundary(), k) a method ST_Envelope(), l) a method ST_ConvexHull(), m) a method ST_Buffer(DOUBLE PRECISION), n) a method ST_Buffer(DOUBLE PRECISION, CHARACTER VARYING), o) a method ST_Intersection(ST_Geometry), p) a method ST_Union(ST_Geometry), q) a method ST_Difference(ST_Geometry), r) a method ST_SymDifference(ST_Geometry), s) a method ST_Distance(ST_Geometry), t) a method ST_Distance(ST_Geometry, CHARACTER VARYING), u) a method ST_Equals(ST_Geometry), v) a method ST_Relate(ST_Geometry, CHARACTER), w) a method ST_Disjoint(ST_Geometry), x) a method ST_Intersects(ST_Geometry), y) a method ST_Touches(ST_Geometry), z) a method ST_Crosses(ST_Geometry), aa) a method ST_Within(ST_Geometry), ab) a method ST_Contains(ST_Geometry), ac) a method ST_Overlaps(ST_Geometry), ad) a method ST_WKTToSQL(CHARACTER LARGE OBJECT), ae) a method ST_AsText(), af) a method ST_WKBToSQL(BINARY LARGE OBJECT), ag) a method ST_AsBinary(), ah) a method ST_GMLToSQL(CHARACTER LARGE OBJECT), ai) a method ST_AsGML(), aj) a function ST_GeomFromText(CHARACTER LARGE OBJECT), ak) a function ST_GeomFromText(CHARACTER LARGE OBJECT, INTEGER), al) a function ST_GeomFromWKB(BINARY LARGE OBJECT), am) a function ST_GeomFromWKB(BINARY LARGE OBJECT, INTEGER) A mnoho dalších... Viz příloha ke slidům 37
-- Př. 1 CREATE TABLE rivers ( NAME VARCHAR(30) PRIMARY KEY, water_amount DOUBLE PRECISION, river_line ST_LINESTRING, flood_zones ST_MULTIPOLYGON ) CREATE TABLE buildings ( customer_name VARCHAR(50) PRIMARY KEY, street VARCHAR(50), city VARCHAR(20), zip VARCHAR(10), ground_plot ST_POLYGON ) 38
--Rozšíření záplavové zóny o 2 km u řeky Vltavy: UPDATE rivers SET flood_zones = flood_zones.st_buffer(2, 'KILOMETER') WHERE name = Vltava' --Nalezení zákazníků jejichž domy leží v záplavových oblastech: SELECT customer_name, street, city, zip FROM buildings AS b, rivers AS r WHERE b.ground_plot.st_within(r.flood_zones)=1 --objektový zápis 39
-- Př. 2 CREATE TABLE customers ( customer_id INTEGER PRIMARY KEY, NAME VARCHAR(20), street VARCHAR(25), city VARCHAR(10), state VARCHAR(2), zip VARCHAR(5), type VARCHAR(10), location ST_POINT ); --jedná se o pobočky velké pojišťovny a každá obsluhuje nějakou (městskou) zónu CREATE TABLE branches ( branch_id INTEGER PRIMARY KEY, NAME VARCHAR(12), manager VARCHAR(20), street VARCHAR(20), city VARCHAR(10), state VARCHAR(2), zip VARCHAR(5), location ST_POINT, zone ST_POLYGON ); 40
CREATE TABLE rivers ( NAME VARCHAR(30) PRIMARY KEY, water_amount DOUBLE PRECISION, river_line ST_LINESTRING, flood_zones ST_MULTIPOLYGON ) CREATE TABLE buildings ( customer_name VARCHAR(50) PRIMARY KEY, street VARCHAR(50), city VARCHAR(20), zip VARCHAR(10), ground_plot ST_POLYGON ) 41
CREATE TABLE accounts ( account_id INTEGER PRIMARY KEY, routing_no INTEGER NOT NULL, customer_id INTEGER NOT NULL, branch_id INTEGER NOT NULL, type VARCHAR(10) NOT NULL, balance DECIMAL(14, 2) NOT NULL, CONSTRAINT fk_customers FOREIGN KEY(customer_id) REFERENCES customers(customer_id), CONSTRAINT fk_branches FOREIGN KEY(branch_id) REFERENCES branches(branch_id) ); 42
-- Seznam zákazníků s více než 10 000 na účtu žijící dále než 20 mil od jejich pobočky: (že bychom jim postavili novou pobočku) SELECT DISTINCT c.customer_id, c.name FROM customers AS c JOIN accounts AS a ON (c.customer_id = a.customer_id) WHERE a.balance > 10000 AND c.location.st_distance( ( SELECT b.location FROM branches AS b WHERE b.branch_id = a.branch_id ), 'MILES') > 20 --vnitřní select vrátí přesně jednu pobočku --(každý zákazník je registrovaný na právně jedné pobočce) 43
--Nalezení překryvu polí působnosti jednotlivých poboček: (vrátí WKT) SELECT b1.branch_id, b2.branch_id, b1.zone.st_intersection(b2.zone).st_astext() FROM branches AS b1 JOIN branches AS b2 ON (b1.branch_id < b2.branch_id) WHERE b1.zone.st_overlaps(b2.zone) = 1 44
--Nalezení zákazníků žijících méně než 10 mil od pobočky, která nespravuje jejich účty: (Možná bych je měl přeregistrovat na tuto pobočku, aby to měli blíž) SELECT c.name, c.phone, b.branch_id FROM branches AS b, customers AS c WHERE b.location.st_buffer(10, 'MILES').ST_Contains(c.location) = 1 AND NOT EXISTS ( SELECT 1 FROM accounts AS a WHERE a.customer_id = c.customer_id AND a.branch_id = b.branch_id ) 45
Shrnutí standardů opengis/sf Základní datové typy Mnoho užitečných funkcí Pouze hranaté tvary Pouze geodata Neuvažuje směry (server, jih, ) Prostorové funkce nelze použít v konjunkci s GROUP BY SQL/MM část 3 I oblouky I Kartézská data (2D, 3D i 4D) běžně označovaná jako SRID 0 SRID 0 technicky (z geografického pohledu) nic neznamená I směry a úhly Další vylepšení a změny... 46
Na co jsme zapomněli? Jak nastavit SRID ST_SRID() Vrací nebo nastavuje SRID geometrie Pokud měříme vzdálenost dvou bodů, musejí mít stejný SRID To samé platí pro všechny ostatní funkce Prostorové indexy Databáze jsou od toho aby přístup k datům byl rychlý SQL/MM se jimi nezabývá 47
Prostorové indexy LZE použít klasické indexy B-tree, bitmap, hash,... Ale jen pro bodové dotazy Např. Vrať dům na souřadnicích 50.083 N, 14.466 E Ale takové dotazy ani nedávají smysl, takže je tento přístup zcela k ničemu Pro dotazy typu Vrať všechny města vzdálená 200 km od Prahy jsou potřeba prostorové indexy Prostorové stromy R-tree Varianty R, R+, R* Prostorová obdoba B-tree Hilbert R-tree UB-tree Prostorové hešování Další metody Grid Z-order viz přednáška OZD 1 (Organizace a Zpracování Dat I) http://dev.mysql.com/doc/refman/5.7/en/creating-spatial-indexes.html 48
Komerčí implementace SLQ/MM (a opengis) 49
Implemetace používající tyto standardy Firmy Oracle, MSSQL, MySQL, PostgreSQL,... Vždy implementují jen podmnožinu SQL/MM Jako rozšíření Někdy jde o separátní produkt PostgreSQL je pravděpodobně nejlepší co se týče prostorových schopností Pro implementaci prostorových datových typů (geometrie) používají objektové rozšíření DBMS Použije se ADT (uživatelem definovaný typ) ADT obecně porušují 1NF 50
Komerce - komunita gis.stackexchange.com Zde také vede PostGIS na plné čáře Stackoverflow.com 51
MySQL a prostorová podpora MySQL spatial Nepodporuje SRID a geografická data Má pouze kartézská data (SRID 0) Tudíž nepodporuje ani Haverine distance Má prostorový index R-strom Zdánlivě se řídí standardem SQL/MM Až na datové typy Těm chybí prefix ST_ Až na funkce Ty nejsou objektové, ale klasické/globální 52
--ukázka MySQL Spatial CREATE TABLE geom (nazev CHARACTER VARYING(100), gps POINT); INSERT INTO geom VALUES ("Abertamy", ST_GeomFromText("POINT(12.818377 50.368855)")), ("Adamov", ST_GeomFromText("POINT(14.539603 49.000624)")), ("Adamov", ST_GeomFromText("POINT(16.663955 49.295708)")); --jedná se o WKT --pozor, gps souřadnice se musejí zadat jako long-lat (takže naopak než normálně) (to není chyba MySQL, ale vlastnost WKT) ALTER TABLE geom ADD SPATIAL INDEX gps_idx(gps); 53
--Najdi všechna města do 50 km od Prahy SELECT * FROM geom WHERE ST_Distance(ST_GeomFromText("POINT(14.4656166 50.0468796)"), gps) < 20 -- Proč je tento dotaz totální nesmysl? 54
--Najdi všechna města do 50 km od Prahy SELECT * FROM geom WHERE ST_Distance(ST_GeomFromText("POINT(14.4656166 50.0468796)"), gps) < 20 -- Proč je tento dotaz totální nesmysl? -- Protože SRID = 0 --takže se snažíme měřit vzdálenost GPS souřadnic na zeměkouli v Kartézské rovině -- Navíc GPS jsou úhly, takže výsledkem ST_Distance je nějaký rozdíl úhlů --nikoliv vzdálenost v km 55
--imlementace aproximace Haversine distance --musíme si naimpelementovat ručně (MySQL nepodporuje) SELECT nazev, gps, (6371 * acos( cos( radians(49.707893) ) * cos( radians( ST_Y(gps) )) * cos( radians( ST_X(gps) ) - radians(14.298816) ) + sin( radians(49.707893) ) * sin(radians(st_y(gps))) ) ) AS distance FROM geom HAVING distance < 10; --je potřeba použít HAVING, protože ve WHERE se o aliasu distance neví, zatímco v HAVING ano. http://stackoverflow.com/questions/574691/mysql-great-circle-distance-haversine-formula 56
Shrnutí Pro silně prostorové aplikace používejte PostgreSQL Velká komunita Velká pravděpodobnost zlepšování funkcionality, debugování atd. gis.stackexchange.com Nesnažte se pracovat s geografickými daty v MySQL Pozor na SRID Pozor na lat-long vs. x-y Požadujte prostorový index 57
Zdroje S. Shekhar a S. Chawla, Spatial Databases: A Tour, Prentice Hall, 2003 (ISBN 013-017480-7) K. Stolze, SQL/MM Spatial: The Standard to Manage Spatial Data in Relational Database Systems SQL/MM part 3 https://www.w3.org/tr/sdw-ucr/ - geodata uscases w3c http://gis.stackexchange.com/questions/48949/epsg-3857-or-4326-for-googlemaps-openstreetmap-andleaflet - souradnice vysvetlene http://www.opengeospatial.org/ogc = opengis/ogc Prezentace prostorové SQL 2015 (Ostatní zdroje uvedené přímo ve slidech) 58