pyproj4 / pyproj

Python interface to PROJ (cartographic projections and coordinate transformations library)
https://pyproj4.github.io/pyproj
MIT License
1.04k stars 210 forks source link

DOC: Converting from fiona CRS to pyproj.crs.CRS #1360

Open idanmiara opened 9 months ago

idanmiara commented 9 months ago

I was struggling with finding the best way to convert between fiona CRS and pyproj CRS.

I think that the section https://pyproj4.github.io/pyproj/dev/crs_compatibility.html#converting-from-fiona-crs-to-pyproj-crs-crs needs to be updated with regards to https://github.com/Toblerity/Fiona/issues/714

Also, dc_crs is undefined: https://pyproj4.github.io/pyproj/dev/crs_compatibility.html#converting-from-pyproj-crs-crs-for-fiona https://pyproj4.github.io/pyproj/dev/crs_compatibility.html#preparing-pyproj-crs-crs-for-geopandas

djhoese commented 9 months ago

@idanmiara Do you have a suggestion of how it should be reworded/updated? Would you be comfortable making a pull request for this? If not, maybe you could post a comment here with the content you want in that section and one of the pyproj maintainers could make the PR.

idanmiara commented 9 months ago

Hi @djhoese I know that proj strings are discouraged and wkt is preferable, so is the following a bug in pyproj or in fiona?

import fiona
import pyproj
from fiona.crs import CRS
from pyproj import Proj

print(f'{fiona.__version__=}')
print(f'{pyproj.__version__=}')

pj = Proj(4326)
pj_str = pj.to_proj4()
wkt_str = pj.to_wkt()

print(f'{pj=}')
print(f'{pj_str=}')
print(f'{wkt_str=}')
print(f'{CRS.from_proj4(pj_str)=}')
print(f'{CRS.from_wkt(wkt_str)=}')  # fails

output:


fiona.__version__='1.9.4.post1'
pyproj.__version__='3.6.1'
pj=<Other Coordinate Operation Transformer: longlat>
Description: PROJ-based coordinate operation
Area of Use:
- undefined
pj_str='+proj=longlat +datum=WGS84 +no_defs'
wkt_str='CONVERSION["PROJ-based coordinate operation",METHOD["PROJ-based operation method: +proj=longlat +datum=WGS84 +no_defs"]]'
CRS.from_proj4(pj_str)=CRS.from_epsg(4326)
ERROR 1: PROJ: internal_proj_crs_get_coordinate_system: Object is not a SingleCRS
Traceback (most recent call last):
  File "fiona/crs.pyx", line 729, in fiona.crs.CRS.from_wkt
  File "fiona/_err.pyx", line 280, in fiona._err.exc_wrap_ogrerr
fiona._err.CPLE_AppDefinedError: PROJ: internal_proj_crs_get_coordinate_system: Object is not a SingleCRS

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "test.py", line 17, in <module>
    print(f'{CRS.from_wkt(wkt_str)=}')  # fails
             ^^^^^^^^^^^^^^^^^^^^^
  File "fiona/crs.pyx", line 731, in fiona.crs.CRS.from_wkt
fiona.errors.CRSError: The WKT could not be parsed. PROJ: internal_proj_crs_get_coordinate_system: Object is not a SingleCRS
djhoese commented 9 months ago
In [1]: from pyproj import CRS

In [2]: from fiona.crs import CRS as fCRS

In [3]: crs = CRS(4326)

In [4]: fCRS.from_wkt(crs.to_wkt())
Out[4]: CRS.from_epsg(4326)

In [5]: fCRS.from_proj4(crs.to_proj4())
/home/davidh/miniconda3/envs/satpy_py311_2/lib/python3.11/site-packages/pyproj/crs/crs.py:1293: UserWarning: You will likely lose important projection information when converting to a PROJ string from another format. See: https://proj.org/faq.html#what-is-the-best-format-for-describing-coordinate-reference-systems
  proj = self._crs.to_proj4(version=version)
Out[5]: CRS.from_epsg(4326)
snowman2 commented 9 months ago

With Fiona 1.9+ and GDAL 3+, the instructions should look similar to rasterio: https://pyproj4.github.io/pyproj/stable/crs_compatibility.html#rasterio

idanmiara commented 9 months ago

With Fiona 1.9+ and GDAL 3+, the instructions should look similar to rasterio: https://pyproj4.github.io/pyproj/stable/crs_compatibility.html#rasterio

In the rio example you take a rio wkt and pass it to pyproj:

import rasterio.crs
from pyproj.crs import CRS

with rasterio.Env(OSR_WKT_FORMAT="WKT2_2018"):
    rio_crs = rasterio.crs.CRS.from_epsg(4326)
    proj_crs = CRS.from_wkt(rio_crs.wkt)

which works fine. But what about the other direction as I did above, why does it fail?

djhoese commented 9 months ago

@idanmiara Could you explain what I'm doing differently in my comment above where I do as you suggest and it works for me?

idanmiara commented 9 months ago

@idanmiara Could you explain what I'm doing differently in my comment above where I do as you suggest and it works for me?

Thanks @djhoese, I've must have missed your comment before. It seems that I've been mistakenly using pyproj.Proj instead of pyproj.CRS (as you did), so now it works. I will try to make a PR to fix the docs accordingly.