hex_grid

class gridkit.hex_grid.HexGrid(*args, size=None, area=None, side_length=None, shape='pointy', offset=(0, 0), rotation=0, **kwargs)[source]

Bases: BaseGrid

Abstraction that represents an infinite grid with hexagonal cell shape.

The size of each cell can be specified through the size or area arguments.

Initialization parameters

size: float

The spacing between two cell centroids in horizontal direction if shape is “pointy”, or in vertical direction if shape is “flat”. Cannot be supplied together with area or ‘side_length’.

area: float

The area of a cell. Cannot be supplied together with size or ‘side_length’.

side_length: float

The length of the sides of a cell, which is 1/6th the cell outline. Cannot be supplied together with size or ‘area’.

shape: Literal[“pointy”, “flat”]

The shape of the layout of the grid. If shape is “pointy” the cells will be pointy side up and the regular axis will be in horizontal direction. If shape is “flat”, the cells will be flat side up and the regular axis will be in vertical direction.

offset: Tuple(float, float) (optional)

The offset in dx and dy. Shifts the whole grid by the specified amount. The shift is always reduced to be maximum one cell size. If the supplied shift is larger, a shift will be performed such that the new center is a multiple of dx or dy away. Default: (0,0)

rotation: float

The counter-clockwise rotation of the grid around the origin in degrees.

crs: pyproj.CRS (optional)

The coordinate reference system of the grid. The value can be anything accepted by pyproj.CRS.from_user_input(), such as an epsg integer (eg 4326), an authority string (eg “EPSG:4326”) or a WKT string. Default: None

property definition

The parameters that define the infinite grid. Passing these parameters into a new object instance will create a perfectly aligned grid. Note that Bounded Grids are defined by the bounds and data. Therefore, the properties returned by this property do describe the grid but cannot be used to create a new Bounded Grid object instance.

Returns:

A dictionary outlying the parameters that define the grid

Return type:

dict

property rotation_matrix

The matrix performing the counter-clockwise rotation of the grid around the origin in degrees. Note: makes a copy every time this is called.

property rotation_matrix_inv

The matrix performing the inverse (clockwise) rotation of the grid around the origin in degrees. Note: makes a copy every time this is called.

property side_length

The lenght of the side of a cell. The length is the same as that of HexGrid.r(). The unit is the unit used for the cell’s BaseGrid.size().

property area

The area of a cell. The unit is the unit used for the cell’s BaseGrid.size(), squared.

property offset: float

The offset off the grid in dx and dy. The offset is never larger than the size of a single grid cell. The offset represents the shift from the origin (0,0).

property dx: float

The spacing between cell centers in x-direction

property dy: float

The spacing between cell centers in y-direction

property r: float

The radius of the cell. The radius is defined to be the distance from the cell center to a cell corner.

property shape: str

The shape of the grid as supplied when initiating the class. This can be either “flat” or “pointy” referring to the top of the cells.

to_bounded(bounds, fill_value=nan)[source]

Create a bounded version of this grid where the data in the bounds is filled with the supplied fill_value

Parameters:
  • bounds (tuple) – The bounds of the area of interest in (minx, miny, maxx, maxy). The bounds need to be aligned to the grid. See BaseGrid.align_bounds()

  • fill_value (numpy.dtype (optional)) – The value to assign to the newly created array that fills the supplied bounds. Default: numpy.nan

Returns:

A bounded version of the current grid where the data is filled with fill_value.

Return type:

BoundedHexGrid or BoundedRectGrid

relative_neighbours(index, depth=1, include_selected=False, connect_corners=False) ndarray[source]

The relative indices of the neighbouring cells.

Parameters:
  • depth (int Default: 1) – Determines the number of neighbours that are returned. If depth=1 the direct neighbours are returned. If depth=2 the direct neighbours are returned, as well as the neighbours of these neighbours. depth=3 returns yet another layer of neighbours, and so forth.

  • index (numpy.ndarray) – The index of the cell of which the relative neighbours are desired. This is mostly relevant because in hexagonal grids the neighbouring indices differ when dealing with odd or even indices.

  • include_selected (bool Default: False) – Whether to include the specified cell in the return array. Even though the specified cell can never be a neighbour of itself, this can be useful when for example a weighted average of the neighbours is desired in which case the cell itself often should also be included.

  • connect_corners (bool Default: False) – Whether to consider cells that touch corners but not sides as neighbours. This is not relevant in hexagonal grids. It does nothing here. See RectGrid.relative_neighbours()

