Kapitel 9. Topologi

Innehållsförteckning

PostGIS Topology-typer och -funktioner används för att hantera topologiska objekt som ytor, kanter och noder.

Sandro Santillis presentation på konferensen PostGIS Day Paris 2011 ger en bra sammanfattning av PostGIS Topology och vart det är på väg Topology with PostGIS 2.0 slide deck..

Vincent Picavet ger en bra sammanfattning och översikt över vad Topology är, hur det används och olika FOSS4G-verktyg som stöder det i PostGIS Topology PGConf EU 2012.

Ett exempel på en topologibaserad GIS-databas är databasen US Census Topologically Integrated Geographic Encoding and Referencing System (TIGER). Den passar om du vill experimentera med PostGIS-topologi och behöver data.

Topologimodulen i PostGIS har funnits länge men har inte alltid ingått i den officiella dokumentationen. En omfattande upprensning tog bort föråldrade funktioner, rättade kända användbarhetsproblem, dokumenterade funktionerna, lade till ny funktionalitet och förbättrade SQL-MM-kompatibiliteten.

Detta kapitel är den underhållna referensen för topologimodulen, inklusive dess primitiva tabeller, typen TopoGeometry, funktioner för topologihantering, redigeringsfunktioner, valideringsfunktioner och konverteringshjälpfunktioner.

Alla funktioner och tabeller som är kopplade till denna modul är installerade i ett schema som kallas topologi.

Funktioner som är definierade i SQL/MM-standarden har prefixet ST_ och funktioner som är specifika för PostGIS har inget prefix.

Topologistöd byggs som standard och kan inaktiveras med konfigurationsalternativet --without-topology vid byggning enligt Kapitel 2, Installation av PostGIS

9.1. Skapa ytor från linjearbete

Detta exempel bygger topologiytor av nodad linjegeometri och kopplar punktattribut till de resulterande ytorna. Det använder ST_CreateTopoGeo för att fylla en tom topologi, ValidateTopology för att kontrollera resultatet, GetFaceByPoint för att hitta varje attributpunkt och ST_GetFaceGeometry för att materialisera vanliga polygongeometrier.

Skapa en tom topologi och fyll den med linjearbete som omsluter två ytor:

Kod
CREATE EXTENSION IF NOT EXISTS postgis_topology;

SELECT topology.CreateTopology('topo_example', 3857);

WITH lines(geom) AS (VALUES
    ('SRID=3857;LINESTRING(0 0, 2 0)'::geometry),
    ('SRID=3857;LINESTRING(0 1, 2 1)'::geometry),
    ('SRID=3857;LINESTRING(0 0, 0 1)'::geometry),
    ('SRID=3857;LINESTRING(1 0, 1 1)'::geometry),
    ('SRID=3857;LINESTRING(2 0, 2 1)'::geometry)
)
SELECT topology.ST_CreateTopoGeo(
    'topo_example',
    ST_Collect(geom)
)
FROM lines;

SELECT * FROM topology.ValidateTopology('topo_example');

Ett tomt resultat från ValidateTopology innebär att inga topologifel hittades. Attributpunkter kan nu matchas mot ytor. En ytid på 0 betecknar den universella ytan, så punkten ligger utanför varje begränsad yta.

Kod
WITH labels(name, geom) AS (VALUES
    ('west', 'SRID=3857;POINT(0.5 0.5)'::geometry),
    ('east', 'SRID=3857;POINT(1.5 0.5)'::geometry),
    ('outside', 'SRID=3857;POINT(3 0.5)'::geometry)
),
located AS (
    SELECT name,
           topology.GetFaceByPoint('topo_example', geom, 0) AS face_id
    FROM labels
)
SELECT name,
       face_id,
       CASE WHEN face_id = 0 THEN NULL
            ELSE topology.ST_GetFaceGeometry('topo_example', face_id)
       END AS geom
FROM located
ORDER BY name;

Innan attribut kopieras till en yttabell bör du kontrollera både punkter utanför begränsade ytor och flera källpunkter som tilldelats samma yta:

