2121import ctypes
2222import logging
2323from typing import Any , ItemsView , Iterable , Iterator , Sequence , Tuple , Union
24+ import sys
2425from warnings import warn
2526
2627from shapely .errors import ShapelyDeprecationWarning
@@ -249,7 +250,9 @@ def query(self, geom: BaseGeometry) -> Sequence[BaseGeometry]:
249250 """
250251 return self .query_geoms (geom )
251252
252- def nearest_item (self , geom : BaseGeometry ) -> Union [Any , None ]:
253+ def nearest_item (
254+ self , geom : BaseGeometry , exclusive : bool = False
255+ ) -> Union [Any , None ]:
253256 """Query the tree for the node nearest to geom and get the item
254257 stored in the node.
255258
@@ -259,6 +262,9 @@ def nearest_item(self, geom: BaseGeometry) -> Union[Any, None]:
259262 ----------
260263 geom : geometry object
261264 The query geometry.
265+ exclusive : bool, optional
266+ Whether to exclude the item corresponding to the given geom
267+ from results or not. Default: False.
262268
263269 Returns
264270 -------
@@ -289,10 +295,14 @@ def nearest_item(self, geom: BaseGeometry) -> Union[Any, None]:
289295
290296 def callback (item1 , item2 , distance , userdata ):
291297 try :
298+ callback_userdata = ctypes .cast (userdata , ctypes .py_object ).value
292299 idx = ctypes .cast (item1 , ctypes .py_object ).value
293300 geom2 = ctypes .cast (item2 , ctypes .py_object ).value
294301 dist = ctypes .cast (distance , ctypes .POINTER (ctypes .c_double ))
295- lgeos .GEOSDistance (self ._rev [idx ]._geom , geom2 ._geom , dist )
302+ if callback_userdata ["exclusive" ] and self ._rev [idx ].equals (geom2 ):
303+ dist [0 ] = sys .float_info .max
304+ else :
305+ lgeos .GEOSDistance (self ._rev [idx ]._geom , geom2 ._geom , dist )
296306 return 1
297307 except Exception :
298308 log .exception ("Caught exception" )
@@ -303,19 +313,24 @@ def callback(item1, item2, distance, userdata):
303313 ctypes .py_object (geom ),
304314 envelope ._geom ,
305315 lgeos .GEOSDistanceCallback (callback ),
306- None ,
316+ ctypes . py_object ({ "exclusive" : exclusive }) ,
307317 )
308318 result = ctypes .cast (item , ctypes .py_object ).value
309319 return result
310320
311- def nearest_geom (self , geom : BaseGeometry ) -> Union [BaseGeometry , None ]:
321+ def nearest_geom (
322+ self , geom : BaseGeometry , exclusive : bool = False
323+ ) -> Union [BaseGeometry , None ]:
312324 """Query the tree for the node nearest to geom and get the
313325 geometry corresponding to the item stored in the node.
314326
315327 Parameters
316328 ----------
317329 geom : geometry object
318330 The query geometry.
331+ exclusive : bool, optional
332+ Whether to exclude the given geom from results or not.
333+ Default: False.
319334
320335 Returns
321336 -------
@@ -325,13 +340,15 @@ def nearest_geom(self, geom: BaseGeometry) -> Union[BaseGeometry, None]:
325340 version 2.0.
326341
327342 """
328- item = self .nearest_item (geom )
343+ item = self .nearest_item (geom , exclusive = exclusive )
329344 if item is None :
330345 return None
331346 else :
332347 return self ._rev [item ]
333348
334- def nearest (self , geom : BaseGeometry ) -> Union [BaseGeometry , None ]:
349+ def nearest (
350+ self , geom : BaseGeometry , exclusive : bool = False
351+ ) -> Union [BaseGeometry , None ]:
335352 """Query the tree for the node nearest to geom and get the
336353 geometry corresponding to the item stored in the node.
337354
@@ -342,6 +359,9 @@ def nearest(self, geom: BaseGeometry) -> Union[BaseGeometry, None]:
342359 ----------
343360 geom : geometry object
344361 The query geometry.
362+ exclusive : bool, optional
363+ Whether to exclude the given geom from results or not.
364+ Default: False.
345365
346366 Returns
347367 -------
@@ -351,4 +371,4 @@ def nearest(self, geom: BaseGeometry) -> Union[BaseGeometry, None]:
351371 version 2.0.
352372
353373 """
354- return self .nearest_geom (geom )
374+ return self .nearest_geom (geom , exclusive = exclusive )
0 commit comments