예제 #1
0
    def closest(self, point, sidx=si.StorageIndex()):
        """
		Returns a list of unique keys that fell within the BoundingBox that 
		contained the point.
		
		:param point: the point of interest
		
		>>> print(tree.closest([7,2]))	
		<<< [5 6]	
		"""

        # Return found points
        if "elements" in self.storage[sidx.storage()]:
            return self.storage[sidx.storage()]["elements"]
        else:  # Or continue recursive seeking
            # > obtain axis and partition.
            # axis: In which axis is the partition located
            axis = self.storage[sidx.storage()]["axis"]
            # partition: the coordinate of split point in the given axis
            partition = self.storage[sidx.storage()]["partition"]

            boxes = []

            # search for the closest point by comparing coordinate of point
            # in the given axis and partition
            if point[axis] <= partition:
                boxes.extend(self.closest(point, sidx.left()))
            if partition < point[axis]:
                boxes.extend(self.closest(point, sidx.right()))

        return boxes
예제 #2
0
    def traverse(self, mtrx, depth=0, sidx=si.StorageIndex()):
        """
		Internal used method for creating the QuadTree.

		This method will be called recursively until the maximum depth
		is reached. In every step it will split the data along a certain
		axis into two equal sized (median) partitions.

		Technically the partion function only needs to be called once,
		but is done repeatedly for clarity.
		"""
        axis = depth % 2

        self.storage[sidx.storage()]["index"] = sidx.tree()
        self.storage[sidx.storage()]["depth"] = depth
        self.storage[sidx.storage()]["axis"] = axis

        # if no more splitting, store ids from the matrix
        if len(mtrx) == 1 or depth + 1 == self.max_depth:
            self.storage[sidx.storage()]["elements"] = mtrx[:, 0]
        else:
            # order the matrix, and partition
            order = np.array_split(self.partition(mtrx, axis + 1), 2)
            self.storage[sidx.storage()]["partition"] = mtrx[order[0][-1],
                                                             axis + 1]
            self.traverse(mtrx[order[0], :], depth + 1, sidx.left())
            self.traverse(mtrx[order[1], :], depth + 1, sidx.right())
예제 #3
0
    def rquery(self, bbox=[], sidx=si.StorageIndex()):
        """
		Returns a list of unique keys that fell within the provided BoundingBox.
		
		:param bbox: the current BoundingBox that will be searched
		:param sidx: helper class for Binary Tree traversal
		
		>>> bbox = bb.BoundingBox(1,2,1,2)
		>>>	print(tree.rquery(bbox))		
		<<< [1, 2]
		
		>>> print(database.query(tree.rquery(bbox)))
		<<< [[1, 2, 3], [2, 5, 4]]		
		"""
        if "elements" in self.storage[sidx.storage()]:
            return self.storage[sidx.storage()]["elements"]

        else:
            axis = self.storage[sidx.storage()]["axis"]
            partition = self.storage[sidx.storage()]["partition"]
            lr = bbox.partition(partition, axis)

            boxes = []
            if lr[0]:
                boxes.extend(self.rquery(bbox, sidx.left()))
            if lr[1]:
                boxes.extend(self.rquery(bbox, sidx.right()))

        return boxes
예제 #4
0
    def closest(self, point, sidx=si.StorageIndex()):
        """
		Returns a list of unique keys that fell within the BoundingBox that 
		contained the point.
		
		:param point: the point of interest
		
		>>> print(tree.closest([7,2]))	
		<<< [5 6]	

		:To be implemented by the student:	
		"""

        if "elements" in self.storage[sidx.storage()]:
            return self.storage[sidx.storage()]["elements"]

        else:
            axis = self.storage[sidx.storage()]["axis"]
            partition = self.storage[sidx.storage()]["partition"]
            # lr = ((point[axis] <= partition) or (point[axis]<=partition), (point[axis] > partition) or (point[axis] > partition))
            boxes = []
            if point[axis] <= partition:
                boxes.extend(self.closest(point, sidx.left()))
            if point[axis] > partition:
                boxes.extend(self.closest(point, sidx.right()))

        return boxes
예제 #5
0
    def closest(self, point, sidx=si.StorageIndex()):
        """
		Returns a list of unique keys that fell within the BoundingBox that
		contained the point.

		:param point: the point of interest
		"""

        # When the condition is satisfied the recurssion is stopped.
        if "elements" in self.storage[sidx.storage()]:
            return self.storage[sidx.storage()]["elements"]

        else:
            """
             Get the axis and the partition number
             Axis - is the orientations, like x-axis (0) or y-axis (1)
             Partition - is the element where the KDTree was split or partitioned.
            """
            axis = self.storage[sidx.storage()]["axis"]
            partition = self.storage[sidx.storage()]["partition"]
            """
			traversal_direction - determines the direction of traversal (Left/Right).
			    If the point is less than or equal to the partition value traverse left
			    else traverse right.
			    The axis == 0 or axis == 1 ensure that we are comparing the partition value against either x or y respectively.
			"""
            traversal_direction = (point[axis] <= partition,
                                   point[axis] > partition)
            """
			Perform recursion until closest leaf node is reached.
			Store the data points in that leaf node in boxes and return the boxes.
			"""
            boxes = []
            if traversal_direction[0]:
                # Recursion/Traverse towards left child
                boxes.extend(self.closest(point, sidx.left()))
            if traversal_direction[1]:
                # Recursion/Traverse towards right child
                boxes.extend(self.closest(point, sidx.right()))

        return boxes
예제 #6
0
    def partitions(self):
        """
		Returns a dictionary containing lists of BoundingBoxes.
		{
			0 : [ 1 x BoundingBox]
			1 : [ 2 x BoundingBox]
			2 : [ 4 x BoundingBox]
		}

			where the key represents the depth, and the collection of BoundingBoxes
			make up the entire space containing this KDTree
		
		:Example:
		>>> for k,v in tree.partitions().items():
		>>>		print(k,len(v))
		<<< (0, 1)
		<<< (1, 2)
		<<< (2, 4)
		"""
        bounding_boxes = {}
        sidx = si.StorageIndex()
        self.traverse_partition(0, sidx, bounding_boxes, self.bb)
        return bounding_boxes
예제 #7
0
 def closest(self, point, sidx=si.StorageIndex()):
     # :To be implemented by the student:
     pass