Skip to content

Commit

Permalink
ENH: Added parameter output_axis_rule to CRS.to_wkt (#1287)
Browse files Browse the repository at this point in the history
  • Loading branch information
jjimenezshaw committed May 19, 2023
1 parent 3d0fb75 commit 4348437
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 5 deletions.
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
20 changes: 16 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 @@ -410,19 +418,23 @@ cdef class Base:
- WKT1_GDAL
- WKT1_ESRI
.. versionadded:: 3.6.0 output_axis_rule
Parameters
----------
version: pyproj.enums.WktVersion, default=pyproj.enums.WktVersion.WKT2_2019
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.
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 @@ -1209,6 +1210,7 @@ def to_wkt(
- WKT1_GDAL
- WKT1_ESRI
.. versionadded:: 3.6.0 output_axis_rule
Parameters
----------
Expand All @@ -1217,12 +1219,17 @@ 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.
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

0 comments on commit 4348437

Please sign in to comment.