Kod
WITH labels(name, geom) AS (VALUES
    ('west', 'SRID=3857;POINT(0.5 0.5)'::geometry),
    ('east', 'SRID=3857;POINT(1.5 0.5)'::geometry),
    ('outside', 'SRID=3857;POINT(3 0.5)'::geometry)
),
located AS (
    SELECT name,
           topology.GetFaceByPoint('topo_example', geom, 0) AS face_id
    FROM labels
)
SELECT 'outside face' AS problem,
       array_agg(name ORDER BY name) AS labels
FROM located
WHERE face_id = 0
HAVING count(*) > 0
UNION ALL
SELECT 'duplicate face ' || face_id,
       array_agg(name ORDER BY name)
FROM located
WHERE face_id != 0
GROUP BY face_id
HAVING count(*) > 1;

Använd DropTopology för att ta bort exempeltopologin när den inte längre behövs:

Kod
SELECT topology.DropTopology('topo_example');

9.2. Topologins primitiva tabeller

Kärnprimitiverna i varje topologi lagras i tabellerna edge_data, node och face i schemat som skapas av CreateTopology. Varje rad i edge_data representerar en orienterad kant: den registrerar en riktad kurva från start_node till end_node, tillsammans med identifieraren för ytan till vänster om riktningen (left_face) och ytan till höger (right_face). Samma geometriska segment kan därför förekomma två gånger, en gång för varje orientering, när det tillhör två ytor.

Kolumnerna next_left_edge och next_right_edge kompletterar orienteringsinformationen genom att koda hur man fortsätter runt en yta. De lagrar heltal med tecken, vars absolutbelopp är identifieraren för nästa orienterade kant och vars tecken avgör om den lagrade orienteringen ska följas som den är eller omvändas vid traversering. Formellt gäller följande regler för varje kant e:

  • abs(next_left_edge) är identifieraren för den kant som nås genom att fortsätta runt ytan till vänster om e. Om värdet är positivt fortsätter vandringen från slutnoden för e längs den refererade kantens lagrade orientering; om det är negativt måste den refererade kanten följas baklänges så att den gemensamma ytan förblir till vänster.

  • abs(next_right_edge) följer på motsvarande sätt gränsen för ytan till höger om e. Ett positivt värde innebär att nästa kant tas med sin registrerade orientering från slutnoden för e, medan ett negativt värde anger att den refererade kanten ska traverseras i omvänd riktning från sin slutnod så att ytan till höger bevaras.

  • Ett värde på noll anger att kanten hänger fritt på motsvarande sida, exempelvis en isolerad kant vars angränsande yta är den universella ytan 0. Kolumnerna abs_next_left_edge och abs_next_right_edge som visas i vyn edge är praktiska projektioner av dessa absolutbelopp.

Denna representation är en variant av en dubbellänkad kantlista och används av många topologirutiner. Funktioner som GetRingEdges och ValidateTopology använder den för att återskapa ytgränser och diagnostisera inkonsekvenser, vilket förklarar diagnoserna ”invalid next_left_edge” och ”invalid next_right_edge” vid validering. Konstruktorer som AddEdge initierar attributen next_* med triviala självreferenser, medan redigeringsrutiner som ST_AddEdgeModFace och ST_RemEdgeModFace uppdaterar länkarna när kanter läggs till eller tas bort. Andra massåtgärder, exempelvis Polygonize, kan avsiktligt lämna fälten oinställda, varför dokumentationen uttryckligen anger detta.

9.3. Topologityper

Sammanfattning

Detta avsnitt listar PostgreSQL-datatyper installerade av PostGIS Topology. Observera att vi beskriver casting-beteendet för dessa, vilket är mycket viktigt, särskilt när du utformar dina egna funktioner.

  • getfaceedges_returntype — En sammansatt typ som består av ett sekvensnummer och ett kantnummer.
  • TopoGeometry — En sammansatt typ som representerar en topologiskt definierad geometri.
  • validatetopology_returntype — En sammansatt typ som består av ett felmeddelande samt id1 och id2 för att ange var felet finns. Detta är returtypen för ValidateTopology.

