]> granicus.if.org Git - postgis/commitdiff
rename ptarray_reverse_axis to ptarray_flip_coordinates. Add lwgeom_flip_coordinates...
authorOlivier Courtin <olivier.courtin@camptocamp.com>
Thu, 25 Feb 2010 13:38:57 +0000 (13:38 +0000)
committerOlivier Courtin <olivier.courtin@camptocamp.com>
Thu, 25 Feb 2010 13:38:57 +0000 (13:38 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@5338 b70326c6-7e19-0410-871a-916f4a2858ee

doc/reference_processing.xml
liblwgeom/cunit/cu_libgeom.c
liblwgeom/liblwgeom.h
liblwgeom/lwgeom.c
liblwgeom/ptarray.c
postgis/lwgeom_functions_basic.c
postgis/lwgeom_in_gml.c
postgis/postgis.sql.in.c

index e10396252e880c125d760df7232b1a0e0ba4578b..431c0a7869705e15b25a7f59fd7e606b32b71d4f 100644 (file)
@@ -1567,7 +1567,7 @@ FROM (SELECT ST_Buffer('POINT(1 3)', 10,12) As the_geom) As foo;
          <refsection>
                <title>Description</title>
                <para>Returns a version of the given geometry with
-                               duplicated points emoved. Will actually do something only with
+                               duplicated points removed. Will actually do something only with
                                (multi)lines, (multi)polygons and multipoints but you can safely call it with
                                any kind of geometry. Since simplification occurs on a
                                object-by-object basis you can also feed a GeometryCollection to
@@ -1582,6 +1582,45 @@ FROM (SELECT ST_Buffer('POINT(1 3)', 10,12) As the_geom) As foo;
                  </refsection>
        </refentry>
 
+       <refentry id="ST_FlipCoordinates">
+         <refnamediv>
+               <refname>ST_FlipCoordinates</refname>
+               <refpurpose>Returns a version of the given geometry with
+                               X and Y axis flipped. Useful for people 
+                               who have built latitude/longitude features
+                               and need to fix them.</refpurpose>
+         </refnamediv>
+
+         <refsynopsisdiv>
+               <funcsynopsis>
+                 <funcprototype>
+                       <funcdef>geometry <function>ST_FlipCoordinates</function></funcdef>
+                       <paramdef><type>geometry</type> <parameter>geom</parameter></paramdef>
+                 </funcprototype>
+               </funcsynopsis>
+         </refsynopsisdiv>
+
+         <refsection>
+               <title>Description</title>
+               <para>Returns a version of the given geometry with X and Y axis flipped.</para>
+               <para>&curve_support;</para>
+               <para>&Z_support;</para>
+               <para>&M_support;</para>
+               <para>Availability: 2.0.0</para>
+         </refsection>
+
+         <refsection>
+               <title>Example</title>
+               <programlisting><![CDATA[
+SELECT ST_AsEWKT(ST_FlipCoordinates(GeomFromEWKT('POINT(1 2)')));
+ st_asewkt  
+------------
+POINT(2 1)
+                ]]></programlisting>
+         </refsection>
+
+       </refentry>
+
        <refentry id="ST_SymDifference">
          <refnamediv>
                <refname>ST_SymDifference</refname>
index cfa5936887aa44f7afffab3377d3cab43b9dda81..256a02e583fb2087b2f27c5d17256864d86c1799 100644 (file)
@@ -326,6 +326,141 @@ static void test_lwgeom_free(void)
 
 }
 