Examples

The direct neighbours of a cell can be returned by using depth=1, which is the default. For hexagonal grids, the relative indices of the neighbours differs depending on the index. There are two cases, neighbour indices for even colums and neighbour indices for odd columns, in the case of a grid ‘pointy’ shape. This works on rows if the grid has a ‘flat’ shape.

>>> from gridkit.hex_grid import HexGrid
>>> grid = HexGrid(size=3)
>>> grid.relative_neighbours(index=[0,0]).index
array([[-1,  1],
       [ 0,  1],
       [-1,  0],
       [ 1,  0],
       [ 0, -1],
       [-1, -1]])
>>> grid.relative_neighbours(index=[0,1]).index
array([[ 0,  1],
       [ 1,  1],
       [-1,  0],
       [ 1,  0],
       [ 1, -1],
       [ 0, -1]])

By specifying depth we can include indirect neighbours from further away. The number of neighbours increases with depth by a factor of depth*6. So the 3rd element in the list will be 1*6 + 2*6 + 3*6 = 36.

>>> [len(grid.relative_neighbours(index=[0,0], depth=depth)) for depth in range(1,5)]
[6, 18, 36, 60]

The specified cell can be included if include_selected is set to True:

>>> grid.relative_neighbours(index=[0,0], include_selected=True).index
array([[-1,  1],
       [ 0,  1],
       [-1,  0],
       [ 0,  0],
       [ 1,  0],
       [ 0, -1],
       [-1, -1]])
centroid(index=None)[source]

Coordinates at the center of the cell(s) specified by index.

Parameters:

index (tuple) – Index of the cell of which the centroid is to be calculated. The index consists of two integers specifying the nth cell in x- and y-direction. Multiple indices can be specified at once in the form of a list of indices or an Nx2 ndarray, where N is the number of cells.

Returns:

The longitude and latitude of the center of each cell. Axes order if multiple indices are specified: (points, xy), else (xy).

Return type:

numpy.ndarray

Raises:

ValueError – No index parameter was supplied. index can only be None in classes that contain data.

Examples

Cell centers of single index are returned as an array with one dimention:

>>> grid = RectGrid(dx=4, dy=1)
>>> grid.centroid((0, 0))
array([2. , 0.5])
>>> grid.centroid((-1, -1))
array([-2. , -0.5])

Multiple cell indices can be supplied as a list of tuples or as an equivalent ndarray:

>>> grid.centroid([(0, 0), (-1, -1)])
array([[ 2. ,  0.5],
       [-2. , -0.5]])
>>> ids = numpy.array([[0, 0], [-1, -1]])
>>> grid.centroid(ids)
array([[ 2. ,  0.5],
       [-2. , -0.5]])

Note that the center coordinate of the cell is also dependent on the grid’s offset:

>>> grid = RectGrid(dx=4, dy=1, offset = (1, 0.5))
>>> grid.centroid((0, 0))
array([3., 1.])
cells_near_point(point)[source]

Nearest 3 cells around a point. This includes the cell the point is contained within, as well as two direct neighbours of this cell and one diagonal neighbor. What neighbours of the containing are selected, depends on where in the cell the point is located.

Parameters:

point (tuple) – Coordinate of the point around which the cells are to be selected. The point consists of two floats specifying x- and y-coordinates, respectively. Multiple points can be specified at once in the form of a list of points or an Nx2 ndarray.

Returns:

The indices of the 4 nearest cells in order (top-left, top-right, bottom-left, bottom-right). If a single point is supplied, the four indices are returned as 1d arrays of length 2. If multiple points are supplied, the four indices are returned as Nx2 ndarrays.

Return type:

GridIndex

cell_at_point(point)[source]

Index of the cell containing the supplied point(s).

Parameters:

point (tuple) – Coordinate of the point for which the containing cell is to be found. The point consists of two floats specifying x- and y-coordinates, respectively. Mutliple poins can be specified at once in the form of a list of points or an Nx2 ndarray.

