1<?xml version="1.0" encoding="UTF-8"?>
2<chapter id="Topology">
3	<title>Topology</title>
4	<para>The PostGIS Topology types and functions are used to manage topological objects such as faces, edges and nodes. </para>
5	<para>Sandro Santilli's presentation at PostGIS Day Paris 2011  conference gives a good synopsis of PostGIS Topology and where it is headed <ulink url="http://strk.kbt.io/projects/postgis/Paris2011_TopologyWithPostGIS_2_0.pdf">Topology with PostGIS 2.0 slide deck</ulink>.</para>
6	<para>Vincent Picavet provides a good synopsis and overview of what is Topology, how is it used, and various FOSS4G tools that support it in <ulink url="https://github.com/Oslandia/presentations/blob/master/pgconf_eu_2012/pgconfeu2012_vincent_picavet_postgis_topology.pdf?raw=true">PostGIS Topology PGConf EU 2012</ulink>.</para>
7    <para>An example of a topologically based GIS database is the <ulink url="https://www.census.gov/geo/maps-data/data/tiger.html">US Census Topologically Integrated Geographic Encoding and Referencing System (TIGER)</ulink> database. If you want to experiment with PostGIS topology and need some data, check out <xref linkend="Topology_Load_Tiger" />.</para>
8	<para>The PostGIS topology module has existed in prior versions of PostGIS but was never part of the Official PostGIS documentation.
9	    In PostGIS 2.0.0 major cleanup is going on to remove use of all deprecated functions in it, fix known usability issues, better document the features and functions, add new functions, and enhance to closer conform to SQL-MM standards.</para>
10	<para>Details of this project can be found at <ulink url="http://trac.osgeo.org/postgis/wiki/UsersWikiPostgisTopology">PostGIS Topology Wiki</ulink></para>
11	<para>All functions and tables associated with this module are installed in a schema called <varname>topology</varname>.</para>
12	<para>Functions that are defined in SQL/MM standard are prefixed with ST_ and functions specific to PostGIS are not prefixed.</para>
13	<para>Topology support is build by default starting with PostGIS 2.0, and can be disabled specifying --without-topology configure option at build time as described in <xref linkend="postgis_installation"/></para>
14
15	<sect1 id="Topology_Types">
16        <sect1info>
17            <abstract>
18                <para>This section lists the PostgreSQL data types installed by PostGIS Topology.  Note we describe the casting behavior of these which is very
19                    important especially when designing your own functions.
20                </para>
21            </abstract>
22        </sect1info>
23        <title>Topology Types</title>
24
25		<refentry id="getfaceedges_returntype">
26		  <refnamediv>
27			<refname>getfaceedges_returntype</refname>
28			<refpurpose>
29A composite type that consists of a sequence
30number and an edge number.
31			</refpurpose>
32		  </refnamediv>
33		  <refsection>
34			<title>Description</title>
35			<para>
36A composite type that consists of a sequence number
37and an edge number.
38This is the return type for <varname>ST_GetFaceEdges</varname>
39and <varname>GetNodeEdges</varname> functions.
40			</para>
41			<orderedlist>
42			  <listitem>
43				<para><varname>sequence</varname> is an integer:  Refers to a topology defined in the topology.topology table which defines the topology schema and srid.</para>
44			  </listitem>
45			  <listitem>
46				<para><varname>edge</varname> is an integer: The identifier of an edge.</para>
47			  </listitem>
48			</orderedlist>
49		  </refsection>
50		</refentry>
51
52		<refentry id="topogeometry">
53			  <refnamediv>
54				<refname>TopoGeometry</refname>
55				<refpurpose>A composite type representing a topologically defined geometry.</refpurpose>
56			  </refnamediv>
57			  <refsection>
58				<title>Description</title>
59				<para>A composite type that refers to a topology geometry in a specific topology layer, having a specific type and a specific id. The elements of a TopoGeometry are the properties: topology_id, layer_id, id integer, type integer.</para>
60				<orderedlist>
61				  <listitem>
62					<para><varname>topology_id</varname> is an integer:  Refers to a topology defined in the topology.topology table which defines the topology schema and srid.</para>
63				  </listitem>
64				  <listitem>
65					<para><varname>layer_id</varname> is an integer: The layer_id in the layers table that the TopoGeometry belongs to.  The combination of topology_id, layer_id provides a unique reference in the topology.layers table.</para>
66				  </listitem>
67				  <listitem>
68					<para><varname>id</varname> is an integer: The id is the autogenerated sequence number that uniquely defines the topogeometry in the respective topology layer.</para>
69				  </listitem>
70				  <listitem>
71					<para><varname>type</varname> integer between 1 - 4 that defines the geometry type: 1:[multi]point, 2:[multi]line, 3:[multi]poly, 4:collection</para>
72				  </listitem>
73				</orderedlist>
74			  </refsection>
75
76			  <refsection>
77				<title>Casting Behavior</title>
78				<para>This section lists the automatic as well as explicit casts allowed for this data type</para>
79				<informaltable rowsep="1" frame="all">
80					<tgroup cols="2">
81						<tbody>
82						  <row>
83							<entry>Cast To</entry>
84							<entry>Behavior</entry>
85						  </row>
86						  <row>
87							<entry>geometry</entry>
88							<entry>automatic</entry>
89						  </row>
90						</tbody>
91					</tgroup>
92				</informaltable>
93			</refsection>
94			<!-- Optionally add a "See Also" section -->
95			<refsection>
96				<title>See Also</title>
97				<para><xref linkend="CreateTopoGeom"/></para>
98			</refsection>
99		</refentry>
100
101		<refentry id="validatetopology_returntype">
102            <refnamediv>
103                <refname>validatetopology_returntype</refname>
104                    <refpurpose>A composite type that consists of an error message and id1 and id2 to denote location of error.  This is the return type for <varname>ValidateTopology</varname>.</refpurpose>
105                </refnamediv>
106            <refsection>
107            <title>Description</title>
108            <para>A composite type that consists of an error message and two integers.  The <xref linkend="ValidateTopology" /> function returns a set of these to denote validation errors and the id1 and id2 to denote the ids of the topology objects involved in the error.</para>
109                <orderedlist>
110                  <listitem>
111                    <para><varname>error</varname> is varchar:  Denotes type of error. </para>
112                    <para>Current error descriptors are: coincident nodes, edge crosses node, edge not simple, edge end node geometry mis-match, edge start node geometry mismatch, face overlaps face,face within face,  </para>
113                  </listitem>
114                  <listitem>
115                    <para><varname>id1</varname> is an integer: Denotes identifier of edge / face / nodes in error.</para>
116                  </listitem>
117                 <listitem>
118                    <para><varname>id2</varname> is an integer: For errors that involve 2 objects denotes the secondary edge / or node</para>
119                  </listitem>
120                </orderedlist>
121
122            </refsection>
123		  <!-- Optionally add a "See Also" section -->
124            <refsection>
125                <title>See Also</title>
126                <para><xref linkend="ValidateTopology"/></para>
127            </refsection>
128		</refentry>
129	</sect1>
130
131	<sect1 id="Topology_Domains">
132        <sect1info>
133            <abstract>
134                <para>This section lists the PostgreSQL domains installed by PostGIS Topology.  Domains can be used like object types as return objects of functions or table columns. The distinction between
135                    a domain and a type is that a domain is an existing type with a check constraint bound to it.
136                </para>
137            </abstract>
138        </sect1info>
139        <title>Topology Domains</title>
140
141		<refentry id="topoelement">
142		  <refnamediv>
143			<refname>TopoElement</refname>
144			<refpurpose>An array of 2 integers generally used to identify a TopoGeometry component.</refpurpose>
145		  </refnamediv>
146		  <refsection>
147			<title>Description</title>
148			<para>
149An array of 2 integers used to represent one component of a simple or
150hierarchical <xref linkend="topogeometry" />.
151			</para>
152			<para>
153In the case of a simple TopoGeometry the first element of the array
154represents the identifier of a topological primitive and the second
155element represents its type (1:node, 2:edge, 3:face). In the case of a
156hierarchical TopoGeometry the first element of the array represents the
157identifier of a child TopoGeometry and the second element represents
158its layer identifier.
159			</para>
160
161<note><para>
162For any given hierarchical TopoGeometry all child TopoGeometry
163elements will come from the same child layer, as specified in
164the topology.layer record for the layer of the TopoGeometry
165being defined.
166</para></note>
167
168		  </refsection>
169            <refsection>
170                <title>Examples</title>
171                 <programlisting>
172SELECT te[1] AS id, te[2] AS type FROM
173( SELECT ARRAY[1,2]::topology.topoelement AS te ) f;
174 id | type
175----+------
176  1 |    2
177                 </programlisting>
178                 <programlisting>SELECT ARRAY[1,2]::topology.topoelement;
179  te
180-------
181 {1,2}
182                 </programlisting>
183                 <programlisting>
184--Example of what happens when you try to case a 3 element array to topoelement
185-- NOTE: topoement has to be a 2 element array so fails dimension check
186SELECT ARRAY[1,2,3]::topology.topoelement;
187ERROR:  value for domain topology.topoelement violates check constraint "dimensions"
188                 </programlisting>
189            </refsection>
190            <!-- Optionally add a "See Also" section -->
191            <refsection>
192                <title>See Also</title>
193                <para>
194                  <xref linkend="GetTopoGeomElements"/>,
195                  <xref linkend="topoelementarray" />,
196                  <xref linkend="topogeometry" />,
197                  <xref linkend="TopoGeom_addElement" />,
198                  <xref linkend="TopoGeom_remElement" />
199                </para>
200            </refsection>
201		</refentry>
202
203		<refentry id="topoelementarray">
204		  <refnamediv>
205			<refname>TopoElementArray</refname>
206			<refpurpose>An array of TopoElement objects.</refpurpose>
207		  </refnamediv>
208		  <refsection>
209			<title>Description</title>
210			<para>An array of 1 or more TopoElement objects, generally used to pass around components of TopoGeometry objects.</para>
211		  </refsection>
212            <refsection>
213                <title>Examples</title>
214                 <programlisting>SELECT '{{1,2},{4,3}}'::topology.topoelementarray As tea;
215  tea
216-------
217{{1,2},{4,3}}
218
219-- more verbose equivalent --
220SELECT ARRAY[ARRAY[1,2], ARRAY[4,3]]::topology.topoelementarray As tea;
221
222  tea
223-------
224{{1,2},{4,3}}
225
226--using the array agg function packaged with topology --
227SELECT topology.TopoElementArray_Agg(ARRAY[e,t]) As tea
228  FROM generate_series(1,4) As e CROSS JOIN generate_series(1,3) As t;
229  tea
230--------------------------------------------------------------------------
231{{1,1},{1,2},{1,3},{2,1},{2,2},{2,3},{3,1},{3,2},{3,3},{4,1},{4,2},{4,3}}
232                 </programlisting>
233                 <programlisting>SELECT '{{1,2,4},{3,4,5}}'::topology.topoelementarray As tea;
234ERROR:  value for domain topology.topoelementarray violates check constraint "dimensions"
235                 </programlisting>
236            </refsection>
237            <!-- Optionally add a "See Also" section -->
238            <refsection>
239                <title>See Also</title>
240                <para>
241<xref linkend="topoelement" />,
242<xref linkend="GetTopoGeomElementArray"/>,
243<xref linkend="TopoElementArray_Agg" />
244                </para>
245            </refsection>
246		</refentry>
247	</sect1>
248
249	<sect1 id="Topology_ManagementFunctions">
250	     <sect1info>
251            <abstract>
252                <para>This section lists the Topology functions for building new Topology schemas, validating topologies, and managing TopoGeometry Columns</para>
253            </abstract>
254        </sect1info>
255	    <title>Topology and TopoGeometry Management</title>
256	    <refentry id="AddTopoGeometryColumn">
257			<refnamediv>
258				<refname>AddTopoGeometryColumn</refname>
259				<refpurpose>Adds a topogeometry column to an existing table, registers this new column as a layer in topology.layer and returns the new layer_id.</refpurpose>
260			</refnamediv>
261
262            <refsynopsisdiv>
263                <funcsynopsis>
264                     <funcprototype>
265                        <funcdef>integer <function>AddTopoGeometryColumn</function></funcdef>
266                        <paramdef><type>varchar </type>
267                        <parameter>topology_name</parameter></paramdef>
268
269                        <paramdef><type>varchar </type>
270                        <parameter>schema_name</parameter></paramdef>
271
272                        <paramdef><type>varchar </type>
273                        <parameter>table_name</parameter></paramdef>
274
275                        <paramdef><type>varchar </type>
276                        <parameter>column_name</parameter></paramdef>
277
278                        <paramdef><type>varchar </type>
279                        <parameter>feature_type</parameter></paramdef>
280                    </funcprototype>
281                    <funcprototype>
282                        <funcdef>integer <function>AddTopoGeometryColumn</function></funcdef>
283
284                        <paramdef><type>varchar </type>
285                        <parameter>topology_name</parameter></paramdef>
286
287                        <paramdef><type>varchar </type>
288                        <parameter>schema_name</parameter></paramdef>
289
290                        <paramdef><type>varchar </type>
291                        <parameter>table_name</parameter></paramdef>
292
293                        <paramdef><type>varchar </type>
294                        <parameter>column_name</parameter></paramdef>
295
296                        <paramdef><type>varchar </type>
297                        <parameter>feature_type</parameter></paramdef>
298
299                        <paramdef><type>integer </type>
300                        <parameter>child_layer</parameter></paramdef>
301                    </funcprototype>
302                </funcsynopsis>
303            </refsynopsisdiv>
304
305			<refsection>
306                <title>Description</title>
307
308                <para>Each TopoGeometry object belongs to a specific Layer of a specific Topology. Before creating a TopoGeometry object you need to create its TopologyLayer.
309                    A Topology Layer is an association of a feature-table with the topology. It also contain type and hierarchy information. We create a layer using the AddTopoGeometryColumn() function: </para>
310                <para>This function will both add the requested column to the table and add a record to the topology.layer table with all the given info.</para>
311                <para>If you don't specify [child_layer] (or set it to NULL) this layer would contain Basic TopoGeometries (composed by primitive topology elements).
312                    Otherwise this layer will contain hierarchical TopoGeometries (composed by TopoGeometries from the child_layer).</para>
313
314                <para>Once the layer is created (its id is returned by the AddTopoGeometryColumn function) you're ready to construct TopoGeometry objects in it</para>
315                <para>Valid <varname>feature_type</varname>s are: POINT, LINE, POLYGON, COLLECTION</para>
316
317                <!-- use this format if new function -->
318                <para>Availability: 1.?</para>
319
320			</refsection>
321
322
323			<refsection>
324				<title>Examples</title>
325				<programlisting>-- Note for this example we created our new table in the ma_topo schema
326-- though we could have created it in a different schema -- in which case topology_name and schema_name would be different
327CREATE SCHEMA ma;
328CREATE TABLE ma.parcels(gid serial, parcel_id varchar(20) PRIMARY KEY, address text);
329SELECT topology.AddTopoGeometryColumn('ma_topo', 'ma', 'parcels', 'topo', 'POLYGON');</programlisting>
330<programlisting>
331CREATE SCHEMA ri;
332CREATE TABLE ri.roads(gid serial PRIMARY KEY, road_name text);
333SELECT topology.AddTopoGeometryColumn('ri_topo', 'ri', 'roads', 'topo', 'LINE');
334</programlisting>
335			</refsection>
336
337			<!-- Optionally add a "See Also" section -->
338			<refsection>
339				<title>See Also</title>
340
341				<para>
342				  <xref linkend="DropTopoGeometryColumn"/>,
343				  <xref linkend="toTopoGeom" />,
344				  <xref linkend="CreateTopology"/>,
345				  <xref linkend="CreateTopoGeom"/>
346				</para>
347			</refsection>
348		</refentry>
349		<refentry id="DropTopology">
350			<refnamediv>
351				<refname>DropTopology</refname>
352
353				<refpurpose>Use with caution: Drops a topology schema and deletes its reference from  topology.topology table and references to tables in that schema from the geometry_columns table.</refpurpose>
354			</refnamediv>
355
356			<refsynopsisdiv>
357				<funcsynopsis>
358					<funcprototype>
359					<funcdef>integer <function>DropTopology</function></funcdef>
360					<paramdef><type>varchar </type> <parameter>topology_schema_name</parameter></paramdef>
361					</funcprototype>
362				</funcsynopsis>
363			</refsynopsisdiv>
364
365			<refsection>
366                <title>Description</title>
367
368                <para>Drops a topology schema and deletes its reference from topology.topology table and references to tables in that schema from the geometry_columns table.
369                This function should be USED WITH CAUTION, as it could destroy data you care about.  If the schema does not exist, it just removes reference entries the named schema.</para>
370
371                <!-- use this format if new function -->
372                <para>Availability: 1.?</para>
373			</refsection>
374
375
376			<refsection>
377				<title>Examples</title>
378				<para>Cascade drops the ma_topo schema and removes all references to it in topology.topology and geometry_columns.</para>
379				<programlisting>SELECT topology.DropTopology('ma_topo');</programlisting>
380			</refsection>
381
382			<!-- Optionally add a "See Also" section -->
383			<refsection>
384				<title>See Also</title>
385
386				<para><xref linkend="DropTopoGeometryColumn"/></para>
387			</refsection>
388		</refentry>
389		<refentry id="DropTopoGeometryColumn">
390			<refnamediv>
391				<refname>DropTopoGeometryColumn</refname>
392
393				<refpurpose>Drops the topogeometry column from the table named <varname>table_name</varname> in schema <varname>schema_name</varname> and unregisters the columns from topology.layer table.</refpurpose>
394			</refnamediv>
395
396			<refsynopsisdiv>
397				<funcsynopsis>
398					<funcprototype>
399					<funcdef>text <function>DropTopoGeometryColumn</function></funcdef>
400					<paramdef><type>varchar </type> <parameter>schema_name</parameter></paramdef>
401					<paramdef><type>varchar </type> <parameter>table_name</parameter></paramdef>
402					<paramdef><type>varchar </type> <parameter>column_name</parameter></paramdef>
403					</funcprototype>
404				</funcsynopsis>
405			</refsynopsisdiv>
406
407			<refsection>
408                <title>Description</title>
409
410                <para>Drops the topogeometry column from the table named <varname>table_name</varname> in schema <varname>schema_name</varname> and unregisters the columns from topology.layer table. Returns summary
411                of drop status.  NOTE: it first sets all values to NULL before dropping to bypass referential integrity checks.</para>
412
413                <!-- use this format if new function -->
414                <para>Availability: 1.?</para>
415			</refsection>
416
417
418			<refsection>
419				<title>Examples</title>
420				<programlisting>SELECT topology.DropTopoGeometryColumn('ma_topo', 'parcel_topo', 'topo');</programlisting>
421			</refsection>
422
423			<!-- Optionally add a "See Also" section -->
424			<refsection>
425				<title>See Also</title>
426				<para><xref linkend="AddTopoGeometryColumn"/></para>
427			</refsection>
428		</refentry>
429
430		<refentry id="Populate_Topology_Layer">
431			<refnamediv>
432				<refname>Populate_Topology_Layer</refname>
433
434				<refpurpose>Adds missing entries to topology.layer table by reading metadata from topo tables.</refpurpose>
435			</refnamediv>
436
437
438			<refsynopsisdiv>
439				<funcsynopsis>
440					<funcprototype>
441					<funcdef>setof record <function>Populate_Topology_Layer</function></funcdef>
442					<paramdef></paramdef>
443					</funcprototype>
444				</funcsynopsis>
445			</refsynopsisdiv>
446
447			<refsection>
448                <title>Description</title>
449
450                <para>Adds missing entries to the <varname>topology.layer</varname> table by inspecting topology constraints on tables.
451                This function is useful for fixing up entries in topology catalog after restores of schemas with topo data.</para>
452                <para>It returns the list of entries created. Returned columns are <varname>schema_name</varname>, <varname>table_name</varname>, <varname>feature_column</varname>.</para>
453
454                <!-- use this format if new function -->
455                <para>Availability: 2.3.0</para>
456			</refsection>
457
458
459			<refsection>
460				<title>Examples</title>
461				<programlisting>SELECT CreateTopology('strk_topo');
462CREATE SCHEMA strk;
463CREATE TABLE strk.parcels(gid serial, parcel_id varchar(20) PRIMARY KEY, address text);
464SELECT topology.AddTopoGeometryColumn('strk_topo', 'strk', 'parcels', 'topo', 'POLYGON');
465-- this will return no records because this feature is already registered
466SELECT *
467  FROM topology.Populate_Topology_Layer();
468
469-- let's rebuild
470TRUNCATE TABLE topology.layer;
471
472SELECT *
473  FROM topology.Populate_Topology_Layer();
474
475SELECT topology_id,layer_id, schema_name As sn, table_name As tn, feature_column As fc
476FROM topology.layer;
477
478				</programlisting>
479				<screen> schema_name | table_name | feature_column
480-------------+------------+----------------
481 strk        | parcels    | topo
482(1 row)
483
484 topology_id | layer_id |  sn  |   tn    |  fc
485-------------+----------+------+---------+------
486           2 |        2 | strk | parcels | topo
487(1 row)</screen>
488			</refsection>
489
490			<!-- Optionally add a "See Also" section -->
491			<refsection>
492				<title>See Also</title>
493				<para><xref linkend="AddTopoGeometryColumn"/></para>
494			</refsection>
495		</refentry>
496
497		<refentry id="TopologySummary">
498			<refnamediv>
499				<refname>TopologySummary</refname>
500
501				<refpurpose>Takes a topology name and provides summary totals of types of objects in topology.</refpurpose>
502			</refnamediv>
503
504			<refsynopsisdiv>
505				<funcsynopsis>
506					<funcprototype>
507					<funcdef>text <function>TopologySummary</function></funcdef>
508					<paramdef><type>varchar </type> <parameter>topology_schema_name</parameter></paramdef>
509					</funcprototype>
510				</funcsynopsis>
511			</refsynopsisdiv>
512
513			<refsection>
514                <title>Description</title>
515
516                <para>Takes a topology name and provides summary totals of types of objects in topology.</para>
517
518                <!-- use this format if new function -->
519                <para>Availability: 2.0.0</para>
520			</refsection>
521
522
523			<refsection>
524				<title>Examples</title>
525				<programlisting>SELECT topology.topologysummary('city_data');
526                    topologysummary
527--------------------------------------------------------
528 Topology city_data (329), SRID 4326, precision: 0
529 22 nodes, 24 edges, 10 faces, 29 topogeoms in 5 layers
530 Layer 1, type Polygonal (3), 9 topogeoms
531  Deploy: features.land_parcels.feature
532 Layer 2, type Puntal (1), 8 topogeoms
533  Deploy: features.traffic_signs.feature
534 Layer 3, type Lineal (2), 8 topogeoms
535  Deploy: features.city_streets.feature
536 Layer 4, type Polygonal (3), 3 topogeoms
537  Hierarchy level 1, child layer 1
538  Deploy: features.big_parcels.feature
539 Layer 5, type Puntal (1), 1 topogeoms
540  Hierarchy level 1, child layer 2
541  Deploy: features.big_signs.feature</programlisting>
542			</refsection>
543			<!-- Optionally add a "See Also" section -->
544			<refsection>
545				<title>See Also</title>
546				<para><xref linkend="Topology_Load_Tiger" /></para>
547			</refsection>
548		</refentry>
549
550		<refentry id="ValidateTopology">
551			<refnamediv>
552				<refname>ValidateTopology</refname>
553
554				<refpurpose>Returns a set of validatetopology_returntype objects detailing issues with topology.</refpurpose>
555			</refnamediv>
556
557			<refsynopsisdiv>
558				<funcsynopsis>
559					<funcprototype>
560					<funcdef>setof validatetopology_returntype <function>ValidateTopology</function></funcdef>
561					<paramdef><type>varchar </type> <parameter>toponame</parameter></paramdef>
562					<paramdef choice="opt"><type>geometry</type> <parameter>bbox</parameter></paramdef>
563					</funcprototype>
564				</funcsynopsis>
565			</refsynopsisdiv>
566
567			<refsection>
568                <title>Description</title>
569
570                <para>
571Returns a set of <xref linkend="validatetopology_returntype"/> objects
572detailing issues with topology, optionally limiting the check to the
573area specified by the <varname>bbox</varname> parameter.
574                </para>
575
576                <para>List of possible errors and what the returned ids represent are displayed below:</para>
577
578                  <informaltable rowsep="1" frame="all">
579                    <tgroup cols="3">
580                        <thead><row><entry>Error</entry><entry>id1</entry><entry>id2</entry></row></thead>
581                        <tbody>
582                            <row>
583                                    <entry>coincident nodes</entry>
584                                    <entry>node_id</entry>
585                                    <entry>null</entry>
586                            </row>
587                            <row>
588                                    <entry>edge crosses node</entry>
589                                    <entry>edge_id</entry>
590                                    <entry>node_id</entry>
591                            </row>
592                            <row>
593                                    <entry>invalid edge</entry>
594                                    <entry>edge_id</entry>
595                                    <entry>null</entry>
596                            </row>
597                            <row>
598                                    <entry>edge not simple</entry>
599                                    <entry>edge_id</entry>
600                                    <entry>null</entry>
601                            </row>
602                            <row>
603                                    <entry>edge crosses edge</entry>
604                                    <entry>edge_id</entry>
605                                    <entry>edge_id</entry>
606                            </row>
607                            <row>
608                                    <entry>edge start node geometry mis-match</entry>
609                                    <entry>edge_id</entry>
610                                    <entry>node_id</entry>
611                            </row>
612                            <row>
613                                    <entry>edge end node geometry mis-match</entry>
614                                    <entry>edge_id</entry>
615                                    <entry>node_id</entry>
616                            </row>
617                            <row>
618                                    <entry>face without edges</entry>
619                                    <entry>face_id</entry>
620                                    <entry>null</entry>
621                            </row>
622                            <row>
623                                    <entry>face has no rings</entry>
624                                    <entry>face_id</entry>
625                                    <entry>null</entry>
626                            </row>
627                            <row>
628                                    <entry>face has wrong mbr</entry>
629                                    <entry>face_id</entry>
630                                    <entry>null</entry>
631                            </row>
632                            <row>
633                                    <entry>hole not in advertised face</entry>
634                                    <entry>signed edge_id identifying the ring</entry>
635                                    <entry>null</entry>
636                            </row>
637                            <row>
638                                    <entry>not-isolated node has not-null containing_face</entry>
639                                    <entry>node_id</entry>
640                                    <entry>null</entry>
641                            </row>
642                            <row>
643                                    <entry>isolated node has null containing_face</entry>
644                                    <entry>node_id</entry>
645                                    <entry>null</entry>
646                            </row>
647                            <row>
648                                    <entry>isolated node has wrong containing_face</entry>
649                                    <entry>node_id</entry>
650                                    <entry>null</entry>
651                            </row>
652                            <row>
653                                    <entry>invalid next_right_edge</entry>
654                                    <entry>edge_id</entry>
655                                    <entry>null</entry>
656                            </row>
657                            <row>
658                                    <entry>invalid next_left_edge</entry>
659                                    <entry>edge_id</entry>
660                                    <entry>null</entry>
661                            </row>
662                            <row>
663                                    <entry>mixed face labeling in ring</entry>
664                                    <entry>signed edge_id identifying the ring</entry>
665                                    <entry>null</entry>
666                            </row>
667                            <row>
668                                    <entry>non-closed ring</entry>
669                                    <entry>signed edge_id identifying the ring</entry>
670                                    <entry>null</entry>
671                            </row>
672                            <row>
673                                    <entry>face has multiple shells</entry>
674                                    <entry>face_id</entry>
675                                    <entry>signed edge_id identifying the ring</entry>
676                            </row>
677                            <row>
678                                    <entry>face overlaps face</entry>
679                                    <entry>face_id</entry>
680                                    <entry>face_id</entry>
681                            </row>
682                            <row>
683                                    <entry>face within face</entry>
684                                    <entry>inner face_id</entry>
685                                    <entry>outer face_id</entry>
686                            </row>
687                            <row>
688                                    <entry>invalid next_left_edge</entry>
689                                    <entry>edge_id</entry>
690                                    <entry>expected next_left_edge value</entry>
691                            </row>
692                            <row>
693                                    <entry>invalid next_right_edge</entry>
694                                    <entry>edge_id</entry>
695                                    <entry>expected next_right_edge value</entry>
696                            </row>
697                         </tbody>
698                        </tgroup>
699                    </informaltable>
700
701                <!-- use this format if new function -->
702                <para>Availability: 1.0.0</para>
703	<!-- use this format if not a new function but functionality enhanced -->
704                <para>Enhanced: 2.0.0 more efficient edge crossing detection and fixes for false positives that were existent in prior versions.</para>
705                <para>Changed: 2.2.0 values for id1 and id2 were swapped for 'edge crosses node' to be consistent with error description.</para>
706                <para>Changed: 3.2.0 added optional bbox parameter, perform face labeling and edge linking checks.</para>
707			</refsection>
708
709
710			<refsection>
711				<title>Examples</title>
712				<programlisting>SELECT * FROM  topology.ValidateTopology('ma_topo');
713      error        | id1 | id2
714-------------------+-----+-----
715face without edges |   1 |
716				</programlisting>
717			</refsection>
718
719			<!-- Optionally add a "See Also" section -->
720			<refsection>
721				<title>See Also</title>
722				<para><xref linkend="validatetopology_returntype"/>, <xref linkend="Topology_Load_Tiger" /></para>
723			</refsection>
724		</refentry>
725
726		<refentry id="ValidateTopologyRelation">
727			<refnamediv>
728				<refname>ValidateTopologyRelation</refname>
729
730				<refpurpose>Returns info about invalid topology relation records</refpurpose>
731			</refnamediv>
732
733			<refsynopsisdiv>
734				<funcsynopsis>
735					<funcprototype>
736					<funcdef>setof record <function>ValidateTopologyRelation</function></funcdef>
737					<paramdef><type>varchar </type> <parameter>toponame</parameter></paramdef>
738					</funcprototype>
739				</funcsynopsis>
740			</refsynopsisdiv>
741
742			<refsection>
743                <title>Description</title>
744
745                <para>
746Returns a set records giving information about invalidities in the
747relation table of the topology.
748                </para>
749
750                <!-- use this format if new function -->
751                <para>Availability: 3.2.0</para>
752			</refsection>
753
754
755			<!-- Optionally add a "See Also" section -->
756			<refsection>
757				<title>See Also</title>
758				<para><xref linkend="ValidateTopology"/></para>
759			</refsection>
760		</refentry>
761
762		<refentry id="FindTopology">
763			<refnamediv>
764				<refname>FindTopology</refname>
765
766				<refpurpose>Returns a topology record by different means.</refpurpose>
767			</refnamediv>
768
769			<refsynopsisdiv>
770				<funcsynopsis>
771					<funcprototype>
772                        <funcdef>topology <function>FindTopology</function></funcdef>
773                        <paramdef><type>TopoGeometry</type> <parameter>topogeom</parameter></paramdef>
774					</funcprototype>
775					<funcprototype>
776                        <funcdef>topology <function>FindTopology</function></funcdef>
777                        <paramdef><type>regclass</type> <parameter>layerTable</parameter></paramdef>
778                        <paramdef><type>name</type> <parameter>layerColumn</parameter></paramdef>
779					</funcprototype>
780					<funcprototype>
781                        <funcdef>topology <function>FindTopology</function></funcdef>
782                        <paramdef><type>name</type> <parameter>layerSchema</parameter></paramdef>
783                        <paramdef><type>name</type> <parameter>layerTable</parameter></paramdef>
784                        <paramdef><type>name</type> <parameter>layerColumn</parameter></paramdef>
785					</funcprototype>
786					<funcprototype>
787                        <funcdef>topology <function>FindTopology</function></funcdef>
788                        <paramdef><type>text</type> <parameter>topoName</parameter></paramdef>
789					</funcprototype>
790					<funcprototype>
791                        <funcdef>topology <function>FindTopology</function></funcdef>
792                        <paramdef><type>int</type> <parameter>id</parameter></paramdef>
793					</funcprototype>
794				</funcsynopsis>
795			</refsynopsisdiv>
796
797			<refsection>
798                <title>Description</title>
799
800                <para>Takes a topology identifier or the identifier of
801a topology-related object and returns a topology.topology record.</para>
802
803                <!-- use this format if new function -->
804                <para>Availability: 3.2.0</para>
805			</refsection>
806
807
808			<refsection>
809				<title>Examples</title>
810<programlisting>
811SELECT name(findTopology('features.land_parcels', 'feature'));
812   name
813-----------
814 city_data
815(1 row)
816</programlisting>
817			</refsection>
818			<!-- Optionally add a "See Also" section -->
819		</refentry>
820	</sect1>
821
822	<sect1 id="Topology_StatsManagement"
823           xreflabel="maintaining statistics during topology editing and population" >
824	     <sect1info>
825            <abstract>
826                <para>
827This section discusses management of database statistics during
828topology building.
829                </para>
830            </abstract>
831        </sect1info>
832	    <title>Topology Statistics Management</title>
833
834<para>
835Adding elements to a topology triggers many database queries for
836finding existing edges that will be split, adding nodes and
837updating edges that will node with the new linework. For this reason
838it is useful that statistics about the data in the topology tables
839are up-to-date.
840</para>
841
842<para>
843PostGIS Topology population and editing functions do not automatically
844update the statistics because a updating stats after each and every
845change in a topology would be overkill, so it is the caller's duty
846to take care of that.
847</para>
848
849<note>
850<para>
851That the statistics updated by autovacuum
852will NOT be visible to transactions which started before autovacuum
853process completed, so long-running transactions will need to run
854ANALYZE themselves, to use updated statistics.
855</para>
856</note>
857
858	</sect1>
859
860	<sect1 id="Topology_Constructors">
861    <sect1info>
862        <abstract>
863            <para>This section covers the topology functions for creating new topologies.</para>
864        </abstract>
865    </sect1info>
866	  <title>Topology Constructors</title>
867
868		<refentry id="CreateTopology">
869			<refnamediv>
870				<refname>CreateTopology</refname>
871				<refpurpose>Creates a new topology schema and registers this new schema in the topology.topology table.</refpurpose>
872			</refnamediv>
873
874			<refsynopsisdiv>
875				<funcsynopsis>
876					<funcprototype>
877						<funcdef>integer <function>CreateTopology</function></funcdef>
878						<paramdef><type>varchar </type> <parameter>topology_schema_name</parameter></paramdef>
879					</funcprototype>
880
881					<funcprototype>
882						<funcdef>integer <function>CreateTopology</function></funcdef>
883						<paramdef><type>varchar </type> <parameter>topology_schema_name</parameter></paramdef>
884						<paramdef><type>integer </type> <parameter>srid</parameter></paramdef>
885					</funcprototype>
886
887					<funcprototype>
888						<funcdef>integer <function>CreateTopology</function></funcdef>
889						<paramdef><type>varchar </type> <parameter>topology_schema_name</parameter></paramdef>
890						<paramdef><type>integer </type> <parameter>srid</parameter></paramdef>
891						<paramdef><type>double precision </type> <parameter>prec</parameter></paramdef>
892					</funcprototype>
893
894					<funcprototype>
895						<funcdef>integer <function>CreateTopology</function></funcdef>
896						<paramdef><type>varchar </type> <parameter>topology_schema_name</parameter></paramdef>
897						<paramdef><type>integer </type> <parameter>srid</parameter></paramdef>
898						<paramdef><type>double precision </type> <parameter>prec</parameter></paramdef>
899						<paramdef><type>boolean </type> <parameter>hasz</parameter></paramdef>
900					</funcprototype>
901				</funcsynopsis>
902			</refsynopsisdiv>
903
904			<refsection>
905                <title>Description</title>
906
907                <para>Creates a new schema with name <varname>topology_name</varname> consisting of tables (<varname>edge_data</varname>,<varname>face</varname>,<varname>node</varname>, <varname>relation</varname>
908                    and registers this new topology in the topology.topology table. It returns the id of the topology in the topology table. The srid is the spatial reference identified as
909                defined in spatial_ref_sys table for that topology.  Topologies must be uniquely named.  The tolerance is measured in the units of the spatial reference system.  If the tolerance (<varname>prec</varname>) is not specified defaults to 0.</para>
910
911                <para>This is similar to the SQL/MM <xref linkend="ST_InitTopoGeo" /> but a bit more functional.  <varname>hasz</varname> defaults to false if not specified.</para>
912
913                <!-- use this format if new function -->
914                <para>Availability: 1.?</para>
915			</refsection>
916
917
918			<refsection>
919				<title>Examples</title>
920				<para>This example creates a new schema called ma_topo that will store edges, faces, and relations in Massachusetts State Plane meters.
921					The tolerance represents 1/2 meter since the spatial reference system is a meter based spatial reference system</para>
922				<programlisting>SELECT topology.CreateTopology('ma_topo',26986, 0.5);</programlisting>
923
924				<para>Create Rhode Island topology in State Plane ft</para>
925<programlisting>SELECT topology.CreateTopology('ri_topo',3438) As topoid;
926topoid
927------
9282</programlisting>
929			</refsection>
930
931			<!-- Optionally add a "See Also" section -->
932			<refsection>
933				<title>See Also</title>
934
935				<para><xref linkend="spatial_ref_sys"/>, <xref linkend="ST_InitTopoGeo" />, <xref linkend="Topology_Load_Tiger" /></para>
936			</refsection>
937		</refentry>
938
939		<refentry id="CopyTopology">
940			<refnamediv>
941				<refname>CopyTopology</refname>
942				<refpurpose>Makes a copy of a topology structure (nodes, edges, faces, layers and TopoGeometries).</refpurpose>
943			</refnamediv>
944
945			<refsynopsisdiv>
946				<funcsynopsis>
947					<funcprototype>
948						<funcdef>integer <function>CopyTopology</function></funcdef>
949						<paramdef><type>varchar </type> <parameter>existing_topology_name</parameter></paramdef>
950						<paramdef><type>varchar </type> <parameter>new_name</parameter></paramdef>
951					</funcprototype>
952				</funcsynopsis>
953			</refsynopsisdiv>
954
955			<refsection>
956                <title>Description</title>
957
958                <para>
959Creates a new topology with name <varname>new_topology_name</varname> and SRID and precision taken from <varname>existing_topology_name</varname>, copies all nodes, edges and faces in there, copies layers and their TopoGeometries too.
960		</para>
961
962                <note><para>
963The new rows in topology.layer will contain synthesized values for schema_name, table_name and feature_column. This is because the TopoGeometry will only exist as a definition but won't be available in any user-level table yet.
964		</para></note>
965
966                <!-- use this format if new function -->
967                <para>Availability: 2.0.0</para>
968			</refsection>
969
970
971			<refsection>
972				<title>Examples</title>
973				<para>
974This example makes a backup of a topology called ma_topo
975				</para>
976				<programlisting>SELECT topology.CopyTopology('ma_topo', 'ma_topo_bakup');</programlisting>
977
978			</refsection>
979
980			<!-- Optionally add a "See Also" section -->
981			<refsection>
982				<title>See Also</title>
983
984				<para><xref linkend="spatial_ref_sys"/>, <xref linkend="CreateTopology" /></para>
985			</refsection>
986		</refentry>
987
988		<refentry id="ST_InitTopoGeo">
989			<refnamediv>
990				<refname>ST_InitTopoGeo</refname>
991				<refpurpose>Creates a new topology schema and registers this new schema in the topology.topology table and details summary of process.</refpurpose>
992			</refnamediv>
993
994			<refsynopsisdiv>
995				<funcsynopsis>
996					<funcprototype>
997						<funcdef>text <function>ST_InitTopoGeo</function></funcdef>
998						<paramdef><type>varchar </type> <parameter>topology_schema_name</parameter></paramdef>
999					</funcprototype>
1000				</funcsynopsis>
1001			</refsynopsisdiv>
1002
1003			<refsection>
1004                <title>Description</title>
1005
1006                <para>This is an SQL-MM equivalent of CreateTopology but lacks the spatial reference and tolerance options of CreateTopology and outputs a text description of creation instead of topology id.</para>
1007
1008                <!-- use this format if new function -->
1009                <para>Availability: 1.?</para>
1010                <para>&sqlmm_compliant; SQL-MM 3 Topo-Geo and Topo-Net 3: Routine Details: X.3.17</para>
1011			</refsection>
1012
1013
1014			<refsection>
1015				<title>Examples</title>
1016				<programlisting>SELECT topology.ST_InitTopoGeo('topo_schema_to_create') AS topocreation;
1017                      astopocreation
1018------------------------------------------------------------
1019 Topology-Geometry 'topo_schema_to_create' (id:7) created.
1020				</programlisting>
1021			</refsection>
1022
1023			<!-- Optionally add a "See Also" section -->
1024			<refsection>
1025				<title>See Also</title>
1026
1027				<para><xref linkend="CreateTopology"/></para>
1028			</refsection>
1029		</refentry>
1030
1031
1032		<refentry id="ST_CreateTopoGeo">
1033			<refnamediv>
1034				<refname>ST_CreateTopoGeo</refname>
1035
1036				<refpurpose>
1037Adds a collection of geometries to a given empty topology and returns a message detailing success.
1038				</refpurpose>
1039			</refnamediv>
1040
1041			<refsynopsisdiv>
1042				<funcsynopsis>
1043					<funcprototype>
1044					<funcdef>text <function>ST_CreateTopoGeo</function></funcdef>
1045					<paramdef><type>varchar </type> <parameter>atopology</parameter></paramdef>
1046					<paramdef><type>geometry </type> <parameter>acollection</parameter></paramdef>
1047					</funcprototype>
1048				</funcsynopsis>
1049			</refsynopsisdiv>
1050
1051			<refsection>
1052                <title>Description</title>
1053
1054                <para>
1055Adds a collection of geometries to a given empty topology and returns a message detailing success.
1056                </para>
1057
1058				<para>Useful for populating an empty topology.</para>
1059
1060
1061                <!-- use this format if new function -->
1062                <para>Availability: 2.0 </para>
1063	<para>&sqlmm_compliant; SQL-MM: Topo-Geo and Topo-Net 3: Routine Details -- X.3.18</para>
1064			</refsection>
1065
1066
1067			<refsection>
1068				<title>Examples</title>
1069				<programlisting>
1070-- Populate topology --
1071SELECT topology.ST_CreateTopoGeo('ri_topo',
1072 ST_GeomFromText('MULTILINESTRING((384744 236928,384750 236923,384769 236911,384799 236895,384811 236890,384833 236884,
1073  384844 236882,384866 236881,384879 236883,384954 236898,385087 236932,385117 236938,
1074  385167 236938,385203 236941,385224 236946,385233 236950,385241 236956,385254 236971,
1075  385260 236979,385268 236999,385273 237018,385273 237037,385271 237047,385267 237057,
1076  385225 237125,385210 237144,385192 237161,385167 237192,385162 237202,385159 237214,
1077  385159 237227,385162 237241,385166 237256,385196 237324,385209 237345,385234 237375,
1078  385237 237383,385238 237399,385236 237407,385227 237419,385213 237430,385193 237439,
1079  385174 237451,385170 237455,385169 237460,385171 237475,385181 237503,385190 237521,
1080  385200 237533,385206 237538,385213 237541,385221 237542,385235 237540,385242 237541,
1081  385249 237544,385260 237555,385270 237570,385289 237584,385292 237589,385291 237596,385284 237630))',3438)
1082  );
1083
1084      st_createtopogeo
1085----------------------------
1086 Topology ri_topo populated
1087
1088
1089-- create tables and topo geometries --
1090CREATE TABLE ri.roads(gid serial PRIMARY KEY, road_name text);
1091
1092SELECT topology.AddTopoGeometryColumn('ri_topo', 'ri', 'roads', 'topo', 'LINE');
1093				</programlisting>
1094			</refsection>
1095
1096			<!-- Optionally add a "See Also" section -->
1097			<refsection>
1098				<title>See Also</title>
1099				<para><xref linkend="AddTopoGeometryColumn"/>, <xref linkend="CreateTopology"/>, <xref linkend="DropTopology"/></para>
1100			</refsection>
1101		</refentry>
1102
1103		<refentry id="TopoGeo_AddPoint">
1104			<refnamediv>
1105				<refname>TopoGeo_AddPoint</refname>
1106
1107				<refpurpose>
1108Adds a point to an existing topology using a tolerance and possibly splitting an existing edge.
1109				</refpurpose>
1110			</refnamediv>
1111
1112			<refsynopsisdiv>
1113				<funcsynopsis>
1114					<funcprototype>
1115						<funcdef>integer <function>TopoGeo_AddPoint</function></funcdef>
1116						<paramdef><type>varchar </type> <parameter>atopology</parameter></paramdef>
1117						<paramdef><type>geometry </type> <parameter>apoint</parameter></paramdef>
1118						<paramdef choice="opt"><type>float8 </type> <parameter>tolerance</parameter></paramdef>
1119					</funcprototype>
1120				</funcsynopsis>
1121			</refsynopsisdiv>
1122
1123			<refsection>
1124                <title>Description</title>
1125
1126                <para>
1127Adds a point to an existing topology and returns its identifier.
1128The given point will snap to existing nodes or edges within given tolerance.
1129An existing edge may be split by the snapped point.
1130                </para>
1131
1132                <!-- use this format if new function -->
1133                <para>Availability: 2.0.0</para>
1134			</refsection>
1135
1136
1137			<!-- Optionally add a "See Also" section -->
1138			<refsection>
1139				<title>See Also</title>
1140				<para>
1141<xref linkend="TopoGeo_AddLineString"/>,
1142<xref linkend="TopoGeo_AddPolygon"/>,
1143<xref linkend="AddNode"/>,
1144<xref linkend="CreateTopology"/>
1145</para>
1146			</refsection>
1147		</refentry>
1148
1149		<refentry id="TopoGeo_AddLineString">
1150			<refnamediv>
1151				<refname>TopoGeo_AddLineString</refname>
1152
1153				<refpurpose>Adds a linestring to an existing topology using a tolerance and possibly splitting existing edges/faces. Returns edge identifiers.</refpurpose>
1154			</refnamediv>
1155
1156			<refsynopsisdiv>
1157				<funcsynopsis>
1158					<funcprototype>
1159						<funcdef>SETOF integer <function>TopoGeo_AddLineString</function></funcdef>
1160						<paramdef><type>varchar </type> <parameter>atopology</parameter></paramdef>
1161						<paramdef><type>geometry </type> <parameter>aline</parameter></paramdef>
1162						<paramdef choice="opt"><type>float8 </type> <parameter>tolerance</parameter></paramdef>
1163					</funcprototype>
1164				</funcsynopsis>
1165			</refsynopsisdiv>
1166
1167			<refsection>
1168                <title>Description</title>
1169
1170                <para>
1171Adds a linestring to an existing topology and returns a set of edge identifiers forming it up.
1172The given line will snap to existing nodes or edges within given tolerance.
1173Existing edges and faces may be split by the line.
1174                </para>
1175
1176                <note><para>
1177Updating statistics about topologies being loaded via this function is
1178up to caller, see <xref linkend="Topology_StatsManagement"/>.
1179                </para></note>
1180
1181                <!-- use this format if new function -->
1182                <para>Availability: 2.0.0</para>
1183			</refsection>
1184
1185
1186			<!-- Optionally add a "See Also" section -->
1187			<refsection>
1188				<title>See Also</title>
1189				<para>
1190<xref linkend="TopoGeo_AddPoint"/>,
1191<xref linkend="TopoGeo_AddPolygon"/>,
1192<xref linkend="AddEdge"/>,
1193<xref linkend="CreateTopology"/>
1194				</para>
1195			</refsection>
1196		</refentry>
1197
1198		<refentry id="TopoGeo_AddPolygon">
1199			<refnamediv>
1200				<refname>TopoGeo_AddPolygon</refname>
1201
1202				<refpurpose>Adds a polygon to an existing topology using a tolerance and possibly splitting existing edges/faces. Returns face identifiers.</refpurpose>
1203			</refnamediv>
1204
1205			<refsynopsisdiv>
1206				<funcsynopsis>
1207					<funcprototype>
1208						<funcdef>SETOF integer <function>TopoGeo_AddPolygon</function></funcdef>
1209						<paramdef><type>varchar </type> <parameter>atopology</parameter></paramdef>
1210						<paramdef><type>geometry </type> <parameter>apoly</parameter></paramdef>
1211						<paramdef choice="opt"><type>float8 </type> <parameter>tolerance</parameter></paramdef>
1212					</funcprototype>
1213				</funcsynopsis>
1214			</refsynopsisdiv>
1215
1216			<refsection>
1217                <title>Description</title>
1218
1219                <para>
1220Adds a polygon to an existing topology and returns a set of face identifiers forming it up.
1221The boundary of the given polygon will snap to existing nodes or edges within given tolerance.
1222Existing edges and faces may be split by the boundary of the new polygon.
1223                </para>
1224
1225                <note><para>
1226Updating statistics about topologies being loaded via this function is
1227up to caller, see <xref linkend="Topology_StatsManagement"/>.
1228                </para></note>
1229
1230                <!-- use this format if new function -->
1231                <para>Availability: 2.0.0</para>
1232			</refsection>
1233
1234
1235			<!-- Optionally add a "See Also" section -->
1236			<refsection>
1237				<title>See Also</title>
1238				<para>
1239<xref linkend="TopoGeo_AddPoint"/>,
1240<xref linkend="TopoGeo_AddLineString"/>,
1241<xref linkend="AddFace"/>,
1242<xref linkend="CreateTopology"/>
1243				</para>
1244			</refsection>
1245		</refentry>
1246
1247
1248	</sect1>
1249
1250	<sect1 id="Topology_Editing">
1251	    <sect1info>
1252            <abstract>
1253                <para>This section covers topology functions for adding, moving, deleting, and splitting edges, faces, and nodes. All of these functions are defined by ISO SQL/MM.</para>
1254            </abstract>
1255        </sect1info>
1256	    <title>Topology Editors</title>
1257
1258		<refentry id="ST_AddIsoNode">
1259			<refnamediv>
1260				<refname>ST_AddIsoNode</refname>
1261
1262				<refpurpose>Adds an isolated node to a face in a topology and returns the nodeid of the new node. If face is null, the node is still created.</refpurpose>
1263			</refnamediv>
1264
1265			<refsynopsisdiv>
1266				<funcsynopsis>
1267					<funcprototype>
1268					<funcdef>integer <function>ST_AddIsoNode</function></funcdef>
1269					<paramdef><type>varchar </type> <parameter>atopology</parameter></paramdef>
1270					<paramdef><type>integer </type> <parameter>aface</parameter></paramdef>
1271					<paramdef><type>geometry </type> <parameter>apoint</parameter></paramdef>
1272					</funcprototype>
1273				</funcsynopsis>
1274			</refsynopsisdiv>
1275
1276			<refsection>
1277                <title>Description</title>
1278
1279                <para>Adds an isolated node with point location <varname>apoint</varname> to an existing face with faceid <varname>aface</varname> to a topology <varname>atopology</varname> and returns the nodeid of the new node.</para>
1280                <para>If the spatial reference system (srid) of the point geometry is not the same as the topology, the <varname>apoint</varname> is not a point geometry, the point is null, or the point intersects an existing edge
1281                    (even at the boundaries) then an exception is thrown. If the point already exists as a node, an exception is thrown.</para>
1282                <para>If <varname>aface</varname> is not null and the <varname>apoint</varname> is not within the face, then an exception is thrown.</para>
1283
1284                <!-- use this format if new function -->
1285                <para>Availability: 1.? </para>
1286	<para>&sqlmm_compliant; SQL-MM: Topo-Net Routines:  X+1.3.1</para>
1287			</refsection>
1288
1289
1290			<refsection>
1291				<title>Examples</title>
1292				<para/>
1293				 <!-- TODO -->
1294			</refsection>
1295
1296			<!-- Optionally add a "See Also" section -->
1297			<refsection>
1298				<title>See Also</title>
1299				<para><xref linkend="AddNode"/>, <xref linkend="CreateTopology"/>, <xref linkend="DropTopology"/>, <xref linkend="ST_Intersects"/></para>
1300			</refsection>
1301		</refentry>
1302
1303		<refentry id="ST_AddIsoEdge">
1304			<refnamediv>
1305				<refname>ST_AddIsoEdge</refname>
1306
1307				<refpurpose>Adds an isolated edge defined by geometry <varname>alinestring</varname> to a topology connecting two existing isolated nodes <varname>anode</varname> and <varname>anothernode</varname> and returns the edge id of the new edge.</refpurpose>
1308			</refnamediv>
1309
1310			<refsynopsisdiv>
1311				<funcsynopsis>
1312					<funcprototype>
1313					<funcdef>integer <function>ST_AddIsoEdge</function></funcdef>
1314					<paramdef><type>varchar </type> <parameter>atopology</parameter></paramdef>
1315					<paramdef><type>integer </type> <parameter>anode</parameter></paramdef>
1316					<paramdef><type>integer </type> <parameter>anothernode</parameter></paramdef>
1317					<paramdef><type>geometry </type> <parameter>alinestring</parameter></paramdef>
1318					</funcprototype>
1319				</funcsynopsis>
1320			</refsynopsisdiv>
1321
1322			<refsection>
1323                <title>Description</title>
1324
1325                <para>Adds an isolated edge defined by geometry <varname>alinestring</varname> to a topology connecting two existing isolated nodes <varname>anode</varname> and <varname>anothernode</varname> and returns the edge id of the new edge.</para>
1326                <para>If the spatial reference system (srid) of the <varname>alinestring</varname> geometry is not the same as the topology, any of the input arguments are null, or the nodes are contained in more than one face, or the nodes are start or end nodes of an existing edge,
1327                    then an exception is thrown.</para>
1328                <para>If the <varname>alinestring</varname> is not within the face of the face the <varname>anode</varname> and <varname>anothernode</varname> belong to, then an exception is thrown.</para>
1329                <para>If the <varname>anode</varname> and <varname>anothernode</varname> are not the start and end points of the <varname>alinestring</varname> then an exception is thrown.</para>
1330
1331                <!-- use this format if new function -->
1332                <para>Availability: 1.? </para>
1333	<para>&sqlmm_compliant; SQL-MM: Topo-Geo and Topo-Net 3: Routine Details:  X.3.4</para>
1334			</refsection>
1335
1336
1337			<refsection>
1338				<title>Examples</title>
1339				<para/>
1340				 <!-- TODO -->
1341			</refsection>
1342
1343			<!-- Optionally add a "See Also" section -->
1344			<refsection>
1345				<title>See Also</title>
1346				<para><xref linkend="ST_AddIsoNode"/>,  <xref linkend="ST_IsSimple"/>, <xref linkend="ST_Within"/></para>
1347			</refsection>
1348		</refentry>
1349
1350		  <refentry id="ST_AddEdgeNewFaces">
1351			<refnamediv>
1352				<refname>ST_AddEdgeNewFaces</refname>
1353
1354				<refpurpose>Add a new edge and, if in doing so it splits a face, delete the original face and replace it with two new faces.</refpurpose>
1355			</refnamediv>
1356
1357			<refsynopsisdiv>
1358				<funcsynopsis>
1359					<funcprototype>
1360					<funcdef>integer <function>ST_AddEdgeNewFaces</function></funcdef>
1361					<paramdef><type>varchar </type> <parameter>atopology</parameter></paramdef>
1362					<paramdef><type>integer </type> <parameter>anode</parameter></paramdef>
1363					<paramdef><type>integer </type> <parameter>anothernode</parameter></paramdef>
1364					<paramdef><type>geometry </type> <parameter>acurve</parameter></paramdef>
1365					</funcprototype>
1366				</funcsynopsis>
1367			</refsynopsisdiv>
1368
1369			<refsection>
1370                <title>Description</title>
1371
1372                <para>
1373Add a new edge and, if in doing so it splits a face, delete the original
1374face and replace it with two new faces.
1375Returns the id of the newly added edge.
1376		</para>
1377
1378                <para>
1379Updates all existing joined edges and relationships accordingly.
1380		</para>
1381
1382                <para>If any arguments are null, the given nodes are unknown (must already exist in the <varname>node</varname> table of the topology schema) ,
1383                    the <varname>acurve</varname> is not a <varname>LINESTRING</varname>, the <varname>anode</varname> and <varname>anothernode</varname> are not the start
1384                    and endpoints of <varname>acurve</varname> then an error is thrown.</para>
1385                <para>If the spatial reference system (srid) of the <varname>acurve</varname> geometry is not the same as the topology an exception is thrown.</para>
1386
1387                <!-- use this format if new function -->
1388                <para>Availability: 2.0 </para>
1389                <para>&sqlmm_compliant; SQL-MM: Topo-Geo and Topo-Net 3: Routine Details:  X.3.12</para>
1390			</refsection>
1391
1392
1393			<refsection>
1394				<title>Examples</title>
1395				<para/>
1396				<!--TODO: Need examples -->
1397			</refsection>
1398
1399			<!-- Optionally add a "See Also" section -->
1400			<refsection>
1401				<title>See Also</title>
1402				<para><xref linkend="ST_RemEdgeNewFace"/></para>
1403				<para><xref linkend="ST_AddEdgeModFace"/></para>
1404			</refsection>
1405		</refentry>
1406
1407		  <refentry id="ST_AddEdgeModFace">
1408			<refnamediv>
1409				<refname>ST_AddEdgeModFace</refname>
1410
1411				<refpurpose>Add a new edge and, if in doing so it splits a face, modify the original face and add a new face.</refpurpose>
1412			</refnamediv>
1413
1414			<refsynopsisdiv>
1415				<funcsynopsis>
1416					<funcprototype>
1417					<funcdef>integer <function>ST_AddEdgeModFace</function></funcdef>
1418					<paramdef><type>varchar </type> <parameter>atopology</parameter></paramdef>
1419					<paramdef><type>integer </type> <parameter>anode</parameter></paramdef>
1420					<paramdef><type>integer </type> <parameter>anothernode</parameter></paramdef>
1421					<paramdef><type>geometry </type> <parameter>acurve</parameter></paramdef>
1422					</funcprototype>
1423				</funcsynopsis>
1424			</refsynopsisdiv>
1425
1426			<refsection>
1427                <title>Description</title>
1428
1429                <para>
1430Add a new edge and, if doing so splits a face, modify the original
1431face and add a new one.
1432                </para>
1433
1434<note><para>
1435If possible, the new face will be created on left side of the new edge.
1436This will not be possible if the face on the left side will need to
1437be the Universe face (unbounded).
1438</para></note>
1439
1440    <para>
1441Returns the id of the newly added edge.
1442		</para>
1443
1444    <para>
1445Updates all existing joined edges and relationships accordingly.
1446		</para>
1447
1448                <para>If any arguments are null, the given nodes are unknown (must already exist in the <varname>node</varname> table of the topology schema) ,
1449                    the <varname>acurve</varname> is not a <varname>LINESTRING</varname>, the <varname>anode</varname> and <varname>anothernode</varname> are not the start
1450                    and endpoints of <varname>acurve</varname> then an error is thrown.</para>
1451                <para>If the spatial reference system (srid) of the <varname>acurve</varname> geometry is not the same as the topology an exception is thrown.</para>
1452                <!-- use this format if new function -->
1453                <para>Availability: 2.0 </para>
1454                <para>&sqlmm_compliant; SQL-MM: Topo-Geo and Topo-Net 3: Routine Details:  X.3.13</para>
1455			</refsection>
1456
1457
1458			<refsection>
1459				<title>Examples</title>
1460				<para/>
1461				<!--TODO: Need examples -->
1462			</refsection>
1463
1464			<!-- Optionally add a "See Also" section -->
1465			<refsection>
1466				<title>See Also</title>
1467				<para><xref linkend="ST_RemEdgeModFace"/></para>
1468				<para><xref linkend="ST_AddEdgeNewFaces"/></para>
1469			</refsection>
1470		</refentry>
1471
1472    <refentry id="ST_RemEdgeNewFace">
1473			<refnamediv>
1474				<refname>ST_RemEdgeNewFace</refname>
1475
1476				<refpurpose>
1477Removes an edge and, if the removed edge separated two faces,
1478delete the original faces and replace them with a new face.
1479        </refpurpose>
1480			</refnamediv>
1481
1482			<refsynopsisdiv>
1483				<funcsynopsis>
1484					<funcprototype>
1485					<funcdef>integer <function>ST_RemEdgeNewFace</function></funcdef>
1486					<paramdef><type>varchar </type> <parameter>atopology</parameter></paramdef>
1487					<paramdef><type>integer </type> <parameter>anedge</parameter></paramdef>
1488					</funcprototype>
1489				</funcsynopsis>
1490			</refsynopsisdiv>
1491
1492			<refsection>
1493                <title>Description</title>
1494
1495                <para>
1496Removes an edge and, if the removed edge separated two faces,
1497delete the original faces and replace them with a new face.
1498		            </para>
1499
1500                <para>
1501Returns the id of a newly created face or NULL, if no new face is created.
1502No new face is created when the removed edge is dangling or isolated or
1503confined with the universe face (possibly making the universe flood into
1504the face on the other side).
1505		            </para>
1506
1507                <para>
1508Updates all existing joined edges and relationships accordingly.
1509		            </para>
1510
1511                <para>
1512Refuses to remove an edge participating in the definition of an
1513existing TopoGeometry.
1514Refuses to heal two faces if any TopoGeometry is defined by only
1515one of them (and not the other).
1516		            </para>
1517
1518                <para>
1519If any arguments are null, the given edge is unknown (must already exist in
1520the <varname>edge</varname> table of the topology schema), the topology
1521name is invalid then an error is thrown.
1522                </para>
1523
1524                <!-- use this format if new function -->
1525                <para>Availability: 2.0 </para>
1526                <para>&sqlmm_compliant; SQL-MM: Topo-Geo and Topo-Net 3: Routine Details:  X.3.14</para>
1527			</refsection>
1528
1529
1530			<refsection>
1531				<title>Examples</title>
1532				<para/>
1533				<!--TODO: Need examples -->
1534			</refsection>
1535
1536			<!-- Optionally add a "See Also" section -->
1537			<refsection>
1538				<title>See Also</title>
1539				<para><xref linkend="ST_RemEdgeModFace"/></para>
1540				<para><xref linkend="ST_AddEdgeNewFaces"/></para>
1541			</refsection>
1542		</refentry>
1543
1544		<refentry id="ST_RemEdgeModFace">
1545			<refnamediv>
1546				<refname>ST_RemEdgeModFace</refname>
1547
1548				<refpurpose>
1549Removes an edge and, if the removed edge separated two faces,
1550delete one of the them and modify the other to take the space of both.
1551        </refpurpose>
1552			</refnamediv>
1553
1554			<refsynopsisdiv>
1555				<funcsynopsis>
1556					<funcprototype>
1557					<funcdef>integer <function>ST_RemEdgeModFace</function></funcdef>
1558					<paramdef><type>varchar </type> <parameter>atopology</parameter></paramdef>
1559					<paramdef><type>integer </type> <parameter>anedge</parameter></paramdef>
1560					</funcprototype>
1561				</funcsynopsis>
1562			</refsynopsisdiv>
1563
1564			<refsection>
1565                <title>Description</title>
1566
1567                <para>
1568Removes an edge and, if the removed edge separated two faces,
1569delete one of the them and modify the other to take the space of both.
1570Preferentially keeps the face on the right, to be symmetric with
1571ST_AddEdgeModFace also keeping it.
1572Returns the id of the face remaining in place of the removed edge.
1573		            </para>
1574
1575                <para>
1576Updates all existing joined edges and relationships accordingly.
1577		            </para>
1578
1579                <para>
1580Refuses to remove an edge partecipating in the definition of an
1581existing TopoGeometry.
1582Refuses to heal two faces if any TopoGeometry is defined by only
1583one of them (and not the other).
1584		            </para>
1585
1586                <para>
1587If any arguments are null, the given edge is unknown (must already exist in
1588the <varname>edge</varname> table of the topology schema), the topology
1589name is invalid then an error is thrown.
1590                </para>
1591
1592                <!-- use this format if new function -->
1593                <para>Availability: 2.0 </para>
1594                <para>&sqlmm_compliant; SQL-MM: Topo-Geo and Topo-Net 3: Routine Details:  X.3.15</para>
1595			</refsection>
1596
1597
1598			<refsection>
1599				<title>Examples</title>
1600				<para/>
1601				<!--TODO: Need examples -->
1602			</refsection>
1603
1604			<!-- Optionally add a "See Also" section -->
1605			<refsection>
1606				<title>See Also</title>
1607				<para><xref linkend="ST_AddEdgeModFace"/></para>
1608				<para><xref linkend="ST_RemEdgeNewFace"/></para>
1609			</refsection>
1610		</refentry>
1611
1612		<refentry id="ST_ChangeEdgeGeom">
1613			<refnamediv>
1614				<refname>ST_ChangeEdgeGeom</refname>
1615
1616				<refpurpose>
1617Changes the shape of an edge without affecting the topology structure.
1618				</refpurpose>
1619			</refnamediv>
1620
1621			<refsynopsisdiv>
1622				<funcsynopsis>
1623					<funcprototype>
1624					<funcdef>integer <function>ST_ChangeEdgeGeom</function></funcdef>
1625					<paramdef><type>varchar </type> <parameter>atopology</parameter></paramdef>
1626					<paramdef><type>integer </type> <parameter>anedge</parameter></paramdef>
1627					<paramdef><type>geometry </type> <parameter>acurve</parameter></paramdef>
1628					</funcprototype>
1629				</funcsynopsis>
1630			</refsynopsisdiv>
1631
1632			<refsection>
1633                <title>Description</title>
1634
1635                <para>
1636Changes the shape of an edge without affecting the topology structure.
1637		</para>
1638                <para>
1639If any arguments are null, the given edge does not exist in
1640the <varname>edge</varname> table of the topology schema, the
1641<varname>acurve</varname> is not a <varname>LINESTRING</varname>, the
1642<varname>anode</varname> and <varname>anothernode</varname> are not the
1643start and endpoints of <varname>acurve</varname> or the modification would
1644change the underlying topology then an error is thrown.
1645		</para>
1646                <para>If the spatial reference system (srid) of the <varname>acurve</varname> geometry is not the same as the topology an exception is thrown.</para>
1647                <para>If the new <varname>acurve</varname> is not simple, then an error is thrown.</para>
1648
1649                <para>
1650If moving the edge from old to new position would hit an obstacle then
1651an error is thrown.
1652		</para>
1653
1654                <!-- use this format if new function -->
1655                <para>Availability: 1.1.0</para>
1656
1657                <!-- use this format if not a new function but functionality enhanced -->
1658                <para>
1659	Enhanced: 2.0.0 adds topological consistency enforcement
1660		</para>
1661
1662                <para>&sqlmm_compliant; SQL-MM: Topo-Geo and Topo-Net 3: Routine Details X.3.6</para>
1663			</refsection>
1664
1665
1666			<refsection>
1667				<title>Examples</title>
1668				<programlisting>SELECT topology.ST_ChangeEdgeGeom('ma_topo', 1,
1669		ST_GeomFromText('LINESTRING(227591.9 893900.4,227622.6 893844.3,227641.6 893816.6, 227704.5 893778.5)', 26986) );
1670 ----
1671 Edge 1 changed</programlisting>
1672			</refsection>
1673
1674			<!-- Optionally add a "See Also" section -->
1675			<refsection>
1676				<title>See Also</title>
1677				<para><xref linkend="ST_AddEdgeModFace"/></para>
1678				<para><xref linkend="ST_RemEdgeModFace"/></para>
1679				<para><xref linkend="ST_ModEdgeSplit"/></para>
1680			</refsection>
1681		</refentry>
1682
1683		<refentry id="ST_ModEdgeSplit">
1684			<refnamediv>
1685				<refname>ST_ModEdgeSplit</refname>
1686
1687				<refpurpose>Split an edge by creating a new node along an existing edge, modifying the original edge and adding a new edge.</refpurpose>
1688			</refnamediv>
1689
1690			<refsynopsisdiv>
1691				<funcsynopsis>
1692					<funcprototype>
1693					<funcdef>integer <function>ST_ModEdgeSplit</function></funcdef>
1694					<paramdef><type>varchar </type> <parameter>atopology</parameter></paramdef>
1695					<paramdef><type>integer </type> <parameter>anedge</parameter></paramdef>
1696					<paramdef><type>geometry </type> <parameter>apoint</parameter></paramdef>
1697					</funcprototype>
1698				</funcsynopsis>
1699			</refsynopsisdiv>
1700
1701			<refsection>
1702                <title>Description</title>
1703
1704                <para>
1705Split an edge by creating a new node along an existing edge,
1706modifying the original edge and adding a new edge.
1707Updates all existing joined edges and relationships accordingly.
1708Returns the identifier of the newly added node.
1709		</para>
1710
1711                <!-- use this format if new function -->
1712                <para>Availability: 1.? </para>
1713                <para>Changed: 2.0 - In prior versions, this was misnamed ST_ModEdgesSplit</para>
1714                <para>&sqlmm_compliant; SQL-MM: Topo-Geo and Topo-Net 3: Routine Details:  X.3.9</para>
1715			</refsection>
1716
1717
1718			<refsection>
1719				<title>Examples</title>
1720				<programlisting>
1721-- Add an edge --
1722 SELECT topology.AddEdge('ma_topo', ST_GeomFromText('LINESTRING(227592 893910, 227600 893910)', 26986) ) As edgeid;
1723
1724-- edgeid-
17253
1726
1727
1728-- Split the edge  --
1729SELECT topology.ST_ModEdgeSplit('ma_topo',  3, ST_SetSRID(ST_Point(227594,893910),26986)  ) As node_id;
1730        node_id
1731-------------------------
17327
1733</programlisting>
1734			</refsection>
1735
1736			<!-- Optionally add a "See Also" section -->
1737			<refsection>
1738				<title>See Also</title>
1739				<para>
1740				<xref linkend="ST_NewEdgesSplit"/>,
1741				<xref linkend="ST_ModEdgeHeal"/>,
1742				<xref linkend="ST_NewEdgeHeal"/>,
1743				<xref linkend="AddEdge"/>
1744				</para>
1745			</refsection>
1746		</refentry>
1747
1748		<refentry id="ST_ModEdgeHeal">
1749			<refnamediv>
1750				<refname>ST_ModEdgeHeal</refname>
1751
1752				<refpurpose>
1753Heals two edges by deleting the node connecting them, modifying the first edge
1754and deleting the second edge. Returns the id of the deleted node.
1755				</refpurpose>
1756			</refnamediv>
1757
1758			<refsynopsisdiv>
1759				<funcsynopsis>
1760					<funcprototype>
1761					<funcdef>int <function>ST_ModEdgeHeal</function></funcdef>
1762					<paramdef><type>varchar </type> <parameter>atopology</parameter></paramdef>
1763					<paramdef><type>integer </type> <parameter>anedge</parameter></paramdef>
1764					<paramdef><type>integer </type> <parameter>anotheredge</parameter></paramdef>
1765					</funcprototype>
1766				</funcsynopsis>
1767			</refsynopsisdiv>
1768
1769			<refsection>
1770                <title>Description</title>
1771
1772                <para>
1773Heals two edges by deleting the node connecting them, modifying the first edge
1774and deleting the second edge.
1775Returns the id of the deleted node.
1776Updates all existing joined edges and relationships accordingly.
1777		</para>
1778
1779                <!-- use this format if new function -->
1780                <para>Availability: 2.0</para>
1781                <para>&sqlmm_compliant; SQL-MM: Topo-Geo and Topo-Net 3: Routine Details:  X.3.9</para>
1782			</refsection>
1783
1784
1785			<!-- Optionally add a "See Also" section -->
1786			<refsection>
1787				<title>See Also</title>
1788				<para>
1789				<xref linkend="ST_ModEdgeSplit"/>
1790				<xref linkend="ST_NewEdgesSplit"/>
1791				</para>
1792			</refsection>
1793		</refentry>
1794
1795		<refentry id="ST_NewEdgeHeal">
1796			<refnamediv>
1797				<refname>ST_NewEdgeHeal</refname>
1798
1799				<refpurpose>
1800Heals two edges by deleting the node connecting them, deleting both edges,
1801and replacing them with an edge whose direction is the same as the first
1802edge provided.
1803				</refpurpose>
1804			</refnamediv>
1805
1806			<refsynopsisdiv>
1807				<funcsynopsis>
1808					<funcprototype>
1809					<funcdef>int <function>ST_NewEdgeHeal</function></funcdef>
1810					<paramdef><type>varchar </type> <parameter>atopology</parameter></paramdef>
1811					<paramdef><type>integer </type> <parameter>anedge</parameter></paramdef>
1812					<paramdef><type>integer </type> <parameter>anotheredge</parameter></paramdef>
1813					</funcprototype>
1814				</funcsynopsis>
1815			</refsynopsisdiv>
1816
1817			<refsection>
1818                <title>Description</title>
1819
1820                <para>
1821Heals two edges by deleting the node connecting them, deleting both edges,
1822and replacing them with an edge whose direction is the same as the first
1823edge provided.
1824Returns the id of the new edge replacing the healed ones.
1825Updates all existing joined edges and relationships accordingly.
1826		</para>
1827
1828
1829                <!-- use this format if new function -->
1830                <para>Availability: 2.0</para>
1831                <para>&sqlmm_compliant; SQL-MM: Topo-Geo and Topo-Net 3: Routine Details:  X.3.9</para>
1832			</refsection>
1833
1834
1835			<!-- Optionally add a "See Also" section -->
1836			<refsection>
1837				<title>See Also</title>
1838				<para>
1839				<xref linkend="ST_ModEdgeHeal"/>
1840				<xref linkend="ST_ModEdgeSplit"/>
1841				<xref linkend="ST_NewEdgesSplit"/>
1842				</para>
1843			</refsection>
1844		</refentry>
1845
1846		<refentry id="ST_MoveIsoNode">
1847			<refnamediv>
1848				<refname>ST_MoveIsoNode</refname>
1849
1850				<refpurpose>Moves an isolated node in a topology from one point to another.  If new <varname>apoint</varname> geometry exists as a node an error is thrown. Returns description of move.</refpurpose>
1851			</refnamediv>
1852
1853			<refsynopsisdiv>
1854				<funcsynopsis>
1855					<funcprototype>
1856					<funcdef>text <function>ST_MoveIsoNode</function></funcdef>
1857					<paramdef><type>varchar </type> <parameter>atopology</parameter></paramdef>
1858					<paramdef><type>integer </type> <parameter>anedge</parameter></paramdef>
1859					<paramdef><type>geometry </type> <parameter>apoint</parameter></paramdef>
1860					</funcprototype>
1861				</funcsynopsis>
1862			</refsynopsisdiv>
1863
1864			<refsection>
1865                <title>Description</title>
1866
1867                <para>Moves an isolated node in a topology from one point to another.  If new <varname>apoint</varname> geometry exists as a node an error is thrown.</para>
1868                <para>If any arguments are null, the
1869<varname>apoint</varname> is not a point, the existing node is not
1870isolated (is a start or end point of an existing edge), new node
1871location intersects an existing edge (even at the end points) or the
1872new location is in a different face (since 3.2.0) then an exception is thrown.
1873                </para>
1874                <para>If the spatial reference system (srid) of the point geometry is not the same as the topology an exception is thrown.</para>
1875
1876
1877                <!-- use this format if new function -->
1878                <para>Availability: 2.0.0 </para>
1879                <para>
1880	Enhanced: 3.2.0 ensures the nod cannot be moved in a different face
1881                </para>
1882	<para>&sqlmm_compliant; SQL-MM: Topo-Net Routines:  X.3.2</para>
1883			</refsection>
1884
1885
1886			<refsection>
1887				<title>Examples</title>
1888				<programlisting>
1889-- Add an isolated node with no face  --
1890SELECT topology.ST_AddIsoNode('ma_topo',  NULL, ST_GeomFromText('POINT(227579 893916)', 26986) ) As nodeid;
1891 nodeid
1892--------
1893      7
1894-- Move the new node --
1895SELECT topology.ST_MoveIsoNode('ma_topo', 7,  ST_GeomFromText('POINT(227579.5 893916.5)', 26986) ) As descrip;
1896                      descrip
1897----------------------------------------------------
1898Isolated Node 7 moved to location 227579.5,893916.5</programlisting>
1899			</refsection>
1900
1901			<!-- Optionally add a "See Also" section -->
1902			<refsection>
1903				<title>See Also</title>
1904				<para><xref linkend="ST_AddIsoNode"/></para>
1905			</refsection>
1906		</refentry>
1907		  <refentry id="ST_NewEdgesSplit">
1908			<refnamediv>
1909				<refname>ST_NewEdgesSplit</refname>
1910
1911				<refpurpose>Split an edge by creating a new node along an existing edge, deleting the original edge and replacing it with two new edges.  Returns the id of the new node created that joins the new edges.</refpurpose>
1912			</refnamediv>
1913
1914			<refsynopsisdiv>
1915				<funcsynopsis>
1916					<funcprototype>
1917					<funcdef>integer <function>ST_NewEdgesSplit</function></funcdef>
1918					<paramdef><type>varchar </type> <parameter>atopology</parameter></paramdef>
1919					<paramdef><type>integer </type> <parameter>anedge</parameter></paramdef>
1920					<paramdef><type>geometry </type> <parameter>apoint</parameter></paramdef>
1921					</funcprototype>
1922				</funcsynopsis>
1923			</refsynopsisdiv>
1924
1925			<refsection>
1926                <title>Description</title>
1927
1928                <para>
1929Split an edge with edge id <varname>anedge</varname> by creating a
1930new node with point location <varname>apoint</varname> along current
1931edge, deleting the original edge and replacing it with two new edges.
1932Returns the id of the new node created that joins the new edges.
1933Updates all existing joined edges and relationships accordingly.
1934		</para>
1935
1936                <para>If the spatial reference system (srid) of the point geometry is not the same as the topology, the <varname>apoint</varname> is not a point geometry, the point is null, the point already exists as a node, the edge does not correspond to an existing edge or the point is not within the edge then an exception is thrown.</para>
1937
1938
1939                <!-- use this format if new function -->
1940                <para>Availability: 1.? </para>
1941	<para>&sqlmm_compliant; SQL-MM: Topo-Net Routines:  X.3.8</para>
1942			</refsection>
1943
1944
1945			<refsection>
1946				<title>Examples</title>
1947				<programlisting>
1948-- Add an edge  --
1949SELECT topology.AddEdge('ma_topo', ST_GeomFromText('LINESTRING(227575 893917,227592 893900)', 26986) ) As edgeid;
1950-- result-
1951edgeid
1952------
1953	2
1954-- Split the new edge --
1955SELECT topology.ST_NewEdgesSplit('ma_topo', 2,  ST_GeomFromText('POINT(227578.5 893913.5)', 26986) ) As newnodeid;
1956 newnodeid
1957---------
1958       6</programlisting>
1959			</refsection>
1960
1961			<!-- Optionally add a "See Also" section -->
1962			<refsection>
1963				<title>See Also</title>
1964				<para>
1965				<xref linkend="ST_ModEdgeSplit"/>
1966				<xref linkend="ST_ModEdgeHeal"/>
1967				<xref linkend="ST_NewEdgeHeal"/>
1968				<xref linkend="AddEdge"/>
1969				</para>
1970			</refsection>
1971		</refentry>
1972
1973		<refentry id="ST_RemoveIsoNode">
1974			<refnamediv>
1975				<refname>ST_RemoveIsoNode</refname>
1976
1977				<refpurpose>Removes an isolated node and returns description of action. If the node is not isolated (is start or end of an edge), then an exception is thrown.</refpurpose>
1978			</refnamediv>
1979
1980			<refsynopsisdiv>
1981				<funcsynopsis>
1982					<funcprototype>
1983					<funcdef>text <function>ST_RemoveIsoNode</function></funcdef>
1984					<paramdef><type>varchar </type> <parameter>atopology</parameter></paramdef>
1985					<paramdef><type>integer </type> <parameter>anode</parameter></paramdef>
1986					</funcprototype>
1987				</funcsynopsis>
1988			</refsynopsisdiv>
1989
1990			<refsection>
1991                <title>Description</title>
1992
1993                <para>Removes an isolated node and returns description of action. If the node is not isolated (is start or end of an edge), then an exception is thrown.</para>
1994
1995
1996                <!-- use this format if new function -->
1997                <para>Availability: 1.? </para>
1998	<para>&sqlmm_compliant; SQL-MM: Topo-Geo and Topo-Net 3: Routine Details:  X+1.3.3</para>
1999			</refsection>
2000
2001
2002			<refsection>
2003				<title>Examples</title>
2004				<programlisting>
2005-- Remove an isolated node with no face  --
2006SELECT topology.ST_RemoveIsoNode('ma_topo',  7 ) As result;
2007         result
2008-------------------------
2009 Isolated node 7 removed
2010</programlisting>
2011			</refsection>
2012
2013			<!-- Optionally add a "See Also" section -->
2014			<refsection>
2015				<title>See Also</title>
2016				<para><xref linkend="ST_AddIsoNode"/></para>
2017			</refsection>
2018		</refentry>
2019
2020		<refentry id="ST_RemoveIsoEdge">
2021			<refnamediv>
2022				<refname>ST_RemoveIsoEdge</refname>
2023
2024				<refpurpose>Removes an isolated edge and returns description of action. If the edge is not isolated, then an exception is thrown.</refpurpose>
2025			</refnamediv>
2026
2027			<refsynopsisdiv>
2028				<funcsynopsis>
2029					<funcprototype>
2030					<funcdef>text <function>ST_RemoveIsoEdge</function></funcdef>
2031					<paramdef><type>varchar </type> <parameter>atopology</parameter></paramdef>
2032					<paramdef><type>integer </type> <parameter>anedge</parameter></paramdef>
2033					</funcprototype>
2034				</funcsynopsis>
2035			</refsynopsisdiv>
2036
2037			<refsection>
2038                <title>Description</title>
2039
2040                <para>Removes an isolated edge and returns description of action. If the edge is not isolated, then an exception is thrown.</para>
2041
2042
2043                <!-- use this format if new function -->
2044                <para>Availability: 1.? </para>
2045	<para>&sqlmm_compliant; SQL-MM: Topo-Geo and Topo-Net 3: Routine Details:  X+1.3.3</para>
2046			</refsection>
2047
2048
2049			<refsection>
2050				<title>Examples</title>
2051				<programlisting>
2052-- Remove an isolated node with no face  --
2053SELECT topology.ST_RemoveIsoNode('ma_topo',  7 ) As result;
2054         result
2055-------------------------
2056 Isolated node 7 removed
2057</programlisting>
2058			</refsection>
2059
2060			<!-- Optionally add a "See Also" section -->
2061			<refsection>
2062				<title>See Also</title>
2063				<para><xref linkend="ST_AddIsoNode"/></para>
2064			</refsection>
2065		</refentry>
2066	</sect1>
2067
2068
2069	<sect1 id="Topology_Accessors">
2070	  <title>Topology Accessors</title>
2071        <refentry id="GetEdgeByPoint">
2072          <refnamediv>
2073            <refname>GetEdgeByPoint</refname>
2074
2075            <refpurpose>Finds the edge-id of an edge that intersects a given point.</refpurpose>
2076          </refnamediv>
2077
2078          <refsynopsisdiv>
2079            <funcsynopsis>
2080              <funcprototype>
2081                <funcdef>integer <function>GetEdgeByPoint</function></funcdef>
2082                <paramdef><type>varchar </type> <parameter>atopology</parameter></paramdef>
2083                <paramdef><type>geometry </type> <parameter>apoint</parameter></paramdef>
2084                <paramdef><type>float8 </type> <parameter>tol1</parameter></paramdef>
2085              </funcprototype>
2086
2087            </funcsynopsis>
2088          </refsynopsisdiv>
2089
2090          <refsection>
2091            <title>Description</title>
2092
2093            <para>Retrieves the id of an edge that intersects a Point.</para>
2094            <para>The function returns an integer (id-edge) given a topology, a POINT and a tolerance. If tolerance = 0 then the point has to intersect the edge.</para>
2095            <para>If <varname>apoint</varname> doesn't intersect an edge, returns 0 (zero).</para>
2096            <para>If use tolerance > 0 and there is more than one edge near the point then an exception is thrown.</para>
2097
2098
2099            <note>
2100              <para>If tolerance = 0, the function uses ST_Intersects otherwise uses ST_DWithin.</para>
2101            </note>
2102            <para>Performed by the GEOS module.</para>
2103            <para>Availability: 2.0.0</para>
2104          </refsection>
2105
2106
2107          <refsection>
2108            <title>Examples</title>
2109                <para>These examples use edges we created in <xref linkend="AddEdge" /></para>
2110                <programlisting>SELECT topology.GetEdgeByPoint('ma_topo',geom, 1) As with1mtol, topology.GetEdgeByPoint('ma_topo',geom,0) As withnotol
2111FROM ST_GeomFromEWKT('SRID=26986;POINT(227622.6 893843)') As geom;
2112 with1mtol | withnotol
2113-----------+-----------
2114         2 |         0
2115</programlisting>
2116                <programlisting>SELECT topology.GetEdgeByPoint('ma_topo',geom, 1) As nearnode
2117FROM ST_GeomFromEWKT('SRID=26986;POINT(227591.9 893900.4)') As geom;
2118
2119-- get error --
2120ERROR:  Two or more edges found</programlisting>
2121          </refsection>
2122
2123          <!-- Optionally add a "See Also" section -->
2124          <refsection>
2125            <title>See Also</title>
2126
2127<para>
2128<xref linkend="AddEdge" />,
2129<xref linkend="GetNodeByPoint" />,
2130<xref linkend="GetFaceByPoint" />
2131</para>
2132          </refsection>
2133        </refentry>
2134
2135        <refentry id="GetFaceByPoint">
2136		<refnamediv>
2137			<refname>GetFaceByPoint</refname>
2138			<refpurpose>Finds face intersecting a given point.</refpurpose>
2139		</refnamediv>
2140		<refsynopsisdiv>
2141			<funcsynopsis>
2142				<funcprototype>
2143					<funcdef>integer <function>GetFaceByPoint</function></funcdef>
2144					<paramdef><type>varchar </type> <parameter>atopology</parameter></paramdef>
2145					<paramdef><type>geometry </type> <parameter>apoint</parameter></paramdef>
2146					<paramdef><type>float8 </type> <parameter>tol1</parameter></paramdef>
2147				</funcprototype>
2148			</funcsynopsis>
2149		</refsynopsisdiv>
2150		<refsection>
2151      <title>Description</title>
2152
2153        <para>
2154Finds a face referenced by a Point, with given tolerance.
2155        </para>
2156
2157        <para>
2158The function will effectively look for a face intersecting a
2159circle having the point as center and the tolerance as radius.
2160        </para>
2161
2162        <para>
2163If no face intersects the given query location, 0 is returned (universal face).
2164        </para>
2165
2166        <para>
2167If more than one face intersect the query location an exception is thrown.
2168        </para>
2169
2170        <para>Availability: 2.0.0</para>
2171        <para>Enhanced: 3.2.0 more efficient implementation and clearer contract, stops working with invalid topologies.</para>
2172		</refsection>
2173		<refsection>
2174			<title>Examples</title>
2175			<programlisting>SELECT topology.GetFaceByPoint('ma_topo',geom, 10) As with1mtol, topology.GetFaceByPoint('ma_topo',geom,0) As withnotol
2176	FROM ST_GeomFromEWKT('POINT(234604.6 899382.0)') As geom;
2177
2178	 with1mtol | withnotol
2179	-----------+-----------
2180			 1 |         0</programlisting>
2181
2182			<programlisting>SELECT topology.GetFaceByPoint('ma_topo',geom, 1) As nearnode
2183	FROM ST_GeomFromEWKT('POINT(227591.9 893900.4)') As geom;
2184
2185-- get error --
2186ERROR:  Two or more faces found</programlisting>
2187		</refsection>
2188		<!-- Optionally add a "See Also" section -->
2189		<refsection>
2190			<title>See Also</title>
2191<para>
2192<xref linkend="GetFaceContainingPoint" />,
2193<xref linkend="AddFace" />,
2194<xref linkend="GetNodeByPoint" />,
2195<xref linkend="GetEdgeByPoint" />
2196</para>
2197		</refsection>
2198	</refentry>
2199
2200        <refentry id="GetFaceContainingPoint">
2201		<refnamediv>
2202			<refname>GetFaceContainingPoint</refname>
2203			<refpurpose>Finds the face containing a point.</refpurpose>
2204		</refnamediv>
2205		<refsynopsisdiv>
2206			<funcsynopsis>
2207				<funcprototype>
2208					<funcdef>integer <function>GetFaceContainingPoint</function></funcdef>
2209					<paramdef><type>text </type> <parameter>atopology</parameter></paramdef>
2210					<paramdef><type>geometry </type> <parameter>apoint</parameter></paramdef>
2211				</funcprototype>
2212			</funcsynopsis>
2213		</refsynopsisdiv>
2214		<refsection>
2215      <title>Description</title>
2216
2217			<para>Returns the id of the face containing a point.</para>
2218			<para>An exception is thrown if the point falls on a face boundary.</para>
2219
2220			<note>
2221				<para>The function relies on a valid topology, using edge linking and face labeling.</para>
2222			</note>
2223
2224			<para>Availability: 3.2.0</para>
2225		</refsection>
2226		<refsection>
2227			<title>See Also</title>
2228<para>
2229<xref linkend="ST_GetFaceGeometry"/>
2230</para>
2231		</refsection>
2232	</refentry>
2233
2234        <refentry id="GetNodeByPoint">
2235          <refnamediv>
2236            <refname>GetNodeByPoint</refname>
2237
2238            <refpurpose>Finds the node-id of a node at a point location.</refpurpose>
2239          </refnamediv>
2240
2241          <refsynopsisdiv>
2242            <funcsynopsis>
2243              <funcprototype>
2244                <funcdef>integer <function>GetNodeByPoint</function></funcdef>
2245                <paramdef><type>varchar </type> <parameter>atopology</parameter></paramdef>
2246                <paramdef><type>geometry </type> <parameter>apoint</parameter></paramdef>
2247                <paramdef><type>float8 </type> <parameter>tol1</parameter></paramdef>
2248              </funcprototype>
2249
2250            </funcsynopsis>
2251          </refsynopsisdiv>
2252
2253          <refsection>
2254            <title>Description</title>
2255
2256            <para>Retrieves the id of a node at a point location.</para>
2257            <para>The function returns an integer (id-node) given a topology, a POINT and a tolerance. If tolerance = 0 means exact intersection, otherwise retrieves the node from an interval.</para>
2258            <para>If <varname>apoint</varname> doesn't intersect a node, returns 0 (zero).</para>
2259            <para>If use tolerance > 0 and there is more than one node near the point then an exception is thrown.</para>
2260            <note>
2261              <para>If tolerance = 0, the function uses ST_Intersects otherwise uses ST_DWithin.</para>
2262            </note>
2263            <para>Performed by the GEOS module.</para>
2264            <para>Availability: 2.0.0</para>
2265          </refsection>
2266
2267
2268          <refsection>
2269            <title>Examples</title>
2270             <para>These examples use edges we created in <xref linkend="AddEdge" /></para>
2271            <programlisting>SELECT topology.GetNodeByPoint('ma_topo',geom, 1) As nearnode
2272 FROM ST_GeomFromEWKT('SRID=26986;POINT(227591.9 893900.4)') As geom;
2273  nearnode
2274----------
2275        2
2276 </programlisting>
2277            <programlisting>SELECT topology.GetNodeByPoint('ma_topo',geom, 1000) As too_much_tolerance
2278 FROM ST_GeomFromEWKT('SRID=26986;POINT(227591.9 893900.4)') As geom;
2279
2280 ----get error--
2281 ERROR:  Two or more nodes found
2282 </programlisting>
2283          </refsection>
2284
2285          <!-- Optionally add a "See Also" section -->
2286          <refsection>
2287            <title>See Also</title>
2288
2289<para>
2290<xref linkend="AddEdge" />,
2291<xref linkend="GetEdgeByPoint" />,
2292<xref linkend="GetFaceByPoint" />
2293</para>
2294          </refsection>
2295        </refentry>
2296
2297		<refentry id="GetTopologyID">
2298			<refnamediv>
2299				<refname>GetTopologyID</refname>
2300
2301				<refpurpose>Returns the id of a topology in the topology.topology table given the name of the topology.</refpurpose>
2302			</refnamediv>
2303
2304			<refsynopsisdiv>
2305				<funcsynopsis>
2306					<funcprototype>
2307					<funcdef>integer <function>GetTopologyID</function></funcdef>
2308					<paramdef><type>varchar</type> <parameter>toponame</parameter></paramdef>
2309					</funcprototype>
2310				</funcsynopsis>
2311			</refsynopsisdiv>
2312
2313			<refsection>
2314                <title>Description</title>
2315
2316                <para>Returns the id of a topology in the topology.topology table given the name of the topology.</para>
2317              <!-- use this format if new function -->
2318                <para>Availability: 1.?</para>
2319			</refsection>
2320
2321
2322			<refsection>
2323				<title>Examples</title>
2324				<programlisting>SELECT topology.GetTopologyID('ma_topo') As topo_id;
2325 topo_id
2326---------
2327       1</programlisting>
2328			</refsection>
2329
2330			<!-- Optionally add a "See Also" section -->
2331			<refsection>
2332				<title>See Also</title>
2333				<para>
2334	<xref linkend="CreateTopology"/>,
2335	<xref linkend="DropTopology"/>,
2336	<xref linkend="GetTopologyName"/>,
2337	<xref linkend="GetTopologySRID"/>
2338				</para>
2339			</refsection>
2340		</refentry>
2341
2342		<refentry id="GetTopologySRID">
2343			<refnamediv>
2344				<refname>GetTopologySRID</refname>
2345
2346				<refpurpose>Returns the SRID of a topology in the topology.topology table given the name of the topology.</refpurpose>
2347			</refnamediv>
2348
2349			<refsynopsisdiv>
2350				<funcsynopsis>
2351					<funcprototype>
2352					<funcdef>integer <function>GetTopologyID</function></funcdef>
2353					<paramdef><type>varchar</type> <parameter>toponame</parameter></paramdef>
2354					</funcprototype>
2355				</funcsynopsis>
2356			</refsynopsisdiv>
2357
2358			<refsection>
2359                <title>Description</title>
2360
2361                <para>Returns the spatial reference id of a topology in the topology.topology table given the name of the topology.</para>
2362              <!-- use this format if new function -->
2363                <para>Availability: 2.0.0</para>
2364			</refsection>
2365
2366
2367			<refsection>
2368				<title>Examples</title>
2369				<programlisting>SELECT topology.GetTopologySRID('ma_topo') As SRID;
2370 SRID
2371-------
2372  4326</programlisting>
2373			</refsection>
2374
2375			<!-- Optionally add a "See Also" section -->
2376			<refsection>
2377				<title>See Also</title>
2378				<para>
2379	<xref linkend="CreateTopology"/>,
2380	<xref linkend="DropTopology"/>,
2381	<xref linkend="GetTopologyName"/>,
2382	<xref linkend="GetTopologyID"/>
2383				</para>
2384			</refsection>
2385		</refentry>
2386
2387		<refentry id="GetTopologyName">
2388			<refnamediv>
2389				<refname>GetTopologyName</refname>
2390
2391				<refpurpose>Returns the name of a topology (schema) given the id of the topology.</refpurpose>
2392			</refnamediv>
2393
2394			<refsynopsisdiv>
2395				<funcsynopsis>
2396					<funcprototype>
2397					<funcdef>varchar <function>GetTopologyName</function></funcdef>
2398					<paramdef><type>integer</type> <parameter>topology_id</parameter></paramdef>
2399					</funcprototype>
2400				</funcsynopsis>
2401			</refsynopsisdiv>
2402
2403			<refsection>
2404                <title>Description</title>
2405
2406                <para>Returns the topology name (schema) of a topology from the topology.topology table given the topology id of the topology.</para>
2407              <!-- use this format if new function -->
2408                <para>Availability: 1.?</para>
2409			</refsection>
2410
2411
2412			<refsection>
2413				<title>Examples</title>
2414				<programlisting>SELECT topology.GetTopologyName(1) As topo_name;
2415 topo_name
2416-----------
2417 ma_topo</programlisting>
2418			</refsection>
2419
2420			<!-- Optionally add a "See Also" section -->
2421			<refsection>
2422				<title>See Also</title>
2423				<para>
2424	<xref linkend="CreateTopology"/>,
2425	<xref linkend="DropTopology"/>,
2426	<xref linkend="GetTopologyID"/>,
2427	<xref linkend="GetTopologySRID"/>
2428				</para>
2429			</refsection>
2430		</refentry>
2431
2432		<refentry id="ST_GetFaceEdges">
2433			<refnamediv>
2434				<refname>ST_GetFaceEdges</refname>
2435
2436				<refpurpose>Returns a set of ordered edges that bound <varname>aface</varname>.</refpurpose>
2437			</refnamediv>
2438
2439			<refsynopsisdiv>
2440				<funcsynopsis>
2441					<funcprototype>
2442					<funcdef>getfaceedges_returntype <function>ST_GetFaceEdges</function></funcdef>
2443					<paramdef><type>varchar </type> <parameter>atopology</parameter></paramdef>
2444					<paramdef><type>integer </type> <parameter>aface</parameter></paramdef>
2445					</funcprototype>
2446				</funcsynopsis>
2447			</refsynopsisdiv>
2448
2449			<refsection>
2450                <title>Description</title>
2451
2452                <para>Returns a set of ordered edges that bound <varname>aface</varname>. Each output consists of a sequence and edgeid. Sequence numbers start with value 1.</para>
2453
2454		<para>
2455Enumeration of each ring edges start from the edge with smallest identifier.
2456Order of edges follows a left-hand-rule (bound face is on the left of each directed edge).
2457		</para>
2458
2459                <!-- use this format if new function -->
2460                <para>Availability: 2.0 </para>
2461	<para>&sqlmm_compliant; SQL-MM 3 Topo-Geo and Topo-Net 3: Routine Details: X.3.5</para>
2462			</refsection>
2463
2464
2465			<refsection>
2466				<title>Examples</title>
2467				<programlisting>
2468-- Returns the edges bounding face 1
2469SELECT (topology.ST_GetFaceEdges('tt', 1)).*;
2470-- result --
2471 sequence | edge
2472----------+------
2473        1 |   -4
2474        2 |    5
2475        3 |    7
2476        4 |   -6
2477        5 |    1
2478        6 |    2
2479        7 |    3
2480(7 rows)
2481</programlisting>
2482<programlisting>
2483-- Returns the sequence, edge id
2484-- and geometry of the edges that bound face 1
2485-- If you just need geom and seq, can use ST_GetFaceGeometry
2486SELECT t.seq, t.edge, geom
2487FROM topology.ST_GetFaceEdges('tt',1) As t(seq,edge)
2488	INNER JOIN tt.edge AS e ON abs(t.edge) = e.edge_id;
2489</programlisting>
2490			</refsection>
2491
2492			<!-- Optionally add a "See Also" section -->
2493			<refsection>
2494				<title>See Also</title>
2495				<para>
2496<xref linkend="GetRingEdges"/>,
2497<xref linkend="AddFace"/>,
2498<xref linkend="ST_GetFaceGeometry"/>
2499				</para>
2500			</refsection>
2501		</refentry>
2502
2503		<refentry id="ST_GetFaceGeometry">
2504			<refnamediv>
2505				<refname>ST_GetFaceGeometry</refname>
2506
2507				<refpurpose>Returns the polygon in the given topology with the specified face id.</refpurpose>
2508			</refnamediv>
2509
2510			<refsynopsisdiv>
2511				<funcsynopsis>
2512					<funcprototype>
2513					<funcdef>geometry <function>ST_GetFaceGeometry</function></funcdef>
2514					<paramdef><type>varchar </type> <parameter>atopology</parameter></paramdef>
2515					<paramdef><type>integer </type> <parameter>aface</parameter></paramdef>
2516					</funcprototype>
2517				</funcsynopsis>
2518			</refsynopsisdiv>
2519
2520			<refsection>
2521                <title>Description</title>
2522
2523                <para>Returns the polygon in the given topology with the specified face id. Builds the polygon from the edges making up the face.</para>
2524
2525
2526                <!-- use this format if new function -->
2527                <para>Availability: 1.? </para>
2528	<para>&sqlmm_compliant; SQL-MM 3 Topo-Geo and Topo-Net 3: Routine Details: X.3.16</para>
2529			</refsection>
2530
2531
2532			<refsection>
2533				<title>Examples</title>
2534				<programlisting>
2535-- Returns the wkt of the polygon added with AddFace
2536SELECT ST_AsText(topology.ST_GetFaceGeometry('ma_topo', 1)) As facegeomwkt;
2537-- result --
2538               facegeomwkt
2539
2540--------------------------------------------------------------------------------
2541 POLYGON((234776.9 899563.7,234896.5 899456.7,234914 899436.4,234946.6 899356.9,
2542234872.5 899328.7,234891 899285.4,234992.5 899145,234890.6 899069,
2543234755.2 899255.4,234612.7 899379.4,234776.9 899563.7))
2544</programlisting>
2545			</refsection>
2546
2547			<!-- Optionally add a "See Also" section -->
2548			<refsection>
2549				<title>See Also</title>
2550				<para><xref linkend="AddFace"/></para>
2551			</refsection>
2552		</refentry>
2553
2554		<refentry id="GetRingEdges">
2555			<refnamediv>
2556				<refname>GetRingEdges</refname>
2557
2558				<refpurpose>
2559Returns the ordered set of signed edge identifiers met by walking on an
2560a given edge side.
2561				</refpurpose>
2562			</refnamediv>
2563
2564			<refsynopsisdiv>
2565				<funcsynopsis>
2566					<funcprototype>
2567					<funcdef>getfaceedges_returntype <function>GetRingEdges</function></funcdef>
2568					<paramdef><type>varchar </type> <parameter>atopology</parameter></paramdef>
2569					<paramdef><type>integer </type> <parameter>aring</parameter></paramdef>
2570					<paramdef choice="opt"><type>integer </type> <parameter>max_edges=null</parameter></paramdef>
2571					</funcprototype>
2572				</funcsynopsis>
2573			</refsynopsisdiv>
2574
2575			<refsection>
2576                <title>Description</title>
2577
2578                <para>
2579Returns the ordered set of signed edge identifiers met by walking on an
2580a given edge side.
2581Each output consists of a sequence and a signed edge id.
2582Sequence numbers start with value 1.
2583                </para>
2584
2585                <para>
2586If you pass a positive edge id, the walk starts on the left side
2587of the corresponding edge and follows the edge direction.
2588If you pass a negative edge id, the walk starts on the right side
2589of it and goes backward.
2590                </para>
2591
2592                <para>
2593If <varname>max_edges</varname> is not null no more than those records
2594are returned by that function. This is meant to be a safety parameter
2595when dealing with possibly invalid topologies.
2596		</para>
2597
2598    <note><para>
2599This function uses edge ring linking metadata.
2600    </para></note>
2601
2602                <!-- use this format if new function -->
2603                <para>Availability: 2.0.0 </para>
2604			</refsection>
2605
2606
2607			<!-- Optionally add a "See Also" section -->
2608			<refsection>
2609				<title>See Also</title>
2610				<para>
2611<xref linkend="ST_GetFaceEdges"/>,
2612<xref linkend="GetNodeEdges"/>
2613				</para>
2614			</refsection>
2615		</refentry>
2616
2617		<refentry id="GetNodeEdges">
2618			<refnamediv>
2619				<refname>GetNodeEdges</refname>
2620
2621				<refpurpose>
2622Returns an ordered set of edges incident to the given node.
2623				</refpurpose>
2624			</refnamediv>
2625
2626			<refsynopsisdiv>
2627				<funcsynopsis>
2628					<funcprototype>
2629					<funcdef>getfaceedges_returntype <function>GetNodeEdges</function></funcdef>
2630					<paramdef><type>varchar </type> <parameter>atopology</parameter></paramdef>
2631					<paramdef><type>integer </type> <parameter>anode</parameter></paramdef>
2632					</funcprototype>
2633				</funcsynopsis>
2634			</refsynopsisdiv>
2635
2636			<refsection>
2637                <title>Description</title>
2638
2639                <para>
2640Returns an ordered set of edges incident to the given node.
2641Each output consists of a sequence and a signed edge id.
2642Sequence numbers start with value 1.
2643A positive edge starts at the given node.
2644A negative edge ends into the given node.
2645Closed edges will appear twice (with both signs).
2646Order is clockwise starting from northbound.
2647		</para>
2648
2649            <note>
2650		<para>
2651This function computes ordering rather than deriving from metadata
2652and is thus usable to build edge ring linking.
2653		</para>
2654            </note>
2655
2656                <!-- use this format if new function -->
2657                <para>Availability: 2.0 </para>
2658			</refsection>
2659
2660			<!-- Optionally add a "See Also" section -->
2661			<refsection>
2662				<title>See Also</title>
2663				<para>
2664<xref linkend="getfaceedges_returntype"/>,
2665<xref linkend="GetRingEdges"/>,
2666<xref linkend="ST_Azimuth"/>
2667				</para>
2668			</refsection>
2669		</refentry>
2670
2671	</sect1>
2672
2673
2674	<sect1 id="Topology_Processing">
2675    <sect1info>
2676        <abstract>
2677            <para>This section covers the functions for processing topologies in non-standard ways.</para>
2678        </abstract>
2679    </sect1info>
2680	  <title>Topology Processing</title>
2681		<refentry id="TopologyPolygonize">
2682			<refnamediv>
2683				<refname>Polygonize</refname>
2684				<refpurpose>Finds and registers all faces defined by topology edges.</refpurpose>
2685			</refnamediv>
2686			<refsynopsisdiv>
2687				<funcsynopsis>
2688					<funcprototype>
2689					<funcdef>text <function>Polygonize</function></funcdef>
2690					<paramdef><type>varchar </type> <parameter>toponame</parameter></paramdef>
2691					</funcprototype>
2692				</funcsynopsis>
2693			</refsynopsisdiv>
2694
2695			<refsection>
2696                <title>Description</title>
2697
2698                <para>Registers all faces that can be built out a topology edge primitives.</para>
2699                <para>The target topology is assumed to contain no self-intersecting edges.</para>
2700                <note><para>Already known faces are recognized, so it is safe to call Polygonize multiple times on the same topology.</para></note>
2701		<note><para>
2702This function does not use nor set the next_left_edge and next_right_edge fields of the edge table.
2703                </para></note>
2704
2705
2706                <!-- use this format if new function -->
2707                <para>Availability: 2.0.0</para>
2708			</refsection>
2709
2710			<!-- Optionally add a "See Also" section -->
2711			<refsection>
2712				<title>See Also</title>
2713				<para><xref linkend="AddFace"/>, <xref linkend="ST_Polygonize"/></para>
2714			</refsection>
2715		</refentry>
2716
2717		<refentry id="AddNode">
2718			<refnamediv>
2719				<refname>AddNode</refname>
2720
2721				<refpurpose>Adds a point node to the node table in the specified topology schema and returns the nodeid of new node. If point already exists as node, the existing nodeid is returned.</refpurpose>
2722			</refnamediv>
2723
2724			<refsynopsisdiv>
2725				<funcsynopsis>
2726					<funcprototype>
2727						<funcdef>integer <function>AddNode</function></funcdef>
2728						<paramdef><type>varchar </type> <parameter>toponame</parameter></paramdef>
2729						<paramdef><type>geometry </type> <parameter>apoint</parameter></paramdef>
2730						<paramdef choice="opt"><type>boolean </type> <parameter>allowEdgeSplitting=false</parameter></paramdef>
2731						<paramdef choice="opt"><type>boolean </type> <parameter>computeContainingFace=false</parameter></paramdef>
2732					</funcprototype>
2733				</funcsynopsis>
2734			</refsynopsisdiv>
2735
2736			<refsection>
2737                <title>Description</title>
2738
2739                <para>
2740Adds a point node to the node table in the specified topology schema.
2741The <xref linkend="AddEdge" /> function automatically adds start and end
2742points of an edge when called so not necessary to explicitly add nodes
2743of an edge.
2744                </para>
2745
2746	<para>
2747If any edge crossing the node is found either an exception is raised or
2748the edge is split, depending on the <varname>allowEdgeSplitting</varname>
2749parameter value.
2750	</para>
2751
2752	<para>
2753If <varname>computeContainingFace</varname> is true a newly added node would
2754get the correct containing face computed.
2755	</para>
2756
2757                <note><para>If the <varname>apoint</varname> geometry already exists as a node, the node is not added but the existing nodeid is returned.</para></note>
2758
2759                <!-- use this format if new function -->
2760                <para>Availability: 2.0.0</para>
2761			</refsection>
2762
2763
2764			<refsection>
2765				<title>Examples</title>
2766				<programlisting>SELECT topology.AddNode('ma_topo', ST_GeomFromText('POINT(227641.6 893816.5)', 26986) ) As nodeid;
2767-- result --
2768nodeid
2769--------
2770 4
2771
2772</programlisting>
2773			</refsection>
2774
2775			<!-- Optionally add a "See Also" section -->
2776			<refsection>
2777				<title>See Also</title>
2778				<para><xref linkend="AddEdge"/>, <xref linkend="CreateTopology"/></para>
2779			</refsection>
2780		</refentry>
2781
2782	     <refentry id="AddEdge">
2783			<refnamediv>
2784				<refname>AddEdge</refname>
2785
2786				<refpurpose>Adds a linestring edge to the edge table and associated start and end points to the point nodes table of the specified topology schema using the specified linestring geometry and returns the edgeid of the new (or existing) edge.</refpurpose>
2787			</refnamediv>
2788
2789			<refsynopsisdiv>
2790				<funcsynopsis>
2791					<funcprototype>
2792					<funcdef>integer <function>AddEdge</function></funcdef>
2793					<paramdef><type>varchar </type> <parameter>toponame</parameter></paramdef>
2794					<paramdef><type>geometry </type> <parameter>aline</parameter></paramdef>
2795					</funcprototype>
2796				</funcsynopsis>
2797			</refsynopsisdiv>
2798
2799			<refsection>
2800                <title>Description</title>
2801
2802                <para>Adds an edge to the edge table and associated nodes to the nodes table of the specified <varname>toponame</varname> schema using the specified linestring geometry and returns the edgeid of the new or existing record.
2803                The newly added edge has "universe" face on both sides and links to itself.</para>
2804                <note><para>If the <varname>aline</varname> geometry crosses, overlaps, contains or is contained by an existing linestring edge, then an error is thrown and the edge is not added.</para></note>
2805                <note><para>The geometry of <varname>aline</varname> must have the same <varname>srid</varname> as defined for the topology otherwise an invalid spatial reference sys error will be thrown.</para></note>
2806                <para>Performed by the GEOS module.</para>
2807                <para>Availability: 2.0.0</para>
2808			</refsection>
2809
2810			<refsection>
2811				<title>Examples</title>
2812				<programlisting>SELECT topology.AddEdge('ma_topo', ST_GeomFromText('LINESTRING(227575.8 893917.2,227591.9 893900.4)', 26986) ) As edgeid;
2813-- result-
2814edgeid
2815--------
2816 1
2817
2818SELECT topology.AddEdge('ma_topo', ST_GeomFromText('LINESTRING(227591.9 893900.4,227622.6 893844.2,227641.6 893816.5,
2819 227704.5 893778.5)', 26986) ) As edgeid;
2820-- result --
2821edgeid
2822--------
2823 2
2824
2825 SELECT topology.AddEdge('ma_topo', ST_GeomFromText('LINESTRING(227591.2 893900, 227591.9 893900.4,
2826  227704.5 893778.5)', 26986) ) As edgeid;
2827 -- gives error --
2828 ERROR:  Edge intersects (not on endpoints) with existing edge 1
2829</programlisting>
2830			</refsection>
2831
2832			<!-- Optionally add a "See Also" section -->
2833			<refsection>
2834				<title>See Also</title>
2835				<para>
2836<xref linkend="TopoGeo_AddLineString"/>,
2837<xref linkend="CreateTopology"/>,
2838<xref linkend="spatial_ref_sys"/>
2839        </para>
2840			</refsection>
2841		</refentry>
2842
2843		<refentry id="AddFace">
2844			<refnamediv>
2845				<refname>AddFace</refname>
2846
2847				<refpurpose>Registers a face primitive to a topology and gets its identifier.</refpurpose>
2848			</refnamediv>
2849
2850			<refsynopsisdiv>
2851				<funcsynopsis>
2852					<funcprototype>
2853					<funcdef>integer <function>AddFace</function></funcdef>
2854					<paramdef><type>varchar </type> <parameter>toponame</parameter></paramdef>
2855					<paramdef><type>geometry </type> <parameter>apolygon</parameter></paramdef>
2856					<paramdef choice="opt"><type>boolean </type> <parameter>force_new=false</parameter></paramdef>
2857					</funcprototype>
2858				</funcsynopsis>
2859			</refsynopsisdiv>
2860
2861			<refsection>
2862                <title>Description</title>
2863
2864                <para>
2865Registers a face primitive to a topology and gets its identifier.
2866                </para>
2867
2868                <para>
2869For a newly added face, the edges forming its boundaries and the ones
2870contained in the face will be updated to have correct values in the
2871left_face and right_face fields.
2872Isolated nodes contained in the face will also be updated to have a correct
2873containing_face field value.
2874                </para>
2875
2876		<note><para>
2877This function does not use nor set the next_left_edge and next_right_edge fields of the edge table.
2878                </para></note>
2879
2880                <para>The target topology is assumed to be valid (containing no self-intersecting edges). An exception is raised if: The polygon boundary is not fully defined by existing edges or the polygon overlaps an existing face.</para>
2881
2882                <para>
2883If the <varname>apolygon</varname> geometry already exists as a face, then:
2884if <varname>force_new</varname> is false (the default) the
2885face id of the existing face is returned;
2886if <varname>force_new</varname> is true a new id will be assigned to
2887the newly registered face.
2888                </para>
2889
2890		<note><para>
2891When a new registration of an existing face is performed (force_new=true),
2892no action will be taken to resolve dangling references to the existing
2893face in the edge, node an relation tables, nor will the MBR field of the
2894existing face record be updated. It is up to the caller to deal with that.
2895                </para></note>
2896
2897                <note><para>The <varname>apolygon</varname> geometry must have the same <varname>srid</varname> as defined for the topology otherwise an invalid spatial reference sys error will be thrown.</para></note>
2898
2899                <!-- use this format if new function -->
2900                <para>Availability: 2.0.0</para>
2901			</refsection>
2902
2903
2904			<refsection>
2905				<title>Examples</title>
2906				<programlisting>
2907-- first add the edges we use generate_series as an iterator (the below
2908-- will only work for polygons with &lt; 10000 points because of our max in gs)
2909SELECT topology.AddEdge('ma_topo', ST_MakeLine(ST_PointN(geom,i), ST_PointN(geom, i + 1) )) As edgeid
2910    FROM (SELECT  ST_NPoints(geom) AS npt, geom
2911            FROM
2912                (SELECT ST_Boundary(ST_GeomFromText('POLYGON((234896.5 899456.7,234914 899436.4,234946.6 899356.9,234872.5 899328.7,
2913                234891 899285.4,234992.5 899145, 234890.6 899069,234755.2 899255.4,
2914                234612.7 899379.4,234776.9 899563.7,234896.5 899456.7))', 26986) )  As geom
2915            )  As geoms) As facen CROSS JOIN generate_series(1,10000) As i
2916         WHERE i &lt; npt;
2917-- result --
2918 edgeid
2919--------
2920      3
2921      4
2922      5
2923      6
2924      7
2925      8
2926      9
2927     10
2928     11
2929     12
2930(10 rows)
2931-- then add the face -
2932
2933SELECT topology.AddFace('ma_topo',
2934    ST_GeomFromText('POLYGON((234896.5 899456.7,234914 899436.4,234946.6 899356.9,234872.5 899328.7,
2935    234891 899285.4,234992.5 899145, 234890.6 899069,234755.2 899255.4,
2936    234612.7 899379.4,234776.9 899563.7,234896.5 899456.7))', 26986) ) As faceid;
2937-- result --
2938faceid
2939--------
2940 1
2941
2942</programlisting>
2943			</refsection>
2944
2945			<!-- Optionally add a "See Also" section -->
2946			<refsection>
2947				<title>See Also</title>
2948				<para><xref linkend="AddEdge"/>, <xref linkend="CreateTopology"/>, <xref linkend="spatial_ref_sys"/></para>
2949			</refsection>
2950		</refentry>
2951
2952	<refentry id="TP_ST_Simplify">
2953	  <refnamediv>
2954		<refname>ST_Simplify</refname>
2955		<refpurpose>Returns a "simplified" geometry version of the given TopoGeometry using
2956				the Douglas-Peucker algorithm.</refpurpose>
2957	  </refnamediv>
2958
2959	  <refsynopsisdiv>
2960		<funcsynopsis>
2961		  <funcprototype>
2962			<funcdef>geometry <function>ST_Simplify</function></funcdef>
2963			<paramdef><type>TopoGeometry</type> <parameter>tg</parameter></paramdef>
2964			<paramdef><type>float8</type> <parameter>tolerance</parameter></paramdef>
2965		  </funcprototype>
2966		</funcsynopsis>
2967	  </refsynopsisdiv>
2968
2969	  <refsection>
2970		<title>Description</title>
2971		<para>Returns a "simplified" geometry version of the given TopoGeometry using
2972				the Douglas-Peucker algorithm on each component edge.</para>
2973
2974		<note><para>The returned geometry may be non-simple or non-valid.</para>
2975    <para>Splitting component edges may help retaining simplicity/validity.</para></note>
2976
2977		<para>Performed by the GEOS module.</para>
2978		<para>Availability: 2.1.0</para>
2979	  </refsection>
2980
2981		  <refsection>
2982			<title>See Also</title>
2983			<para>Geometry <xref linkend="ST_Simplify" />, <xref linkend="ST_IsSimple" />, <xref linkend="ST_IsValid" />, <xref linkend="ST_ModEdgeSplit" /></para>
2984		  </refsection>
2985	</refentry>
2986
2987
2988	</sect1>
2989
2990	<sect1 id="TopoGeometry_Constructors">
2991    <sect1info>
2992        <abstract>
2993            <para>This section covers the topology functions for creating new topogeometries.</para>
2994        </abstract>
2995    </sect1info>
2996	  <title>TopoGeometry Constructors</title>
2997		<refentry id="CreateTopoGeom">
2998			<refnamediv>
2999				<refname>CreateTopoGeom</refname>
3000
3001				<refpurpose>Creates a new topo geometry object from topo element array - tg_type: 1:[multi]point, 2:[multi]line, 3:[multi]poly, 4:collection</refpurpose>
3002			</refnamediv>
3003
3004			<refsynopsisdiv>
3005				<funcsynopsis>
3006					<funcprototype>
3007					<funcdef>topogeometry <function>CreateTopoGeom</function></funcdef>
3008					<paramdef><type>varchar </type> <parameter>toponame</parameter></paramdef>
3009					<paramdef><type>integer </type> <parameter>tg_type</parameter></paramdef>
3010					<paramdef><type>integer</type> <parameter>layer_id</parameter></paramdef>
3011					<paramdef><type>topoelementarray</type> <parameter>tg_objs</parameter></paramdef>
3012					</funcprototype>
3013
3014					<funcprototype>
3015					<funcdef>topogeometry <function>CreateTopoGeom</function></funcdef>
3016					<paramdef><type>varchar </type> <parameter>toponame</parameter></paramdef>
3017					<paramdef><type>integer </type> <parameter>tg_type</parameter></paramdef>
3018					<paramdef><type>integer</type> <parameter>layer_id</parameter></paramdef>
3019					</funcprototype>
3020				</funcsynopsis>
3021			</refsynopsisdiv>
3022
3023			<refsection>
3024                <title>Description</title>
3025
3026                <para>Creates a topogeometry object for layer denoted by <varname>layer_id</varname> and registers it in the relations table in the <varname>toponame</varname> schema.</para>
3027                <para><varname>tg_type</varname> is an integer: 1:[multi]point (punctal), 2:[multi]line (lineal), 3:[multi]poly (areal), 4:collection. <varname>layer_id</varname> is the layer id in the topology.layer table.</para>
3028                <para>punctal layers are formed from set of nodes, lineal layers are formed from a set of edges, areal layers are formed from a set of faces,
3029	and collections can be formed from a mixture of nodes, edges, and faces.</para>
3030                <para>Omitting the array of components generates an empty TopoGeometry object.</para>
3031                <!-- use this format if new function -->
3032                <para>Availability: 1.?</para>
3033			</refsection>
3034
3035
3036			<refsection>
3037				<title>Examples: Form from existing edges</title>
3038				<para>Create a topogeom in ri_topo schema for layer 2 (our ri_roads), of type (2) LINE, for the first edge (we loaded in <varname>ST_CreateTopoGeo</varname>).</para>
3039				<programlisting>INSERT INTO ri.ri_roads(road_name, topo) VALUES('Unknown', topology.CreateTopoGeom('ri_topo',2,2,'{{1,2}}'::topology.topoelementarray);</programlisting>
3040
3041			</refsection>
3042
3043			<refsection>
3044				<title>Examples: Convert an areal geometry to best guess topogeometry</title>
3045				<para>Lets say we have geometries that should be formed from a collection of faces. We have for example blockgroups table
3046					and want to know the topo geometry of each block group. If our data was perfectly aligned, we could do this:</para>
3047				<programlisting>
3048-- create our topo geometry column --
3049SELECT topology.AddTopoGeometryColumn(
3050	'topo_boston',
3051	'boston', 'blockgroups', 'topo', 'POLYGON');
3052
3053-- addtopgeometrycolumn --
30541
3055
3056-- update our column assuming
3057-- everything is perfectly aligned with our edges
3058UPDATE boston.blockgroups AS bg
3059	SET topo = topology.CreateTopoGeom('topo_boston'
3060        ,3,1
3061        , foo.bfaces)
3062FROM (SELECT b.gid,  topology.TopoElementArray_Agg(ARRAY[f.face_id,3]) As bfaces
3063	FROM boston.blockgroups As b
3064            INNER JOIN topo_boston.face As f ON b.geom &amp;&amp; f.mbr
3065        WHERE ST_Covers(b.geom, topology.ST_GetFaceGeometry('topo_boston', f.face_id))
3066            GROUP BY b.gid) As foo
3067WHERE foo.gid = bg.gid;
3068</programlisting>
3069
3070<programlisting>
3071--the world is rarely perfect allow for some error
3072--count the face if 50% of it falls
3073-- within what we think is our blockgroup boundary
3074UPDATE boston.blockgroups AS bg
3075	SET topo = topology.CreateTopoGeom('topo_boston'
3076        ,3,1
3077        , foo.bfaces)
3078FROM (SELECT b.gid,  topology.TopoElementArray_Agg(ARRAY[f.face_id,3]) As bfaces
3079	FROM boston.blockgroups As b
3080            INNER JOIN topo_boston.face As f ON b.geom &amp;&amp; f.mbr
3081        WHERE ST_Covers(b.geom, topology.ST_GetFaceGeometry('topo_boston', f.face_id))
3082	OR
3083 (  ST_Intersects(b.geom, topology.ST_GetFaceGeometry('topo_boston', f.face_id))
3084            AND ST_Area(ST_Intersection(b.geom, topology.ST_GetFaceGeometry('topo_boston', f.face_id) ) ) >
3085                ST_Area(topology.ST_GetFaceGeometry('topo_boston', f.face_id))*0.5
3086                )
3087            GROUP BY b.gid) As foo
3088WHERE foo.gid = bg.gid;
3089
3090-- and if we wanted to convert our topogeometry back
3091-- to a denormalized geometry aligned with our faces and edges
3092-- cast the topo to a geometry
3093-- The really cool thing is my new geometries
3094-- are now aligned with my tiger street centerlines
3095UPDATE boston.blockgroups SET new_geom = topo::geometry;
3096</programlisting>
3097			</refsection>
3098
3099			<!-- Optionally add a "See Also" section -->
3100			<refsection>
3101				<title>See Also</title>
3102				<para>
3103<xref linkend="AddTopoGeometryColumn"/>,
3104<xref linkend="toTopoGeom" />
3105<xref linkend="ST_CreateTopoGeo" />,
3106<xref linkend="ST_GetFaceGeometry"/>,
3107<xref linkend="topoelementarray" />,
3108<xref linkend="TopoElementArray_Agg" />
3109				</para>
3110			</refsection>
3111		</refentry>
3112
3113		<refentry id="toTopoGeom">
3114			<refnamediv>
3115				<refname>toTopoGeom</refname>
3116
3117				<refpurpose>Converts a simple Geometry into a topo geometry.</refpurpose>
3118			</refnamediv>
3119
3120			<refsynopsisdiv>
3121				<funcsynopsis>
3122					<funcprototype>
3123					<funcdef>topogeometry <function>toTopoGeom</function></funcdef>
3124					<paramdef><type>geometry </type> <parameter>geom</parameter></paramdef>
3125					<paramdef><type>varchar </type> <parameter>toponame</parameter></paramdef>
3126					<paramdef><type>integer</type> <parameter>layer_id</parameter></paramdef>
3127					<paramdef choice="opt"><type>float8</type> <parameter>tolerance</parameter></paramdef>
3128					</funcprototype>
3129
3130					<funcprototype>
3131					<funcdef>topogeometry <function>toTopoGeom</function></funcdef>
3132					<paramdef><type>geometry </type> <parameter>geom</parameter></paramdef>
3133					<paramdef><type>topogeometry </type> <parameter>topogeom</parameter></paramdef>
3134					<paramdef choice="opt"><type>float8</type> <parameter>tolerance</parameter></paramdef>
3135					</funcprototype>
3136				</funcsynopsis>
3137			</refsynopsisdiv>
3138
3139			<refsection>
3140                <title>Description</title>
3141
3142                <para>
3143Converts a simple Geometry into a <xref linkend="topogeometry" />.
3144                </para>
3145
3146                <para>
3147Topological primitives required to represent the input geometry will be
3148added to the underlying topology, possibly splitting existing ones,
3149and they will be associated with the output TopoGeometry in the
3150<varname>relation</varname> table.
3151                </para>
3152
3153                <para>
3154Existing TopoGeometry objects (with the possible exception of
3155<varname>topogeom</varname>, if given) will retain their shapes.
3156                </para>
3157
3158                <para>
3159When <varname>tolerance</varname> is given it will be used to snap the
3160input geometry to existing primitives.
3161                </para>
3162
3163                <para>
3164In the first form a new TopoGeometry will be created for the given
3165layer (<varname>layer_id</varname>) of the given topology (<varname>toponame</varname>).
3166                </para>
3167
3168                <para>
3169In the second form the primitives resulting from the conversion will be
3170added to the pre-existing TopoGeometry (<varname>topogeom</varname>),
3171possibly adding space to its final shape. To have the new shape completely
3172replace the old one see <xref linkend="clearTopoGeom" />.
3173                </para>
3174
3175                <!-- use this format if new function -->
3176                <para>Availability: 2.0</para>
3177                <para>Enhanced: 2.1.0 adds the version taking an existing TopoGeometry.</para>
3178			</refsection>
3179			<refsection>
3180				<title>Examples</title>
3181				<para>This is a full self-contained workflow</para>
3182				<programlisting> -- do this if you don't have a topology setup already
3183-- creates topology not allowing any tolerance
3184SELECT topology.CreateTopology('topo_boston_test', 2249);
3185-- create a new table
3186CREATE TABLE nei_topo(gid serial primary key, nei varchar(30));
3187--add a topogeometry column to it
3188SELECT topology.AddTopoGeometryColumn('topo_boston_test', 'public', 'nei_topo', 'topo', 'MULTIPOLYGON') As new_layer_id;
3189new_layer_id
3190-----------
31911
3192
3193--use new layer id in populating the new topogeometry column
3194-- we add the topogeoms to the new layer with 0 tolerance
3195INSERT INTO nei_topo(nei, topo)
3196SELECT nei,  topology.toTopoGeom(geom, 'topo_boston_test', 1)
3197FROM neighborhoods
3198WHERE gid BETWEEN 1 and 15;
3199
3200--use to verify what has happened --
3201SELECT * FROM
3202    topology.TopologySummary('topo_boston_test');
3203
3204-- summary--
3205Topology topo_boston_test (5), SRID 2249, precision 0
320661 nodes, 87 edges, 35 faces, 15 topogeoms in 1 layers
3207Layer 1, type Polygonal (3), 15 topogeoms
3208 Deploy: public.nei_topo.topo</programlisting>
3209
3210        <programlisting>
3211-- Shrink all TopoGeometry polygons by 10 meters
3212UPDATE nei_topo SET topo = ST_Buffer(clearTopoGeom(topo), -10);
3213
3214-- Get the no-one-lands left by the above operation
3215-- I think GRASS calls this "polygon0 layer"
3216SELECT ST_GetFaceGeometry('topo_boston_test', f.face_id)
3217  FROM topo_boston_test.face f
3218  WHERE f.face_id > 0 -- don't consider the universe face
3219  AND NOT EXISTS ( -- check that no TopoGeometry references the face
3220    SELECT * FROM topo_boston_test.relation
3221    WHERE layer_id = 1 AND element_id = f.face_id
3222  );
3223        </programlisting>
3224			</refsection>
3225
3226			<!-- Optionally add a "See Also" section -->
3227			<refsection>
3228				<title>See Also</title>
3229        <para>
3230<xref linkend="CreateTopology" />,
3231<xref linkend="AddTopoGeometryColumn"/>,
3232<xref linkend="CreateTopoGeom" />,
3233<xref linkend="TopologySummary" />,
3234<xref linkend="clearTopoGeom" />
3235        </para>
3236			</refsection>
3237		</refentry>
3238
3239		<refentry id="TopoElementArray_Agg">
3240          <refnamediv>
3241            <refname>TopoElementArray_Agg</refname>
3242            <refpurpose>Returns a <varname>topoelementarray</varname> for a set of element_id, type arrays (topoelements).</refpurpose>
3243          </refnamediv>
3244
3245          <refsynopsisdiv>
3246            <funcsynopsis>
3247              <funcprototype>
3248                <funcdef>topoelementarray <function>TopoElementArray_Agg</function></funcdef>
3249                <paramdef><type>topoelement set</type> <parameter>tefield</parameter></paramdef>
3250              </funcprototype>
3251            </funcsynopsis>
3252          </refsynopsisdiv>
3253
3254	<refsection>
3255                <title>Description</title>
3256
3257                <para>Used to create a <xref linkend="topoelementarray" /> from a set of <xref linkend="topoelement" />.</para>
3258
3259                <!-- use this format if new function -->
3260                <para>Availability: 2.0.0</para>
3261			</refsection>
3262
3263
3264			<refsection>
3265				<title>Examples</title>
3266				<programlisting>SELECT topology.TopoElementArray_Agg(ARRAY[e,t]) As tea
3267  FROM generate_series(1,3) As e CROSS JOIN generate_series(1,4) As t;
3268  tea
3269--------------------------------------------------------------------------
3270{{1,1},{1,2},{1,3},{1,4},{2,1},{2,2},{2,3},{2,4},{3,1},{3,2},{3,3},{3,4}}</programlisting>
3271			</refsection>
3272			<refsection>
3273				<title>See Also</title>
3274				<para><xref linkend="topoelement"/>, <xref linkend="topoelementarray"/></para>
3275			</refsection>
3276          </refentry>
3277	</sect1>
3278
3279	<sect1 id="TopoGeometry_Editors">
3280    <sect1info>
3281        <abstract>
3282            <para>This section covers the topology functions for editing existing topogeometries.</para>
3283        </abstract>
3284    </sect1info>
3285	  <title>TopoGeometry Editors</title>
3286
3287		<refentry id="clearTopoGeom">
3288			<refnamediv>
3289				<refname>clearTopoGeom</refname>
3290
3291				<refpurpose>Clears the content of a topo geometry.</refpurpose>
3292			</refnamediv>
3293
3294			<refsynopsisdiv>
3295				<funcsynopsis>
3296					<funcprototype>
3297					<funcdef>topogeometry <function>clearTopoGeom</function></funcdef>
3298					<paramdef><type>topogeometry </type> <parameter>topogeom</parameter></paramdef>
3299					</funcprototype>
3300				</funcsynopsis>
3301			</refsynopsisdiv>
3302
3303			<refsection>
3304                <title>Description</title>
3305
3306                <para>
3307Clears the content a <xref linkend="topogeometry" />
3308turning it into an empty one. Mostly useful in conjunction with <xref
3309linkend="toTopoGeom" /> to replace the shape of existing
3310objects and any dependent object in higher hierarchical levels.
3311                </para>
3312
3313                <!-- use this format if new function -->
3314                <para>Availability: 2.1</para>
3315			</refsection>
3316			<refsection>
3317				<title>Examples</title>
3318        <programlisting>
3319-- Shrink all TopoGeometry polygons by 10 meters
3320UPDATE nei_topo SET topo = ST_Buffer(clearTopoGeom(topo), -10);
3321				</programlisting>
3322			</refsection>
3323
3324			<!-- Optionally add a "See Also" section -->
3325			<refsection>
3326				<title>See Also</title>
3327        <para>
3328<xref linkend="toTopoGeom" />
3329        </para>
3330			</refsection>
3331		</refentry>
3332
3333    <refentry id="TopoGeom_addElement">
3334			<refnamediv>
3335				<refname>TopoGeom_addElement</refname>
3336				<refpurpose>Adds an element to the definition of a TopoGeometry.</refpurpose>
3337			</refnamediv>
3338			<refsynopsisdiv>
3339				<funcsynopsis>
3340					<funcprototype>
3341					<funcdef>topogeometry <function>TopoGeom_addElement</function></funcdef>
3342					<paramdef><type>topogeometry </type> <parameter>tg</parameter></paramdef>
3343          <paramdef><type>topoelement </type> <parameter>el</parameter></paramdef>
3344					</funcprototype>
3345				</funcsynopsis>
3346			</refsynopsisdiv>
3347
3348			<refsection>
3349                <title>Description</title>
3350
3351                <para>
3352Adds a <xref linkend="topoelement" /> to the definition of a
3353TopoGeometry object. Does not error out if the element is already
3354part of the definition.
3355                </para>
3356
3357                <!-- use this format if new function -->
3358                <para>Availability: 2.3</para>
3359			</refsection>
3360			<refsection>
3361				<title>Examples</title>
3362        <programlisting>
3363-- Add edge 5 to TopoGeometry tg
3364UPDATE mylayer SET tg = TopoGeom_addElement(tg, '{5,2}');
3365				</programlisting>
3366			</refsection>
3367
3368			<!-- Optionally add a "See Also" section -->
3369			<refsection>
3370				<title>See Also</title>
3371        <para>
3372<xref linkend="TopoGeom_remElement" />,
3373<xref linkend="CreateTopoGeom" />
3374        </para>
3375			</refsection>
3376		</refentry>
3377
3378    <refentry id="TopoGeom_remElement">
3379			<refnamediv>
3380				<refname>TopoGeom_remElement</refname>
3381
3382				<refpurpose>Removes an element from the definition of a TopoGeometry.</refpurpose>
3383			</refnamediv>
3384
3385			<refsynopsisdiv>
3386				<funcsynopsis>
3387					<funcprototype>
3388					<funcdef>topogeometry <function>TopoGeom_remElement</function></funcdef>
3389					<paramdef><type>topogeometry </type> <parameter>tg</parameter></paramdef>
3390          <paramdef><type>topoelement </type> <parameter>el</parameter></paramdef>
3391					</funcprototype>
3392				</funcsynopsis>
3393			</refsynopsisdiv>
3394
3395			<refsection>
3396                <title>Description</title>
3397
3398                <para>
3399Removes a <xref linkend="topoelement" /> from the definition of a
3400TopoGeometry object.
3401                </para>
3402
3403                <!-- use this format if new function -->
3404                <para>Availability: 2.3</para>
3405			</refsection>
3406			<refsection>
3407				<title>Examples</title>
3408        <programlisting>
3409-- Remove face 43 from TopoGeometry tg
3410UPDATE mylayer SET tg = TopoGeom_remElement(tg, '{43,3}');
3411				</programlisting>
3412			</refsection>
3413
3414			<!-- Optionally add a "See Also" section -->
3415			<refsection>
3416				<title>See Also</title>
3417        <para>
3418<xref linkend="TopoGeom_addElement" />,
3419<xref linkend="CreateTopoGeom" />
3420        </para>
3421			</refsection>
3422		</refentry>
3423
3424    <refentry id="TopoGeom_addTopoGeom">
3425			<refnamediv>
3426				<refname>TopoGeom_addTopoGeom</refname>
3427				<refpurpose>Adds element of a TopoGeometry to the definition of another TopoGeometry.</refpurpose>
3428			</refnamediv>
3429			<refsynopsisdiv>
3430				<funcsynopsis>
3431					<funcprototype>
3432					<funcdef>topogeometry <function>TopoGeom_addTopoGeom</function></funcdef>
3433					<paramdef><type>topogeometry </type> <parameter>tgt</parameter></paramdef>
3434                    <paramdef><type>topogeometry </type> <parameter>src</parameter></paramdef>
3435					</funcprototype>
3436				</funcsynopsis>
3437			</refsynopsisdiv>
3438
3439			<refsection>
3440                <title>Description</title>
3441
3442                <para>
3443Adds the elements of a <xref linkend="topogeometry" /> to the definition of
3444another TopoGeometry, possibly changing its cached type (type attribute)
3445to a collection, if needed to hold all elements in the source object.
3446                </para>
3447
3448                <para>
3449The two TopoGeometry objects need be defined against the *same*
3450topology and, if hierarchically defined, need be composed by elements
3451of the same child layer.
3452                </para>
3453
3454                <!-- use this format if new function -->
3455                <para>Availability: 3.2</para>
3456			</refsection>
3457			<refsection>
3458				<title>Examples</title>
3459        <programlisting>
3460-- Set an "overall" TopoGeometry value to be composed by all
3461-- elements of specific TopoGeometry values
3462UPDATE mylayer SET tg_overall = TopoGeom_addTopogeom(
3463    TopoGeom_addTopoGeom(
3464        clearTopoGeom(tg_overall),
3465        tg_specific1
3466    ),
3467    tg_specific2
3468);
3469				</programlisting>
3470			</refsection>
3471
3472			<!-- Optionally add a "See Also" section -->
3473			<refsection>
3474				<title>See Also</title>
3475        <para>
3476<xref linkend="TopoGeom_addElement" />,
3477<xref linkend="clearTopoGeom" />,
3478<xref linkend="CreateTopoGeom" />
3479        </para>
3480			</refsection>
3481		</refentry>
3482
3483    <refentry id="toTopoGeom_editor_proxy">
3484			<refnamediv>
3485        <refname>toTopoGeom</refname>
3486				<refpurpose>Adds a geometry shape to an existing topo geometry.</refpurpose>
3487			</refnamediv>
3488			<refsection>
3489                <title>Description</title>
3490<para>
3491Refer to <xref linkend="toTopoGeom" />.
3492</para>
3493      </refsection>
3494    </refentry>
3495
3496
3497	</sect1>
3498
3499	<sect1 id="TopoGeom_Accessors">
3500	  <title>TopoGeometry Accessors</title>
3501
3502	      <refentry id="GetTopoGeomElementArray">
3503			<refnamediv>
3504				<refname>GetTopoGeomElementArray</refname>
3505
3506				<refpurpose>Returns a <varname>topoelementarray</varname> (an array of topoelements) containing the topological elements and type of the given TopoGeometry (primitive elements).</refpurpose>
3507			</refnamediv>
3508
3509			<refsynopsisdiv>
3510				<funcsynopsis>
3511					<funcprototype>
3512					<funcdef>topoelementarray <function>GetTopoGeomElementArray</function></funcdef>
3513					<paramdef><type>varchar </type> <parameter>toponame</parameter></paramdef>
3514					<paramdef><type>integer </type> <parameter>layer_id</parameter></paramdef>
3515					<paramdef><type>integer</type> <parameter>tg_id</parameter></paramdef>
3516					</funcprototype>
3517				</funcsynopsis>
3518				<funcsynopsis>
3519					<funcprototype>
3520					<funcdef>topoelementarray topoelement <function>GetTopoGeomElementArray</function></funcdef>
3521					<paramdef><type>topogeometry </type> <parameter>tg</parameter></paramdef>
3522					</funcprototype>
3523				</funcsynopsis>
3524			</refsynopsisdiv>
3525
3526			<refsection>
3527                <title>Description</title>
3528
3529                <para>Returns a <xref linkend="topoelementarray"/> containing the topological elements and type of the given TopoGeometry (primitive elements).  This is similar to GetTopoGeomElements except it returns the elements as an array rather
3530                than as a dataset.</para>
3531                <para>tg_id is the topogeometry id of the topogeometry object in the topology in the layer denoted by <varname>layer_id</varname> in the topology.layer table.</para>
3532
3533                <!-- use this format if new function -->
3534                <para>Availability: 1.?</para>
3535			</refsection>
3536
3537
3538			<refsection>
3539				<title>Examples</title>
3540				<para/>
3541				<!-- TODO: -->
3542			</refsection>
3543
3544			<!-- Optionally add a "See Also" section -->
3545			<refsection>
3546				<title>See Also</title>
3547				<para><xref linkend="GetTopoGeomElements"/>, <xref linkend="topoelementarray"/></para>
3548			</refsection>
3549		</refentry>
3550		<refentry id="GetTopoGeomElements">
3551			<refnamediv>
3552				<refname>GetTopoGeomElements</refname>
3553
3554				<refpurpose>Returns a set of <varname>topoelement</varname> objects containing the topological element_id,element_type of the given TopoGeometry (primitive elements).</refpurpose>
3555			</refnamediv>
3556
3557			<refsynopsisdiv>
3558				<funcsynopsis>
3559					<funcprototype>
3560					<funcdef>setof topoelement <function>GetTopoGeomElements</function></funcdef>
3561					<paramdef><type>varchar </type> <parameter>toponame</parameter></paramdef>
3562					<paramdef><type>integer </type> <parameter>layer_id</parameter></paramdef>
3563					<paramdef><type>integer</type> <parameter>tg_id</parameter></paramdef>
3564					</funcprototype>
3565				</funcsynopsis>
3566				<funcsynopsis>
3567					<funcprototype>
3568					<funcdef>setof topoelement <function>GetTopoGeomElements</function></funcdef>
3569					<paramdef><type>topogeometry </type> <parameter>tg</parameter></paramdef>
3570					</funcprototype>
3571				</funcsynopsis>
3572			</refsynopsisdiv>
3573
3574			<refsection>
3575                <title>Description</title>
3576
3577                <para>Returns a set of element_id,element_type (topoelements) for a given topogeometry object in <varname>toponame</varname> schema.</para>
3578                <para>tg_id is the topogeometry id of the topogeometry object in the topology in the layer denoted by <varname>layer_id</varname> in the topology.layer table.</para>
3579
3580                <!-- use this format if new function -->
3581                <para>Availability: 2.0.0</para>
3582			</refsection>
3583
3584
3585			<refsection>
3586				<title>Examples</title>
3587				<para/>
3588				<!-- TODO: -->
3589			</refsection>
3590
3591			<!-- Optionally add a "See Also" section -->
3592			<refsection>
3593				<title>See Also</title>
3594				<para>
3595          <xref linkend="GetTopoGeomElementArray"/>,
3596          <xref linkend="topoelement"/>,
3597          <xref linkend="TopoGeom_addElement" />,
3598          <xref linkend="TopoGeom_remElement" />
3599        </para>
3600			</refsection>
3601		</refentry>
3602
3603	</sect1>
3604
3605
3606	<sect1 id="TopoGeometry_Outputs">
3607	  <title>TopoGeometry Outputs</title>
3608	  <refentry id="AsGML">
3609		    <refnamediv>
3610				<refname>AsGML</refname>
3611
3612				<refpurpose>Returns the GML representation of a topogeometry.</refpurpose>
3613			</refnamediv>
3614
3615			<refsynopsisdiv>
3616				<funcsynopsis>
3617					<funcprototype>
3618                        <funcdef>text <function>AsGML</function></funcdef>
3619                        <paramdef><type>topogeometry </type> <parameter>tg</parameter></paramdef>
3620					</funcprototype>
3621					<funcprototype>
3622                        <funcdef>text <function>AsGML</function></funcdef>
3623                        <paramdef><type>topogeometry </type> <parameter>tg</parameter></paramdef>
3624                        <paramdef><type>text </type> <parameter>nsprefix_in</parameter></paramdef>
3625					</funcprototype>
3626					<funcprototype>
3627                        <funcdef>text <function>AsGML</function></funcdef>
3628                        <paramdef><type>topogeometry </type> <parameter>tg</parameter></paramdef>
3629                        <paramdef><type>regclass </type> <parameter>visitedTable</parameter></paramdef>
3630					</funcprototype>
3631					<funcprototype>
3632                        <funcdef>text <function>AsGML</function></funcdef>
3633                        <paramdef><type>topogeometry </type> <parameter>tg</parameter></paramdef>
3634                        <paramdef><type>regclass </type> <parameter>visitedTable</parameter></paramdef>
3635                        <paramdef><type>text </type> <parameter>nsprefix</parameter></paramdef>
3636					</funcprototype>
3637					<funcprototype>
3638                        <funcdef>text <function>AsGML</function></funcdef>
3639                        <paramdef><type>topogeometry </type> <parameter>tg</parameter></paramdef>
3640                        <paramdef><type>text </type> <parameter>nsprefix_in</parameter></paramdef>
3641                        <paramdef><type>integer </type> <parameter>precision</parameter></paramdef>
3642                        <paramdef><type>integer </type> <parameter>options</parameter></paramdef>
3643					</funcprototype>
3644					<funcprototype>
3645                        <funcdef>text <function>AsGML</function></funcdef>
3646                        <paramdef><type>topogeometry </type> <parameter>tg</parameter></paramdef>
3647                        <paramdef><type>text </type> <parameter>nsprefix_in</parameter></paramdef>
3648                        <paramdef><type>integer </type> <parameter>precision</parameter></paramdef>
3649                        <paramdef><type>integer </type> <parameter>options</parameter></paramdef>
3650                        <paramdef><type>regclass </type> <parameter>visitedTable</parameter></paramdef>
3651					</funcprototype>
3652					<funcprototype>
3653                        <funcdef>text <function>AsGML</function></funcdef>
3654                        <paramdef><type>topogeometry </type> <parameter>tg</parameter></paramdef>
3655                        <paramdef><type>text </type> <parameter>nsprefix_in</parameter></paramdef>
3656                        <paramdef><type>integer </type> <parameter>precision</parameter></paramdef>
3657                        <paramdef><type>integer </type> <parameter>options</parameter></paramdef>
3658                        <paramdef><type>regclass </type> <parameter>visitedTable</parameter></paramdef>
3659                        <paramdef><type>text </type> <parameter>idprefix</parameter></paramdef>
3660					</funcprototype>
3661					<funcprototype>
3662                        <funcdef>text <function>AsGML</function></funcdef>
3663                        <paramdef><type>topogeometry </type> <parameter>tg</parameter></paramdef>
3664                        <paramdef><type>text </type> <parameter>nsprefix_in</parameter></paramdef>
3665                        <paramdef><type>integer </type> <parameter>precision</parameter></paramdef>
3666                        <paramdef><type>integer </type> <parameter>options</parameter></paramdef>
3667                        <paramdef><type>regclass </type> <parameter>visitedTable</parameter></paramdef>
3668                        <paramdef><type>text </type> <parameter>idprefix</parameter></paramdef>
3669                        <paramdef><type>int </type> <parameter>gmlversion</parameter></paramdef>
3670					</funcprototype>
3671				</funcsynopsis>
3672			</refsynopsisdiv>
3673
3674			<refsection>
3675                <title>Description</title>
3676
3677                <para>Returns the GML representation of a topogeometry in version GML3 format. If no <varname>nsprefix_in</varname> is specified then <varname>gml</varname> is used. Pass in an empty string for nsprefix to get a non-qualified name space. The precision (default: 15) and options (default 1) parameters, if given, are passed untouched to the underlying call to ST_AsGML.</para>
3678
3679		<para>
3680The <varname>visitedTable</varname> parameter, if given, is used for keeping track of the visited Node and Edge elements so to use cross-references (xlink:xref) rather than duplicating definitions. The table is expected to have (at least) two integer fields: 'element_type' and 'element_id'. The calling user must have both read and write privileges on the given table.
3681For best performance, an index should be defined on
3682<varname>element_type</varname> and <varname>element_id</varname>,
3683in that order. Such index would be created automatically by adding a unique
3684constraint to the fields. Example:
3685<programlisting>
3686CREATE TABLE visited (
3687  element_type integer, element_id integer,
3688  unique(element_type, element_id)
3689);
3690</programlisting>
3691		</para>
3692
3693		<para>The <varname>idprefix</varname> parameter, if given, will be prepended to Edge and Node tag identifiers.</para>
3694
3695		<para>The <varname>gmlver</varname> parameter, if given, will be passed to the underlying ST_AsGML. Defaults to 3.</para>
3696
3697                <!-- use this format if new function -->
3698                <para>Availability: 2.0.0 </para>
3699			</refsection>
3700
3701
3702			<refsection>
3703				<title>Examples</title>
3704				<para>This uses the topo geometry we created in <xref linkend="CreateTopoGeom" /></para>
3705				<programlisting>SELECT topology.AsGML(topo) As rdgml
3706  FROM ri.roads
3707  WHERE road_name = 'Unknown';
3708
3709-- rdgml--
3710<![CDATA[<gml:TopoCurve>
3711    <gml:directedEdge>
3712        <gml:Edge gml:id="E1">
3713            <gml:directedNode orientation="-">
3714                <gml:Node gml:id="N1"/>
3715            </gml:directedNode>
3716            <gml:directedNode></gml:directedNode>
3717            <gml:curveProperty>
3718                <gml:Curve srsName="urn:ogc:def:crs:EPSG::3438">
3719                    <gml:segments>
3720                        <gml:LineStringSegment>
3721                            <gml:posList srsDimension="2">384744 236928 384750 236923 384769 236911 384799 236895 384811 236890
3722                            384833 236884 384844 236882 384866 236881 384879 236883 384954 236898 385087 236932 385117 236938
3723                            385167 236938 385203 236941 385224 236946 385233 236950 385241 236956 385254 236971
3724                            385260 236979 385268 236999 385273 237018 385273 237037 385271 237047 385267 237057 385225 237125
3725                            385210 237144 385192 237161 385167 237192 385162 237202 385159 237214 385159 237227 385162 237241
3726                            385166 237256 385196 237324 385209 237345 385234 237375 385237 237383 385238 237399 385236 237407
3727                            385227 237419 385213 237430 385193 237439 385174 237451 385170 237455 385169 237460 385171 237475
3728                            385181 237503 385190 237521 385200 237533 385206 237538 385213 237541 385221 237542 385235 237540 385242 237541
3729                            385249 237544 385260 237555 385270 237570 385289 237584 385292 237589 385291 237596 385284 237630</gml:posList>
3730                        </gml:LineStringSegment>
3731                    </gml:segments>
3732                </gml:Curve>
3733            </gml:curveProperty>
3734        </gml:Edge>
3735    </gml:directedEdge>
3736</gml:TopoCurve>]]>
3737</programlisting>
3738<para>Same exercise as previous without namespace</para>
3739<programlisting>SELECT topology.AsGML(topo,'') As rdgml
3740  FROM ri.roads
3741  WHERE road_name = 'Unknown';
3742
3743-- rdgml--
3744<![CDATA[<TopoCurve>
3745    <directedEdge>
3746        <Edge id="E1">
3747            <directedNode orientation="-">
3748                <Node id="N1"/>
3749            </directedNode>
3750            <directedNode></directedNode>
3751            <curveProperty>
3752                <Curve srsName="urn:ogc:def:crs:EPSG::3438">
3753                    <segments>
3754                        <LineStringSegment>
3755                            <posList srsDimension="2">384744 236928 384750 236923 384769 236911 384799 236895 384811 236890
3756                            384833 236884 384844 236882 384866 236881 384879 236883 384954 236898 385087 236932 385117 236938
3757                            385167 236938 385203 236941 385224 236946 385233 236950 385241 236956 385254 236971
3758                            385260 236979 385268 236999 385273 237018 385273 237037 385271 237047 385267 237057 385225 237125
3759                            385210 237144 385192 237161 385167 237192 385162 237202 385159 237214 385159 237227 385162 237241
3760                            385166 237256 385196 237324 385209 237345 385234 237375 385237 237383 385238 237399 385236 237407
3761                            385227 237419 385213 237430 385193 237439 385174 237451 385170 237455 385169 237460 385171 237475
3762                            385181 237503 385190 237521 385200 237533 385206 237538 385213 237541 385221 237542 385235 237540 385242 237541
3763                            385249 237544 385260 237555 385270 237570 385289 237584 385292 237589 385291 237596 385284 237630</posList>
3764                         </LineStringSegment>
3765                    </segments>
3766                </Curve>
3767            </curveProperty>
3768        </Edge>
3769    </directedEdge>
3770</TopoCurve>]]>
3771</programlisting>
3772			</refsection>
3773
3774			<!-- Optionally add a "See Also" section -->
3775			<refsection>
3776				<title>See Also</title>
3777				<para><xref linkend="CreateTopoGeom"/>, <xref linkend="ST_CreateTopoGeo" /></para>
3778			</refsection>
3779	  </refentry>
3780	  <refentry id="AsTopoJSON">
3781		    <refnamediv>
3782				<refname>AsTopoJSON</refname>
3783
3784				<refpurpose>Returns the TopoJSON representation of a topogeometry.</refpurpose>
3785			</refnamediv>
3786
3787			<refsynopsisdiv>
3788				<funcsynopsis>
3789					<funcprototype>
3790                        <funcdef>text <function>AsTopoJSON</function></funcdef>
3791                        <paramdef><type>topogeometry </type> <parameter>tg</parameter></paramdef>
3792                        <paramdef><type>regclass </type> <parameter>edgeMapTable</parameter></paramdef>
3793					</funcprototype>
3794				</funcsynopsis>
3795			</refsynopsisdiv>
3796
3797			<refsection>
3798                <title>Description</title>
3799
3800                <para>Returns the TopoJSON representation of a topogeometry. If <varname>edgeMapTable</varname> is not null, it will be used as a lookup/storage mapping of edge identifiers to arc indices. This is to be able to allow for a compact "arcs" array in the final document.
3801</para>
3802
3803<para>
3804The table, if given, is expected to have an "arc_id" field of type "serial" and an "edge_id" of type integer; the code will query the table for "edge_id" so it is recommended to add an index on that field.
3805</para>
3806
3807		<note>
3808<para>
3809Arc indices in the TopoJSON output are 0-based but they are 1-based
3810in the "edgeMapTable" table.
3811</para>
3812    </note>
3813
3814		<para>
3815A full TopoJSON document will be need to contain, in
3816addition to the snippets returned by this function,
3817the actual arcs plus some headers. See the <ulink
3818url="http://github.com/mbostock/topojson-specification/blob/master/README.md"
3819>TopoJSON specification</ulink>.
3820		</para>
3821
3822                <!-- use this format if new function -->
3823                <para>Availability: 2.1.0 </para>
3824                <para>Enhanced: 2.2.1 added support for puntal inputs</para>
3825			</refsection>
3826
3827
3828			<!-- Optionally add a "See Also" section -->
3829			<refsection>
3830				<title>See Also</title>
3831				<para><xref linkend="ST_AsGeoJSON" /></para>
3832			</refsection>
3833
3834            <refsection>
3835                <title>Examples</title>
3836<programlisting>
3837CREATE TEMP TABLE edgemap(arc_id serial, edge_id int unique);
3838
3839-- header
3840SELECT '{ "type": "Topology", "transform": { "scale": [1,1], "translate": [0,0] }, "objects": {'
3841
3842-- objects
3843UNION ALL SELECT '"' || feature_name || '": ' || AsTopoJSON(feature, 'edgemap')
3844FROM features.big_parcels WHERE feature_name = 'P3P4';
3845
3846-- arcs
3847WITH edges AS (
3848  SELECT m.arc_id, e.geom FROM edgemap m, city_data.edge e
3849  WHERE e.edge_id = m.edge_id
3850), points AS (
3851  SELECT arc_id, (st_dumppoints(geom)).* FROM edges
3852), compare AS (
3853  SELECT p2.arc_id,
3854         CASE WHEN p1.path IS NULL THEN p2.geom
3855              ELSE ST_Translate(p2.geom, -ST_X(p1.geom), -ST_Y(p1.geom))
3856         END AS geom
3857  FROM points p2 LEFT OUTER JOIN points p1
3858  ON ( p1.arc_id = p2.arc_id AND p2.path[1] = p1.path[1]+1 )
3859  ORDER BY arc_id, p2.path
3860), arcsdump AS (
3861  SELECT arc_id, (regexp_matches( ST_AsGeoJSON(geom), '\[.*\]'))[1] as t
3862  FROM compare
3863), arcs AS (
3864  SELECT arc_id, '[' || array_to_string(array_agg(t), ',') || ']' as a FROM arcsdump
3865  GROUP BY arc_id
3866  ORDER BY arc_id
3867)
3868SELECT '}, "arcs": [' UNION ALL
3869SELECT array_to_string(array_agg(a), E',\n') from arcs
3870
3871-- footer
3872UNION ALL SELECT ']}'::text as t;
3873
3874-- Result:
3875{ "type": "Topology", "transform": { "scale": [1,1], "translate": [0,0] }, "objects": {
3876"P3P4": { "type": "MultiPolygon", "arcs": [[[-1]],[[6,5,-5,-4,-3,1]]]}
3877}, "arcs": [
3878 [[25,30],[6,0],[0,10],[-14,0],[0,-10],[8,0]],
3879 [[35,6],[0,8]],
3880 [[35,6],[12,0]],
3881 [[47,6],[0,8]],
3882 [[47,14],[0,8]],
3883 [[35,22],[12,0]],
3884 [[35,14],[0,8]]
3885 ]}
3886</programlisting>
3887            </refsection>
3888	  </refentry>
3889</sect1>
3890
3891<sect1 id="Topology_Relationships">
3892	     <sect1info>
3893            <abstract>
3894                <para>This section lists the Topology functions used to check relationships between topogeometries and topology primitives</para>
3895            </abstract>
3896        </sect1info>
3897	    <title>Topology Spatial Relationships</title>
3898	    <refentry id="TG_Equals">
3899        <refnamediv>
3900          <refname>Equals</refname>
3901
3902          <refpurpose>Returns true if two topogeometries are composed of the same topology primitives.</refpurpose>
3903        </refnamediv>
3904
3905        <refsynopsisdiv>
3906          <funcsynopsis>
3907            <funcprototype>
3908              <funcdef>boolean <function>Equals</function></funcdef>
3909              <paramdef><type>topogeometry </type> <parameter>tg1</parameter></paramdef>
3910              <paramdef><type>topogeometry </type> <parameter>tg2</parameter></paramdef>
3911            </funcprototype>
3912          </funcsynopsis>
3913        </refsynopsisdiv>
3914
3915        <refsection>
3916          <title>Description</title>
3917
3918          <para>Returns true if two topogeometries are composed of the same topology primitives: faces, edges, nodes.</para>
3919
3920          <!-- optionally mention that this function uses indexes if appropriate -->
3921          <note>
3922            <para>This function not supported for topogeometries that are geometry collections.  It also can not compare topogeometries from different topologies.</para>
3923          </note>
3924          <!-- use this format if new function -->
3925        <para>Availability: 1.1.0 </para>
3926
3927
3928        <!-- Optionally mention 3d support -->
3929        <para>&Z_support;</para>
3930        </refsection>
3931
3932
3933        <refsection>
3934          <title>Examples</title>
3935
3936          <programlisting><!--TODO: Need example --></programlisting>
3937        </refsection>
3938
3939        <!-- Optionally add a "See Also" section -->
3940        <refsection>
3941          <title>See Also</title>
3942
3943          <para><xref linkend="GetTopoGeomElements" />, <xref linkend="ST_Equals" /></para>
3944        </refsection>
3945      </refentry>
3946
3947      <refentry id="TG_Intersects">
3948        <refnamediv>
3949          <refname>Intersects</refname>
3950
3951          <refpurpose>Returns true if any pair of primitives from the two topogeometries intersect.</refpurpose>
3952        </refnamediv>
3953
3954        <refsynopsisdiv>
3955          <funcsynopsis>
3956            <funcprototype>
3957              <funcdef>boolean <function>Intersects</function></funcdef>
3958              <paramdef><type>topogeometry </type> <parameter>tg1</parameter></paramdef>
3959              <paramdef><type>topogeometry </type> <parameter>tg2</parameter></paramdef>
3960            </funcprototype>
3961          </funcsynopsis>
3962        </refsynopsisdiv>
3963
3964        <refsection>
3965          <title>Description</title>
3966
3967          <para>
3968Returns true if any pair of primitives from the
3969two topogeometries intersect.
3970          </para>
3971
3972          <!-- optionally mention that this function uses indexes if appropriate -->
3973          <note>
3974            <para>This function not supported for topogeometries that are geometry collections.  It also can not compare topogeometries from different topologies.
3975            Also not currently supported for hierarchichal topogeometries (topogeometries composed of other topogeometries).</para>
3976          </note>
3977          <!-- use this format if new function -->
3978        <para>Availability: 1.1.0 </para>
3979
3980
3981        <!-- Optionally mention 3d support -->
3982        <para>&Z_support;</para>
3983        </refsection>
3984
3985
3986        <refsection>
3987          <title>Examples</title>
3988
3989          <programlisting><!--TODO: Need example --></programlisting>
3990        </refsection>
3991
3992        <!-- Optionally add a "See Also" section -->
3993        <refsection>
3994          <title>See Also</title>
3995
3996          <para><xref linkend="ST_Intersects" /></para>
3997        </refsection>
3998      </refentry>
3999</sect1>
4000</chapter>
4001