+static void do_lwgeom_flip_coordinates(char *in, char *out)
+{
+       LWGEOM *g,*h;
+        char * t;
+
+        g = lwgeom_from_ewkt(in, PARSER_CHECK_NONE);
+        h = lwgeom_flip_coordinates(g);
+
+       t = lwgeom_to_wkt(g, 8, WKT_EXTENDED); 
+       if (t == NULL) fprintf(stderr, "In:%s", in);
+        if (strcmp(t, out))
+                fprintf(stderr, "\nIn:   %s\nOut:  %s\nTheo: %s\n", in, t, out);
+
+        CU_ASSERT_STRING_EQUAL(t, out)
+
+        lwgeom_free(g);
+        lwfree(t);
+}
+
+static void test_lwgeom_flip_coordinates(void) 
+{
+       /* 
+         * 2D geometries types 
+         */
+       do_lwgeom_flip_coordinates(
+               "POINT(1 2)",
+               "POINT(2 1)"
+               );
+
+       do_lwgeom_flip_coordinates(
+               "LINESTRING(1 2,3 4)",
+               "LINESTRING(2 1,4 3)"
+               );
+
+       do_lwgeom_flip_coordinates(
+               "POLYGON((1 2,3 4,5 6,1 2))",
+               "POLYGON((2 1,4 3,6 5,2 1))"
+               );
+
+       do_lwgeom_flip_coordinates(
+               "POLYGON((1 2,3 4,5 6,1 2),(7 8,9 10,11 12,7 8))",
+               "POLYGON((2 1,4 3,6 5,2 1),(8 7,10 9,12 11,8 7))"
+               );
+
+       do_lwgeom_flip_coordinates(
+               "MULTIPOINT(1 2,3 4)",
+               "MULTIPOINT(2 1,4 3)"
+               );
+
+       do_lwgeom_flip_coordinates(
+               "MULTILINESTRING((1 2,3 4),(5 6,7 8))",
+               "MULTILINESTRING((2 1,4 3),(6 5,8 7))"
+               );
+
+       do_lwgeom_flip_coordinates(
+               "MULTIPOLYGON(((1 2,3 4,5 6,7 8)),((9 10,11 12,13 14,10 9)))",
+               "MULTIPOLYGON(((2 1,4 3,6 5,8 7)),((10 9,12 11,14 13,9 10)))"
+               );
+
+       do_lwgeom_flip_coordinates(
+               "GEOMETRYCOLLECTION EMPTY",
+               "GEOMETRYCOLLECTION EMPTY"
+               );
+
+       do_lwgeom_flip_coordinates(
+               "GEOMETRYCOLLECTION(POINT(1 2),LINESTRING(3 4,5 6))",
+               "GEOMETRYCOLLECTION(POINT(2 1),LINESTRING(4 3,6 5))"
+               );
+
+       do_lwgeom_flip_coordinates(
+               "GEOMETRYCOLLECTION(POINT(1 2),GEOMETRYCOLLECTION(LINESTRING(3 4,5 6)))",
+               "GEOMETRYCOLLECTION(POINT(2 1),GEOMETRYCOLLECTION(LINESTRING(4 3,6 5)))"
+               );
+
+       do_lwgeom_flip_coordinates(
+               "CIRCULARSTRING(-2 0,0 2,2 0,0 2,2 4)",
+               "CIRCULARSTRING(0 -2,2 0,0 2,2 0,4 2)"
+               );
+
+       do_lwgeom_flip_coordinates(
+               "COMPOUNDCURVE(CIRCULARSTRING(0 1,1 1,1 0),(1 0,0 1))",
+               "COMPOUNDCURVE(CIRCULARSTRING(1 0,1 1,0 1),(0 1,1 0))"
+       );
+
+       do_lwgeom_flip_coordinates(
+               "CURVEPOLYGON(CIRCULARSTRING(-2 0,-1 -1,0 0,1 -1,2 0,0 2,-2 0),(-1 0,0 0.5,1 0,0 1,-1 0))",
+               "CURVEPOLYGON(CIRCULARSTRING(0 -2,-1 -1,0 0,-1 1,0 2,2 0,0 -2),(0 -1,0.5 0,0 1,1 0,0 -1))"
+       );
+
+       do_lwgeom_flip_coordinates(
+               "MULTICURVE((5 5,3 5,3 3,0 3),CIRCULARSTRING(0 0,2 1,2 3))",
+               "MULTICURVE((5 5,5 3,3 3,3 0),CIRCULARSTRING(0 0,1 2,3 2))"
+       );
+
+       do_lwgeom_flip_coordinates(
+               "MULTISURFACE(CURVEPOLYGON(CIRCULARSTRING(-2 0,-1 -1,0 0,1 -1,2 0,0 2,-2 0),(-1 0,0 0.5,1 0,0 1,-1 0)),((7 8,10 10,6 14,4 11,7 8)))",
+               "MULTISURFACE(CURVEPOLYGON(CIRCULARSTRING(0 -2,-1 -1,0 0,-1 1,0 2,2 0,0 -2),(0 -1,0.5 0,0 1,1 0,0 -1)),((8 7,10 10,14 6,11 4,8 7)))"
+       );
+
+
+       /* 
+         * Ndims
+         */
+
+       do_lwgeom_flip_coordinates(
+               "POINT(1 2 3)",
+               "POINT(2 1 3)"
+               );
+
+       do_lwgeom_flip_coordinates(
+               "POINTM(1 2 3)",
+               "POINTM(2 1 3)"
+               );
+
+       do_lwgeom_flip_coordinates(
+               "POINT(1 2 3 4)",
+               "POINT(2 1 3 4)"
+               );
+
+
+       /* 
+         * Srid
+         */
+
+       do_lwgeom_flip_coordinates(
+               "SRID=4326;POINT(1 2)",
+               "SRID=4326;POINT(2 1)"
+               );
+
+       do_lwgeom_flip_coordinates(
+               "SRID=-1;POINT(1 2)",
+               "POINT(2 1)"
+               );
+}
+
 /*
 ** Used by test harness to register the tests in this file.
 */