Returns:

The index of the cell containing the point(s). If a single point is supplied, the index is returned as a 1d array of length 2. If multiple points are supplied, the indices are returned as Nx2 ndarrays.

Return type:

numpy.ndarray

cell_corners(index: ndarray = None) ndarray[source]

Coordinates of the cell corners as specified by index.

Parameters:

index (GridIndex) – The indices of the cells of interest. Each id contains an x and y value.

Returns:

An array of coordinates in (x,y) specifying each of the corners. The returned array will be of the same shape as the input index, but with an extra axis containing the corners. The last axis is always of size 2 (x,y). The second to last axis is the length of the corners. The other axis are in the shape of the supplied index.

Return type:

numpy.ndarray

to_crs(crs, location=(0, 0), adjust_rotation=False)[source]

Transforms the Coordinate Reference System (CRS) from the current CRS to the desired CRS. This will update the cell size and the origin offset.

The crs attribute on the current grid must be set.

Parameters:
  • crs (Union[int, str, pyproj.CRS]) – The value can be anything accepted by pyproj.CRS.from_user_input(), such as an epsg integer (eg 4326), an authority string (eg “EPSG:4326”) or a WKT string.

  • location ((float, float) (default: (0,0))) –

    The location at which to perform the conversion. When transforming to a new coordinate system, it matters at which location the transformation is performed. The chosen location will be used to determinde the cell size of the new grid. If you are unsure what location to use, pich the center of the area you are interested in.

    Warning

    The location is defined in the original CRS, not in the CRS supplied as the argument to this function call.

  • adjust_rotation (bool (default: False)) – If False, the grid in the new crs has the same rotation as the original grid. Since coordinate transformations often warp and rotate the grid, the original rotation is often not a good fit anymore. If True, set the new rotation to match the orientation of the grid at location after coordinate transformation.

Returns:

A copy of the grid with modified cell spacing to match the specified CRS

Return type:

HexGrid

cells_in_bounds(bounds, return_cell_count: bool = False)[source]

Cells contained within a bounding box.

Parameters:
  • bounds (tuple) – The bounding box in which to find the cells in (min_x, min_y, max_x, max_y)

  • return_cell_count (bool) – Return a tuple containing the nr of cells in x and y direction inside the provided bounds

Returns:

The indices of the cells contained in the bounds

Return type:

GridIndex

subdivide(factor: int)[source]

Create a new grid that is factor times smaller than the existing grid and aligns perfectly with it.

Since a hexagonal grid that is divided into another hexagonal grid will always cut through some of the cells. They will never perfectly align. Therefore, this subdivide will return a triangular grid instead. This trianglar grid will perfectly subdivide the hexagonal one. If factor is one, the side lengths of the triangular cells will be of the same size as the side lengths of the hexagonal cells, which means there will be 6 trianglular cells that perfectly divide up the original hexagonal cell.

Note

In order to properly align the new TriGrid, it will be rotated by 30 degrees if the shape of the hexagonal grid is ‘pointy’.

The number of cells scale with the supplied factor in the following way: 6 * factor**2. So if factor is 1, there will be 6 times as many cells in the new grid. If factor is 2, there will be 24 times as many cells in the new grid, etc..

If you do, in fact, want to create a smaller HexGrid nd not a TriGrid, try something akin to the following code snippet:

>>> from gridkit.hex_grid import HexGrid
>>> grid = HexGrid(size=3)
>>> new_grid = grid.update(size=grid.size/2)
>>> anchor_point = grid.cell_corners([0,0])[0] # take an arbitrary corner of the original grid
>>> new_grid.anchor(anchor_point, cell_element="corner", in_place=True) # put corner of new grid on that of the old one
>>> print(new_grid.size)
1.5
>>> print(grid.r / new_grid.r)
2.0
Parameters:

factor (int) – An integer (whole number) indicating how many times smaller the new gridsize will be. It refers to the side of a grid cell. If factor is 1, the new grid will have cell sides of the same length as the cell sides of the original. If factor is 2, the side of the grid cell will be half the cell side length of the original.

Returns:

A new grid that is factor times smaller then the original grid.

Return type:

