<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
</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>
}
+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.
*/
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};
+
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);
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 *);
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);
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);
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
{
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;
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;
}
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;
|| (*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]);
}
}
|| (*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++;
}
}
|| (*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]);
}
}
lwerror("invalid GML representation");
if (srs->reverse_axis)
- ppa[ring] = ptarray_reverse_axis(ppa[ring]);
+ ppa[ring] = ptarray_flip_coordinates(ppa[ring]);
ring++;
}