]> granicus.if.org Git - postgis/commitdiff
Add ST_Normalize function
authorSandro Santilli <strk@keybit.net>
Wed, 15 Jun 2016 09:49:50 +0000 (09:49 +0000)
committerSandro Santilli <strk@keybit.net>
Wed, 15 Jun 2016 09:49:50 +0000 (09:49 +0000)
Includes tests and documentation

Closes #1768

git-svn-id: http://svn.osgeo.org/postgis/trunk@14949 b70326c6-7e19-0410-871a-916f4a2858ee

NEWS
doc/reference_editor.xml
postgis/lwgeom_functions_basic.c
postgis/postgis.sql.in
regress/Makefile.in
regress/normalize.sql [new file with mode: 0644]
regress/normalize_expected [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index f88fbfbf825cbbe561ffd7a8218e25671d8cba67..6dd21f4286c949fcc5fd2546572389b78fb2114c 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -17,6 +17,7 @@ PostGIS 2.3.0
   - Add parameters for geography ST_Buffer (Thomas Bonfort)
   - TopoGeom_addElement, TopoGeom_remElement (Sandro Santilli)
   - populate_topology_layer (Sandro Santilli)
+  - #1758, ST_Normalize (Sandro Santilli)
   - #2259, ST_Voronoi (Dan Baston)
   - #2991, Enable ST_Transform to use PROJ.4 text (Mike Toews)
   - #3059, Allow passing per-dimension parameters in ST_Expand (Dan Baston)
index 58339c80976f90baefd875c4e2e5ecfdf331cb8c..6aa3d37fff939f3ad62113264270970862434b6b 100644 (file)
@@ -897,6 +897,67 @@ MULTILINESTRING((0 0, 1 1), (2 2, 3 3))
                </refsection>
        </refentry>
 
+       <refentry id="ST_Normalize">
+               <refnamediv>
+                       <refname>ST_Normalize</refname>
+
+                       <refpurpose>Returns the geometry in its canonical form.</refpurpose>
+               </refnamediv>
+
+               <refsynopsisdiv>
+                       <funcsynopsis>
+                         <funcprototype>
+                               <funcdef>geometry <function>ST_Normalized</function></funcdef>
+                               <paramdef><type>geometry </type> <parameter>geom</parameter></paramdef>
+                         </funcprototype>
+                       </funcsynopsis>
+               </refsynopsisdiv>
+
+               <refsection>
+                       <title>Description</title>
+
+                       <para>
+        Returns the geometry in its normalized/canonical form.
+        May reorder vertices in polygon rings, rings in a polygon,
+        elements in a multi-geometry complex.
+      </para>
+
+                       <para>
+        Mostly only useful for testing purposes (comparing expected
+        and obtained results).
+      </para>
+
+               </refsection>
+
+               <refsection>
+                       <title>Examples</title>
+
+                       <programlisting>
+SELECT ST_AsText(ST_Normalize(ST_GeomFromText(
+  'GEOMETRYCOLLECTION(
+    POINT(2 3),
+    MULTILINESTRING((0 0, 1 1),(2 2, 3 3)),
+    POLYGON(
+      (0 10,0 0,10 0,10 10,0 10),
+      (4 2,2 2,2 4,4 4,4 2),
+      (6 8,8 8,8 6,6 6,6 8)
+    )
+  )'
+)));
+                                                                     st_astext
+----------------------------------------------------------------------------------------------------------------------------------------------------
+ GEOMETRYCOLLECTION(POLYGON((0 0,0 10,10 10,10 0,0 0),(6 6,8 6,8 8,6 8,6 6),(2 2,4 2,4 4,2 4,2 2)),MULTILINESTRING((2 2,3 3),(0 0,1 1)),POINT(2 3))
+(1 row)
+                       </programlisting>
+               </refsection>
+               <refsection>
+                       <title>See Also</title>
+                       <para>
+        <xref linkend="ST_Equals" />,
+      </para>
+               </refsection>
+       </refentry>
+
        <refentry id="ST_RemovePoint">
          <refnamediv>
                <refname>ST_RemovePoint</refname>