9.4. Topologidomäner

Sammanfattning

Detta avsnitt listar PostgreSQL-domänerna installerade av PostGIS Topology. Domäner kan användas som objekttyper som returobjekt för funktioner eller tabellkolumner. Skillnaden mellan en domän och en typ är att en domän är en befintlig typ med en kontrollbegränsning bunden till den.

  • TopoElement — En matris med 2 heltal som vanligtvis används för att identifiera en TopoGeometry-komponent.
  • TopoElementArray — En array av TopoElement-objekt.

9.5. Hantering av topologi och topogeometri

Sammanfattning

I det här avsnittet listas Topology-funktioner för att skapa nya Topology-scheman, validera topologier och hantera TopoGeometry-kolumner

  • AddTopoGeometryColumn — Lägger till en topogeometrikolumn i en befintlig tabell, registrerar den nya kolumnen som ett lager i topology.layer och returnerar det nya layer_id.
  • RenameTopoGeometryColumn — Byter namn på en topogeometri-kolumn
  • DropTopology — Använd med försiktighet: Tar bort ett topologischema och raderar dess referens från tabellen topology.topology och referenser till tabeller i det schemat från tabellen geometry_columns.
  • RenameTopology — Byter namn på en topologi
  • DropTopoGeometryColumn — Tar bort kolumnen topogeometry från tabellen med namnet table_name i schema schema_name och avregistrerar kolumnerna från tabellen topology.layer.
  • FixCorruptTopoGeometryColumn — Åtgärdar skadade topogeometrier som orsakas av uppgradering till postgis_topology 3.6.0 eller senare
  • Populate_Topology_Layer — Lägger till saknade poster i tabellen topology.layer genom att läsa metadata från topotabeller.
  • TopologySummary — Tar ett topologinamn och ger sammanfattande totalsummor för olika typer av objekt i topologin.
  • ValidateTopology — Returnerar en uppsättning validatetopology_returntype-objekt som beskriver problem med topologin.
  • ValidateTopologyRelation — Returnerar information om ogiltiga topologirelationsposter
  • ValidateTopologyPrecision — Returnerar icke-precisa toppunkter i topologin.
  • MakeTopologyPrecise — Fäst topologivinklar till precisionsrutnätet.
  • FindTopology — Returnerar en topologipost på olika sätt.
  • FindLayer — Returnerar en topology.layer-post på olika sätt.
  • TotalTopologySize — Totalt diskutrymme som används av den angivna topologin, inklusive alla index och TOAST-data.
  • UpgradeTopology — Uppgraderar den angivna topologin till att stödja stora ids (int8) för topologi och primitiva ids.

9.6. Hantering av topologistatistik

Sammanfattning

I detta avsnitt beskrivs hantering av databasstatistik under topologibyggandet.

Att lägga till element i en topologi utlöser många databasfrågor för att hitta befintliga kanter som ska delas, lägga till noder och uppdatera kanter som ska knytas till det nya linjeverket. Därför är det bra om statistiken över data i topologitabellerna är uppdaterad.

PostGIS topologipopulation och redigeringsfunktioner uppdaterar inte statistiken automatiskt eftersom det skulle vara onödigt att uppdatera statistiken efter varje ändring i en topologi, så det är uppringarens skyldighet att ta hand om det.

[Notera]

Att statistiken som uppdateras av autovacuum INTE kommer att vara synlig för transaktioner som startade innan autovacuum-processen slutfördes, så långvariga transaktioner måste köra ANALYZE själva för att använda uppdaterad statistik.

9.7. Topology Constructors

Sammanfattning

