Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions docs/api/crs/crs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@ CustomConstructorCRS
:special-members: __init__


guess_wkt_version
-----------------

.. autofunction:: pyproj.crs.guess_wkt_version


is_wkt
-----------------

Expand Down
1 change: 1 addition & 0 deletions docs/history.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ Change Log

Latest
------
- ENH: Added :func:`pyproj.crs.guess_wkt_version` to return the WKT version of a string (issue #1031)
- WHL: Wheels contain PROJ 9.7.1 (pull #1573)
- WHL: Upgrade from MacOS 13 to MacOS 15 (X86_64) wheels (issue #1532 & #1543)
- ENH: Add :meth:`database.query_geodetic_crs_from_datum` (pull #1390)
Expand Down
1 change: 1 addition & 0 deletions pyproj/_crs.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -230,4 +230,5 @@ class _CRS(Base):

def is_proj(proj_string: str) -> bool: ...
def is_wkt(proj_string: str) -> bool: ...
def guess_wkt_version(proj_string: str) -> Optional[WktVersion]: ...
def _load_proj_json(in_proj_json: str) -> dict: ...
32 changes: 32 additions & 0 deletions pyproj/_crs.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,38 @@ def is_wkt(str proj_string not None):
return proj_context_guess_wkt_dialect(NULL, b_proj_string) != PJ_GUESSED_NOT_WKT


def guess_wkt_version(str proj_string not None):
"""
.. versionadded:: 3.8.0

Guess the version of the Well-Known Text format of the input string.

Parameters
----------
proj_string: str
The projection string.

Returns
-------
Optional[pyproj.enums.WktVersion]:
The WKT version of the string or None if it is not WKT.
"""
cdef bytes b_proj_string = cstrencode(proj_string)
cdef PJ_GUESSED_WKT_DIALECT dialect = proj_context_guess_wkt_dialect(
NULL, b_proj_string
)
# PJ_GUESSED_WKT2_2018 is the legacy alias of PJ_GUESSED_WKT2_2019.
if dialect == PJ_GUESSED_WKT2_2019:
return WktVersion.WKT2_2019
if dialect == PJ_GUESSED_WKT2_2015:
return WktVersion.WKT2_2015
if dialect == PJ_GUESSED_WKT1_GDAL:
return WktVersion.WKT1_GDAL
if dialect == PJ_GUESSED_WKT1_ESRI:
return WktVersion.WKT1_ESRI
return None
Comment on lines +73 to +81

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this is just the python programmer in me, but this feels like it would work better as a dictionary .get:

return WKT_DIALECTS.get(dialect)

where the dictionary is a mapping of the dialect strings and the WktVersion value. I assume these constants being compared against are just strings or integers so the dictionary hashing isn't a problem. I don't feel that strongly about it, but I do think it may be cleaner and more flexible in the long run.



def is_proj(str proj_string not None):
"""
.. versionadded:: 2.2.2
Expand Down
2 changes: 2 additions & 0 deletions pyproj/crs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
Datum,
Ellipsoid,
PrimeMeridian,
guess_wkt_version,
is_proj,
is_wkt,
)
Expand All @@ -36,6 +37,7 @@
"GeographicCRS",
"ProjectedCRS",
"VerticalCRS",
"guess_wkt_version",
"is_proj",
"is_wkt",
]
1 change: 1 addition & 0 deletions pyproj/proj.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ cdef extern from "proj.h" nogil:
void proj_int_list_destroy(int* list)
void proj_context_use_proj4_init_rules(PJ_CONTEXT *ctx, int enable)
ctypedef enum PJ_GUESSED_WKT_DIALECT:
PJ_GUESSED_WKT2_2019
PJ_GUESSED_WKT2_2018
PJ_GUESSED_WKT2_2015
PJ_GUESSED_WKT1_GDAL
Expand Down
19 changes: 19 additions & 0 deletions test/crs/test_crs.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
Datum,
Ellipsoid,
PrimeMeridian,
guess_wkt_version,
)
from pyproj.crs.enums import CoordinateOperationType, DatumType
from pyproj.enums import ProjVersion, WktVersion
Expand Down Expand Up @@ -1000,6 +1001,24 @@ def test_to_wkt_enum__invalid():
crs.to_wkt("WKT_INVALID")


@pytest.mark.parametrize(
"wkt_version",
[
WktVersion.WKT2_2019,
WktVersion.WKT2_2015,
WktVersion.WKT1_GDAL,
WktVersion.WKT1_ESRI,
],
)
def test_guess_wkt_version(wkt_version):
crs = CRS.from_epsg(4326)
assert guess_wkt_version(crs.to_wkt(wkt_version)) == wkt_version


def test_guess_wkt_version__not_wkt():
assert guess_wkt_version("+proj=longlat +datum=WGS84 +no_defs +type=crs") is None


@pytest.mark.parametrize(
"wkt_version",
["WKT2_2015", "WKT2_2015_SIMPLIFIED", "WKT1_GDAL", "WKT1_ESRI"],
Expand Down
Loading