Python implementation of Priority R-Tree
Project description
python_prtree
python_prtree is a python/c++ implementation of the Priority R-Tree (see references below). The supported futures are as follows:
- Construct a Priority R-Tree (PRTree) from an array of rectangles
- The array shape is (xmin, ymin, xmax, ymax) in 2D and (xmin, ymin, zmin, xmax, ymax, zmax) in 3D.
- 3D PRTree is supported since
>=0.4.0
. - Changed the ordering of the array shape since
>=0.5.0
.
query
andbatch_query
with rectangle(s)- Supports Point query with (x, y) in 2D and (x, y, z) in 3D since
>=0.5.1
- Supports Point query with (x, y) in 2D and (x, y, z) in 3D since
insert
anderase
(but not yet optimized)- Fixed a bug that one cannot insert to an empty PRTree at
0.5.0
.
- Fixed a bug that one cannot insert to an empty PRTree at
rebuild
with already given data since>=0.5.0
.- For better performance when too many insert/erase operations are called since.
- The
insert
andquery
methods can now be passed pickable Python objects instead of int64 indexes since>=0.5.2
.- See the example below for more details.
This package is mainly for mostly static situations where insertion and deletion events rarely occur (e.g. map matching).
Installation
You can install python_prtree with the pip command:
pip install python-prtree
If the pip installation does not work (e.g. on an M1 Mac), please git clone clone and install as follows:
pip install -U cmake pybind11
git clone --recursive https://github.com/atksh/python_prtree
cd python_prtree
python setup.py install
A Simple Example
import numpy as np
from python_prtree import PRTree2D
idxes = np.array([1, 2]) # must be unique because it uses idx as key for hash map
rects = np.array([[0.0, 0.0, 1.0, 0.5],
[1.0, 1.5, 1.2, 3.0]]) # (xmin, ymin, xmax, ymax)
prtree = PRTree2D(idxes, rects) # initial construction
q = np.array([[0.5, 0.2, 0.6, 0.3],
[0.8, 0.5, 1.5, 3.5]])
result = prtree.batch_query(q)
print(result)
# [[1], [1, 2]]
# You can insert an additional rectangle,
prtree.insert(3, np.array([1.0, 1.0, 2.0, 2.0]))
q = np.array([[0.5, 0.2, 0.6, 0.3],
[0.8, 0.5, 1.5, 3.5]])
result = prtree.batch_query(q)
print(result)
# [[1], [1, 2, 3]]
# And erase by index.
prtree.erase(2)
result = prtree.batch_query(q)
print(result)
# [[1], [1, 3]]
# Point query
print(prtree.query(0.5, 0.5))
# [1]
print(prtree.query((0.5, 0.5)))
# [1]
New Features and Changes
python-prtree>=0.5.3
- Add gzip compression for pickled objects.
python-prtree>=0.5.2
You can use pickable Python objects instead of int64 indexes for insert
and query
methods:
import numpy as np
from python_prtree import PRTree2D
objs = [{"name": "foo"}, (1, 2, 3)] # must NOT be unique but pickable
rects = np.array([[0.0, 0.0, 1.0, 0.5],
[1.0, 1.5, 1.2, 3.0]]) # (xmin, ymin, xmax, ymax)
prtree = PRTree2D()
for obj, rect in zip(objs, rects):
# keyword argments: bb(bounding box) and obj(object)
prtree.insert(bb=rect, obj=obj)
# returns indexes genereted by incremental rule.
result = prtree.query((0, 0, 1, 1))
print(result)
# [1]
# returns objects when you specify the keyword argment return_obj=True
result = prtree.query((0, 0, 1, 1), return_obj=True)
print(result)
# [{'name': 'foo'}]
python-prtree>=0.5.0
- [CRUTIAL] Changed the input order from (xmin, xmax, ymin, ymax, ...) to (xmin, ymin, xmax, ymax, ...).
- [FEATURE] Added rebuild method to build the PRTree from scratch using the already given data.
- [BUGFIX] Fixed a bug that prevented insertion into an empty PRTree.
- [REMIND] Cross-version saving and loading compatibility is not guaranteed.
python-prtree>=0.4.0
You can use PRTree3D:
import numpy as np
from python_prtree import PRTree3D
idxes = np.array([1, 2]) # must be unique because it uses idx as key for hash map
rects = np.array([[0.0, 0.5, 0.0, 0.5, 1.0, 0.5],
[1.0, 1.5, 2.0, 1.2, 2.5, 3.0]]) # (xmin, ymin, zmin, xmax, ymax, zmax)
prtree = PRTree3D(idxes, rects) # initial construction
q = np.array([[0.5, 0.2, 0.2, 0.6, 0.3, 0.3],
[0.8, 0.5, 0.5, 1.5, 3.5, 3.5]])
result = prtree.batch_query(q)
print(result)
# [[], [2]]
python-prtree>=0.3.0
You can save and load a binary file as follows:
# save
prtree.save('tree.bin')
# load with binary file
prtree = PRTree('tree.bin')
# or defered load
prtree = PRTree()
prtree.load('tree.bin')
Cross-version compatibility is NOT guaranteed, so please reconstruct your tree when you update this package.
Note
The 1d-array batch query will be implicitly treated as a batch with size = 1.
If you want 1d result, please use query
method.
result = prtree.query(q[0])
print(result)
# [1]
result = prtree.batch_query(q[0])
print(result)
# [[1]]
You can also erase(delete) by index and insert a new one.
prtree.erase(1) # delete the rectangle with idx=1 from the PRTree
prtree.insert(3, np.array([0.3, 0.5, 0.1, 0.2])) # add a new rectangle to the PRTree
Performance
Construction
2d
3d
Query and batch query
2d
3d
Delete and insert
2d
3d
Requirement
- numpy
NOTE
- C++ implements this PRTree with Pybind11 and much faster than the numba implementation of PRTree.
- If you can use C++, you should use boost::geometry (I did not know it and sadly made this package).
- Please note that insert / erase operations are not optimized compared to ordinary r-tree. Plus, this implementation does not exactly follow that of the paper due to my technical skills.
Reference
The Priority R-Tree: A Practically Efficient and Worst-Case Optimal R-Tree Lars Arge, Mark de Berg, Herman Haverkort, and Ke Yi Proceedings of the 2004 ACM SIGMOD International Conference on Management of Data (SIGMOD '04), Paris, France, June 2004, 347-358. Journal version in ACM Transactions on Algorithms. author's page
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Hashes for python_prtree-0.5.5-cp39-cp39-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 5370d0b1cc08aa9bd4f220bb41b88f52bbe85815701d895fadf7d7607439365f |
|
MD5 | 84edc674cc28cc7c9a5c001921e6bc57 |
|
BLAKE2b-256 | a82f3bcaa8f488eab8c6728627a486803903eeab612baae7f512c9ecacc9b042 |
Hashes for python_prtree-0.5.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | b89d2a6f8540d8fe2d8d4a621cebe901155a1d180db9939e47f286fdceac60f4 |
|
MD5 | 79297817151d0c5c16070153e733ee8e |
|
BLAKE2b-256 | d87325bafa3d2236fc0908b44f89de082d1c8b82d6542b7bd72b619e505e7493 |
Hashes for python_prtree-0.5.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 0879f2324f2732302b554857090cc8835b71e880ae5d0e7b757507dbf706a512 |
|
MD5 | 440610845a86428f93a22ce8c748bcd4 |
|
BLAKE2b-256 | c27568067b2f9c7927fa36adb04c8978dde19a87d87629ecfb24b8fa33312326 |
Hashes for python_prtree-0.5.5-cp39-cp39-macosx_10_15_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 563a3d6ede99f114f4a65f1c481515e586c34ae5fa79d09dc95b9767556ee8c0 |
|
MD5 | 724571c7258dc2c9516a370428a1b552 |
|
BLAKE2b-256 | c0bc04c004b7344168f1b799b0e2bd96093ea00e7b64c89eb9416566b37a3907 |
Hashes for python_prtree-0.5.5-cp38-cp38-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 0b56fb35319fd5b3b28d29cb5e120484b364b63e67a9a12023fed0b17c5b082a |
|
MD5 | c72bebc6609920659baeeab15a9363ce |
|
BLAKE2b-256 | 7865407322c4eaa6533cb07cc8f9fd4efa5f5ee9b49cd729819fd1b022b2e8aa |
Hashes for python_prtree-0.5.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | b1632fd017a783fba1f759b3d38c6b38aa947981b895ba53cccdd6d7b9b6b821 |
|
MD5 | 264922539e75ce00ccecb1e6a1f30440 |
|
BLAKE2b-256 | 5adc55ca245c6b541aba2b91655e27faae075d60356a6c37fd58b83b0c78c78b |
Hashes for python_prtree-0.5.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | d3dfae815f82eb315c93d82bb19d642670f84196d461a033440999bd993b1332 |
|
MD5 | c85498d725f9ab7fc3182503524ab132 |
|
BLAKE2b-256 | 0af881b8cc6fc1e04249894f7c376f69d256dbd3e27ed1d8a6de323d88aad7a1 |
Hashes for python_prtree-0.5.5-cp38-cp38-macosx_10_15_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | e5b6add95bf7db13bb4fce8a5e8c065fdb9f4a9867612beed401e1a04a6c370e |
|
MD5 | 4ecfb8692c19613a74ef0dc0d31defc7 |
|
BLAKE2b-256 | 5e9735f2c2828f81fb2bcd5bdde6edd21be3f9b38a0d54440f04803e9f2c8c67 |
Hashes for python_prtree-0.5.5-cp37-cp37m-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | b9224f986664e6a68aec7114760d3d9c551f59efeb113198e403e129aa33a10d |
|
MD5 | b2a49be257deeeace38fbb58e508068b |
|
BLAKE2b-256 | 2ed06e9989adf82e2b35e66657426c8b4c0c3a7f1ed2fbe3ab19d3a20abdee0b |
Hashes for python_prtree-0.5.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | a2a628ef3ad215f0700ea35463cdb9cd1aa63ddc56da9b213058538e5464a5e7 |
|
MD5 | 318e6018d91d358b6ed544e7f19b9290 |
|
BLAKE2b-256 | 375586ae6428f7d2dfc6819a1ea7b5cea3242b0a5c420d5ef8945c228a05f5c4 |
Hashes for python_prtree-0.5.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 65e551a7d0058b67370ef535e4b41b2b478db497cd1ce2c615b3260a3d3de905 |
|
MD5 | 5265a54efecab56dfae00110e6f84fde |
|
BLAKE2b-256 | bd6316f192b290177a85acc9a7c6e7621cbfdfb7d82536687ea97b919e42a576 |
Hashes for python_prtree-0.5.5-cp37-cp37m-macosx_10_15_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 2334ae1c19177eae17a2d775ecc8de5b32fd7e244d2879b63d36c9ed65e12f63 |
|
MD5 | 14f38d53aced7123ee6a33b51eb0ce6d |
|
BLAKE2b-256 | 23ab39374b69e2e9bb5c5c65ea0c0916ed56342210d6da4c5af463121dfcd65f |
Hashes for python_prtree-0.5.5-cp36-cp36m-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | bff628999fc9d72699577fecb758673e5ca829870351d2e73dc965f9121b8081 |
|
MD5 | e971c9829aa7f96d880e1cd59bc0a0dc |
|
BLAKE2b-256 | 02dadca4ca1e92762f630d0897423f63f286d0874cd6924d3567b0cfddcdb819 |
Hashes for python_prtree-0.5.5-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 6002364335b8bc0de26b085241189d0a64bd3d511dfaf2af119ce96b7e41c4e0 |
|
MD5 | 6e4912cd984d24eefae0a0d5dd45a278 |
|
BLAKE2b-256 | e02809b82eee8e482b632ac9dd36162976ce4c256e02ecc780c455cd77570b41 |
Hashes for python_prtree-0.5.5-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | eca5627fe640f3d4147ecdb668599e53b3f73339fd9376d2e5c5a9998ca7a279 |
|
MD5 | 141b2ea4910e89d3698d881ba42aa956 |
|
BLAKE2b-256 | e84df5ee3a8438276c204ab7e0ccaa3e206fe8bd63aebf211aa9982f7dcb74c3 |
Hashes for python_prtree-0.5.5-cp36-cp36m-macosx_10_15_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 0e749d9371b55ed072e2a9fd5c929e60e3e9fe238362b7f629c85fd03e938633 |
|
MD5 | 7c8a0d4cadf635c53159405558bc8f72 |
|
BLAKE2b-256 | ddace1339b2e9d0973a9d1b84f1c633b1e05f9204817d1bd6a93988acbecf6e3 |