Interchange y, x to x, y with geopandas (python) or QGIS
shapely.ops.transform
module allows passing a function to operate on coordinates. Therefore if you want to swap x, y coordinates in a GeoDataFrame you can use :
import shapely
gdf.geometry.map(lambda polygon: shapely.ops.transform(lambda x, y: (y, x), polygon))
To swap (x,y) for any Shapely geometry type, here is a general function. It also preserves z coordinates (if present):
def swap_xy(geom):
if geom.is_empty:
return geom
if geom.has_z:
def swap_xy_coords(coords):
for x, y, z in coords:
yield (y, x, z)
else:
def swap_xy_coords(coords):
for x, y in coords:
yield (y, x)
# Process coordinates from each supported geometry type
if geom.type in ('Point', 'LineString', 'LinearRing'):
return type(geom)(list(swap_xy_coords(geom.coords)))
elif geom.type == 'Polygon':
ring = geom.exterior
shell = type(ring)(list(swap_xy_coords(ring.coords)))
holes = list(geom.interiors)
for pos, ring in enumerate(holes):
holes[pos] = type(ring)(list(swap_xy_coords(ring.coords)))
return type(geom)(shell, holes)
elif geom.type.startswith('Multi') or geom.type == 'GeometryCollection':
# Recursive call
return type(geom)([swap_xy(part) for part in geom.geoms])
else:
raise ValueError('Type %r not recognized' % geom.type)
For example:
from shapely.geometry import Point, Polygon, MultiPoint, MultiLineString
# POINT Z (1 2 3) -> POINT Z (2 1 3)
swap_xy(Point(1, 2, 3))
# MULTILINESTRING ((1 2, 3 4)) -> MULTILINESTRING ((2 1, 4 3))
swap_xy(MultiLineString([[(1, 2), (3, 4)]]))
# Map the function to a geopandas geometry column
table.geometry = table.geometry.map(swap_xy)
from shapely.geometry import Point, LineString
import geopandas
def swap(x):
coords = list(x.coords)
coords = [Point(t[1], t[0]) for t in coords] #Swap each coordinate using list comprehension and create Points
return LineString(coords)
df.geometry = df.geometry.map(swap) #Apply the function to the geometry of dataframe df