@@ -341,6 +476,8 @@ CU_TestInfo libgeom_tests[] = {
        PG_TEST(test_geometry_type_from_string),
        PG_TEST(test_lwcollection_extract),
        PG_TEST(test_lwgeom_free),
+       PG_TEST(test_lwgeom_flip_coordinates),
        CU_TEST_INFO_NULL
 };
 CU_SuiteInfo libgeom_suite = {"LibGeom Suite",  NULL,  NULL, libgeom_tests};
+
index 8d84ca10a8a443cb13e8a24f626735580fdb3c1d..b1262bc74bdcd3f33243aaee7fa706a1d4a6223b 100644 (file)
@@ -1270,7 +1270,7 @@ extern int32 lwgeom_npoints(uchar *serialized);
 extern int lwgeom_has_srid(const LWGEOM *geom);
 
 /**
-* Return true or false depending on whether a geometry is an "empty"
+* Return true of false depending on whether a geometry is an "empty"
 * geometry (no vertices members)
 */
 extern int lwgeom_is_empty(const LWGEOM *geom);
@@ -1388,7 +1388,7 @@ extern void ptarray_longitude_shift(POINTARRAY *pa);
 
 extern int32 lwgeom_nrings_recursive(uchar *serialized);
 extern void ptarray_reverse(POINTARRAY *pa);
-extern POINTARRAY* ptarray_reverse_axis(POINTARRAY *pa);
+extern POINTARRAY* ptarray_flip_coordinates(POINTARRAY *pa);
 
 extern POINTARRAY *ptarray_substring(POINTARRAY *, double, double);
 extern double ptarray_locate_point(POINTARRAY *, POINT2D *);
@@ -1421,6 +1421,7 @@ extern char * lwgeom_to_kml2(uchar *geom, int precision);
 extern char * lwgeom_to_geojson(uchar *geom, char *srs, int precision, int has_bbox);
 extern char * lwgeom_to_svg(uchar *geom, int precision, int relative);
 
+
 extern POINTARRAY *ptarray_remove_repeated_points(POINTARRAY *in);
 extern LWGEOM* lwgeom_remove_repeated_points(LWGEOM *in);
 extern LWGEOM* lwmpoint_remove_repeated_points(LWMPOINT *in);
@@ -1428,6 +1429,7 @@ extern LWGEOM* lwline_remove_repeated_points(LWLINE *in);
 extern LWGEOM* lwcollection_remove_repeated_points(LWCOLLECTION *in);
 extern LWGEOM* lwpoly_remove_repeated_points(LWPOLY *in);
 
+extern LWGEOM* lwgeom_flip_coordinates(LWGEOM *in);
 
 extern uchar parse_hex(char *str);
 extern void deparse_hex(uchar str, char *result);
index 08f69193333e2e8748fcbab4df67e05f89e4a5a8..d8e670924f03deb9ab4c5206f0614d907286b6b9 100644 (file)
@@ -1227,3 +1227,51 @@ extern LWGEOM* lwgeom_remove_repeated_points(LWGEOM *in)
        }
        return 0;
 }
