GeoPandas extends pandas functionality to handle geographic and geospatial data operations with GeoSeries and GeoDataFrame classes.
—
GeoPandas provides comprehensive support for coordinate reference system (CRS) management and coordinate transformations. This enables working with different spatial reference systems, projections, and datum transformations essential for accurate geospatial analysis.
Methods for setting, accessing, and managing coordinate reference systems on GeoDataFrame and GeoSeries objects.
class GeoDataFrame:
@property
def crs(self):
"""
The Coordinate Reference System (CRS) represented as a pyproj.CRS object.
Returns:
- pyproj.CRS or None: The coordinate reference system
"""
...
@crs.setter
def crs(self, value):
"""
Set the Coordinate Reference System.
Parameters:
- value: CRS definition (string, dict, EPSG code, or pyproj.CRS)
"""
...
def set_crs(self, crs, allow_override=False, inplace=False):
"""
Set the Coordinate Reference System (CRS).
Parameters:
- crs: CRS definition (string, dict, EPSG code, or pyproj.CRS)
- allow_override: Allow overriding existing CRS without warning
- inplace: Whether to return a new GeoDataFrame or modify in place
Returns:
- GeoDataFrame or None: New GeoDataFrame or None if inplace=True
"""
...
def to_crs(self, crs=None, epsg=None, inplace=False):
"""
Transform geometries to a new coordinate reference system.
Parameters:
- crs: Target CRS (string, dict, EPSG code, or pyproj.CRS)
- epsg: EPSG code for target CRS (alternative to crs parameter)
- inplace: Whether to return a new GeoDataFrame or modify in place
Returns:
- GeoDataFrame or None: Transformed GeoDataFrame or None if inplace=True
"""
...
def estimate_utm_crs(self, datum_name='WGS 84'):
"""
Estimate the most appropriate UTM CRS based on geometry bounds.
Parameters:
- datum_name: Name of the datum to use (default: 'WGS 84')
Returns:
- pyproj.CRS: Estimated UTM coordinate reference system
"""
...
class GeoSeries:
@property
def crs(self):
"""
The Coordinate Reference System (CRS) represented as a pyproj.CRS object.
Returns:
- pyproj.CRS or None: The coordinate reference system
"""
...
@crs.setter
def crs(self, value):
"""
Set the Coordinate Reference System.
Parameters:
- value: CRS definition (string, dict, EPSG code, or pyproj.CRS)
"""
...
def set_crs(self, crs, allow_override=False, inplace=False):
"""
Set the Coordinate Reference System (CRS).
Parameters:
- crs: CRS definition (string, dict, EPSG code, or pyproj.CRS)
- allow_override: Allow overriding existing CRS without warning
- inplace: Whether to return a new GeoSeries or modify in place
Returns:
- GeoSeries or None: New GeoSeries or None if inplace=True
"""
...
def to_crs(self, crs=None, epsg=None, inplace=False):
"""
Transform geometries to a new coordinate reference system.
Parameters:
- crs: Target CRS (string, dict, EPSG code, or pyproj.CRS)
- epsg: EPSG code for target CRS (alternative to crs parameter)
- inplace: Whether to return a new GeoSeries or modify in place
Returns:
- GeoSeries or None: Transformed GeoSeries or None if inplace=True
"""
...
def estimate_utm_crs(self, datum_name='WGS 84'):
"""
Estimate the most appropriate UTM CRS based on geometry bounds.
Parameters:
- datum_name: Name of the datum to use (default: 'WGS 84')
Returns:
- pyproj.CRS: Estimated UTM coordinate reference system
"""
...import geopandas as gpd
from shapely.geometry import Point
# Create GeoDataFrame without CRS
gdf = gpd.GeoDataFrame({
'city': ['New York', 'London', 'Tokyo'],
'geometry': [Point(-74.0, 40.7), Point(-0.1, 51.5), Point(139.7, 35.7)]
})
# Set CRS using different methods
gdf = gdf.set_crs('EPSG:4326') # Using EPSG code string
gdf = gdf.set_crs(4326) # Using EPSG code integer
gdf = gdf.set_crs({'init': 'EPSG:4326'}) # Using dictionary
gdf = gdf.set_crs('WGS84') # Using common name
# Set CRS directly via property
gdf.crs = 'EPSG:4326'
# Check current CRS
print(gdf.crs)
print(gdf.crs.to_string())
print(gdf.crs.to_epsg())# Transform to different projections
gdf_wgs84 = gpd.read_file('data.shp') # Assume WGS84
# Transform to Web Mercator
gdf_mercator = gdf_wgs84.to_crs('EPSG:3857')
# Transform to UTM (estimated)
utm_crs = gdf_wgs84.estimate_utm_crs()
gdf_utm = gdf_wgs84.to_crs(utm_crs)
# Transform using EPSG parameter
gdf_utm = gdf_wgs84.to_crs(epsg=32633) # UTM Zone 33N
# In-place transformation
gdf_wgs84.to_crs('EPSG:3857', inplace=True)# EPSG codes
gdf = gdf.to_crs('EPSG:4326') # WGS84
gdf = gdf.to_crs('EPSG:3857') # Web Mercator
gdf = gdf.to_crs('EPSG:32633') # UTM Zone 33N
# PROJ strings
gdf = gdf.to_crs('+proj=longlat +datum=WGS84 +no_defs')
# Well-Known Text (WKT)
wkt_crs = '''
GEOGCS["WGS 84",
DATUM["WGS_1984",
SPHEROID["WGS 84",6378137,298.257223563]],
PRIMEM["Greenwich",0],
UNIT["degree",0.0174532925199433]]
'''
gdf = gdf.to_crs(wkt_crs)
# Using pyproj.CRS objects
from pyproj import CRS
crs = CRS.from_epsg(4326)
gdf = gdf.to_crs(crs)# Automatically estimate appropriate UTM zone
utm_crs = gdf.estimate_utm_crs()
print(f"Estimated UTM CRS: {utm_crs}")
# Transform to estimated UTM for accurate area/distance calculations
gdf_utm = gdf.to_crs(utm_crs)
areas = gdf_utm.geometry.area # Now in square meters
# Estimate with different datum
utm_nad83 = gdf.estimate_utm_crs(datum_name='NAD83')
gdf_nad83 = gdf.to_crs(utm_nad83)# Check if CRS is set
if gdf.crs is None:
print("No CRS defined")
else:
print(f"CRS: {gdf.crs}")
# Get CRS information
print(f"EPSG Code: {gdf.crs.to_epsg()}")
print(f"Authority: {gdf.crs.to_authority()}")
print(f"PROJ String: {gdf.crs.to_proj4()}")
print(f"WKT: {gdf.crs.to_wkt()}")
# Check if CRS is geographic (lat/lon) or projected
print(f"Is Geographic: {gdf.crs.is_geographic}")
print(f"Is Projected: {gdf.crs.is_projected}")
print(f"Units: {gdf.crs.axis_info[0].unit_name}")# Reading files with different CRS
gdf1 = gpd.read_file('file1.shp') # UTM Zone 33N
gdf2 = gpd.read_file('file2.shp') # WGS84
# Ensure same CRS before operations
if gdf1.crs != gdf2.crs:
gdf2 = gdf2.to_crs(gdf1.crs)
# Or transform both to common CRS
common_crs = 'EPSG:4326'
gdf1 = gdf1.to_crs(common_crs)
gdf2 = gdf2.to_crs(common_crs)
# Override existing CRS (use with caution)
gdf = gdf.set_crs('EPSG:4326', allow_override=True)# CRS is preserved when reading files
gdf = gpd.read_file('data.shp')
print(f"File CRS: {gdf.crs}")
# Specify CRS when writing files
gdf.to_file('output.shp', crs='EPSG:4326')
# Transform before writing
gdf.to_crs('EPSG:3857').to_file('output_mercator.shp')
# Read file and immediately transform
gdf = gpd.read_file('data.shp').to_crs('EPSG:4326')# For area/distance calculations, use appropriate projected CRS
gdf_geographic = gpd.read_file('world.shp') # WGS84
# Inaccurate - using geographic coordinates
areas_bad = gdf_geographic.geometry.area
# Accurate - using projected coordinates
gdf_projected = gdf_geographic.to_crs(gdf_geographic.estimate_utm_crs())
areas_good = gdf_projected.geometry.area
# For global data, consider equal-area projections
gdf_mollweide = gdf_geographic.to_crs('+proj=moll +datum=WGS84')
areas_global = gdf_mollweide.geometry.areaInstall with Tessl CLI
npx tessl i tessl/pypi-geopandas