Skip to content

Commit

Permalink
closetPoint(s): Add unit tests and static methods.
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 663762804
  • Loading branch information
schwehr authored and Google Earth Engine Authors committed Oct 8, 2024
1 parent 63c5020 commit 74488a1
Show file tree
Hide file tree
Showing 4 changed files with 199 additions and 0 deletions.
58 changes: 58 additions & 0 deletions python/ee/feature.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,64 @@ def centroid(
self.name() + '.centroid', self, maxError, proj
)

def closestPoint(
self,
right: _arg_types.Element,
# pylint: disable-next=invalid-name
maxError: Optional[_arg_types.ErrorMargin] = None,
proj: Optional[_arg_types.Projection] = None,
) -> computedobject.ComputedObject:
"""Returns the point on the right input that is nearest to the left input.
If either input is empty, null is returned. If both inputs are unbounded, an
arbitrary point is returned. If one input is unbounded, an arbitrary point
in the bounded input is returned.
Args:
right: The feature containing the geometry used as the right operand of
the operation.
maxError: The maximum amount of error tolerated when performing any
necessary reprojection.
proj: The projection in which to perform the operation. If not specified,
the operation will be performed in a spherical coordinate system, and
linear distances will be in meters on the sphere.
"""

return apifunction.ApiFunction.call_(
self.name() + '.closestPoint', self, right, maxError, proj
)

def closestPoints(
self,
right: _arg_types.Element,
# pylint: disable-next=invalid-name
maxError: Optional[_arg_types.ErrorMargin] = None,
proj: Optional[_arg_types.Projection] = None,
) -> computedobject.ComputedObject:
"""Returns the points on the right input that are nearest to the left input.
Returns a dictionary containing up to two entries representing a point on
each input feature's geometry that is closest to the geometry of the other
input. If either geometry is empty, an empty dictionary is returned. If both
geometries are unbounded, the dictionary has an arbitrary point for both
'left' and 'right'. If one geometry is unbounded, the dictionary has an
arbitrary point contained in the bounded geometry for both 'left' and
'right'.
Args:
right: The feature containing the geometry used as the right operand of
the operation.
maxError: The maximum amount of error tolerated when performing any
necessary reprojection.
proj: The projection in which to perform the operation. If not specified,
the operation will be performed in a spherical coordinate system, and
linear distances will be in meters on the sphere.
"""

return apifunction.ApiFunction.call_(
self.name() + '.closestPoints', self, right, maxError, proj
)

