[SCM] PostGIS branch master updated. 3.5.0-296-ge7270fd02

git at osgeo.org git at osgeo.org
Tue Apr 29 08:50:42 PDT 2025


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "PostGIS".

The branch, master has been updated
       via  e7270fd02ec1a50d3840b875fbb01334f19caa8e (commit)
      from  e59b5823e935558289137850b3d7630e6a7a3797 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit e7270fd02ec1a50d3840b875fbb01334f19caa8e
Author: Sandro Santilli <strk at kbt.io>
Date:   Mon Apr 28 19:18:30 2025 +0200

    ValidateTopologyPrecision & MakeTopologyPrecise functions
    
    Closes #5890
    Includes regression test and documentation

diff --git a/NEWS b/NEWS
index 082c60ce9..28471efa8 100644
--- a/NEWS
+++ b/NEWS
@@ -16,6 +16,7 @@ PostGIS 3.6.0
 
 * New Features *
 
+  - #5890, ValidateTopologyPrecision, MakeTopologyPrecise (Sandro Santilli)
   - #5861, Add --drop-topology switch to pgtopo_import (Sandro Santilli)
   - #1247, ST_AsRasterAgg (Sandro Santilli)
   - #5784, GT-223 Export circ_tree_distance_tree_internal for mobilitydb use
diff --git a/doc/extras_topology.xml b/doc/extras_topology.xml
index 560f1b5ee..71f4e9cda 100644
--- a/doc/extras_topology.xml
+++ b/doc/extras_topology.xml
@@ -964,6 +964,126 @@ relation table of the topology.
 			</refsection>
 		</refentry>
 
+		<refentry xml:id="ValidateTopologyPrecision">
+			<refnamediv>
+				<refname>ValidateTopologyPrecision</refname>
+
+				<refpurpose>Returns non-precise vertices in the topology.</refpurpose>
+			</refnamediv>
+
+			<refsynopsisdiv>
+				<funcsynopsis>
+					<funcprototype>
+					<funcdef>geometry <function>ValidateTopologyPrecision</function></funcdef>
+					<paramdef><type>name </type> <parameter>toponame</parameter></paramdef>
+					<paramdef choice="opt"><type>geometry</type> <parameter>bbox</parameter></paramdef>
+					<paramdef choice="opt"><type>float8</type> <parameter>gridSize</parameter></paramdef>
+					</funcprototype>
+				</funcsynopsis>
+			</refsynopsisdiv>
+
+			<refsection>
+                <title>Description</title>
+
+                <para>
+Returns all vertices that are not rounded to the topology or given
+<varname>gridSize</varname> as a puntal geometry, optionally limiting
+the check to the area specified by the <varname>bbox</varname> parameter.
+                </para>
+
+                <!-- use this format if new function -->
+                <para role="availability" conformance="3.6.0">Availability: 3.6.0</para>
+			</refsection>
+
+
+			<refsection>
+				<title>Examples</title>
+				<programlisting>
+SELECT ST_AsEWKT(g) FROM
+ topology.ValidateTopologyPrecision(
+    'city_data',
+    gridSize => 2,
+    bbox => ST_MakeEnvelope(0,0,20,20)
+) g;
+      st_asewkt
+----------------------
+ MULTIPOINT(9 6,9 14)
+(1 row)
+				</programlisting>
+			</refsection>
+
+			<refsection>
+				<title>See Also</title>
+				<para>
+<xref linkend="MakeTopologyPrecise"/>
+                </para>
+			</refsection>
+		</refentry>
+
+		<refentry xml:id="MakeTopologyPrecise">
+			<refnamediv>
+				<refname>MakeTopologyPrecise</refname>
+
+				<refpurpose>Snap topology vertices to precision grid.</refpurpose>
+			</refnamediv>
+
+			<refsynopsisdiv>
+				<funcsynopsis>
+					<funcprototype>
+					<funcdef>void <function>MakeTopologyPrecise</function></funcdef>
+					<paramdef><type>name </type> <parameter>toponame</parameter></paramdef>
+					<paramdef choice="opt"><type>geometry</type> <parameter>bbox</parameter></paramdef>
+					<paramdef choice="opt"><type>float8</type> <parameter>gridSize</parameter></paramdef>
+					</funcprototype>
+				</funcsynopsis>
+			</refsynopsisdiv>
+
+			<refsection>
+                <title>Description</title>
+
+                <para>
+Snaps all vertices of a topology to the topology precision grid or to
+the grid whose size is specified with the <varname>gridSize</varname>
+parameter, optionally limiting the operation to the objects
+intersecting the area specified by the <varname>bbox</varname> parameter.
+                </para>
+
+<note>
+<para>
+Snapping could make the topology invalid, so it is recommended to
+check the outcome of operation with <xref
+linkend="ValidateTopology"/>.
+</para>
+</note>
+
+                <!-- use this format if new function -->
+                <para role="availability" conformance="3.6.0">Availability: 3.6.0</para>
+			</refsection>
+
+
+			<refsection>
+				<title>Examples</title>
+				<programlisting>
+SELECT topology.MakeTopologyPrecise(
+    'city_data',
+    gridSize => 2
+);
+ maketopologyprecise
+---------------------
+
+(1 row)
+				</programlisting>
+			</refsection>
+
+			<refsection>
+				<title>See Also</title>
+				<para>
+<xref linkend="ValidateTopologyPrecision"/>,
+<xref linkend="ValidateTopology"/>
+                </para>
+			</refsection>
+		</refentry>
+
 		<refentry xml:id="FindTopology">
 			<refnamediv>
 				<refname>FindTopology</refname>
