Computing bounding box for a list of coordinates in Python

Problem:

You have a list of X/Y coordinates, for example:

coords = [(6.74219, -53.57835),
          (6.74952, -53.57241),
          (6.75652, -53.56289),
          (6.74756, -53.56598),
          (6.73462, -53.57518)]

For these coordinates you want to compute the minimum bounding box.

Solution 1 (no NumPy):

class BoundingBox(object):
    """
    A 2D bounding box
    """
    def __init__(self, points):
        if len(points) == 0:
            raise ValueError("Can't compute bounding box of empty list")
        self.minx, self.miny = float("inf"), float("inf")
        self.maxx, self.maxy = float("-inf"), float("-inf")
        for x, y in points:
            # Set min coords
            if x < self.minx:
                self.minx = x
            if y < self.miny:
                self.miny = y
            # Set max coords
            if x > self.maxx:
                self.maxx = x
            elif y > self.maxy:
                self.maxy = y
    @property
    def width(self):
        return self.maxx - self.minx
    @property
    def height(self):
        return self.maxy - self.miny
    def __repr__(self):
        return "BoundingBox({}, {}, {}, {})".format(
            self.minx, self.maxx, self.miny, self.maxy)

# Usage example:
BoundingBox(coords)
# BoundingBox(6.73462, 6.75652, -53.57835, -53.56289)

By using the BoundingBox class, you can directly access bbox.width and bbox.height. Although you can access the coordinates at bbox[0], bbox[1], ...,  you can avoid mixing up the coordinates by accessing them using bbox.minx, bbox.maxx, bbox.miny and bbox.maxy.

Solution 2 (NumPy):

Using numpy makes managing a large amount of coordinates much more efficient. For this example, we’ll assume you stored the coordinates in a (n,2)-shaped array. For the example coordinates above, that’s easy:

import numpy as np
coords = np.asarray(coords)

We can use numpy’s builtin min and max functions to compute the min/max instead of writing them ourselves. You can have a look at  the source code, but for most applications it’s recommended to install UliEngineering and just use the code:

sudo pip3 install git+https://github.com/ulikoehler/UliEngineering.git

Example:

from UliEngineering.Math.Coordinates import BoundingBox

# Usage example:
BoundingBox(coords)
# BoundingBox(6.73462, 6.75652, -53.57835, -53.56289)

You can use this on a list of coordinates without explicitly converting them to a numpy array, because min and max will convert the list implicitly. However, this is inefficient, as it will be converted two times: Once in min and once in max.