add_sites

site.SiteProblem.add_sites(
    candidate_site_df,
    candidate_id_col,
    required_sites_col=None,
    geometry_col='geometry',
    vertical_geometry_col='lat',
    horizontal_geometry_col='long',
    crs=None,
    capacity_col=None,
    cost_col=None,
    allow_missing_cost=False,
    current_load_col=None,
    utilisation_col=None,
    skip_cols=None,
)

Add candidate facility sites to the problem and handle spatial alignment.

This method ingests site data from either a standard DataFrame or a GeoDataFrame. If tabular data is provided, it automatically converts coordinates into point geometries. It also ensures the data matches the object’s preferred CRS, attempting to guess the CRS if it’s not provided.

Parameters

Name Type Description Default
candidate_site_df pandas.DataFrame or geopandas.GeoDataFrame or str The dataset containing potential site locations, or a local or web path to its location. required
candidate_id_col str The name of the column containing unique identifiers for each site. required
required_sites_col str The name of a boolean or binary column indicating if a site must be included in the final solution. Defaults to None. None
geometry_col str The name of the geometry column (used if candidate_site_df is already a GeoDataFrame or is a path to a geodataframe). "geometry"
vertical_geometry_col str The column name for latitude/y-coordinates (used if input is tabular or a path to a tabular file format like .csv). "lat"
horizontal_geometry_col str The column name for longitude/x-coordinates (used if input is tabular or a path to a tabular file format like .csv). "long"
crs str or pyproj.CRS The coordinate reference system of the input data. If None and the input is tabular, the method will attempt to guess the CRS. None
capacity_col str The column name representing the capacity of each site. Defaults to None. None
cost_col str The column name representing the fixed cost (e.g. build or operating cost) of each site. Must contain numeric values. Defaults to None. The total cost of the sites selected in a solution is reported in solutions_df, but cost only influences which solution is chosen if it is explicitly passed as a weight via solve(weights={"cost": ...}). By default, any site missing a value in this column raises a ValueError – see allow_missing_cost. None
allow_missing_cost bool Whether to allow rows with a missing (NaN) cost_col value. By default, missing costs raise a ValueError naming the affected sites, since a missing cost would otherwise silently behave like a $0 cost. Pass True to allow it: sites with a missing cost then propagate as NaN in any solution’s total_cost (rather than being treated as free), for cases where cost data is genuinely incomplete. Ignored if cost_col is not provided. False
current_load_col str The column name representing each site’s current real-world activity/caseload – today’s baseline, not anything derived from solve(). Must be paired with capacity_col (needed to turn a raw count into a utilisation ratio); pass a precomputed ratio via utilisation_col instead if you don’t have raw counts. Used by site_utilisation_summary() and plot_site_utilisation(). Defaults to None. None
utilisation_col str The column name representing each site’s current utilisation as a precomputed ratio or percentage, for analysts who don’t have raw current-load/capacity counts to hand. Mutually exclusive with current_load_col. May optionally be combined with capacity_col to also derive headroom in site_utilisation_summary(). Defaults to None. None
skip_cols list of str A list of column names to ignore during the data loading process. None

Returns

Name Type Description
None

Raises

Name Type Description
ValueError If required columns (ID, capacity, or geometry) are missing from the input data, if cost_col has a missing value for one or more sites and allow_missing_cost=False (the default), if both current_load_col and utilisation_col are given, if current_load_col is given without capacity_col, or if current_load_col/utilisation_col contains a negative value.

Notes

The method performs the following transformations: 1. Infers data type (spatial vs. tabular). 2. Validates schema based on the data type. 3. If tabular, converts to a geopandas.GeoDataFrame using the specified horizontal and vertical coordinate columns. 4. Matches or converts the dataset to self.preferred_crs.

Updates internal state including self.candidate_sites and self.total_n_sites.

Unlike cost_col, current_load_col/utilisation_col have no allow_missing_* flag and a missing (NaN) value is never rejected here. candidate_sites typically mixes already-operating sites (which have a real current load) with not-yet-built proposals (which have no current load simply because they don’t exist yet, not because of a data-entry gap). A missing cost has a dangerous silent default (looks free); a missing utilisation figure doesn’t – it means “not applicable”, not “0% full” – so site_utilisation_summary() reports it as an explicit NaN rather than coercing it to 0.

Back to top