I detta avsnitt beskrivs topologifunktionerna för att skapa nya topologier.

  • CreateTopology — Skapar ett nytt topologischema och registrerar det i tabellen topology.topology.
  • CopyTopology — Gör en kopia av en topologi (noder, kanter, ytor, lager och TopoGeometries) till ett nytt schema
  • ST_InitTopoGeo — Skapar ett nytt topologischema och registrerar det i tabellen topology.topology.
  • ST_CreateTopoGeo — Lägger till en samling geometrier till en given tom topologi och returnerar ett meddelande om det lyckas.
  • TopoGeo_AddPoint — Lägger till en punkt i en befintlig topologi med hjälp av en tolerans och eventuellt genom att dela en befintlig kant.
  • TopoGeo_AddLineString — Lägger till en linestrings till en befintlig topologi med hjälp av en tolerans och eventuellt delning av befintliga kanter/ytor.
  • TopoGeo_AddPolygon — Lägger till en polygon till en befintlig topologi med hjälp av en tolerans och eventuellt delning av befintliga kanter/ytor. Returnerar ytidentifierare.
  • TopoGeo_LoadGeometry — Läs in en geometri i en befintlig topologi, snappa och dela efter behov.

9.8. Topologiredigerare

Sammanfattning

I detta avsnitt beskrivs topologifunktioner för att lägga till, flytta, ta bort och dela kanter, ytor och noder. Alla dessa funktioner definieras av ISO SQL/MM.

  • ST_AddIsoNode — Lägger till en isolerad nod till en face i en topologi och returnerar nodeid för den nya noden. Om face är null skapas noden ändå.
  • ST_AddIsoEdge — Lägger till en isolerad kant definierad av geometrin alinestring till en topologi som förbinder två befintliga isolerade noder anode och anothernode och returnerar kant-ID för den nya kanten.
  • ST_AddEdgeNewFaces — Lägg till en ny kant och, om den delar en yta, ta bort den ursprungliga ytan och ersätt den med två nya ytor.
  • ST_AddEdgeModFace — Lägg till en ny kant och, om den delar en yta, modifiera den ursprungliga ytan och lägg till en ny yta.
  • ST_RemEdgeNewFace — Tar bort en kant och, om den borttagna kanten separerade två ytor, tar bort de ursprungliga ytorna och ersätter dem med en ny yta.
  • ST_RemEdgeModFace — Tar bort en kant och, om kanten separerar två ytor, tar bort den ena ytan och ändrar den andra så att den täcker utrymmet för båda ytorna.
  • ST_ChangeEdgeGeom — Ändrar formen på en kant utan att påverka topologins struktur.
  • ST_ModEdgeSplit — Dela en kant genom att skapa en ny nod längs en befintlig kant, modifiera den ursprungliga kanten och lägga till en ny kant.
  • ST_ModEdgeHeal — Läker två kanter genom att ta bort den nod som förbinder dem, modifiera den första kanten och ta bort den andra kanten. Returnerar id för den borttagna noden.
  • ST_NewEdgeHeal — Läker två kanter genom att ta bort noden som förbinder dem, ta bort båda kanterna och ersätta dem med en kant vars riktning är densamma som den första tillhandahållna kanten.
  • ST_MoveIsoNode — Flyttar en isolerad nod i en topologi från en punkt till en annan. Om den nya apoint-geometrin existerar som en nod kastas ett fel. Returnerar beskrivning av förflyttning.
  • ST_NewEdgesSplit — Dela en kant genom att skapa en ny nod längs en befintlig kant, ta bort den ursprungliga kanten och ersätta den med två nya kanter. Returnerar id för den nya nod som skapats och som sammanfogar de nya kanterna.
  • ST_RemoveIsoNode — Tar bort en isolerad nod och returnerar en beskrivning av åtgärden. Om noden inte är isolerad (är början eller slutet på en kant), kastas ett undantag.
  • ST_RemoveIsoEdge — Tar bort en isolerad kant och returnerar en beskrivning av åtgärden. Om kanten inte är isolerad kastas ett undantag.

