Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

REF: use regex to process PROJ strings in CRS.to_dict() #1086

Merged
merged 1 commit into from Jun 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/history.rst
Expand Up @@ -7,6 +7,7 @@ Latest
- BUG: Fix transformer list for 3D transformations in :class:`pyproj.transformer.TransformerGroup` (discussion #1072)
- ENH: Added authority, accuracy, and allow_ballpark kwargs to :class:`pyproj.transformer.TransformerGroup` (pull #1076)
- CLN: Remove deprecated `skip_equivalent` kwarg from transformers and `errcheck` kwarg from :meth:`pyproj.crs.CRS.from_cf` (pull #1077)
- REF: use regex to process PROJ strings in :meth:`pyproj.crs.CRS.to_dict()`(pull #1086)

3.3.1
-------
Expand Down
34 changes: 24 additions & 10 deletions pyproj/crs/crs.py
Expand Up @@ -37,6 +37,17 @@
from pyproj.exceptions import CRSError
from pyproj.geod import Geod

_RE_PROJ_PARAM = re.compile(
r"""
\+ # parameter starts with '+' character
(?P<param>\w+) # capture parameter name
\=? # match both key only and key-value parameters
(?P<value>\S+)? # capture all characters up to next space (None if no value)
\s*? # consume remaining whitespace, if any
""",
re.X,
)


class CRSLocal(threading.local):
"""
Expand Down Expand Up @@ -573,7 +584,11 @@ def to_dict(self) -> dict:

"""

def parse(val):
proj_string = self.to_proj4()
if proj_string is None:
return {}

def _parse(val):
if val.lower() == "true":
return True
if val.lower() == "false":
Expand All @@ -588,16 +603,15 @@ def parse(val):
pass
return _try_list_if_string(val)

proj_string = self.to_proj4()
if proj_string is None:
return {}

items = map(
lambda kv: len(kv) == 2 and (kv[0], parse(kv[1])) or (kv[0], None),
(part.lstrip("+").split("=", 1) for part in proj_string.strip().split()),
)
proj_dict = {}
for param in _RE_PROJ_PARAM.finditer(proj_string):
key, value = param.groups()
if value is not None:
value = _parse(value)
if value is not False:
proj_dict[key] = value

return {key: value for key, value in items if value is not False}
return proj_dict

def to_cf(
self,
Expand Down