Add a country

Mobility gets the country list from the study area and transport zones. The modeller should still define only the study area, transport zones, population, activities, modes, surveys, and run parameters.

Adding a country means preparing the data that those objects need.

See current countries for the sources used today by France and Switzerland.

Start with local admin units. A country can only appear in a study area after Mobility can load its local administrative units. Population, activity, survey, and public transport data are only requested for countries that are present in the transport zones.

This means a radius around a border city does not automatically add a country that has no local admin units yet. For example, a Strasbourg study area remains France-only until German local admin units are added.

Edit points

Add the new country close to the data it describes.

Input

Add country here

Example to copy

Local admin units

mobility/spatial/countries.py

FrenchAdminUnits

Local admin unit categories

mobility/spatial/countries.py

FrenchLocalAdminUnitsCategories

Legal population

mobility/population/countries.py

FrenchCityLegalPopulation

Population groups

mobility/population/countries.py

FrenchPopulationGroups

Work data

mobility/activities/work/countries/

FrenchWork

Study data

mobility/activities/studies/countries/

FrenchStudy

Shopping data

mobility/activities/shopping/countries/

FrenchShopping

Public transport

mobility/transport/modes/public_transport/gtfs/countries.py

FrenchGTFS

Each edit point has a short country list. Add the country code there after the country file exists.

Example:

def available_work_data():
    return {
        "fr": FrenchWork(),
        "ch": SwissWork(),
        "de": GermanWork(),
    }

Local admin units

Prepare local admin units with:

  • admin_id,

  • admin_name,

  • country,

  • geometry.

The geometry must have a CRS. The shared LocalAdminUnits object converts these columns to the historical local admin unit table used by the model.

Local admin unit IDs should be prefixed to avoid collisions, for example fr-75056 or ch-6621. Keep the country in the country column. Model code should not read the country from the ID prefix.

Also prepare local admin unit categories with:

  • local_admin_unit_id,

  • urban_unit_category.

Population

Legal population must return:

  • local_admin_unit_id,

  • legal_population.

Population groups must build rows with:

  • transport_zone_id,

  • local_admin_unit_id,

  • age,

  • socio_pro_category,

  • ref_pers_socio_pro_category,

  • n_pers_household,

  • n_cars,

  • weight,

  • country.

Every country present in the transport zones must have legal population and population groups.

Surveys

Every population country must have survey coverage.

Each survey object must have:

  • survey_name,

  • country.

The survey tables must be compatible with the daily activity, time, mode, and immobility calculations used by PopulationGroupDayTrips.

Work data

Create a country file in mobility/activities/work/countries/.

The country work object has:

  • opportunities,

  • flows.

WorkOpportunities.validate_opportunities(...) checks the required columns. WorkFlows.validate_flows(...) checks the required flow columns. These checks fail before invalid tables are cached.

Work opportunities need:

  • jobs index named local_admin_unit_id,

  • jobs column n_jobs_total,

  • active population index named local_admin_unit_id,

  • active population column active_pop.

Work flows need:

  • local_admin_unit_id_from,

  • local_admin_unit_id_to,

  • mode,

  • ref_flow_volume.

Flow filters should keep rows where the origin or the destination is in the selected local admin units. This keeps boundary-crossing flows.

If two national files contain the same cross-border flow, use country_priority_order to choose one source:

work_flows = mobility.WorkFlows(
    countries=["fr", "ch"],
    local_admin_unit_ids=["fr-74010", "ch-6621"],
    country_priority_order=["ch", "fr"],
)

Study data

Create a country file in mobility/activities/studies/countries/.

The country study object has:

  • opportunities,

  • flows when flow data exists.

StudyOpportunities.validate_opportunities(...) checks the required opportunity columns. StudyFlows.validate_flows(...) checks the required flow columns.

Study opportunities need:

  • local_admin_unit_id,

  • geometry,

  • school_type,

  • n_students.

Study flows need:

  • local_admin_unit_id_from,

  • local_admin_unit_id_to,

  • school_type,

  • n_students.

If a country has no study flow source yet, the country flow object should fail with a clear message.

Shopping data

Create a country file in mobility/activities/shopping/countries/.

The country shopping object has:

  • opportunities.

ShoppingOpportunities.validate_opportunities(...) checks the required columns.

Shopping opportunities need:

  • local_admin_unit_id,

  • lon,

  • lat,

  • turnover.

France and Switzerland currently use a shared NAF/NOGA turnover bridge in the shopping country folder. A new country should prepare its own shopping source in its country file and return the required columns above.

Public transport

Add GTFS source support in mobility/transport/modes/public_transport/gtfs/countries.py.

The source class must insert GTFS rows into the GTFSSources table. The routing code then uses the combined source list for the selected study area.

France also uses an area filter based on declared GTFS coverage. Other countries can add a similar filter when their source metadata supports it.

Checks before use

Before using a new country in a scenario study, check:

  • all selected transport zones have a country,

  • every population country has survey coverage,

  • all opportunity tables pass their required-column checks,

  • opportunities are positive and spatially plausible,

  • cross-border flows are kept when they matter,

  • public transport sources cover the study area and the study period,

  • units and reference years are documented.