diff --git a/topology/Makefile.in b/topology/Makefile.in
index ef8de4bb9..0339a5dee 100644
--- a/topology/Makefile.in
+++ b/topology/Makefile.in
@@ -142,10 +142,12 @@ topology.sql: \
 	sql/manage/FindLayer.sql.in \
 	sql/manage/FindTopology.sql.in \
 	sql/manage/ManageHelper.sql.in \
+	sql/manage/MakeTopologyPrecise.sql.in \
 	sql/manage/populate_topology_layer.sql.in \
 	sql/manage/RenameTopology.sql.in \
 	sql/manage/TopologySummary.sql.in \
 	sql/manage/ValidateTopologyRelation.sql.in \
+	sql/manage/ValidateTopologyPrecision.sql.in \
 	sql/manage/ValidateTopology.sql.in \
 	sql/topoelement/topoelement_agg.sql.in \
 	sql/topogeometry/type.sql.in \
diff --git a/topology/sql/manage/MakeTopologyPrecise.sql.in b/topology/sql/manage/MakeTopologyPrecise.sql.in
new file mode 100644
index 000000000..24cf395ac
--- /dev/null
+++ b/topology/sql/manage/MakeTopologyPrecise.sql.in
@@ -0,0 +1,107 @@
+-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+--
+--
+-- PostGIS - Spatial Types for PostgreSQL
+-- http://postgis.net
+--
+-- Copyright (C) 2025 Sandro Santilli <strk at kbt.io>
+--
+-- This is free software; you can redistribute and/or modify it under
+-- the terms of the GNU General Public Licence. See the COPYING file.
+--
+-- Author: Sandro Santilli <strk at kbt.io>
+--
+-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+-- {
+-- Invalidities are represented by any vertex that does not fall on
+-- the topology precision grid.
+-- }{
+CREATE OR REPLACE FUNCTION topology.MakeTopologyPrecise(toponame name, bbox GEOMETRY DEFAULT NULL, gridSize float8 DEFAULT NULL)
+RETURNS void AS
+$BODY$
+DECLARE
+  topo topology.topology;
+  imprecisePoints GEOMETRY;
+  sql TEXT;
+  dataBox GEOMETRY;
+  dataMagnitude FLOAT8;
+  minGridSize FLOAT8;
+BEGIN
+  topo := findTopology(toponame);
+  IF topo.id IS NULL THEN
+    RAISE EXCEPTION 'Could not find topology "%"', toponame;
+  END IF;
+
+  IF gridSize IS NULL THEN
+    gridSize := topo.precision;
+  END IF;
+
+  IF gridSize <= 0 THEN
+    RAISE NOTICE 'Every vertex is precise with grid size %', gridSize;
+    RETURN;
+  END IF;
+
+  -- TODO: compute real extent instead of estimated/float4 one?
+  -- TODO: generalize a topology.MinTolerance(toponame) ?
+  SELECT ST_Union(g) b
+  FROM (
+    SELECT ST_EstimatedExtent(topo.name, 'edge_data', 'geom')::geometry g
+    UNION
+    SELECT ST_EstimatedExtent(topo.name, 'node', 'geom')::geometry
+  ) foo
+  INTO dataBox;
+
+  IF dataBox IS NULL THEN
+    RAISE NOTICE 'Every vertex is precise in an empty topology';
+    RETURN;
+  END IF;
+
+   dataMagnitude = greatest(
+      abs(ST_Xmin(dataBox)),
+      abs(ST_Xmax(dataBox)),
+      abs(ST_Ymin(dataBox)),
+      abs(ST_Ymax(dataBox))
+  );
+  -- TODO: restrict data magnitude computation to requested bbox ?
+  minGridSize := topology._st_mintolerance(dataMagnitude);
+  IF minGridSize > gridSize THEN
+    RAISE EXCEPTION 'Presence of max ordinate value % requires a minimum grid size of %', dataMagnitude, minGridSize;
+  END IF;
+
+  -- TODO: recursively grow working bbox to include all edges connected
+  --       to all endpoints of edges intersecting it ?
+
+  sql := format(
+    $$
+UPDATE %1$I.edge_data
+SET geom = ST_SnapToGrid(geom, $2)
+WHERE ( $1 IS NULL OR geom && $1 )
+    $$, topo.name
+  );
+  EXECUTE sql USING bbox, gridSize;
+
+  sql := format(
+    $$
+UPDATE %1$I.node
+SET geom = ST_SnapToGrid(geom, $2)
+WHERE ( $1 IS NULL OR geom && $1 )
+    $$, topo.name
+  );
+  EXECUTE sql USING bbox, gridSize;
+
+  sql := format(
+    $$
+UPDATE %1$I.face
+SET mbr = ST_SnapToGrid(mbr, $2)
+WHERE ( $1 IS NULL OR mbr && $1 )
+    $$, topo.name
+  );
+  EXECUTE sql USING bbox, gridSize;
+
+  -- TODO: validate topology if requested ?
+
+END;
+$BODY$
+LANGUAGE 'plpgsql' VOLATILE; --}
+
diff --git a/topology/sql/manage/ValidateTopologyPrecision.sql.in b/topology/sql/manage/ValidateTopologyPrecision.sql.in
new file mode 100644
index 000000000..dc480dad7
--- /dev/null
+++ b/topology/sql/manage/ValidateTopologyPrecision.sql.in
@@ -0,0 +1,106 @@
+-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+--
+--
+-- PostGIS - Spatial Types for PostgreSQL
+-- http://postgis.net
+--
+-- Copyright (C) 2025 Sandro Santilli <strk at kbt.io>
+--
+-- This is free software; you can redistribute and/or modify it under
+-- the terms of the GNU General Public Licence. See the COPYING file.
+--
+-- Author: Sandro Santilli <strk at kbt.io>
+--
+-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+-- {
+-- Invalidities are represented by any vertex that does not fall on
+-- the topology precision grid.
+-- }{
+CREATE OR REPLACE FUNCTION topology.ValidateTopologyPrecision(toponame name, bbox geometry DEFAULT NULL, gridSize float8 DEFAULT NULL)
+RETURNS geometry AS
+$BODY$
+DECLARE
+  topo topology.topology;
+  imprecisePoints GEOMETRY;
+  sql TEXT;
+  dataBox GEOMETRY;
+  dataMagnitude FLOAT8;
+  minGridSize FLOAT8;
+BEGIN
+
+  topo := findTopology(toponame);
+  IF topo.id IS NULL THEN
+    RAISE EXCEPTION 'Could not find topology "%"', toponame;
+  END IF;
+
+  IF gridSize IS NULL THEN
+    gridSize := topo.precision;
+  END IF;
+
+  imprecisePoints = ST_SetSRID('MULTIPOINT EMPTY'::geometry, topo.srid);
+
+  IF gridSize <= 0 THEN
+    RAISE NOTICE 'Every vertex is precise with grid size %', gridSize;
+    RETURN imprecisePoints;
+  END IF;
+
+  SELECT ST_Union(g) b
+  FROM (
+    SELECT ST_EstimatedExtent(topo.name, 'edge_data', 'geom')::geometry g
+    UNION
+    SELECT ST_EstimatedExtent(topo.name, 'node', 'geom')::geometry
+  ) foo
+  INTO dataBox;
+
+  IF dataBox IS NULL THEN
+    RAISE NOTICE 'Every vertex is precise in an empty topology';
+    RETURN imprecisePoints;
+  END IF;
+
+   dataMagnitude = greatest(
+      abs(ST_Xmin(dataBox)),
+      abs(ST_Xmax(dataBox)),
+      abs(ST_Ymin(dataBox)),
+      abs(ST_Ymax(dataBox))
+  );
+  -- TODO: restrict data magnitude computation to given bbox ?
+  minGridSize := topology._st_mintolerance(dataMagnitude);
+  IF minGridSize > gridSize THEN
+    RAISE EXCEPTION 'Presence of max ordinate value % requires a minimum grid size of %', dataMagnitude, minGridSize;
+  END IF;
+
+  sql := format(
+    $$
+WITH edgePoints AS (
+  SELECT geom FROM (
+    SELECT (ST_DumpPoints(geom)).geom FROM %1$I.edge
+    WHERE ( $1 IS NULL OR geom && $1 )
+  ) foo
+  WHERE ( $1 IS NULL OR geom && $1 )
+), isolatedNodes AS (
+  SELECT geom FROM %1$I.node
+  WHERE containing_face IS NOT NULL
+  AND ( $1 IS NULL OR geom && $1 )
+), allVertices AS (
+  SELECT geom from edgePoints
+  UNION
+  SELECT geom from isolatedNodes
+)
+SELECT ST_Union(geom) FROM allVertices
+WHERE NOT ST_Equals( ST_ReducePrecision(geom, $2), geom )
+    $$,
+    topo.name
+  );
+
+  EXECUTE sql USING bbox, gridSize
+  INTO imprecisePoints;
+
+  -- Return invalid vertices
+
+  RETURN imprecisePoints;
+
+END;
+
+$BODY$
+LANGUAGE 'plpgsql' STABLE; --}
diff --git a/topology/sql/populate.sql.in b/topology/sql/populate.sql.in
index 9abd6780a..e947c9d1e 100644
--- a/topology/sql/populate.sql.in
+++ b/topology/sql/populate.sql.in
@@ -28,15 +28,25 @@
 -- 3.5527136788005009294e-15 for the starting value of 9.0
 --
 -- }{
+CREATE OR REPLACE FUNCTION topology._st_mintolerance(val float8)
+  RETURNS float8
+AS $$
+    SELECT 3.6 * power(10,  - ( 15 - log(val) ));
+$$ LANGUAGE 'sql' IMMUTABLE STRICT;
+-- }
+
+-- {
+-- Get min tolerance for a given geometry
+-- }{
 CREATE OR REPLACE FUNCTION topology._st_mintolerance(ageom Geometry)
   RETURNS float8
 AS $$
-    SELECT 3.6 * power(10,  - ( 15 - log(coalesce(
+    SELECT topology._st_mintolerance(coalesce(
       nullif(
-        greatest(abs(ST_xmin($1)), abs(ST_ymin($1)),
-                 abs(ST_xmax($1)), abs(ST_ymax($1))),
+        greatest(abs(ST_Xmin($1)), abs(ST_Ymin($1)),
+                 abs(ST_Xmax($1)), abs(ST_Ymax($1))),
         0),
-      1)) ));
+      1));
 $$ LANGUAGE 'sql' IMMUTABLE STRICT;
 -- }
 