def containedIn(
self,
right: _arg_types.Any,
Expand Down
61 changes: 61 additions & 0 deletions python/ee/geometry.py
Original file line number Diff line number Diff line change
Expand Up @@ -975,6 +975,67 @@ def centroid(
self.name() + '.centroid', self, maxError, proj
)

def closestPoint(
self,
right: _arg_types.Geometry,
# pylint: disable-next=invalid-name
maxError: Optional[_arg_types.ErrorMargin] = None,
proj: Optional[_arg_types.Projection] = None,
) -> computedobject.ComputedObject:
"""Returns the point on the right input that is nearest to the left input.
If either input is empty, null is returned. If both inputs are unbounded, an
arbitrary point is returned. If one input is unbounded, an arbitrary point
in the bounded input is returned.
Args:
right: The geometry used as the right operand of the operation.
maxError: The maximum amount of error tolerated when performing any
necessary reprojection.
proj: The projection in which to perform the operation. If not specified,
the operation will be performed in a spherical coordinate system, and
linear distances will be in meters on the sphere.
Returns:
An ee.Object.
"""

return apifunction.ApiFunction.call_(
self.name() + '.closestPoint', self, right, maxError, proj
)

def closestPoints(
self,
right: _arg_types.Geometry,
# pylint: disable-next=invalid-name
maxError: Optional[_arg_types.ErrorMargin] = None,
proj: Optional[_arg_types.Projection] = None,
) -> computedobject.ComputedObject:
"""Returns the points on the right input that are nearest to the left input.
Returns a dictionary containing up to two entries representing a point on
each input geometry that is closest to the other input geometry. If either
geometry is empty, an empty dictionary is returned. If both geometries are
unbounded, the dictionary has an arbitrary point for both 'left' and
'right'. If one geometry is unbounded, the dictionary has an arbitrary point
contained in the bounded geometry for both 'left' and 'right'.
Args:
right: The geometry used as the right operand of the operation.
maxError: The maximum amount of error tolerated when performing any
necessary reprojection.
proj: The projection in which to perform the operation. If not specified,
the operation will be performed in a spherical coordinate system, and
linear distances will be in meters on the sphere.
Returns:
An ee.Object.
"""

return apifunction.ApiFunction.call_(
self.name() + '.closestPoints', self, right, maxError, proj
)

def containedIn(
self,
right: _arg_types.Geometry,
Expand Down
46 changes: 46 additions & 0 deletions python/ee/tests/feature_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,52 @@ def test_centroid(self):
result = json.loads(expression.serialize())
self.assertEqual(expect, result)

def test_closest_point(self):
right = ee.Feature(None, {'a': 'b'})
max_error = 10
proj = EPSG_4326
expect = make_expression_graph({
'arguments': {
'left': FEATURE_NONE_GRAPH,
'right': FEATURE_A_GRAPH,
'maxError': MAX_ERROR_GRAPH,
'proj': PROJ_GRAPH,
},
'functionName': 'Feature.closestPoint',
})
expression = ee.Feature(None).closestPoint(right, max_error, proj)
result = json.loads(expression.serialize())
self.assertEqual(expect, result)

expression = ee.Feature(None).closestPoint(
right=right, maxError=max_error, proj=proj
)
result = json.loads(expression.serialize())
self.assertEqual(expect, result)

def test_closest_points(self):
right = ee.Feature(None, {'a': 'b'})
max_error = 10
proj = EPSG_4326
expect = make_expression_graph({
'arguments': {
'left': FEATURE_NONE_GRAPH,
'right': FEATURE_A_GRAPH,
'maxError': MAX_ERROR_GRAPH,
'proj': PROJ_GRAPH,
},
'functionName': 'Feature.closestPoints',
})
expression = ee.Feature(None).closestPoints(right, max_error, proj)
result = json.loads(expression.serialize())
self.assertEqual(expect, result)

expression = ee.Feature(None).closestPoints(
right=right, maxError=max_error, proj=proj
)
result = json.loads(expression.serialize())
self.assertEqual(expect, result)

def test_contained_in(self):
expect = right_maxerror_proj('containedIn')

Expand Down
34 changes: 34 additions & 0 deletions python/ee/tests/geometry_point_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,40 @@ def test_centroid(self):
)
self.assertEqual(actual, expect)

def test_closest_point(self):
expect = make_expression_graph_geom(
'closestPoint',
{'left': POINT, 'right': POINT2, 'maxError': MAX_ERROR, 'proj': PROJ},
)
actual = json.loads(
self.point.closestPoint(self.point2, MAX_ERROR_VAL, EPSG).serialize()
)
self.assertEqual(actual, expect)

actual = json.loads(
self.point.closestPoint(
right=self.point2, maxError=MAX_ERROR_VAL, proj=EPSG
).serialize()
)
self.assertEqual(actual, expect)

def test_closest_points(self):
expect = make_expression_graph_geom(
'closestPoints',
{'left': POINT, 'right': POINT2, 'maxError': MAX_ERROR, 'proj': PROJ},
)
actual = json.loads(
self.point.closestPoints(self.point2, MAX_ERROR_VAL, EPSG).serialize()
)
self.assertEqual(actual, expect)

actual = json.loads(
self.point.closestPoints(
right=self.point2, maxError=MAX_ERROR_VAL, proj=EPSG
).serialize()
)
self.assertEqual(actual, expect)

def test_contained_in(self):
expect = make_expression_graph_geom(
'containedIn',
Expand Down

0 comments on commit 74488a1

Please sign in to comment.