pyproj Documentation

repository·main·Indexed 22 days ago

https://github.com/pyproj4/pyproj

A Python interface to the PROJ library for cartographic projections and coordinate transformations. It provides tools for managing Coordinate Reference Systems (CRS) via the pyproj.crs.CRS class, performing efficient transformations using pyproj.transformer.Transformer, and handling complex geospatial operations including 2D/3D CRS promotion, AreaOfInterest definitions, and specialized projection conversion classes.

Tokens
20.9K
Snippets
41
Records
164
Agent score
78%

What's inside pyproj

  1. Overview of pyproj

    main
    pyproj is a Python interface to PROJ, a library used for cartographic projections and coordinate transformations. It allows developers to perform complex geospatial transformations and coordinate system operations within Python environments.
  2. Use TransformerGroup to manage multiple transformation options

    main

    The pyproj.transformer.TransformerGroup provides access to all available transformations between two CRSs, as well as information about missing transformations (e.g., missing grids). This is useful for:

    1. Selecting an alternative transformation if the default is not suitable.
    2. Checking if the best possible transformation is available and identifying required grids to download if it is not.
  3. Use pyproj.Transformer for coordinate transformations

    main

    The pyproj.Transformer class is used to perform 2D, 3D, and 4D (time) transformations between any pair of definable coordinate reference systems (CRS), including datum transformations. It provides the same capabilities as the PROJ command-line tools proj, cs2cs, and cct.

    Important: Axis Order By default, the axis order may be swapped if the source and destination CRSs are defined as having the first coordinate component point in a northerly direction. To ensure your coordinates always follow an x, y (longitude, latitude) order regardless of the CRS definition, use the always_xy=True option when initializing the Transformer.

  4. Understand the min_confidence parameter in CRS methods

    main

    When using pyproj.crs.CRS.to_epsg() or pyproj.crs.CRS.to_authority(), the min_confidence parameter controls how strictly the CRS must match an existing authority code.

    Because a CRS can be initialized via various methods (WKT, PROJ strings, etc.), they might not always be identical to an official EPSG definition.

    • A high min_confidence ensures that the returned EPSG code is a near-exact match for your CRS.
    • A lower min_confidence allows you to retrieve the closest matching EPSG code even if the definitions differ slightly (e.g., in axis order).
  5. Thread safety of CRS and Transformer objects

    main
    As of version 3.1, pyproj.crs.CRS and pyproj.transformer.Transformer objects are thread-safe and can be shared across multiple threads. If you are using a version older than 3.1, you must create the object within the specific thread that uses it.
  6. Choose the best format for storing CRS information

    main

    When describing a Coordinate Reference System (CRS), use Well-Known Text (WKT) or Spatial Reference IDs (SRID) such as EPSG codes.

    • WKT2 is preferred over WKT1.
    • Avoid PROJ strings for long-term storage as they can be lossy and may not be supported in future major versions of PROJ.
  7. Use Transformer instead of Proj for latitude/longitude conversions

    main

    The pyproj.Proj class is limited to converting between geographic and projection coordinates within the same datum.

    If you need to convert latitude/longitude (typically EPSG:4326) to a projection with a different datum, you must use pyproj.transformer.Transformer. This ensures that necessary datum shifts are accounted for. Using Proj for different datums may result in inaccurate transformations.

  8. Convert between fiona.crs.CRS and pyproj.crs.CRS

    main

    For fiona >= 1.9, you can pass the dataset's CRS directly into CRS.from_user_input(). For older versions, use the crs_wkt attribute.

    To convert from pyproj.crs.CRS to fiona.crs.CRS, if you have fiona >= 1.9 and GDAL 3+, you can pass the pyproj.crs.CRS object directly into fiona.crs.CRS.from_user_input(). For compatibility with older GDAL versions, use WktVersion.WKT1_GDAL when exporting to WKT.

    import fiona
    from pyproj.crs import CRS
    
    # fiona -> pyproj
    with fiona.open(...) as fds:
        proj_crs = CRS.from_user_input(fds.crs)
    
    # pyproj -> fiona (compatible version)
    from packaging import version
    from pyproj.enums import WktVersion
    
    proj_crs = CRS.from_epsg(4326)
    if version.parse(fiona.__gdal_version__) < version.parse("3.0.0"):
        fio_crs = fiona.crs.CRS.from_wkt(proj_crs.to_wkt(WktVersion.WKT1_GDAL))
    else:
        fio_crs = fiona.crs.CRS.from_wkt(proj_crs.to_wkt())
  9. Create a Bound CRS

    main

    A BoundCRS is used to represent a CRS that includes a transformation to a target CRS (often WGS 84). This is typically used when dealing with legacy datum shifts (e.g., using towgs84 parameters). You must provide the source_crs, the target_crs (as a string or CRS object), and a transformation object (like ToWGS84Transformation).

    from pyproj.crs import BoundCRS, Ellipsoid, GeographicCRS, ProjectedCRS
    from pyproj.crs.coordinate_operation import (
        TransverseMercatorConversion,
        ToWGS84Transformation,
    )
    from pyproj.crs.datum import CustomDatum
    import pyproj
    
    proj_crs = ProjectedCRS(
        conversion=TransverseMercatorConversion(
            latitude_natural_origin=0,
            longitude_natural_origin=15,
            false_easting=2520000,
            false_northing=0,
            scale_factor_natural_origin=0.9996,
        ),
        geodetic_crs=GeographicCRS(
            datum=CustomDatum(ellipsoid="International 1924 (Hayford 1909, 1910)")
        ),
    )
    bound_crs = BoundCRS(
        source_crs=proj_crs,
        target_crs="WGS 84",
        transformation=ToWGS84Transformation(
            proj_crs.geodetic_crs, -122.74, -34.27, -22.83, -1.884, -3.4, -3.03, -15.62
        ),
    )
    crs_wkt = bound_crs.to_wkt()
    from pyproj.crs import BoundCRS, Ellipsoid, GeographicCRS, ProjectedCRS
    from pyproj.crs.coordinate_operation import (
        TransverseMercatorConversion,
        ToWGS84Transformation,
    )
    from pyproj.crs.datum import CustomDatum
    import pyproj
    
    proj_crs = ProjectedCRS(
        conversion=TransverseMercatorConversion(
            latitude_natural_origin=0,
            longitude_natural_origin=15,
            false_easting=2520000,
            false_northing=0,
            scale_factor_natural_origin=0.9996,
        ),
        geodetic_crs=GeographicCRS(
            datum=CustomDatum(ellipsoid="International 1924 (Hayford 1909, 1910)")
        ),
    )
    bound_crs = BoundCRS(
        source_crs=proj_crs,
        target_crs="WGS 84",
        transformation=ToWGS84Transformation(
            proj_crs.geodetic_crs, -122.74, -34.27, -22.83, -1.884, -3.4, -3.03, -15.62
        ),
    )
    crs_wkt = bound_crs.to_wkt()
  10. Create a Geographic CRS

    main

    You can construct a Geographic Coordinate Reference System (CRS) using the GeographicCRS class. This is useful for transitioning from PROJ strings to the more descriptive WKT (Well-Known Text) format. You can initialize it with default values or customize it using CustomDatum, Ellipsoid, and PrimeMeridian objects.

    Basic initialization:

    from pyproj.crs import GeographicCRS
    
    geog_crs = GeographicCRS()
    geog_wkt = geog_crs.to_wkt()

    Custom initialization with a specific datum, ellipsoid, and prime meridian:

    from pyproj.crs import Ellipsoid, GeographicCRS, PrimeMeridian
    from pyproj.crs.datum import CustomDatum
    
    cd = CustomDatum(
        ellipsoid=Ellipsoid.from_epsg(7001),
        prime_meridian=PrimeMeridian.from_name("Lisbon"),
    )
    geog_crs = GeographicCRS(datum=cd)
    geog_wkt = geog_crs.to_wkt()
    from pyproj.crs import GeographicCRS
    
    geog_crs = GeographicCRS()
    geog_wkt = geog_crs.to_wkt()
  11. Convert between rasterio.crs.CRS and pyproj.crs.CRS

    main

    For rasterio >= 1.0.14, you can pass a rasterio.crs.CRS object directly into CRS.from_user_input(). For older versions, use the .wkt property.

    To convert from pyproj.crs.CRS to rasterio.crs.CRS, if you have rasterio >= 1.0.26 and GDAL 3+, you can pass the pyproj.crs.CRS object directly into rasterio.crs.CRS.from_user_input(). For compatibility with older GDAL versions, use WktVersion.WKT1_GDAL for the WKT export.

    import rasterio
    import rasterio.crs
    from pyproj.crs import CRS
    
    # rasterio -> pyproj
    with rasterio.Env(OSR_WKT_FORMAT="WKT2_2018"):
        rio_crs = rasterio.crs.CRS.from_epsg(4326)
        proj_crs = CRS.from_user_input(rio_crs)
    
    # pyproj -> rasterio (compatible version)
    from packaging import version
    from pyproj.enums import WktVersion
    
    proj_crs = CRS.from_epsg(4326)
    if version.parse(rasterio.__gdal_version__) < version.parse("3.0.0"):
        rio_crs = rasterio.crs.CRS.from_wkt(proj_crs.to_wkt(WktVersion.WKT1_GDAL))
    else:
        rio_crs = rasterio.crs.CRS.from_wkt(proj_crs.to_wkt())
  12. Convert between pycrs and pyproj.crs.CRS

    main

    Note that pycrs does not support WKT2.

    To convert from pyproj.crs.CRS to pycrs, use pycrs.parse.from_ogc_wkt() with a WKT1 GDAL export: proj_crs.to_wkt("WKT1_GDAL").

    To convert from pycrs to pyproj.crs.CRS, use CRS.from_wkt() with the WKT string from py_crs.to_ogc_wkt().

    import pycrs
    from pyproj.crs import CRS
    
    # pyproj -> pycrs
    proj_crs = CRS.from_epsg(4326)
    py_crs = pycrs.parse.from_ogc_wkt(proj_crs.to_wkt("WKT1_GDAL"))
    
    # pycrs -> pyproj
    py_crs = pycrs.parse.from_epsg_code(4326)
    proj_crs = CRS.from_wkt(py_crs.to_ogc_wkt())