With PostGIS you would use the accessors ST_X()
and ST_Y()
, and recreate the point with a constructor like ST_MakePoint(x,y)
for example:
SELECT ST_AsText(geom) AS old, ST_AsText(newgeom) AS new
FROM ( VALUES (ST_MakePoint(0,1)) ) AS t(geom)
CROSS JOIN LATERAL
ST_SetSRID( ST_MakePoint(ST_Y(geom),ST_X(geom)), ST_SRID(geom) )
AS t2(newgeom);
old | new
------------+------------
POINT(0 1) | POINT(1 0)
(1 row)
You can create a simple function _ST_SwapXY
to accomplish this on points.
CREATE FUNCTION _ST_SwapXY(geom geometry(point))
RETURNS geometry(point) AS $$
SELECT ST_SetSRID( ST_MakePoint(ST_Y(geom),ST_X(geom)), ST_SRID(geom) );
$$ LANGUAGE sql
IMMUTABLE;
CREATE FUNCTION _ST_SwapXY(geog geography(point))
RETURNS geography(point) AS $$
SELECT ST_SetSRID( ST_MakePoint(ST_Y(geog::geometry),ST_X(geog::geometry)), ST_SRID(geog) )::geography;
$$ LANGUAGE sql
IMMUTABLE;
Testing it over a geography and geometry object (EWKT
is Extended Well-known Text (WKT) to include the SRID.)
SELECT ST_AsEWKT(pt) AS orig,
ST_AsEWKT( _ST_SwapXY(pt::geometry) ) AS geom,
ST_AsEWKT( _ST_SwapXY(pt::geography) ) AS geog
FROM ( VALUES
(ST_MakePoint(0,1)),
(ST_SetSRID(ST_MakePoint(0,1),4326))
) AS t(pt);
orig | geom | geog
----------------------+----------------------+----------------------
POINT(0 1) | POINT(1 0) | SRID=4326;POINT(1 0)
SRID=4326;POINT(0 1) | SRID=4326;POINT(1 0) | SRID=4326;POINT(1 0)
Note: MySQL's ST_SwapXY()
is substantially more powerful covering LINESTRINGS
and POLYGON
too, but hopefully your structures are not internally that screwed up. If they are you'll have to recursively do this.