Skip to content

Commit

Permalink
ENH: Add inplace kwarg to Geod.fwd and Geod.inv (#1201)
Browse files Browse the repository at this point in the history
  • Loading branch information
greglucas authored Dec 16, 2022
1 parent c560046 commit 67558d9
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 9 deletions.
37 changes: 28 additions & 9 deletions pyproj/geod.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,13 @@ def __init__(self, initstring: Optional[str] = None, **kwargs) -> None:
)

def fwd( # pylint: disable=invalid-name
self, lons: Any, lats: Any, az: Any, dist: Any, radians: bool = False
self,
lons: Any,
lats: Any,
az: Any,
dist: Any,
radians: bool = False,
inplace: bool = False,
) -> Tuple[Any, Any, Any]:
"""
Forward transformation
Expand All @@ -249,6 +255,8 @@ def fwd( # pylint: disable=invalid-name
points given longitudes and latitudes of initial points,
plus forward azimuths and distances.
.. versionadded:: 3.5.0 inplace
Accepted numeric scalar or array:
- :class:`int`
Expand Down Expand Up @@ -276,6 +284,10 @@ def fwd( # pylint: disable=invalid-name
radians: bool, default=False
If True, the input data is assumed to be in radians.
Otherwise, the data is assumed to be in degrees.
inplace: bool, default=False
If True, will attempt to write the results to the input array
instead of returning a new array. This will fail if the input
is not an array in C order with the double data type.
Returns
-------
Expand All @@ -287,10 +299,10 @@ def fwd( # pylint: disable=invalid-name
Back azimuth(s)
"""
# process inputs, making copies that support buffer API.
inx, x_data_type = _copytobuffer(lons)
iny, y_data_type = _copytobuffer(lats)
inz, z_data_type = _copytobuffer(az)
ind = _copytobuffer(dist)[0]
inx, x_data_type = _copytobuffer(lons, inplace=inplace)
iny, y_data_type = _copytobuffer(lats, inplace=inplace)
inz, z_data_type = _copytobuffer(az, inplace=inplace)
ind = _copytobuffer(dist, inplace=inplace)[0]
self._fwd(inx, iny, inz, ind, radians=radians)
# if inputs were lists, tuples or floats, convert back.
outx = _convertback(x_data_type, inx)
Expand All @@ -305,13 +317,16 @@ def inv(
lons2: Any,
lats2: Any,
radians: bool = False,
inplace: bool = False,
) -> Tuple[Any, Any, Any]:
"""
Inverse transformation
Determine forward and back azimuths, plus distances
between initial points and terminus points.
.. versionadded:: 3.5.0 inplace
Accepted numeric scalar or array:
- :class:`int`
Expand All @@ -338,6 +353,10 @@ def inv(
radians: bool, default=False
If True, the input data is assumed to be in radians.
Otherwise, the data is assumed to be in degrees.
inplace: bool, default=False
If True, will attempt to write the results to the input array
instead of returning a new array. This will fail if the input
is not an array in C order with the double data type.
Returns
-------
Expand All @@ -350,10 +369,10 @@ def inv(
in meters
"""
# process inputs, making copies that support buffer API.
inx, x_data_type = _copytobuffer(lons1)
iny, y_data_type = _copytobuffer(lats1)
inz, z_data_type = _copytobuffer(lons2)
ind = _copytobuffer(lats2)[0]
inx, x_data_type = _copytobuffer(lons1, inplace=inplace)
iny, y_data_type = _copytobuffer(lats1, inplace=inplace)
inz, z_data_type = _copytobuffer(lons2, inplace=inplace)
ind = _copytobuffer(lats2, inplace=inplace)[0]
self._inv(inx, iny, inz, ind, radians=radians)
# if inputs were lists, tuples or floats, convert back.
outx = _convertback(x_data_type, inx)
Expand Down
18 changes: 18 additions & 0 deletions test/test_geod.py
Original file line number Diff line number Diff line change
Expand Up @@ -658,6 +658,24 @@ def test_geod_inv_honours_input_types(lons1, lats1, lons2):
assert isinstance(outz, type(lons2))


def test_geod_fwd_inv_inplace():
gg = Geod(ellps="clrk66")
lon1pt = np.array([0], dtype=np.float64)
lat1pt = np.array([0], dtype=np.float64)
lon2pt = np.array([1], dtype=np.float64)
lat2pt = np.array([1], dtype=np.float64)

az12, az21, dist = gg.inv(lon1pt, lat1pt, lon2pt, lat2pt, inplace=True)
assert az12 is lon1pt
assert az21 is lat1pt
assert dist is lon2pt

endlon, endlat, backaz = gg.fwd(lon1pt, lat1pt, az12, dist, inplace=True)
assert endlon is lon1pt
assert endlat is lat1pt
assert backaz is az12


@pytest.mark.parametrize("kwarg", ["b", "f", "es", "rf", "e"])
def test_geod__build_kwargs(kwarg):
gg = Geod(ellps="clrk66")
Expand Down

0 comments on commit 67558d9

Please sign in to comment.