Python >> Tutoriel Python >  >> Python Tag >> Pandas

Échangez y, x à x, y avec geopandas (python) ou QGIS

shapely.ops.transform permet de passer une fonction pour opérer sur les coordonnées. Par conséquent, si vous souhaitez échanger les coordonnées x, y dans un GeoDataFrame, vous pouvez utiliser :

import shapely

gdf.geometry.map(lambda polygon: shapely.ops.transform(lambda x, y: (y, x), polygon))

Pour échanger (x, y) pour n'importe quel type de géométrie Shapely, voici une fonction générale. Il conserve également les coordonnées z (si présentes) :

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)

Par exemple :

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