Skip to content

Commit

Permalink
REF: Use _transform_point inside of transform
Browse files Browse the repository at this point in the history
  • Loading branch information
snowman2 committed Dec 20, 2022
1 parent bf07808 commit 03ee8f5
Show file tree
Hide file tree
Showing 3 changed files with 190 additions and 166 deletions.
44 changes: 37 additions & 7 deletions pyproj/_transformer.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -716,20 +716,44 @@ cdef class _Transformer(Base):
@cython.wraparound(False)
def _transform_point(
self,
double inx,
double iny,
double inz,
double intime,
object inx,
object iny,
object inz,
object intime,
object direction,
bint radians,
bint errcheck,
):
cdef double coord_x = inx
cdef double coord_y = iny
cdef double coord_z = 0
cdef double coord_t = HUGE_VAL
cdef tuple expected_numeric_types = (int, float)
if not isinstance(inx, expected_numeric_types):
raise TypeError("Scalar input expected for x")
if not isinstance(iny, expected_numeric_types):
raise TypeError("Scalar input expected for y")
if inz is not None:
if not isinstance(inz, expected_numeric_types):
raise TypeError("Scalar input expected for z")
coord_z = inz
if intime is not None:
if not isinstance(intime, expected_numeric_types):
raise TypeError("Scalar input expected for t")
coord_t = intime

cdef tuple return_data
if self.id == "noop":
return inx, iny, inz, intime
return_data = (inx, iny)
if inz is not None:
return_data += (inz,)
if intime is not None:
return_data += (intime,)
return return_data

cdef PJ_DIRECTION pj_direction = get_pj_direction(direction)
cdef PJ_COORD projxyout
cdef PJ_COORD projxyin = proj_coord(inx, iny, inz, intime)
cdef PJ_COORD projxyin = proj_coord(coord_x, coord_y, coord_z, coord_t)
with nogil:
# degrees to radians
if not radians and proj_angular_input(self.projobj, pj_direction):
Expand Down Expand Up @@ -762,7 +786,13 @@ cdef class _Transformer(Base):
projxyout.xy.x *= _DG2RAD
projxyout.xy.y *= _DG2RAD
ProjError.clear()
return projxyout.xyzt.x, projxyout.xyzt.y, projxyout.xyzt.z, projxyout.xyzt.t

return_data = (projxyout.xyzt.x, projxyout.xyzt.y)
if inz is not None:
return_data += (projxyout.xyzt.z,)
if intime is not None:
return_data += (projxyout.xyzt.t,)
return return_data

@cython.boundscheck(False)
@cython.wraparound(False)
Expand Down
118 changes: 15 additions & 103 deletions pyproj/transformer.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
"TransformerGroup",
"AreaOfInterest",
]
import math
import numbers
import threading
import warnings
from abc import ABC, abstractmethod
Expand Down Expand Up @@ -791,6 +789,19 @@ def transform( # pylint: disable=invalid-name
'33 98'
"""
try:
# function optimized for point data
return self._transformer._transform_point(
inx=xx,
iny=yy,
inz=zz,
intime=tt,
direction=direction,
radians=radians,
errcheck=errcheck,
)
except TypeError:
pass
# process inputs, making copies that support buffer API.
inx, x_data_type = _copytobuffer(xx, inplace=inplace)
iny, y_data_type = _copytobuffer(yy, inplace=inplace)
Expand All @@ -804,8 +815,8 @@ def transform( # pylint: disable=invalid-name
intime = None
# call pj_transform. inx,iny,inz buffers modified in place.
self._transformer._transform(
inx,
iny,
inx=inx,
iny=iny,
inz=inz,
intime=intime,
direction=direction,
Expand All @@ -822,105 +833,6 @@ def transform( # pylint: disable=invalid-name
return_data += (_convertback(t_data_type, intime),)
return return_data

@overload
def transform_point( # pylint: disable=invalid-name
self,
xx: numbers.Real,
yy: numbers.Real,
radians: bool = False,
errcheck: bool = False,
direction: Union[TransformDirection, str] = TransformDirection.FORWARD,
) -> Tuple[float, float]:
...

@overload
def transform_point( # pylint: disable=invalid-name
self,
xx: numbers.Real,
yy: numbers.Real,
zz: numbers.Real,
radians: bool = False,
errcheck: bool = False,
direction: Union[TransformDirection, str] = TransformDirection.FORWARD,
) -> Tuple[float, float, float]:
...

@overload
def transform_point( # pylint: disable=invalid-name
self,
xx: numbers.Real,
yy: numbers.Real,
zz: numbers.Real,
tt: numbers.Real,
radians: bool = False,
errcheck: bool = False,
direction: Union[TransformDirection, str] = TransformDirection.FORWARD,
) -> Tuple[float, float, float, float]:
...

def transform_point( # pylint: disable=invalid-name
self,
xx,
yy,
zz=None,
tt=None,
radians=False,
errcheck=False,
direction=TransformDirection.FORWARD,
):
"""
Optimized to transform a single point between two coordinate systems.
See: :c:func:`proj_trans`
.. versionadded:: 3.5.0
Examples of accepted numeric scalar:
- :class:`int`
- :class:`float`
- :class:`numpy.floating`
- :class:`numpy.integer`
Parameters
----------
xx: numbers.Real
Input x coordinate.
yy: numbers.Real
Input y coordinate.
zz: numbers.Real, optional
Input z coordinate.
tt: numbers.Real, optional
Input time coordinate.
radians: bool, default=False
If True, will expect input data to be in radians and will return radians
if the projection is geographic. Otherwise, it uses degrees.
Ignored for pipeline transformations with pyproj 2,
but will work in pyproj 3.
errcheck: bool, default=False
If True, an exception is raised if the errors are found in the process.
If False, ``inf`` is returned for errors.
direction: pyproj.enums.TransformDirection, optional
The direction of the transform.
Default is :attr:`pyproj.enums.TransformDirection.FORWARD`.
"""
outx, outy, outz, outt = self._transformer._transform_point(
xx,
yy,
inz=0 if zz is None else zz,
intime=math.inf if tt is None else tt,
direction=direction,
radians=radians,
errcheck=errcheck,
)
return_data: Tuple[float, ...] = (outx, outy)
if zz is not None:
return_data += (outz,)
if tt is not None:
return_data += (outt,)
return return_data

def itransform(
self,
points: Any,
Expand Down

0 comments on commit 03ee8f5

Please sign in to comment.