9.9. Topologi-accessorer

  • GetEdgeByPoint — Hittar kant-id för en kant som skär en given punkt.
  • GetFaceByPoint — Hitta en yta som skär en given punkt.
  • GetFaceContainingPoint — Hittar den yta som innehåller en punkt.
  • GetNodeByPoint — Hittar nod-id för en nod vid en punktposition.
  • GetTopologyID — Returnerar id för en topologi i tabellen topology.topology givet topologins namn.
  • GetTopologySRID — Returnerar SRID för en topologi i tabellen topology.topology med topologins namn.
  • GetTopologyName — Returnerar namnet på en topologi (schema) givet topologins id.
  • ST_GetFaceEdges — Returnerar en uppsättning ordnade kanter som avgränsar en yta..
  • ST_GetFaceGeometry — Returnerar polygonen i den angivna topologin med det angivna ytans id.
  • GetRingEdges — Returnerar den ordnade uppsättningen av signerade kantidentifierare som man möter när man går på en given kantsida.
  • GetNodeEdges — Returnerar en ordnad uppsättning kanter som är kopplade till den angivna noden.
  • FindVertexSegmentPairsBelowDistance — Hitta par av topologivertex/-segment som ligger närmare varandra än tolererat avstånd

9.10. Bearbetning av topologi

Sammanfattning

I detta avsnitt beskrivs funktionerna för att bearbeta topologier på icke-standardiserade sätt.

  • Polygonize — Hittar och registrerar alla ytor som definieras av topologikanter.
  • AddNode — Lägger till en punktnod i nodtabellen i det angivna topologischemat och returnerar den nya nodens nodid. Om punkten redan finns som nod returneras det befintliga nodid.
  • AddEdge — Lägger till en linestringskant i tabellen edge och associerade start- och slutpunkter i tabellen point nodes i det angivna topologischemat med hjälp av den angivna linestringsgeometrin och returnerar edgeid för den nya (eller befintliga) kanten.
  • AddFace — Registrerar en ytprimitiv till en topologi och hämtar dess identifierare.
  • ST_Simplify — Returnerar en "förenklad" geometriversion av den angivna TopoGeometry med hjälp av Douglas-Peucker-algoritmen.
  • RemoveUnusedPrimitives — Tar bort topologiprimitiver som inte behövs för att definiera befintliga TopoGeometry-objekt.

9.11. TopoGeometry Constructors

Sammanfattning

I detta avsnitt beskrivs topologifunktionerna för att skapa nya topogeometrier.

  • CreateTopoGeom — Skapar ett nytt topogeometriobjekt från en array av topoelement - tg_type: 1:[multi]punkt, 2:[multi]linje, 3:[multi]poly, 4:samling
  • toTopoGeom — Konverterar en enkel geometri till en topogeometri.
  • TopoElementArray_Agg — Returnerar en topoelementarray för en uppsättning element_id, typ arrayer (topoelements).
  • TopoElement — Konverterar en topogeometri till ett topoelement.

9.12. TopoGeometry-redigerare

Sammanfattning

I detta avsnitt beskrivs topologifunktionerna för redigering av befintliga topogeometrier.

  • clearTopoGeom — Rensar innehållet i en topogeometri.
  • TopoGeom_addElement — Lägger till ett element till definitionen av en TopoGeometry.
  • TopoGeom_remElement — Tar bort ett element från definitionen av en TopoGeometry.
  • TopoGeom_addTopoGeom — Lägger till element i en TopoGeometry till definitionen av en annan TopoGeometry.
  • toTopoGeom — Lägger till en geometrisk form till en befintlig topogeometri.

9.13. TopoGeometry-accessorer

  • GetTopoGeomElementArray — Returnerar en topoelementarray (en array av topoelements) som innehåller de topologiska elementen och typen för den givna TopoGeometry (primitiva element).
  • GetTopoGeomElements — Returnerar en uppsättning topoelement-objekt som innehåller topologiska element_id,element_type för den givna TopoGeometry (primitiva element).
  • ST_SRID — Returnerar den spatiala referensidentifieraren för en topogeometri.

9.14. TopoGeometry-utdata

  • AsGML — Returnerar GML-representationen av en topogeometri.
  • AsTopoJSON — Returnerar TopoJSON-representationen av en topogeometri.

9.15. Spatiala relationer mellan topologier

Sammanfattning