TriGrid

property parent_grid_class
update(size=None, shape=None, area=None, offset=None, rotation=None, crs=None, **kwargs)[source]

Modify attributes of the existing grid and return a copy. The original grid remains un-mutated.

Parameters:
  • size (float) – The new spacing between cell centers in x-direction. Cannot be supplied together with area.

  • area (float) – The area of a cell. Cannot be supplied together with size.

  • shape (Literal["pointy", "flat"]) – The new shape of the grid cells

  • offset (Tuple[float, float]) – The new offset of the origin of the grid

  • rotation (float) – The new counter-clockwise rotation of the grid in degrees. Can be negative for clockwise rotation.

  • crs (Union[int, str, pyproj.CRS]) – The value can be anything accepted by pyproj.CRS.from_user_input(), such as an epsg integer (eg 4326), an authority string (eg “EPSG:4326”) or a WKT string.

Returns:

A modified copy of the current grid

Return type:

RectGrid

class gridkit.hex_grid.BoundedHexGrid(data, *args, bounds=None, shape='flat', **kwargs)[source]

Bases: BoundedGrid, HexGrid

A HexGrid with data encapsulated within a bounding box.

Initialization parameters

data: numpy.ndarray

A 2D ndarray containing the data

bounds: Tuple(float, float, float, float)

The extend of the data in minx, miny, maxx, maxy.

shape: Literal[“pointy”, “flat”]

The shape of the cells in the grid. If shape is “pointy”, the hexagons will be standing upright on a point with the flat sides to the left and right. If shape is “flat”, the hexagons will be flat side up and below and pointy side on the left and right.

crs: pyproj.CRS (optional)

The coordinate reference system of the grid. The value can be anything accepted by pyproj.CRS.from_user_input(), such as an epsg integer (eg 4326), an authority string (eg “EPSG:4326”) or a WKT string. Default: None

property height

Raster height

Returns:

The number of grid cells in y-direction

Return type:

int

property width

Raster width

Returns:

The number of grid cells in x-direction

Return type:

int

property nr_cells

Number of cells

Returns:

The total number of cells in the grid

Return type:

int

property lon

Array of long values

Returns:

1D-Array of size width, containing the longitudinal values from left to right

Return type:

numpy.ndarray

property lat

Array of lat values

Returns:

1D-Array of size height, containing the latitudinal values from top to bottom

Return type:

numpy.ndarray

intersecting_cells(other)[source]
crop(new_bounds, bounds_crs=None, buffer_cells=0)[source]

Cut out a slice of data contained within the supplied bounds.

Parameters:
  • new_bounds (Tuple(minx, miny, maxx, maxy)) – The bounds defining the area to crop, in (minx, miny, maxx, maxy).

  • bounds_crs (pyproj.CRS (optional)) – The bounds defining the extent of the cropped data. The value can be anything accepted by pyproj.CRS.from_user_input().

Returns:

A BoundedGrid containing the data included in the cropped area contained within the bounds.

Return type:

class: BoundedGrid

cell_corners(index: ndarray | None = None) ndarray[source]

Coordinates of the cell corners as specified by index.

Parameters:

index (GridIndex) – The indices of the cells of interest. Each id contains an x and y value.

Returns:

An array of coordinates in (x,y) specifying each of the corners. The returned array will be of the same shape as the input index, but with an extra axis containing the corners. The last axis is always of size 2 (x,y). The second to last axis is the length of the corners. The other axis are in the shape of the supplied index.

Return type:

numpy.ndarray

to_shapely(index=None, as_multipolygon: bool = False)[source]

Refer to BaseGrid.to_shapely()

Difference with BaseGrid.to_shapely():

index is optional. If index is None (default) the cells containing data are used as the index argument.

to_crs(crs, resample_method='nearest')[source]

Transforms the Coordinate Reference System (CRS) from the current CRS to the desired CRS. This will modify the cell size and the bounds accordingly.

The crs attribute on the current grid must be set.

Parameters:
  • crs (Union[int, str, pyproj.CRS]) – The value can be anything accepted by pyproj.CRS.from_user_input(), such as an epsg integer (eg 4326), an authority string (eg “EPSG:4326”) or a WKT string.

  • resample_method (str) – The resampling method to be used for BoundedGrid.resample().

