Skip to content

Adjacency neighbourhood

Adjacency neighbourhood.

This module contains the AdjacencyNeighbourhood class, that allows to get the neighbours of any region based on its borders.

AdjacencyNeighbourhood(regions_gdf, include_center=False)

Bases: Neighbourhood[Hashable]

Adjacency Neighbourhood.

This class allows to get the neighbours of any region based on common border. Additionally, a lookup table is implemented to accelerate repeated queries.

By default, a lookup table will be populated lazily based on queries. A dedicated function generate_neighbourhoods allows for precalculation of all the neighbourhoods at once.

PARAMETER DESCRIPTION
regions_gdf

regions for which a neighbourhood will be calculated.

TYPE: GeoDataFrame

include_center

Whether to include the region itself in the neighbours.

TYPE: bool DEFAULT: False

RAISES DESCRIPTION
ValueError

If regions_gdf doesn't have geometry column.

Source code in srai/neighbourhoods/adjacency_neighbourhood.py
def __init__(self, regions_gdf: gpd.GeoDataFrame, include_center: bool = False) -> None:
    """
    Init AdjacencyNeighbourhood.

    Args:
        regions_gdf (gpd.GeoDataFrame): regions for which a neighbourhood will be calculated.
        include_center (bool): Whether to include the region itself in the neighbours.
        This is the default value used for all the methods of the class,
        unless overridden in the function call.

    Raises:
        ValueError: If regions_gdf doesn't have geometry column.
    """
    super().__init__(include_center)
    if GEOMETRY_COLUMN not in regions_gdf.columns:
        raise ValueError("Regions must have a geometry column.")
    self.regions_gdf = regions_gdf
    self.lookup: dict[Hashable, set[Hashable]] = {}

get_neighbours_up_to_distance(
    index, distance, include_center=None
)

Get the neighbours of a region up to a certain distance.

PARAMETER DESCRIPTION
index

Unique identifier of the region. Dependant on the implementation.

TYPE: IndexType

distance

Maximum distance to the neighbours.

TYPE: int

include_center

Whether to include the region itself in the neighbours.

TYPE: Optional[bool] DEFAULT: None

RETURNS DESCRIPTION
set[IndexType]

Set[IndexType]: Indexes of the neighbours.

Source code in srai/neighbourhoods/_base.py
def get_neighbours_up_to_distance(
    self, index: IndexType, distance: int, include_center: Optional[bool] = None
) -> set[IndexType]:
    """
    Get the neighbours of a region up to a certain distance.

    Args:
        index (IndexType): Unique identifier of the region.
            Dependant on the implementation.
        distance (int): Maximum distance to the neighbours.
        include_center (Optional[bool]): Whether to include the region itself in the neighbours.
        If None, the value set in __init__ is used. Defaults to None.

    Returns:
        Set[IndexType]: Indexes of the neighbours.
    """
    neighbours_with_distances = self._get_neighbours_with_distances(index, distance)
    neighbours: set[IndexType] = (
        seq(neighbours_with_distances).map(operator.itemgetter(0)).to_set()
    )
    neighbours = self._handle_center(
        index,
        distance,
        neighbours,
        at_distance=False,
        include_center_override=include_center,
    )
    return neighbours

get_neighbours_at_distance(
    index, distance, include_center=None
)

Get the neighbours of a region at a certain distance.

PARAMETER DESCRIPTION
index

Unique identifier of the region. Dependant on the implementation.

TYPE: IndexType

distance

Distance to the neighbours.

TYPE: int

include_center

Whether to include the region itself in the neighbours.

TYPE: Optional[bool] DEFAULT: None

RETURNS DESCRIPTION
set[IndexType]

Set[IndexType]: Indexes of the neighbours.

Source code in srai/neighbourhoods/_base.py
def get_neighbours_at_distance(
    self, index: IndexType, distance: int, include_center: Optional[bool] = None
) -> set[IndexType]:
    """
    Get the neighbours of a region at a certain distance.

    Args:
        index (IndexType): Unique identifier of the region.
            Dependant on the implementation.
        distance (int): Distance to the neighbours.
        include_center (Optional[bool]): Whether to include the region itself in the neighbours.
        If None, the value set in __init__ is used. Defaults to None.

    Returns:
        Set[IndexType]: Indexes of the neighbours.
    """
    neighbours_up_to_distance = self._get_neighbours_with_distances(index, distance)
    neighbours_at_distance: set[IndexType] = (
        seq(neighbours_up_to_distance)
        .filter(lambda x: x[1] == distance)
        .map(operator.itemgetter(0))
        .to_set()
    )
    neighbours_at_distance = self._handle_center(
        index,
        distance,
        neighbours_at_distance,
        at_distance=True,
        include_center_override=include_center,
    )
    return neighbours_at_distance

generate_neighbourhoods()

Generate the lookup table for all regions.

Source code in srai/neighbourhoods/adjacency_neighbourhood.py
def generate_neighbourhoods(self) -> None:
    """Generate the lookup table for all regions."""
    for region_id in self.regions_gdf.index:
        if region_id not in self.lookup:
            self.lookup[region_id] = self._get_adjacent_neighbours(region_id)

get_neighbours(index, include_center=None)

Get the direct neighbours of any region using its index.

PARAMETER DESCRIPTION
index

Unique identifier of the region.

TYPE: Hashable

include_center

Whether to include the region itself in the neighbours.

TYPE: Optional[bool] DEFAULT: None

RETURNS DESCRIPTION
set[Hashable]

Set[Hashable]: Indexes of the neighbours.

Source code in srai/neighbourhoods/adjacency_neighbourhood.py
def get_neighbours(
    self, index: Hashable, include_center: Optional[bool] = None
) -> set[Hashable]:
    """
    Get the direct neighbours of any region using its index.

    Args:
        index (Hashable): Unique identifier of the region.
        include_center (Optional[bool]): Whether to include the region itself in the neighbours.
        If None, the value set in __init__ is used. Defaults to None.

    Returns:
        Set[Hashable]: Indexes of the neighbours.
    """
    if self._index_incorrect(index):
        return set()

    if index not in self.lookup:
        self.lookup[index] = self._get_adjacent_neighbours(index)

    neighbours = self.lookup[index]
    neighbours = self._handle_center(
        index, 1, neighbours, at_distance=False, include_center_override=include_center
    )
    return neighbours