I detta avsnitt listas de topologifunktioner som används för att kontrollera relationer mellan topogeometrier och topologiprimitiver

  • Equals — Returnerar true om två topogeometrier består av samma topologiprimitiver.
  • Intersects — Returnerar true om något par av primitiver från de två topogeometrierna korsar varandra.

9.16. Importera och exportera topologier

När du har skapat topologier och kanske tillhörande topologiska lager kanske du vill exportera dem till ett filbaserat format för säkerhetskopiering eller överföring till en annan databas.

Att använda standardverktygen för dumpning / återställning av PostgreSQL är problematiskt eftersom topologier består av en uppsättning tabeller (4 för primitiver, ett godtyckligt antal för lager) och poster i metadatatabeller (topology.topology och topology.layer). Dessutom är topologiidentifierare inte univoque över databaser så att parametern för din topologi måste ändras när du återställer den.

För att förenkla export/återställning av topologier tillhandahålls ett par körbara program: pgtopo_export och pgtopo_import. Exempel på användning:

Kod
pgtopo_export dev_db topo1 | pgtopo_import topo1 | psql staging_db

9.16.1. Använda topologiexportören

Skriptet pgtopo_export tar namnet på en databas och en topologi och matar ut en dumpfil som kan användas för att importera topologin (och tillhörande lager) till en ny databas.

Som standard skriver pgtopo_export dumpfilen till standardutdata så att den kan pipas till pgtopo_import eller omdirigeras till en fil (vägrar att skriva till terminalen). Du kan ange ett filnamn för utdata med kommandoradsalternativet -f..

Som standard inkluderar pgtopo_export en dumpning av alla lager som definierats mot den givna topologin. Detta kan vara mer data än du behöver, eller kanske inte fungerar (om dina lagertabeller har komplexa beroenden), i vilket fall du kan begära att lagren hoppas över med omkopplaren --skip-layers och hantera dem separat.

Om pgtopo_export an ropas med kommandot --help (eller -h förkortat) skrivs alltid en kort användningssträng ut.

Dumpfilformatet är ett komprimerat tar-arkiv med en pgtopo_export-katalog som innehåller minst en pgtopo_dump_version-fil med information om formatversion. Från och med version 1 innehåller katalogen tabbavgränsade CSV-filer med data från de primitiva tabellerna för topologi (nod, kantdata, yta, relation), topologi- och lagerposterna som är associerade med den och (om inte --skip-layers ges) en PostgreSQL-dump i anpassat format av tabeller som rapporteras som lager i den givna topologin.

9.16.2. Använda topologiimportören

Skriptet pgtopo_import tar en topologidump i pgtopo_export-format och ett namn på den topologi som ska skapas och matar ut ett SQL-skript som rekonstruerar topologin och tillhörande lager.

Den genererade SQL-filen kommer att innehålla satser som skapar en topologi med det angivna namnet, laddar primitiva data i den, återställer och registrerar alla topologilager genom att korrekt länka alla TopoGeometry-värden till deras korrekta topologi.

Som standard läser pgtopo_import dumpningen från standardinmatningen så att den kan användas tillsammans med pgtopo_export i en pipeline. Du kan eventuellt ange ett filnamn för indata med kommandoradsalternativet -f.

Som standard inkluderar pgtopo_import i SQL-filen koden för att återställa alla lager som finns i dumpningen.

Detta kan vara oönskat eller inte fungera om din måldatabas redan har tabeller med samma namn som de i dumpningen. I så fall kan du begära att lagren hoppas över med --skip-layers och hantera dem separat (eller senare).

SQL för att endast läsa in och länka lager till en namngiven topologi kan genereras med hjälp av omkopplaren --only-layers. Detta kan vara användbart för att läsa in lager EFTER att namnkonflikterna har lösts eller för att länka lager till en annan topologi (t.ex. en spatialt förenklad version av starttopologin).

Om måltopologin redan finns och du vill att den ska tas bort i förväg kan du använda kommandot --drop-topology (sedan PostGIS-3.6.0).