Package: e-pyquadtree
PyQuadTreeA simple pure Python quadtree implementation.Supports fast query, insertion, deletion, and nearest neighbor search.Installationpipinstalle-pyquadtreeUsage1. Creating a QuadTreebboxis a tuple of the form(x1, y1, x2, y2)where(x1, y1)is the top left corner of the bounding box and(x2, y2)is the bottom right corner of the bounding box.max_elementsis the maximum number of elements that can be stored in a node before it splits.max_depthis the maximum depth of the quadtree.frompyquadtreeimportQuadTreequadtree=QuadTree(bbox=(0,0,1000,500),max_elements=10,max_depth=5)2. Adding elements to the QuadTreeThe first argument can be any object you want to store in the quadtree.
The second argument is a tuple of the form(x, y)where(x, y)is the location of the object.quadtree.add("apple",(100,100))3. Deleting elements from the QuadTreeThe first argument is the object you want to delete from the quadtree.
It performs a lookup on the object and deletes it from the quadtree.quadtree.delete("apple")4. Querying the QuadTreeThe first argument is a tuple of the form(x1, y1, x2, y2)where(x1, y1)is the top left corner of the bounding box and(x2, y2)is the bottom right corner of the bounding box.Returns a list of elements within the bounding box.
Each element has anitemand apointattribute.
These are the same as the arguments passed toquadtree.add()when this element was added to the quadtree.found_elements=quadtree.query((50,50,150,150))5. Finding the nearest neighborAllows you to find the nearest n neighbors to a point.
The first argument is the point of interest.There are a couple of optional arguments:conditionis a function that takes in an item and returns a boolean.
If the function returnsTrue, the item is considered a valid neighbor.
If the function returnsFalse, the item is not considered a valid neighbor.max_distanceis the maximum distance from the point of interest to a neighbor.
If the distance between the point of interest and a neighbor is greater thanmax_distance,
the neighbor is not considered a valid neighbor.number_of_neighborsis the number of neighbors to return.
Ifnumber_of_neighborsis 1 by default.condition=lambdax:x=="apple"neighbors=quadtree.nearest_neighbors((200,100),condition=condition,max_distance=100,number_of_neighbors=3)6. Drawing the treeCallingget_all_bbox()on the root node will return a flat list of all bounding boxes that make up the tree.
These can then be drawn using your favorite drawing library.frompyquadtreeimportQuadTreeimportrandomimportmatplotlib.pyplotaspltfrommatplotlib.patchesimportRectanglequadtree=QuadTree(bbox=(0,0,1000,500),max_elements=10,max_depth=5)foriinrange(100):quadtree.add(i,(random.randint(0,100),random.randint(0,500)))all_bbox=quadtree.get_all_bbox()fig,ax=plt.subplots()ax.set_xlim(0,1000)ax.set_ylim(0,500)forbboxinall_bbox:print(bbox)rectangle=Rectangle((bbox[0],bbox[1]),bbox[2]-bbox[0],bbox[3]-bbox[1],fill=False,edgecolor="r",linewidth=1)ax.add_patch(rectangle)plt.show()ExamplefrompyquadtreeimportQuadTree# Creating a quadtree from (0, 0) to (1000, 500)# It will have a maximum depth of 5 and a maximum number of 10 objects per nodequadtree=QuadTree(bbox=(0,0,1000,500),max_elements=10,max_depth=5)# Inserting a string object with a location of (100, 100)quadtree.add("apple",(100,100))# Inserting another string object with a location of (200, 50)quadtree.add("orange",(200,50))# Querying the quadtree for all objects in the bounding box (50, 50, 150, 150)# Returns the list of elements within the bounding boxfound_elements=quadtree.query((50,50,150,150))forelementinfound_elements:print(element.point,element.item)# (100, 100) apple# Finding the element nearest to (200, 100)nearest_neighbor=quadtree.nearest_neighbors((200,100))[0]print(nearest_neighbor.point,nearest_neighbor.item)# (200, 50) orange# Getting a list all elements in the quadtreeall_elements=quadtree.get_all_elements()forelementinall_elements:print(element.point,element.item)# (100, 100) apple, (200, 50) orangePerformanceThe following performance tests were run on a quadtree with a maximum depth of 10 and
a maximum number of 20 elements per node.
The values are the number of seconds needed to both build the tree and then do 500 random queries.pyqtree is an alternative pure Python quadtree implementation which can be foundhere. It was a big part in the inspiration
for this project.Number of elementsBrute Forcepyquadtreepyqtree20000.0570.0290.03240000.1120.0520.06160000.1650.0970.180000.2220.1080.132100000.2730.130.163120000.3340.1770.197140000.4050.20.241160000.4570.2160.314180000.5040.2820.334200000.5640.2780.41220000.6230.3590.458240000.6810.350.557260000.730.4250.592280000.7920.4930.657At 28000 elements, pyquadtree is 25% faster than pyqtree and 38% faster than brute force.