+
+extern LWGEOM* lwgeom_flip_coordinates(LWGEOM *in)
+{
+       LWCOLLECTION *col;
+       LWPOLY *poly;
+       int i;
+
+       LWDEBUGF(3, "lwgeom_flip_coordinates: unsupported type: %s",
+               lwgeom_typename(in->type));
+
+       switch (TYPE_GETTYPE(in->type))
+       {
+       case POINTTYPE:
+               ptarray_flip_coordinates(lwgeom_as_lwpoint(in)->point);
+               return in;
+
+       case LINETYPE:
+               ptarray_flip_coordinates(lwgeom_as_lwline(in)->points);
+               return in;
+
+       case CIRCSTRINGTYPE:
+               ptarray_flip_coordinates(lwgeom_as_lwcircstring(in)->points);
+               return in;
+
+       case POLYGONTYPE:
+               poly = (LWPOLY *) in;
+               for (i=0; i<poly->nrings; i++)
+                       ptarray_flip_coordinates(poly->rings[i]);
+               return in;
+
+       case MULTIPOINTTYPE:
+       case MULTILINETYPE:
+       case MULTIPOLYGONTYPE:
+       case COLLECTIONTYPE:
+       case COMPOUNDTYPE:
+       case CURVEPOLYTYPE:
+       case MULTISURFACETYPE:
+       case MULTICURVETYPE:
+               col = (LWCOLLECTION *) in;
+               for (i=0; i<col->ngeoms; i++)
+                       lwgeom_flip_coordinates(col->geoms[i]);
+
+       default:
+               lwerror("unsupported input geometry type: %d",
+                        TYPE_GETTYPE(in->type));
+       }
+       return NULL;
+}
index a25f7641e481e37c1c4ce63b658683dbe8c31ac4..e68433c5a68c5a01b4690f323cf2de75fdf2715f 100644 (file)
@@ -78,7 +78,7 @@ ptarray_reverse(POINTARRAY *pa)
  * Reverse X and Y axis on a given POINTARRAY
  */
 POINTARRAY*
-ptarray_reverse_axis(POINTARRAY *pa)
+ptarray_flip_coordinates(POINTARRAY *pa)
 {
         int i;
         double d;
index 724acea10388cc7ed843c5c51f054bc0ce3480da..3724889506d06e49bf2ba8029b824a506a86f1b4 100644 (file)
@@ -3650,3 +3650,21 @@ Datum ST_RemoveRepeatedPoints(PG_FUNCTION_ARGS)
 
        PG_RETURN_POINTER(output);
 }
+
+Datum ST_FlipCoordinates(PG_FUNCTION_ARGS);
+PG_FUNCTION_INFO_V1(ST_FlipCoordinates);
+Datum ST_FlipCoordinates(PG_FUNCTION_ARGS)
+{
+       PG_LWGEOM *input = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+       PG_LWGEOM *output;
+       LWGEOM *lwgeom_in = pglwgeom_deserialize(input);
+       LWGEOM *lwgeom_out;
+
+       lwgeom_out = lwgeom_flip_coordinates(lwgeom_in);
+       output = pglwgeom_serialize(lwgeom_out);
+
+       lwgeom_free(lwgeom_in);
+       PG_FREE_IF_COPY(input, 0);
+
+       PG_RETURN_POINTER(output);
+}
index 9d57186366de72e9165417974c7a1ac1215652ed..dbd429e4adf072e270e3027b8cf0a3ba230b3911 100644 (file)
@@ -955,7 +955,7 @@ static POINTARRAY* parse_gml_data(xmlNodePtr xnode, bool *hasz, int *root_srid)
                                lwerror("invalid GML representation");
 
                        srs = parse_gml_srs(xb);