diff --git a/topology/test/regress/maketopologyprecise.sql b/topology/test/regress/maketopologyprecise.sql
new file mode 100644
index 000000000..0469816b4
--- /dev/null
+++ b/topology/test/regress/maketopologyprecise.sql
@@ -0,0 +1,16 @@
+SET client_min_messages TO NOTICE;
+SELECT NULL FROM topology.CreateTopology('topo');
+SELECT topology.MakeTopologyPrecise('topo');
+UPDATE topology.topology SET precision = 5 WHERE name = 'topo';
+SELECT topology.MakeTopologyPrecise('topo');
+SELECT NULL FROM topology.TopoGeo_addLineString('topo', 'LINESTRING(123456789 0.1, 6 -1002003004)');
+SELECT topology.MakeTopologyPrecise('topo', gridSize => 1e-10);
+SELECT 'start', 'e', edge_id, ST_AsEWKT(geom) FROM topo.edge ORDER BY edge_id;
+SELECT topology.MakeTopologyPrecise('topo');
+SELECT 'prec5', 'e', edge_id, ST_AsEWKT(geom) FROM topo.edge ORDER BY edge_id;
+
+-- TODO: test bbox limited made-precise topology
+
+-- Cleanup
+
+SELECT NULL FROM topology.DropTopology('topo');
diff --git a/topology/test/regress/maketopologyprecise_expected b/topology/test/regress/maketopologyprecise_expected
new file mode 100644
index 000000000..e7bfc4063
--- /dev/null
+++ b/topology/test/regress/maketopologyprecise_expected
@@ -0,0 +1,7 @@
+NOTICE:  Every vertex is precise with grid size 0
+NOTICE:  Every vertex is precise in an empty topology
+ERROR:  Presence of max ordinate value 1002003008 requires a minimum grid size of 3.60721082879999e-6
+start|e|1|LINESTRING(123456789 0.1,6 -1002003004)
+prec5|e|1|LINESTRING(123456790 0,5 -1002003005)
+NOTICE:  Dropping all layers from topology 'topo' (1)
+NOTICE:  drop cascades to 6 other objects
diff --git a/topology/test/regress/validatetopologyprecision.sql b/topology/test/regress/validatetopologyprecision.sql
new file mode 100644
index 000000000..7aeb57c76
--- /dev/null
+++ b/topology/test/regress/validatetopologyprecision.sql
@@ -0,0 +1,54 @@
+\set VERBOSITY terse
+set client_min_messages to WARNING;
+
+-- Create a topology in floating precision model
+SELECT NULL FROM topology.CreateTopology('topo', 4326);
+
+-- Add a linestring on a grid of size 2
+SELECT NULL FROM topology.TopoGeo_AddLineString('topo',
+  ST_Segmentize('SRID=4326;LINESTRING(0 0, 8 0)'::geometry, 2));
+
+-- Add a connected linestring on a grid of size 2
+SELECT NULL FROM topology.TopoGeo_AddLineString('topo',
+  ST_Segmentize('SRID=4326;LINESTRING(8 0, 8 8)'::geometry, 2));
+
+-- Add an isolated node on a grid of size 1
+SELECT NULL FROM topology.TopoGeo_AddPoint('topo',
+  'SRID=4326;POINT(-3 -1)'::geometry);
+
+SELECT 'start', 'edge', edge_id, ST_AsEWKT(geom) FROM topo.edge ORDER BY edge_id;
+SELECT 'start', 'node', node_id, ST_AsEWKT(geom) FROM topo.node WHERE containing_face IS NOT NULL ORDER BY node_id;
+
+-- Validate as such
+SELECT 'topo_float', ST_AsEWKT(ST_Normalize(
+  topology.ValidateTopologyPrecision('topo')
+));
+
+-- Update topology precision to 4
+UPDATE topology.topology SET precision = 4 WHERE name = 'topo';
+
+-- Validate with precision 4
+SELECT 'topo_prec4', ST_AsEWKT(ST_Normalize(
+  topology.ValidateTopologyPrecision('topo')
+));
+
+-- Validate with precision 4 and limited bbox
+SELECT 'topo_prec4_bbox', ST_AsEWKT(ST_Normalize(
+  topology.ValidateTopologyPrecision(
+    'topo',
+    'LINESTRING(-1 -1,7 7)'::geometry
+  )
+));
+
+-- Validate with gridSize 2
+SELECT 'topo_prec2', ST_AsEWKT(ST_Normalize(
+  topology.ValidateTopologyPrecision('topo', gridSize => 2)
+));
+
+-- Validate with too small gridSize
+SELECT 'topo_prec_too_small', ST_AsEWKT(ST_Normalize(
+  topology.ValidateTopologyPrecision('topo', gridSize => 1e-20)
+));
+
+SELECT NULL FROM topology.DropTopology('topo');
+
diff --git a/topology/test/regress/validatetopologyprecision_expected b/topology/test/regress/validatetopologyprecision_expected
new file mode 100644
index 000000000..fa60e3737
--- /dev/null
+++ b/topology/test/regress/validatetopologyprecision_expected
@@ -0,0 +1,8 @@
+start|edge|1|SRID=4326;LINESTRING(0 0,2 0,4 0,6 0,8 0)
+start|edge|2|SRID=4326;LINESTRING(8 0,8 2,8 4,8 6,8 8)
+start|node|4|SRID=4326;POINT(-3 -1)
+topo_float|SRID=4326;MULTIPOINT EMPTY
+topo_prec4|SRID=4326;MULTIPOINT(8 6,8 2,6 0,2 0,-3 -1)
+topo_prec4_bbox|SRID=4326;MULTIPOINT(6 0,2 0)
+topo_prec2|SRID=4326;POINT(-3 -1)
+ERROR:  Presence of max ordinate value 8 requires a minimum grid size of 2.88e-14
diff --git a/topology/test/tests.mk b/topology/test/tests.mk
index cbe263369..3776692c1 100644
--- a/topology/test/tests.mk
+++ b/topology/test/tests.mk
@@ -45,6 +45,7 @@ TESTS += \
 	$(top_srcdir)/topology/test/regress/legacy_predicate.sql \
 	$(top_srcdir)/topology/test/regress/legacy_query.sql \
 	$(top_srcdir)/topology/test/regress/legacy_validate.sql \
