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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ENH: Added parameter output_axis_rule to CRS.to_wkt #1287

Merged
merged 8 commits into from
May 19, 2023
Merged
Show file tree
Hide file tree
Changes from 7 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
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Latest
- DEP: Minimum supported Python version 3.9 (issue #1111)
- ENH: Added allow_superseded kwargs to :class:`pyproj.transformer.TransformerGroup` (pull #1269)
- ENH: Added :meth:`CRS.to_2d` to demote 3D CRS to 2D (issue #1266)
- ENH: Added parameter `output_axis_rule` to :meth:`CRS.to_wkt` (pull #1287)

3.5.0
------
Expand Down
3 changes: 3 additions & 0 deletions pyproj/_crs.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ include "proj.pxi"

from pyproj.enums import WktVersion

from cpython cimport bool


cdef extern from "proj_experimental.h":
PJ *proj_crs_promote_to_3D(PJ_CONTEXT *ctx,
Expand All @@ -25,6 +27,7 @@ cdef _to_wkt(
PJ* projobj,
object version,
bint pretty,
bool output_axis_rule=*,
)

cdef class Axis:
Expand Down
1 change: 1 addition & 0 deletions pyproj/_crs.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class Base:
self,
version: Union[WktVersion, str] = WktVersion.WKT2_2019,
pretty: bool = False,
output_axis_rule: Optional[bool] = None,
) -> str: ...
def to_json(self, pretty: bool = False, indentation: int = 2) -> str: ...
def to_json_dict(self) -> dict: ...
Expand Down
21 changes: 17 additions & 4 deletions pyproj/_crs.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ cdef _to_wkt(
PJ* projobj,
object version,
bint pretty,
bool output_axis_rule=None,
):
"""
Convert a PJ object to a wkt string.
Expand All @@ -85,6 +86,7 @@ cdef _to_wkt(
projobj: PJ*
wkt_out_type: PJ_WKT_TYPE
pretty: bool
output_axis_rule: bool or None

Return
------
Expand All @@ -104,12 +106,18 @@ cdef _to_wkt(
cdef PJ_WKT_TYPE wkt_out_type
wkt_out_type = supported_wkt_types[WktVersion.create(version)]

cdef const char* options_wkt[2]
cdef const char* options_wkt[3]
cdef bytes multiline = b"MULTILINE=NO"
if pretty:
multiline = b"MULTILINE=YES"
cdef bytes output_axis = b"OUTPUT_AXIS=AUTO"
if output_axis_rule is False:
output_axis = b"OUTPUT_AXIS=NO"
elif output_axis_rule is True:
output_axis = b"OUTPUT_AXIS=YES"
options_wkt[0] = multiline
options_wkt[1] = NULL
options_wkt[1] = output_axis
options_wkt[2] = NULL
cdef const char* proj_string
proj_string = proj_as_wkt(
context,
Expand Down Expand Up @@ -398,7 +406,7 @@ cdef class Base:
"""
return self._scope

def to_wkt(self, version=WktVersion.WKT2_2019, pretty=False):
def to_wkt(self, version=WktVersion.WKT2_2019, pretty=False, output_axis_rule=None):
"""
Convert the projection to a WKT string.

Expand All @@ -417,12 +425,17 @@ cdef class Base:
The version of the WKT output.
pretty: bool, default=False
If True, it will set the output to be a multiline string.
output_axis_rule: bool, optional, default=None
If True, it will set the axis rule on any case. If false, never.
None for AUTO, that depends on the CRS and version.
.. versionadded:: 3.5.1
snowman2 marked this conversation as resolved.
Show resolved Hide resolved


Returns
-------
str
"""
return _to_wkt(self.context, self.projobj, version, pretty=pretty)
return _to_wkt(self.context, self.projobj, version, pretty=pretty, output_axis_rule=output_axis_rule)

def to_json(self, bint pretty=False, int indentation=2):
"""
Expand Down
9 changes: 8 additions & 1 deletion pyproj/crs/crs.py
Original file line number Diff line number Diff line change
Expand Up @@ -1197,6 +1197,7 @@ def to_wkt(
self,
version: Union[WktVersion, str] = WktVersion.WKT2_2019,
pretty: bool = False,
output_axis_rule: Optional[bool] = None,
) -> str:
"""
Convert the projection to a WKT string.
Expand All @@ -1217,12 +1218,18 @@ def to_wkt(
Default is :attr:`pyproj.enums.WktVersion.WKT2_2019`.
pretty: bool, default=False
If True, it will set the output to be a multiline string.
output_axis_rule: bool, optional, default=None
If True, it will set the axis rule on any case. If false, never.
None for AUTO, that depends on the CRS and version.
.. versionadded:: 3.5.1

Returns
-------
str
"""
wkt = self._crs.to_wkt(version=version, pretty=pretty)
wkt = self._crs.to_wkt(
version=version, pretty=pretty, output_axis_rule=output_axis_rule
)
if wkt is None:
raise CRSError(
f"CRS cannot be converted to a WKT string of a '{version}' version. "
Expand Down
34 changes: 34 additions & 0 deletions test/crs/test_crs.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,40 @@ def test_to_wkt_pretty():
assert "\n" not in crs.to_wkt()


@pytest.mark.parametrize(
"version, expected",
[
("WKT1_GDAL", False),
("WKT1_ESRI", False),
("WKT2_2019", True),
],
)
def test_to_wkt_with_axis_rule_4326(version, expected):
crs = CRS.from_epsg(4326)
axis = "AXIS"
assert (axis in crs.to_wkt(version)) == expected
assert (axis in crs.to_wkt(version, output_axis_rule=None)) == expected
assert axis in crs.to_wkt(version, output_axis_rule=True)
assert axis not in crs.to_wkt(version, output_axis_rule=False)


@pytest.mark.parametrize(
"version, expected",
[
("WKT1_GDAL", True),
("WKT1_ESRI", False),
("WKT2_2019", True),
],
)
def test_to_wkt_with_axis_rule_32630(version, expected):
crs = CRS.from_epsg(32630)
axis = "AXIS"
assert (axis in crs.to_wkt(version)) == expected
assert (axis in crs.to_wkt(version, output_axis_rule=None)) == expected
assert axis in crs.to_wkt(version, output_axis_rule=True)
assert axis not in crs.to_wkt(version, output_axis_rule=False)


def test_repr():
with pytest.warns(FutureWarning):
assert repr(CRS({"init": "EPSG:4326"})) == (
Expand Down