-                       if (srs->reverse_axis) tmp_pa = ptarray_reverse_axis(tmp_pa);
+                       if (srs->reverse_axis) tmp_pa = ptarray_flip_coordinates(tmp_pa);
                        if (!*root_srid) *root_srid = srs->srid;
                        else
                        {
@@ -990,7 +990,7 @@ static LWGEOM* parse_gml_point(xmlNodePtr xnode, bool *hasz, int *root_srid)
        if (pa->npoints != 1) lwerror("invalid GML representation");
 
        srs = parse_gml_srs(xnode);
-       if (srs->reverse_axis) pa = ptarray_reverse_axis(pa);
+       if (srs->reverse_axis) pa = ptarray_flip_coordinates(pa);
        if (!*root_srid)
        {
                *root_srid = srs->srid;
@@ -1024,7 +1024,7 @@ static LWGEOM* parse_gml_line(xmlNodePtr xnode, bool *hasz, int *root_srid)
        if (pa->npoints < 2) lwerror("invalid GML representation");
 
        srs = parse_gml_srs(xnode);
-       if (srs->reverse_axis) pa = ptarray_reverse_axis(pa);
+       if (srs->reverse_axis) pa = ptarray_flip_coordinates(pa);
        if (!*root_srid)
        {
                *root_srid = srs->srid;
@@ -1140,7 +1140,7 @@ static LWGEOM* parse_gml_curve(xmlNodePtr xnode, bool *hasz, int *root_srid)
        }
 
        srs = parse_gml_srs(xnode);
-       if (srs->reverse_axis) pa = ptarray_reverse_axis(pa);
+       if (srs->reverse_axis) pa = ptarray_flip_coordinates(pa);
        if (!*root_srid)
        {
                *root_srid = srs->srid;
@@ -1197,7 +1197,7 @@ static LWGEOM* parse_gml_polygon(xmlNodePtr xnode, bool *hasz, int *root_srid)
                                ||  (*hasz && !ptarray_isclosed3d(ppa[0])))
                                lwerror("invalid GML representation");
 
-                       if (srs->reverse_axis) ppa[0] = ptarray_reverse_axis(ppa[0]);
+                       if (srs->reverse_axis) ppa[0] = ptarray_flip_coordinates(ppa[0]);
                }
        }
 
@@ -1227,7 +1227,7 @@ static LWGEOM* parse_gml_polygon(xmlNodePtr xnode, bool *hasz, int *root_srid)
                                ||  (*hasz && !ptarray_isclosed3d(ppa[ring])))
                                lwerror("invalid GML representation");
 
-                       if (srs->reverse_axis) ppa[ring] = ptarray_reverse_axis(ppa[ring]);
+                       if (srs->reverse_axis) ppa[ring] = ptarray_flip_coordinates(ppa[ring]);
                        ring++;
                }
        }
@@ -1328,7 +1328,7 @@ static LWGEOM* parse_gml_surface(xmlNodePtr xnode, bool *hasz, int *root_srid)
                                        ||  (*hasz && !ptarray_isclosed3d(ppa[0])))
                                        lwerror("invalid GML representation");
 
-                               if (srs->reverse_axis) ppa[0] = ptarray_reverse_axis(ppa[0]);
+                               if (srs->reverse_axis) ppa[0] = ptarray_flip_coordinates(ppa[0]);
                        }
                }
 
@@ -1356,7 +1356,7 @@ static LWGEOM* parse_gml_surface(xmlNodePtr xnode, bool *hasz, int *root_srid)
                                        lwerror("invalid GML representation");
 
                                if (srs->reverse_axis)
-                                       ppa[ring] = ptarray_reverse_axis(ppa[ring]);
+                                       ppa[ring] = ptarray_flip_coordinates(ppa[ring]);
 
                                ring++;
                        }
index 450322e7eb8db7a37263b450310413da92fa8e0a..52a2ffe89869682a047adc1915bb169e8ddf4ed7 100644 (file)
@@ -6100,7 +6100,11 @@ CREATE OR REPLACE FUNCTION ST_DFullyWithin(geometry, geometry, float8)
        AS 'SELECT $1 && ST_Expand($2,$3) AND $2 && ST_Expand($1,$3) AND _ST_DFullyWithin(ST_ConvexHull($1), ST_ConvexHull($2), $3)'
        LANGUAGE 'SQL' IMMUTABLE; 
        
-       
+CREATE OR REPLACE FUNCTION ST_FlipCoordinates(geometry)
+       RETURNS geometry
+       AS 'MODULE_PATHNAME', 'ST_FlipCoordinates'
+       LANGUAGE 'C' IMMUTABLE STRICT; 
+
 --
 -- SFSQL 1.1
 --