GeoPandas extends pandas functionality to handle geographic and geospatial data operations with GeoSeries and GeoDataFrame classes.
—
GeoPandas provides a comprehensive set of geometric operations for spatial analysis and geometric computations. These operations work on individual geometries and return new geometric objects or scalar values, enabling complex spatial analysis workflows.
Properties that return scalar values describing geometric characteristics.
class GeoSeries:
@property
def area(self):
"""
Area of each geometry in the GeoSeries.
Returns:
- pandas.Series: Area values (units depend on CRS)
"""
...
@property
def length(self):
"""
Length of each geometry in the GeoSeries.
Returns:
- pandas.Series: Length values (units depend on CRS)
"""
...
@property
def geom_type(self):
"""
Geometry type of each geometry.
Returns:
- pandas.Series: Geometry type names ('Point', 'LineString', etc.)
"""
...
@property
def is_empty(self):
"""
Whether each geometry is empty.
Returns:
- pandas.Series: Boolean values indicating if geometry is empty
"""
...
@property
def is_ring(self):
"""
Whether each geometry is a closed ring.
Returns:
- pandas.Series: Boolean values indicating if geometry is a ring
"""
...
@property
def is_simple(self):
"""
Whether each geometry is simple (non-self-intersecting).
Returns:
- pandas.Series: Boolean values indicating if geometry is simple
"""
...
@property
def is_valid(self):
"""
Whether each geometry is valid.
Returns:
- pandas.Series: Boolean values indicating if geometry is valid
"""
...
@property
def is_closed(self):
"""
Whether each LinearRing or LineString geometry is closed.
Returns:
- pandas.Series: Boolean values indicating if geometry is closed
"""
...
@property
def is_ccw(self):
"""
Whether each LinearRing geometry has counter-clockwise orientation.
Returns:
- pandas.Series: Boolean values indicating counter-clockwise orientation
"""
...
@property
def has_z(self):
"""
Whether each geometry has Z (3D) coordinates.
Returns:
- pandas.Series: Boolean values indicating presence of Z coordinates
"""
...
@property
def has_m(self):
"""
Whether each geometry has M (measure) coordinates.
Returns:
- pandas.Series: Boolean values indicating presence of M coordinates
"""
...Methods that create new geometries based on existing ones.
class GeoSeries:
def buffer(self, distance, resolution=16, **kwargs):
"""
Buffer each geometry by given distance.
Parameters:
- distance: Buffer distance (units depend on CRS)
- resolution: Number of segments for circular arcs
- **kwargs: Additional parameters for shapely buffer
Returns:
- GeoSeries: Buffered geometries
"""
...
def boundary(self):
"""
Boundary of each geometry.
Returns:
- GeoSeries: Boundary geometries
"""
...
def centroid(self):
"""
Centroid of each geometry.
Returns:
- GeoSeries: Point geometries representing centroids
"""
...
def convex_hull(self):
"""
Convex hull of each geometry.
Returns:
- GeoSeries: Convex hull geometries
"""
...
def envelope(self):
"""
Envelope (bounding box) of each geometry.
Returns:
- GeoSeries: Rectangular envelope geometries
"""
...
def exterior(self):
"""
Exterior ring of each Polygon geometry.
Returns:
- GeoSeries: LinearRing geometries
"""
...
def interiors(self):
"""
Interior rings of each Polygon geometry.
Returns:
- pandas.Series: Lists of LinearRing geometries
"""
...
def representative_point(self):
"""
Representative point for each geometry (guaranteed to be within geometry).
Returns:
- GeoSeries: Point geometries within original geometries
"""
...
def simplify(self, tolerance, preserve_topology=True):
"""
Simplify geometries using Douglas-Peucker algorithm.
Parameters:
- tolerance: Simplification tolerance (units depend on CRS)
- preserve_topology: Whether to preserve topology
Returns:
- GeoSeries: Simplified geometries
"""
...
def minimum_rotated_rectangle(self):
"""
Minimum rotated bounding rectangle for each geometry.
Returns:
- GeoSeries: Rectangular geometries with minimum area enclosing original
"""
...
def minimum_bounding_circle(self):
"""
Minimum bounding circle for each geometry.
Returns:
- GeoSeries: Circular geometries with minimum area enclosing original
"""
...
def minimum_bounding_radius(self):
"""
Radius of minimum bounding circle for each geometry.
Returns:
- pandas.Series: Radius values for minimum bounding circles
"""
...
def concave_hull(self, ratio=0.0, allow_holes=False):
"""
Concave hull of each geometry using alpha shapes algorithm.
Parameters:
- ratio: Ratio parameter controlling concaveness (0.0 = convex hull, 1.0 = maximum concaveness)
- allow_holes: Whether to allow holes in the hull
Returns:
- GeoSeries: Concave hull geometries
"""
...
def delaunay_triangles(self, tolerance=0.0, only_edges=False):
"""
Delaunay triangulation of geometry coordinates.
Parameters:
- tolerance: Coordinate tolerance for triangulation
- only_edges: Return only triangle edges instead of filled triangles
Returns:
- GeoSeries: Triangle geometries or edge LineStrings
"""
...
def voronoi_polygons(self, tolerance=0.0, extend_to=None, only_edges=False):
"""
Voronoi diagram of Point geometries.
Parameters:
- tolerance: Coordinate tolerance for diagram generation
- extend_to: Geometry to extend diagram to (default: bounding box)
- only_edges: Return only diagram edges instead of filled polygons
Returns:
- GeoSeries: Voronoi polygon geometries or edge LineStrings
"""
...
def offset_curve(self, distance, quad_segs=8, join_style=1, mitre_limit=5.0):
"""
Create offset curve (parallel line) from LineString geometries.
Parameters:
- distance: Offset distance (positive for left, negative for right)
- quad_segs: Number of segments for quarter circle
- join_style: Join style (1=round, 2=mitre, 3=bevel)
- mitre_limit: Mitre ratio limit for mitre joins
Returns:
- GeoSeries: Offset curve geometries
"""
...
def line_merge(self, directed=False):
"""
Merge connected LineString geometries into continuous lines.
Parameters:
- directed: Whether to consider line direction in merging
Returns:
- GeoSeries: Merged LineString or MultiLineString geometries
"""
...Methods for working with linear geometries and distance-based positioning.
class GeoSeries:
def project(self, other, normalized=False):
"""
Project point onto line geometry and return distance along line.
Parameters:
- other: Point geometry or GeoSeries of Points to project
- normalized: Return distance as fraction of line length (0.0 to 1.0)
Returns:
- pandas.Series: Distance values along the line
"""
...
def interpolate(self, distance, normalized=False):
"""
Return point at specified distance along line geometry.
Parameters:
- distance: Distance along line or array of distances
- normalized: Interpret distance as fraction of line length
Returns:
- GeoSeries: Point geometries at specified distances
"""
...Methods for applying affine transformations to geometries.
class GeoSeries:
def translate(self, xoff=0.0, yoff=0.0, zoff=0.0):
"""
Translate geometries by given offsets.
Parameters:
- xoff: X offset
- yoff: Y offset
- zoff: Z offset
Returns:
- GeoSeries: Translated geometries
"""
...
def rotate(self, angle, origin='center', use_radians=False):
"""
Rotate geometries by given angle.
Parameters:
- angle: Rotation angle
- origin: Center of rotation ('center', 'centroid', or Point)
- use_radians: Whether angle is in radians (default: degrees)
Returns:
- GeoSeries: Rotated geometries
"""
...
def scale(self, xfact=1.0, yfact=1.0, zfact=1.0, origin='center'):
"""
Scale geometries by given factors.
Parameters:
- xfact: X scale factor
- yfact: Y scale factor
- zfact: Z scale factor
- origin: Center of scaling ('center', 'centroid', or Point)
Returns:
- GeoSeries: Scaled geometries
"""
...
def skew(self, xs=0.0, ys=0.0, origin='center', use_radians=False):
"""
Skew geometries by given angles.
Parameters:
- xs: X skew angle
- ys: Y skew angle
- origin: Center of skewing ('center', 'centroid', or Point)
- use_radians: Whether angles are in radians (default: degrees)
Returns:
- GeoSeries: Skewed geometries
"""
...Properties for accessing coordinate information from Point geometries.
class GeoSeries:
@property
def x(self):
"""
X coordinates of Point geometries.
Returns:
- pandas.Series: X coordinate values (NaN for non-Point geometries)
"""
...
@property
def y(self):
"""
Y coordinates of Point geometries.
Returns:
- pandas.Series: Y coordinate values (NaN for non-Point geometries)
"""
...
@property
def z(self):
"""
Z coordinates of Point geometries.
Returns:
- pandas.Series: Z coordinate values (NaN for 2D or non-Point geometries)
"""
...
@property
def m(self):
"""
M coordinates of Point geometries.
Returns:
- pandas.Series: M coordinate values (NaN for non-M or non-Point geometries)
"""
...
@property
def bounds(self):
"""
Bounds of each geometry as (minx, miny, maxx, maxy).
Returns:
- pandas.DataFrame: DataFrame with minx, miny, maxx, maxy columns
"""
...
@property
def total_bounds(self):
"""
Total bounds of all geometries as (minx, miny, maxx, maxy).
Returns:
- numpy.ndarray: Array with [minx, miny, maxx, maxy]
"""
...Methods for validating and repairing geometries.
class GeoSeries:
def make_valid(self, method='auto'):
"""
Make invalid geometries valid.
Parameters:
- method: Repair method ('auto', 'structure', 'linework')
Returns:
- GeoSeries: Valid geometries
"""
...
def normalize(self):
"""
Normalize geometries to canonical form.
Returns:
- GeoSeries: Normalized geometries
"""
...
def is_valid_reason(self):
"""
Return reason why each geometry is invalid.
Returns:
- pandas.Series: Text descriptions of invalidity reasons
"""
...
def clip_by_rect(self, xmin, ymin, xmax, ymax):
"""
Clip geometries to rectangular bounds.
Parameters:
- xmin: Minimum X coordinate
- ymin: Minimum Y coordinate
- xmax: Maximum X coordinate
- ymax: Maximum Y coordinate
Returns:
- GeoSeries: Clipped geometries
"""
...
def snap(self, other, tolerance):
"""
Snap vertices of geometries to reference geometries within tolerance.
Parameters:
- other: Reference geometry or GeoSeries to snap to
- tolerance: Snapping tolerance distance
Returns:
- GeoSeries: Snapped geometries
"""
...
def polygonize(self, node=True, full=False):
"""
Create polygons from collection of LineString geometries.
Parameters:
- node: Whether to node the lines first
- full: Return all polygonization products
Returns:
- GeoSeries: Polygonal geometries
"""
...
def unary_union(self):
"""
Union all geometries in the series into a single geometry.
Returns:
- Geometry: Single geometry representing union of all geometries
"""
...
def get_coordinates(self, include_z=None, ignore_index=False, index_parts=False):
"""
Extract coordinate arrays from geometries.
Parameters:
- include_z: Include Z coordinates if available
- ignore_index: Reset index in result
- index_parts: Include part indices for multi-part geometries
Returns:
- pandas.DataFrame: Coordinate arrays with x, y (and optionally z) columns
"""
...import geopandas as gpd
from shapely.geometry import Point, Polygon, LineString
# Create sample geometries
gdf = gpd.GeoDataFrame({
'name': ['Circle', 'Square', 'Line'],
'geometry': [
Point(0, 0).buffer(1), # Circle
Polygon([(0, 0), (1, 0), (1, 1), (0, 1)]), # Square
LineString([(0, 0), (1, 1), (2, 0)]) # Line
]
})
# Calculate geometric properties
print(f"Areas: {gdf.geometry.area}")
print(f"Lengths: {gdf.geometry.length}")
print(f"Types: {gdf.geometry.geom_type}")
print(f"Bounds: {gdf.geometry.bounds}")
print(f"Total bounds: {gdf.geometry.total_bounds}")# Create derived geometries
centroids = gdf.geometry.centroid
envelopes = gdf.geometry.envelope
convex_hulls = gdf.geometry.convex_hull
boundaries = gdf.geometry.boundary
# Buffer operations
buffered_small = gdf.geometry.buffer(0.5)
buffered_large = gdf.geometry.buffer(2.0, resolution=32)
# Simplification
complex_line = LineString([(i/10, (i/10)**2) for i in range(100)])
simplified = gpd.GeoSeries([complex_line]).simplify(0.1)# Translation
translated = gdf.geometry.translate(xoff=10, yoff=5)
# Rotation (45 degrees counterclockwise)
rotated = gdf.geometry.rotate(45, origin='center')
# Scaling
scaled = gdf.geometry.scale(xfact=2.0, yfact=0.5, origin='center')
# Skewing
skewed = gdf.geometry.skew(xs=15, ys=0, origin='center')
# Combine transformations
transformed = (gdf.geometry
.translate(xoff=5, yoff=5)
.rotate(30, origin='center')
.scale(xfact=1.5, yfact=1.5, origin='center'))# Create points
points = gpd.GeoSeries([
Point(1, 2),
Point(3, 4, 5), # 3D point
Point(6, 7)
])
# Access coordinates
print(f"X coordinates: {points.x}")
print(f"Y coordinates: {points.y}")
print(f"Z coordinates: {points.z}") # NaN for 2D points
# For non-Point geometries, coordinates are NaN
mixed_geoms = gpd.GeoSeries([
Point(1, 2),
LineString([(0, 0), (1, 1)]),
Polygon([(0, 0), (1, 0), (1, 1), (0, 1)])
])
print(f"X coordinates: {mixed_geoms.x}") # Only Point has valid X# Polygon with holes
exterior = [(0, 0), (10, 0), (10, 10), (0, 10)]
hole1 = [(2, 2), (4, 2), (4, 4), (2, 4)]
hole2 = [(6, 6), (8, 6), (8, 8), (6, 8)]
polygon_with_holes = Polygon(exterior, [hole1, hole2])
gdf_complex = gpd.GeoDataFrame({'geometry': [polygon_with_holes]})
# Access polygon components
exterior_ring = gdf_complex.geometry.exterior
interior_rings = gdf_complex.geometry.interiors
print(f"Exterior: {exterior_ring.iloc[0]}")
print(f"Number of holes: {len(interior_rings.iloc[0])}")from shapely.geometry import Polygon
# Create invalid geometry (self-intersecting polygon)
invalid_polygon = Polygon([(0, 0), (2, 2), (2, 0), (0, 2)])
gdf_invalid = gpd.GeoDataFrame({'geometry': [invalid_polygon]})
# Check validity
print(f"Is valid: {gdf_invalid.geometry.is_valid.iloc[0]}")
# Repair invalid geometry
gdf_repaired = gdf_invalid.copy()
gdf_repaired['geometry'] = gdf_repaired.geometry.make_valid()
print(f"Repaired is valid: {gdf_repaired.geometry.is_valid.iloc[0]}")
# Normalize geometries
normalized = gdf_repaired.geometry.normalize()# For accurate measurements, use projected CRS
gdf_geographic = gpd.read_file('world.shp') # WGS84
# Convert to appropriate UTM zone for accurate area calculation
utm_crs = gdf_geographic.estimate_utm_crs()
gdf_utm = gdf_geographic.to_crs(utm_crs)
# Calculate areas in square meters
areas_sqm = gdf_utm.geometry.area
# Calculate perimeters in meters
perimeters_m = gdf_utm.geometry.length
# Convert back to square kilometers for readability
areas_sqkm = areas_sqm / 1_000_000
print(f"Country areas (sq km): {areas_sqkm}")# For complex polygons, centroids might fall outside the geometry
# Representative points are guaranteed to be inside
complex_polygon = gpd.read_file('complex_country.shp')
centroids = complex_polygon.geometry.centroid
rep_points = complex_polygon.geometry.representative_point()
# Check which centroids fall outside their polygons
centroids_outside = ~complex_polygon.geometry.contains(centroids)
print(f"Centroids outside polygon: {centroids_outside.sum()}")
# Representative points are always inside
rep_points_inside = complex_polygon.geometry.contains(rep_points)
print(f"Representative points inside: {rep_points_inside.all()}")Install with Tessl CLI
npx tessl i tessl/pypi-geopandas