| 1 | Testing Rtree |
|---|
| 2 | ================ |
|---|
| 3 | |
|---|
| 4 | >>> from rtree import index |
|---|
| 5 | >>> from rtree.index import Rtree |
|---|
| 6 | |
|---|
| 7 | Ensure libspatialindex version is >= 1.4.0 |
|---|
| 8 | >>> index.__version__.split('.')[1] >= 4 |
|---|
| 9 | True |
|---|
| 10 | |
|---|
| 11 | Make an instance, index stored in memory |
|---|
| 12 | |
|---|
| 13 | >>> p = index.Property() |
|---|
| 14 | |
|---|
| 15 | >>> idx = index.Index(properties=p) |
|---|
| 16 | >>> idx |
|---|
| 17 | <rtree.index.Index object at 0x...> |
|---|
| 18 | |
|---|
| 19 | Add 100 largish boxes randomly distributed over the domain |
|---|
| 20 | |
|---|
| 21 | >>> for i, coords in enumerate(boxes15): |
|---|
| 22 | ... idx.add(i, coords) |
|---|
| 23 | |
|---|
| 24 | >>> hits = idx.intersection((0, 0, 60, 60)) |
|---|
| 25 | >>> len(hits) |
|---|
| 26 | 10 |
|---|
| 27 | |
|---|
| 28 | >>> hits |
|---|
| 29 | [0L, 4L, 16L, 27L, 35L, 40L, 47L, 50L, 76L, 80L] |
|---|
| 30 | |
|---|
| 31 | Insert an object into the index that can be pickled |
|---|
| 32 | |
|---|
| 33 | >>> idx.insert(4321, (34.3776829412, 26.7375853734, 49.3776829412, 41.7375853734), obj=42) |
|---|
| 34 | |
|---|
| 35 | Fetch our straggler that contains a pickled object |
|---|
| 36 | >>> hits = idx.intersection((0, 0, 60, 60), objects=True) |
|---|
| 37 | >>> for i in hits: |
|---|
| 38 | ... if i.id == 4321: |
|---|
| 39 | ... i.object |
|---|
| 40 | ... i.bbox |
|---|
| 41 | 42 |
|---|
| 42 | [34.3776829412, 26.737585373400002, 49.3776829412, 41.737585373400002] |
|---|
| 43 | |
|---|
| 44 | |
|---|
| 45 | Can also get the results back as an iterator by requesting as_list=False |
|---|
| 46 | >>> iterator = idx.intersection((0, 0, 60, 60), objects=True, as_list=False) |
|---|
| 47 | >>> iterator |
|---|
| 48 | <generator object ...> |
|---|
| 49 | |
|---|
| 50 | >>> len(list(iterator)) == len(hits) |
|---|
| 51 | True |
|---|
| 52 | |
|---|
| 53 | >>> itlist = sorted(list(idx.intersection((0, 0, 60, 60), objects=False, as_list=False))) |
|---|
| 54 | >>> aslist = sorted(idx.intersection((0, 0, 60, 60), objects=False)) |
|---|
| 55 | >>> itlist == aslist |
|---|
| 56 | True |
|---|
| 57 | |
|---|
| 58 | |
|---|
| 59 | Find the three items nearest to this one |
|---|
| 60 | >>> hits = idx.nearest((0,0,10,10), 3) |
|---|
| 61 | >>> hits |
|---|
| 62 | [76L, 48L, 19L] |
|---|
| 63 | >>> len(hits) |
|---|
| 64 | 3 |
|---|
| 65 | |
|---|
| 66 | |
|---|
| 67 | Default order is [xmin, ymin, xmax, ymax] |
|---|
| 68 | >>> idx.bounds |
|---|
| 69 | [-186.673789279, -96.717721818399994, 184.76138755599999, 96.604369977800005] |
|---|
| 70 | |
|---|
| 71 | To get in order [xmin, xmax, ymin, ymax (... for n-d indexes)] use the kwarg: |
|---|
| 72 | >>> idx.get_bounds(coordinate_interleaved=False) |
|---|
| 73 | [-186.673789279, 184.76138755599999, -96.717721818399994, 96.604369977800005] |
|---|
| 74 | |
|---|
| 75 | Delete index members |
|---|
| 76 | |
|---|
| 77 | >>> for i, coords in enumerate(boxes15): |
|---|
| 78 | ... idx.delete(i, coords) |
|---|
| 79 | |
|---|
| 80 | Delete our straggler too |
|---|
| 81 | >>> idx.delete(4321, (34.3776829412, 26.7375853734, 49.3776829412, 41.7375853734) ) |
|---|
| 82 | |
|---|
| 83 | Check that we have deleted stuff |
|---|
| 84 | |
|---|
| 85 | >>> hits = 0 |
|---|
| 86 | >>> hits = idx.intersection((0, 0, 60, 60)) |
|---|
| 87 | >>> len(hits) |
|---|
| 88 | 0 |
|---|
| 89 | |
|---|
| 90 | # >>> assert(idx.valid()) |
|---|
| 91 | |
|---|
| 92 | Check that nearest returns *all* of the items that are nearby |
|---|
| 93 | >>> idx2 = Rtree() |
|---|
| 94 | >>> idx2 |
|---|
| 95 | <rtree.index.Index object at 0x...> |
|---|
| 96 | |
|---|
| 97 | >>> locs = [(14, 10, 14, 10), |
|---|
| 98 | ... (16, 10, 16, 10)] |
|---|
| 99 | |
|---|
| 100 | >>> for i, (minx, miny, maxx, maxy) in enumerate(locs): |
|---|
| 101 | ... idx2.add(i, (minx, miny, maxx, maxy)) |
|---|
| 102 | |
|---|
| 103 | >>> sorted(idx2.nearest((15, 10, 15, 10), 1)) |
|---|
| 104 | [0L, 1L] |
|---|
| 105 | |
|---|
| 106 | |
|---|
| 107 | Check that nearest returns *all* of the items that are nearby (with objects) |
|---|
| 108 | >>> idx2 = Rtree() |
|---|
| 109 | >>> idx2 |
|---|
| 110 | <rtree.index.Index object at 0x...> |
|---|
| 111 | |
|---|
| 112 | >>> locs = [(14, 10, 14, 10), |
|---|
| 113 | ... (16, 10, 16, 10)] |
|---|
| 114 | |
|---|
| 115 | >>> for i, (minx, miny, maxx, maxy) in enumerate(locs): |
|---|
| 116 | ... idx2.add(i, (minx, miny, maxx, maxy), obj={'a': 42}) |
|---|
| 117 | |
|---|
| 118 | >>> sorted([(i.id, i.object) for i in idx2.nearest((15, 10, 15, 10), 1, objects=True)]) |
|---|
| 119 | [(0L, {'a': 42}), (1L, {'a': 42})] |
|---|
| 120 | |
|---|
| 121 | |
|---|
| 122 | >>> idx2 = Rtree() |
|---|
| 123 | >>> idx2 |
|---|
| 124 | <rtree.index.Index object at 0x...> |
|---|
| 125 | |
|---|
| 126 | >>> locs = [(2, 4), (6, 8), (10, 12), (11, 13), (15, 17), (13, 20)] |
|---|
| 127 | |
|---|
| 128 | >>> for i, (start, stop) in enumerate(locs): |
|---|
| 129 | ... idx2.add(i, (start, 1, stop, 1)) |
|---|
| 130 | |
|---|
| 131 | >>> sorted(idx2.nearest((13, 0, 20, 2), 1)) |
|---|
| 132 | [3L, 4L, 5L] |
|---|
| 133 | |
|---|
| 134 | Default page size 4096 |
|---|
| 135 | |
|---|
| 136 | >>> idx3 = Rtree(u"defaultidx") |
|---|
| 137 | >>> for i, coords in enumerate(boxes15): |
|---|
| 138 | ... idx3.add(i, coords) |
|---|
| 139 | >>> hits = idx3.intersection((0, 0, 60, 60)) |
|---|
| 140 | >>> len(hits) |
|---|
| 141 | 10 |
|---|
| 142 | |
|---|
| 143 | Make sure to delete the index or the file is not flushed and it |
|---|
| 144 | will be invalid |
|---|
| 145 | |
|---|
| 146 | >>> del idx3 |
|---|
| 147 | |
|---|
| 148 | Page size 3 |
|---|
| 149 | |
|---|
| 150 | >>> idx4 = Rtree("pagesize3", pagesize=3) |
|---|
| 151 | >>> for i, coords in enumerate(boxes15): |
|---|
| 152 | ... idx4.add(i, coords) |
|---|
| 153 | >>> hits = idx4.intersection((0, 0, 60, 60)) |
|---|
| 154 | >>> len(hits) |
|---|
| 155 | 10 |
|---|
| 156 | |
|---|
| 157 | >>> idx4.close() |
|---|
| 158 | >>> del idx4 |
|---|
| 159 | |
|---|
| 160 | Test invalid name |
|---|
| 161 | |
|---|
| 162 | >>> inv = Rtree("bogus/foo") |
|---|
| 163 | Traceback (most recent call last): |
|---|
| 164 | ... |
|---|
| 165 | IOError: Unable to open file 'bogus/foo.idx' for index storage |
|---|
| 166 | |
|---|
| 167 | Load a persisted index |
|---|
| 168 | |
|---|
| 169 | >>> import shutil |
|---|
| 170 | >>> _ = shutil.copy("defaultidx.dat", "testing.dat") |
|---|
| 171 | >>> _ = shutil.copy("defaultidx.idx", "testing.idx") |
|---|
| 172 | |
|---|
| 173 | # >>> import pdb;pdb.set_trace() |
|---|
| 174 | |
|---|
| 175 | >>> idx = Rtree("testing") |
|---|
| 176 | >>> hits = idx.intersection((0, 0, 60, 60)) |
|---|
| 177 | >>> len(hits) |
|---|
| 178 | 10 |
|---|
| 179 | |
|---|
| 180 | Make a 3D index |
|---|
| 181 | >>> p = index.Property() |
|---|
| 182 | >>> p.dimension = 3 |
|---|
| 183 | |
|---|
| 184 | |
|---|
| 185 | with interleaved=False, the order of input and output is: |
|---|
| 186 | (xmin, xmax, ymin, ymax, zmin, zmax) |
|---|
| 187 | |
|---|
| 188 | >>> idx3d = index.Index(properties=p, interleaved=False) |
|---|
| 189 | >>> idx3d |
|---|
| 190 | <rtree.index.Index object at 0x...> |
|---|
| 191 | |
|---|
| 192 | >>> idx3d.insert(1, (0, 0, 60, 60, 22, 22.0)) |
|---|
| 193 | |
|---|
| 194 | >>> idx3d.intersection((-1, 1, 58, 62, 22, 24)) |
|---|
| 195 | [1L] |
|---|
| 196 | |
|---|
| 197 | |
|---|
| 198 | Make a 4D index |
|---|
| 199 | >>> p = index.Property() |
|---|
| 200 | >>> p.dimension = 4 |
|---|
| 201 | |
|---|
| 202 | |
|---|
| 203 | with interleaved=False, the order of input and output is: (xmin, xmax, ymin, ymax, zmin, zmax, kmin, kmax) |
|---|
| 204 | |
|---|
| 205 | >>> idx4d = index.Index(properties=p, interleaved=False) |
|---|
| 206 | >>> idx4d |
|---|
| 207 | <rtree.index.Index object at 0x...> |
|---|
| 208 | |
|---|
| 209 | >>> idx4d.insert(1, (0, 0, 60, 60, 22, 22.0, 128, 142)) |
|---|
| 210 | |
|---|
| 211 | >>> idx4d.intersection((-1, 1, 58, 62, 22, 24, 120, 150)) |
|---|
| 212 | [1L] |
|---|
| 213 | |
|---|
| 214 | Check that we can make an index with custom filename extensions |
|---|
| 215 | |
|---|
| 216 | >>> p = index.Property() |
|---|
| 217 | >>> p.dat_extension = 'data' |
|---|
| 218 | >>> p.idx_extension = 'index' |
|---|
| 219 | |
|---|
| 220 | >>> idx_cust = Rtree('custom', properties=p) |
|---|
| 221 | >>> for i, coords in enumerate(boxes15): |
|---|
| 222 | ... idx_cust.add(i, coords) |
|---|
| 223 | >>> hits = idx_cust.intersection((0, 0, 60, 60)) |
|---|
| 224 | >>> len(hits) |
|---|
| 225 | 10 |
|---|
| 226 | |
|---|
| 227 | >>> del idx_cust |
|---|
| 228 | |
|---|
| 229 | Reopen the index |
|---|
| 230 | >>> p2 = index.Property() |
|---|
| 231 | >>> p2.dat_extension = 'data' |
|---|
| 232 | >>> p2.idx_extension = 'index' |
|---|
| 233 | |
|---|
| 234 | >>> idx_cust2 = Rtree('custom', properties=p2) |
|---|
| 235 | >>> hits = idx_cust2.intersection((0, 0, 60, 60)) |
|---|
| 236 | >>> len(hits) |
|---|
| 237 | 10 |
|---|
| 238 | |
|---|
| 239 | >>> del idx_cust2 |
|---|
| 240 | |
|---|
| 241 | Adding the same id twice does not overwrite existing data |
|---|
| 242 | |
|---|
| 243 | >>> r = Rtree() |
|---|
| 244 | >>> r.add(1, (2, 2)) |
|---|
| 245 | >>> r.add(1, (3, 3)) |
|---|
| 246 | >>> r.intersection((0, 0, 5, 5)) |
|---|
| 247 | [1L, 1L] |
|---|
| 248 | |
|---|
| 249 | A stream of data need that needs to be an iterator that will raise a |
|---|
| 250 | StopIteration. The order depends on the interleaved kwarg sent to the |
|---|
| 251 | constructor. |
|---|
| 252 | |
|---|
| 253 | The object can be None, but you must put a place holder of 'None' there. |
|---|
| 254 | |
|---|
| 255 | >>> p = index.Property() |
|---|
| 256 | >>> def data_gen(interleaved=True): |
|---|
| 257 | ... for i, (minx, miny, maxx, maxy) in enumerate(boxes15): |
|---|
| 258 | ... if interleaved: |
|---|
| 259 | ... yield (i, (minx, miny, maxx, maxy), 42) |
|---|
| 260 | ... else: |
|---|
| 261 | ... yield (i, (minx, maxx, miny, maxy), 42) |
|---|
| 262 | |
|---|
| 263 | >>> strm_idx = index.Rtree(data_gen(), properties = p) |
|---|
| 264 | |
|---|
| 265 | >>> hits = strm_idx.intersection((0, 0, 60, 60)) |
|---|
| 266 | |
|---|
| 267 | >>> len(hits) |
|---|
| 268 | 10 |
|---|
| 269 | |
|---|
| 270 | |
|---|
| 271 | >>> sorted(hits) |
|---|
| 272 | [0L, 4L, 16L, 27L, 35L, 40L, 47L, 50L, 76L, 80L] |
|---|
| 273 | |
|---|
| 274 | >>> hits = strm_idx.intersection((0, 0, 60, 60), objects=True) |
|---|
| 275 | >>> len(hits) |
|---|
| 276 | 10 |
|---|
| 277 | |
|---|
| 278 | >>> hits[0].object |
|---|
| 279 | 42 |
|---|
| 280 | |
|---|
| 281 | Try streaming against a persisted index without interleaving. |
|---|
| 282 | >>> strm_idx = index.Rtree('streamed', data_gen(interleaved=False), properties = p, interleaved=False) |
|---|
| 283 | |
|---|
| 284 | Note the arguments to intersection must be xmin, xmax, ymin, ymax for interleaved=False |
|---|
| 285 | >>> hits = strm_idx.intersection((0, 60, 0, 60)) |
|---|
| 286 | >>> len(hits) |
|---|
| 287 | 10 |
|---|
| 288 | |
|---|
| 289 | >>> sorted(hits) |
|---|
| 290 | [0L, 4L, 16L, 27L, 35L, 40L, 47L, 50L, 76L, 80L] |
|---|
| 291 | |
|---|
| 292 | >>> hits = strm_idx.intersection((0, 60, 0, 60), objects=True) |
|---|
| 293 | >>> len(hits) |
|---|
| 294 | 10 |
|---|
| 295 | |
|---|
| 296 | >>> hits[0].object |
|---|
| 297 | 42 |
|---|
| 298 | |
|---|
| 299 | >>> hits = strm_idx.intersection((0, 60, 0, 60), objects='raw') |
|---|
| 300 | >>> hits[0] |
|---|
| 301 | 42 |
|---|
| 302 | |
|---|
| 303 | >>> del strm_idx |
|---|
| 304 | |
|---|
| 305 | >>> p = index.Property() |
|---|
| 306 | >>> p.leaf_capacity = 100 |
|---|
| 307 | >>> p.fill_factor = 0.5 |
|---|
| 308 | >>> p.index_capacity = 10 |
|---|
| 309 | >>> p.near_minimum_overlap_factor = 7 |
|---|
| 310 | >>> idx = index.Index(data_gen(interleaved=False), properties = p, interleaved=False) |
|---|
| 311 | |
|---|
| 312 | >>> leaves = idx.leaves() |
|---|
| 313 | >>> leaves[0] == (0L, [2L, 92L, 51L, 55L, 26L], [-132.41727847799999, -96.717721818399994, -132.41727847799999, -96.717721818399994]) |
|---|
| 314 | True |
|---|
| 315 | |
|---|
| 316 | >>> del idx |
|---|