+	$(top_srcdir)/topology/test/regress/maketopologyprecise.sql \
 	$(top_srcdir)/topology/test/regress/polygonize.sql \
 	$(top_srcdir)/topology/test/regress/populate_topology_layer.sql \
 	$(top_srcdir)/topology/test/regress/removeunusedprimitives.sql \
@@ -87,5 +88,6 @@ TESTS += \
 	$(top_srcdir)/topology/test/regress/topojson.sql \
 	$(top_srcdir)/topology/test/regress/topologysummary.sql \
 	$(top_srcdir)/topology/test/regress/totopogeom.sql \
+	$(top_srcdir)/topology/test/regress/validatetopologyprecision.sql \
 	$(top_srcdir)/topology/test/regress/validatetopologyrelation.sql \
 	$(top_srcdir)/topology/test/regress/validatetopology.sql
diff --git a/topology/topology.sql.in b/topology/topology.sql.in
index 849963e4c..c2ba6f303 100644
--- a/topology/topology.sql.in
+++ b/topology/topology.sql.in
@@ -1401,6 +1401,8 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
 #include "sql/manage/RenameTopology.sql.in"
 #include "sql/manage/ValidateTopology.sql.in"
 #include "sql/manage/ValidateTopologyRelation.sql.in"
+#include "sql/manage/ValidateTopologyPrecision.sql.in"
+#include "sql/manage/MakeTopologyPrecise.sql.in"
 
 -- Cleanup functions
 #include "sql/cleanup/RemoveUnusedPrimitives.sql.in"

