Skip to content

Commit d771128

Browse files
Add support for bulk-query APIs.
1 parent fe7db71 commit d771128

File tree

2 files changed

+139
-0
lines changed

2 files changed

+139
-0
lines changed

Diff for: rtree/core.py

+38
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,44 @@ def free_error_msg_ptr(result, func, cargs):
238238
rt.Index_NearestNeighbors_id.restype = ctypes.c_int
239239
rt.Index_NearestNeighbors_id.errcheck = check_return # type: ignore
240240

241+
try:
242+
rt.Index_NearestNeighbors_id_v.argtypes = [
243+
ctypes.c_void_p,
244+
ctypes.c_int64,
245+
ctypes.c_int64,
246+
ctypes.c_uint32,
247+
ctypes.c_uint64,
248+
ctypes.c_uint64,
249+
ctypes.c_uint64,
250+
ctypes.c_void_p,
251+
ctypes.c_void_p,
252+
ctypes.c_void_p,
253+
ctypes.c_void_p,
254+
ctypes.c_void_p,
255+
ctypes.POINTER(ctypes.c_int64),
256+
]
257+
rt.Index_NearestNeighbors_id_v.restype = ctypes.c_int
258+
rt.Index_NearestNeighbors_id_v.errcheck = check_return # type: ignore
259+
260+
rt.Index_Intersects_id_v.argtypes = [
261+
ctypes.c_void_p,
262+
ctypes.c_int64,
263+
ctypes.c_uint32,
264+
ctypes.c_uint64,
265+
ctypes.c_uint64,
266+
ctypes.c_uint64,
267+
ctypes.c_void_p,
268+
ctypes.c_void_p,
269+
ctypes.c_void_p,
270+
ctypes.c_void_p,
271+
ctypes.POINTER(ctypes.c_int64),
272+
]
273+
rt.Index_Intersects_id_v.restype = ctypes.c_int
274+
rt.Index_Intersects_id_v.errcheck = check_return # type: ignore
275+
except AttributeError:
276+
pass
277+
278+
241279
rt.Index_GetLeaves.argtypes = [
242280
ctypes.c_void_p,
243281
ctypes.POINTER(ctypes.c_uint32),

Diff for: rtree/index.py

+101
Original file line numberDiff line numberDiff line change
@@ -1046,6 +1046,107 @@ def nearest(
10461046

10471047
return self._get_ids(it, p_num_results.contents.value)
10481048

1049+
def intersection_v(self, mins, maxs):
1050+
import numpy as np
1051+
1052+
assert mins.shape == maxs.shape
1053+
assert mins.strides == maxs.strides
1054+
1055+
# Cast
1056+
mins = mins.astype(np.float64)
1057+
maxs = maxs.astype(np.float64)
1058+
1059+
# Extract counts
1060+
n, d = mins.shape
1061+
1062+
# Compute strides
1063+
d_i_stri = mins.strides[0] // mins.itemsize
1064+
d_j_stri = mins.strides[1] // mins.itemsize
1065+
1066+
ids = np.empty(2*n, dtype=np.int64)
1067+
counts = np.empty(n, dtype=np.uint64)
1068+
nr = ctypes.c_int64(0)
1069+
offn, offi = 0, 0
1070+
1071+
while True:
1072+
core.rt.Index_Intersects_id_v(
1073+
self.handle,
1074+
n - offn,
1075+
d,
1076+
len(ids),
1077+
d_i_stri,
1078+
d_j_stri,
1079+
mins[offn:].ctypes.data,
1080+
maxs[offn:].ctypes.data,
1081+
ids[offi:].ctypes.data,
1082+
counts[offn:].ctypes.data,
1083+
ctypes.byref(nr)
1084+
)
1085+
1086+
# If we got the expected nuber of results then return
1087+
if nr.value == n - offn:
1088+
return ids[:counts.sum()], counts
1089+
# Otherwise, if our array is too small then resize
1090+
else:
1091+
offi += counts[offn:offn + nr.value].sum()
1092+
offn += nr.value
1093+
1094+
ids = ids.resize(2*len(ids), refcheck=False)
1095+
1096+
def nearest_v(self, mins, maxs, num_results=1, strict=False,
1097+
return_max_dists=False):
1098+
import numpy as np
1099+
1100+
assert mins.shape == maxs.shape
1101+
assert mins.strides == maxs.strides
1102+
1103+
# Cast
1104+
mins = mins.astype(np.float64)
1105+
maxs = maxs.astype(np.float64)
1106+
1107+
# Extract counts
1108+
n, d = mins.shape
1109+
1110+
# Compute strides
1111+
d_i_stri = mins.strides[0] // mins.itemsize
1112+
d_j_stri = mins.strides[1] // mins.itemsize
1113+
1114+
ids = np.empty(n*num_results, dtype=np.int64)
1115+
counts = np.empty(n, dtype=np.uint64)
1116+
dists = np.empty(n) if return_max_dists else None
1117+
nr = ctypes.c_int64(0)
1118+
offn, offi = 0, 0
1119+
1120+
while True:
1121+
core.rt.Index_NearestNeighbors_id_v(
1122+
self.handle,
1123+
num_results if not strict else -num_results,
1124+
n - offn,
1125+
d,
1126+
len(ids),
1127+
d_i_stri,
1128+
d_j_stri,
1129+
mins[offn:].ctypes.data,
1130+
maxs[offn:].ctypes.data,
1131+
ids[offi:].ctypes.data,
1132+
counts[offn:].ctypes.data,
1133+
dists[offn:].ctypes.data if return_max_dists else None,
1134+
ctypes.byref(nr)
1135+
)
1136+
1137+
# If we got the expected nuber of results then return
1138+
if nr.value == n - offn:
1139+
if return_max_dists:
1140+
return ids[:counts.sum()], counts, dists
1141+
else:
1142+
return ids[:counts.sum()], counts
1143+
# Otherwise, if our array is too small then resize
1144+
else:
1145+
offi += counts[offn:offn + nr.value].sum()
1146+
offn += nr.value
1147+
1148+
ids = ids.resize(2*len(ids), refcheck=False)
1149+
10491150
def _nearestTP(self, coordinates, velocities, times, num_results=1, objects=False):
10501151
p_mins, p_maxs = self.get_coordinate_pointers(coordinates)
10511152
pv_mins, pv_maxs = self.get_coordinate_pointers(velocities)

0 commit comments

Comments
 (0)