PostGIS Topology

Z FreeGIS portál
Přejít na: navigace, hledání

PostGIS Topology je rozšíření pro PostGIS umožňující topologickou správu vektorových dat v prostředí PostGIS/PostgreSQL.

Příklad (sousedící polygony)

Ke stažení jako SQL dávka.

create schema landamar;
SET search_path TO landamar,topology,public;

(1) Příprava testovacích dat

CREATE TABLE p2 (fid serial primary key, geom geometry(Polygon));

INSERT INTO p2 (geom) VALUES (ST_GeomFromText('Polygon(
       (0 0, 100 0, 100 100, 0 100, 0 0))'));

INSERT INTO p2 (geom) VALUES (ST_GeomFromText('Polygon(
       (100 0, 200 0, 200 100, 100 100, 100 0))'));
Příklad: 2 sousedící polygony

(2) Vytvoření topologického schématu

SELECT CreateTopology('topo_p2');

SELECT * from topology;
 id |  name   | srid | precision | hasz 
----+---------+------+-----------+------
  1 | topo_p2 |    0 |         0 | f

(3) Přidání TopoGeometry do feature table

SELECT AddTopoGeometryColumn('topo_p2', 'landamar', 'p2', 'topo', 'POLYGON');

SELECT * FROM layer;
 topology_id | layer_id | schema_name | table_name | feature_column | feature_type | level | child_id 
-------------+----------+-------------+------------+----------------+--------------+-------+----------
           1 |        1 | landamar    | p2         | topo           |            3 |     0 |         

(4a) Vytvoření topologických vektorových dat (manuální postup)

(1) Přidání samostatné hrany
SELECT AddEdge('topo_p2',
       ST_GeomFromText('LineString(100 0, 0 0, 0 100, 100 100)'));
Příklad: tvorba topologických dat (1)

SELECT node_id,containing_face from topo_p2.node order by node_id;
 node_id | containing_face 
---------+-----------------
       1 |                
       2 |                
(2 rows)
select edge_id,start_node,end_node,next_left_edge,next_right_edge,left_face,right_face from topo_p2.edge order by edge_id;
 edge_id | start_node | end_node | next_left_edge | next_right_edge | left_face | right_face 
---------+------------+----------+----------------+-----------------+-----------+------------
       1 |          1 |        2 |             -1 |               1 |         0 |          0
(1 rows)
(2) Přidání hrany, vytvoření nové stěny
SELECT ST_AddEdgeNewFaces('topo_p2', 1, 2,
       ST_GeomFromText('LineString(100 0, 200 0, 200 100, 100 100)'));
Příklad: tvorba topologických dat (2)

select edge_id,start_node,end_node,next_left_edge,next_right_edge,left_face,right_face from topo_p2.edge order by edge_id;
 edge_id | start_node | end_node | next_left_edge | next_right_edge | left_face | right_face 
---------+------------+----------+----------------+-----------------+-----------+------------
       1 |          1 |        2 |             -2 |               2 |         0 |          1
       2 |          1 |        2 |             -1 |               1 |         1 |          0
(2 rows)

select face_id from topo_p2.face order by face_id;
 face_id 
---------
       0
       1
(2 rows)
(3) Přidání hrany, modifikace existující stěny, přidání stěny nové
SELECT ST_AddEdgeModFace('topo_p2', 2, 1,
       ST_GeomFromText('LineString(100 100, 100 0)'));
Příklad: tvorba topologických dat (3)

SELECT edge_id,start_node,end_node,next_left_edge,next_right_edge,left_face,right_face FROM topo_p2.edge ORDER BY edge_id;
 edge_id | start_node | end_node | next_left_edge | next_right_edge | left_face | right_face 
---------+------------+----------+----------------+-----------------+-----------+------------
       1 |          1 |        2 |             -2 |              -3 |         0 |          1
       2 |          1 |        2 |              3 |               1 |         2 |          0
       3 |          2 |        1 |              2 |              -1 |         2 |          1
(3 rows)
SELECT face_id FROM topo_p2.face ORDER BY face_id;
 face_id 
---------
       0
       1
       2
(3 rows)

(4b) Vytvoření topologických vektorových dat (dávkově ze simple features geometrie)

UPDATE p2 SET topo = toTopoGeom(geom, 'topo_p2', 1);

(5) Kontrola dat

SELECT TopologySummary('topo_p2');

SELECT ValidateTopology('topo_p2');

Příklad (kltm50)

Data z cvičné databáze pgis_student.

CREATE SCHEMA my_schema;
SET search_path TO my_schema,public,topology,gis1;

Feature table 'tm50_cr'

CREATE TABLE tm50_cr AS SELECT DISTINCT k.ogc_fid,k.tm50,k.geom FROM kltm50 AS k JOIN obce AS o ON ST_Overlaps(k.geom, o.geom);
SELECT COUNT(*) FROM tm50_cr;
 count 
-------
   289
(1 row)
Klad mapových listu TM50 (území ČR)

Vytvoření topologického schématu 'topo_tm50_cr'

SELECT topology.createtopology('topo_tm50_cr', find_srid('gis1', 'kltm50', 'geom'), 1);

Argumenty:

  • find_srid('gis1', 'kltm50', 'geom') → 2065 (EPSG)
  • 1 (přesnost v mapových jednotkách, tj. v tomto případě v metrech)
SELECT * from topology.topology;
 id |     name     | srid | precision | hasz 
----+--------------+------+-----------+------
  1 | topo_tm50_cr | 2065 |         1 | f
(1 row)
\dt topo_tm50_cr.
             List of relations
    Schema    |   Name    | Type  |  Owner  
--------------+-----------+-------+---------
 topo_tm50_cr | edge_data | table | postgis
 topo_tm50_cr | face      | table | postgis
 topo_tm50_cr | node      | table | postgis
 topo_tm50_cr | relation  | table | postgis
(4 rows)

Přidání atributu topologie do feature table

SELECT topology.AddTopoGeometryColumn('topo_tm50_cr', 'my_schema', 'tm50_cr', 'topo', 'POLYGON');
SELECT * FROM topology.layer;
 topology_id | layer_id | schema_name | table_name | feature_column | feature_type | level | child_id 
-------------+----------+-------------+------------+----------------+--------------+-------+----------
           1 |        1 | my_schema   | tm50_cr    | topo           |            3 |     0 |         

Poznámka: feature_type '3' odpovídá 'face' (1 - node, 2 - edge).

Sestavení topologie (Geometry → TopoGeometry)

UPDATE tm50_cr set topo = topology.toTopoGeom(geom, 'topo_tm50_cr', 1);
SELECT tm50,(topo).* from tm50_cr limit 3;
   tm50    | topology_id | layer_id | id | type 
-----------+-------------+----------+----+------
 M-33-29-D |           1 |        1 |  1 |    3
 M-33-30-C |           1 |        1 |  2 |    3
 M-33-30-D |           1 |        1 |  3 |    3
(3 rows)
  • Počet uzlů:
SELECT count(*) FROM topo_tm50_cr.node;
 count 
-------
   313
(1 row)
  • Počet hran:
SELECT count(*) FROM topo_tm50_cr.edge;
 count 
-------
   601
(1 row)
  • Počet stěn:
SELECT count(*) FROM topo_tm50_cr.face;
 count 
-------
   290
(1 row)
  • Hrany, které vedou z anebo do uzlu číslo '164'
SELECT edge_id,left_face,right_face FROM topo_tm50_cr.edge WHERE start_node = 164 OR end_node = 164;
 edge_id | left_face | right_face 
---------+-----------+------------
     289 |       146 |        134
     310 |       160 |        146
     308 |       172 |        134
     360 |       172 |        160
(4 rows)
Klad mapových listu TM50 (území ČR) - topologická primitiva - uzly a hrany

Příklad (obce)

CREATE SCHEMA my_schema;
SET search_path TO my_schema,public,topology,gis1;
  • Vytvoření kopie tabulky 'obce' ve vlastním schématu
CREATE TABLE obce AS SELECT * FROM gis1.obce;
ALTER TABLE obce ADD PRIMARY KEY (ogc_fid);
CREATE INDEX obce_geom_idx ON obce USING GIST (geom);
  • Vytvoření topologického schématu 'topo_obce'
SELECT topology.createtopology('topo_obce', find_srid('my_schema', 'obce', 'geom'), 1e-6);
  • Přidání atributu topologie do feature table
SELECT topology.AddTopoGeometryColumn('topo_obce', 'my_schema', 'obce', 'topo', 'POLYGON');
UPDATE obce SET topo = topology.toTopoGeom(geom, 'topo_obce', 1);
Vizualizace topologických dat v prostředí QGIS

Poznámky

toTopoGeom skončí chybou (Spatial exception - geometry intersects edge)

→ Může pomoct změna tolerance, viz CreateTopology()

Topologické schéma není v QGIS dostupné

→ Nastavte práva pro jednotlivé tabulky, např.
GRANT SELECT ON topo_obce.node TO public;
GRANT SELECT ON topo_obce.edge_data TO public;
GRANT SELECT ON topo_obce.face TO public;

Podpora PostGIS Topology

Externí odkazy