-----------------------------------------------------------------------

Summary of changes:
 NEWS                                               |   1 +
 doc/extras_topology.xml                            | 120 +++++++++++++++++++++
 topology/Makefile.in                               |   2 +
 topology/sql/manage/MakeTopologyPrecise.sql.in     | 107 ++++++++++++++++++
 .../sql/manage/ValidateTopologyPrecision.sql.in    | 106 ++++++++++++++++++
 topology/sql/populate.sql.in                       |  18 +++-
 topology/test/regress/maketopologyprecise.sql      |  16 +++
 topology/test/regress/maketopologyprecise_expected |   7 ++
 .../test/regress/validatetopologyprecision.sql     |  54 ++++++++++
 .../regress/validatetopologyprecision_expected     |   8 ++
 topology/test/tests.mk                             |   2 +
 topology/topology.sql.in                           |   2 +
 12 files changed, 439 insertions(+), 4 deletions(-)
 create mode 100644 topology/sql/manage/MakeTopologyPrecise.sql.in
 create mode 100644 topology/sql/manage/ValidateTopologyPrecision.sql.in
 create mode 100644 topology/test/regress/maketopologyprecise.sql
 create mode 100644 topology/test/regress/maketopologyprecise_expected
 create mode 100644 topology/test/regress/validatetopologyprecision.sql
 create mode 100644 topology/test/regress/validatetopologyprecision_expected


hooks/post-receive
-- 
PostGIS


More information about the postgis-tickets mailing list