Returns:

A copy of the grid with modified cell spacing and bounds to match the specified CRS

Return type:

BoundedHexGrid

numpy_id_to_grid_id(np_index)[source]

Turn numpy indices that select values from self.data into a GridIndex instance that represents those same cells and can be used on the Grid object.

Parameters:

np_index (numpy.ndarray) – The numpy indices to convert

Returns:

The GridIndex representation of the cells

Return type:

GridIndex

argmax(*args, **kwargs)
argmin(*args, **kwargs)
grid_id_to_numpy_id(index)[source]
max(*args, **kwargs)
mean(*args, **kwargs)
median(*args, **kwargs)
min(*args, **kwargs)
std(*args, **kwargs)
sum(*args, **kwargs)
interp_nodata(*args, **kwargs)[source]

Please refer to interp_nodata().

centroid(index=None)[source]

Coordinates at the center of the cell(s) specified by index.

Parameters:

index (tuple) – Index of the cell of which the centroid is to be calculated. The index consists of two integers specifying the nth cell in x- and y-direction. Multiple indices can be specified at once in the form of a list of indices or an Nx2 ndarray, where N is the number of cells.

Returns:

The longitude and latitude of the center of each cell. Axes order if multiple indices are specified: (points, xy), else (xy).

Return type:

numpy.ndarray

Raises:

ValueError – No index parameter was supplied. index can only be None in classes that contain data.

Examples

Cell centers of single index are returned as an array with one dimention:

>>> grid = RectGrid(dx=4, dy=1)
>>> grid.centroid((0, 0))
array([2. , 0.5])
>>> grid.centroid((-1, -1))
array([-2. , -0.5])

Multiple cell indices can be supplied as a list of tuples or as an equivalent ndarray:

>>> grid.centroid([(0, 0), (-1, -1)])
array([[ 2. ,  0.5],
       [-2. , -0.5]])
>>> ids = numpy.array([[0, 0], [-1, -1]])
>>> grid.centroid(ids)
array([[ 2. ,  0.5],
       [-2. , -0.5]])

Note that the center coordinate of the cell is also dependent on the grid’s offset:

>>> grid = RectGrid(dx=4, dy=1, offset = (1, 0.5))
>>> grid.centroid((0, 0))
array([3., 1.])
anchor(target_loc: Tuple[float, float], cell_element: Literal['centroid', 'corner'] = 'centroid', resample_method='nearest')[source]

Position a specified part of a grid cell at a specified location. This shifts (the origin of) the grid such that the specified cell_element is positioned at the specified target_loc. This is useful for example to align two grids by anchoring them to the same location. The data values for the new grid will need to be resampled since it has been shifted.

Parameters:
  • target_loc (Tuple[float, float]) – The coordinates of the point at which to anchor the grid in (x,y)

  • cell_element (Literal["centroid", "corner"] - Default: "centroid") – The part of the cell that is to be positioned at the specified target_loc. Currently only “centroid” and “corner” are supported. When “centroid” is specified, the cell is centered around the target_loc. When “corner” is specified, a nearby cell_corner is placed onto the target_loc.

  • resample_method (str) – The resampling method to be used for BoundedGrid.resample().

Returns:

The shifted and resampled grid

Return type:

BoundedGrid

update(new_data, bounds=None, crs=None, nodata_value=None, shape=None)[source]

Modify attributes of the existing grid and return a copy. The original grid remains un-mutated.

Parameters:
  • size (float) – The new spacing between cell centers in x-direction. Cannot be supplied together with area.

  • area (float) – The area of a cell. Cannot be supplied together with size.

  • shape (Literal["pointy", "flat"]) – The new shape of the grid cells

  • offset (Tuple[float, float]) – The new offset of the origin of the grid

  • rotation (float) – The new counter-clockwise rotation of the grid in degrees. Can be negative for clockwise rotation.

  • crs (Union[int, str, pyproj.CRS]) – The value can be anything accepted by pyproj.CRS.from_user_input(), such as an epsg integer (eg 4326), an authority string (eg “EPSG:4326”) or a WKT string.

Returns:

A modified copy of the current grid

Return type:

RectGrid