index dec8e3c60bc0719c02e6a5a01e52024452d19d62..f023f5aa857c7b710d18fb7a634bd8b6291e3896 100644 (file)
@@ -1900,6 +1900,33 @@ Datum LWGEOM_noop(PG_FUNCTION_ARGS)
        PG_RETURN_POINTER(out);
 }
 
+Datum ST_Normalize(PG_FUNCTION_ARGS);
+PG_FUNCTION_INFO_V1(ST_Normalize);
+Datum ST_Normalize(PG_FUNCTION_ARGS)
+{
+       GSERIALIZED *in, *out;
+       LWGEOM *lwgeom_in, *lwgeom_out;
+
+       POSTGIS_DEBUG(2, "ST_Normalize called");
+
+       in = PG_GETARG_GSERIALIZED_P_COPY(0);
+
+       lwgeom_in = lwgeom_from_gserialized(in);
+       POSTGIS_DEBUGF(3, "Deserialized: %s", lwgeom_summary(lwgeom_in, 0));
+
+       lwgeom_out = lwgeom_normalize(lwgeom_in);
+       POSTGIS_DEBUGF(3, "Normalized: %s", lwgeom_summary(lwgeom_out, 0));
+
+       out = geometry_serialize(lwgeom_out);
+       lwgeom_free(lwgeom_in);
+       lwgeom_free(lwgeom_out);
+
+       PG_FREE_IF_COPY(in, 0);
+
+       PG_RETURN_POINTER(out);
+}
+
+
 /**
  *  @return:
  *   0==2d
index 9082231ea0b1f6b2fa15a0aac31db5c4c383e541..d53be8df35f5804f57d9967cfb0ed77f9a5454fd 100644 (file)
@@ -1477,6 +1477,13 @@ CREATE OR REPLACE FUNCTION postgis_noop(geometry)
        LANGUAGE 'c' VOLATILE STRICT
        COST 10;
 
+-- Availability: 2.3.0
+CREATE OR REPLACE FUNCTION ST_Normalize(geom geometry)
+       RETURNS geometry
+       AS 'MODULE_PATHNAME', 'ST_Normalize'
+       LANGUAGE 'c' IMMUTABLE STRICT _PARALLEL
+       COST 20; -- 20 as it delegates to GEOS
+
 -- Deprecation in 1.5.0
 CREATE OR REPLACE FUNCTION ST_zmflag(geometry)
        RETURNS smallint
index 40b32298a2f3cb334ea60740e9d7e20314b0ed16..09abbea8bc8a608b84ec9184846b7041b8dd80fc 100644 (file)
@@ -98,6 +98,7 @@ TESTS = \
        lwgeom_regress \
        measures \
        minimum_bounding_circle \
+       normalize \
        operators \
        out_geometry \
        out_geography \
diff --git a/regress/normalize.sql b/regress/normalize.sql
new file mode 100644 (file)
index 0000000..02aac65
--- /dev/null
@@ -0,0 +1,7 @@
+select 1, ST_AsText(ST_Normalize(
+'GEOMETRYCOLLECTION(POINT(2 3),MULTILINESTRING((0 0, 1 1),(2 2, 3 3)))'
+::geometry));
+
+select 2, ST_AsText(ST_Normalize(
+'POLYGON((0 10,0 0,10 0,10 10,0 10),(4 2,2 2,2 4,4 4,4 2),(6 8,8 8,8 6,6 6,6 8))'
+::geometry));
diff --git a/regress/normalize_expected b/regress/normalize_expected
new file mode 100644 (file)
index 0000000..cf1c454
--- /dev/null
@@ -0,0 +1,3 @@
+1|GEOMETRYCOLLECTION(MULTILINESTRING((2 2,3 3),(0 0,1 1)),POINT(2 3))
+2|POLYGON((0 0,0 10,10 10,10 0,0 0),(6 6,8 6,8 8,6 8,6 6),(2 2,4 2,4 4,2 4,2 2))
+