Tutorial: POI features (baseline)
This tutorial describes the baseline Point-Of-Interest (POI) features that can be included in a substrate build.
POI features are computed during substrate building and stored on the returned
Substrate as substrate.poi.
What you get
When POIs are enabled, substrate.poi is a POIFeatures object:
x: a NumPy array with shape(n_cells, n_features)feature_names: list of feature names aligned to the columns ofx
Count features
We always include the total count:
poi_count
Optionally, you can request tag/value breakout counts using poi_tags.
Examples:
{"amenity": true}adds a featureamenitycounting POIs with a non-nullamenityproperty.{"amenity": ["cafe", "restaurant"]}addsamenity=cafeandamenity=restaurant.
Travel-time-to-nearest features (min travel time)
If poi_travel_time_features=true, the builder appends travel-time-based
features derived from the cached sparse travel-time neighbourhoods:
poi_min_travel_time_s: minimum travel time (seconds) from each grid cell to any cell that contains at least one POI.
If you also specify poi_tags, tag/value-specific min travel time features are
added too:
poi_<tag>_min_travel_time_sfor<tag>: true(e.g.poi_amenity_min_travel_time_s)poi_<tag>=<value>_min_travel_time_sfor<tag>: [values](e.g.poi_amenity=school_min_travel_time_s)
If a POI target is not reachable within the neighbourhood cutoff, the feature is
set to max_travel_time_s.
Configuration knobs (SubstrateConfig)
POI behaviour is controlled by these SubstrateConfig fields:
disable_pois(bool, defaultfalse): disable all POI feature generation.poi_geojson_path(string, optional): path to a local GeoJSON file providing POIs (offline / tests / reproducible experiments).poi_tags(object/dict, optional): tag/value selection for breakout features. Interpreted as:{"tag": true}: count all POIs whereproperties[tag]is non-null{"tag": ["v1", "v2"]}: count only specific values
poi_travel_time_features(bool, defaultfalse): add min-travel-time features to the nearest POI target(s).
POIs can be sourced either by:
poi_geojson_path(local file), orOSM-derived POIs using
poi_tagstogether with a region spec (placeornorth/south/east/westorgraphml_path).
Example JSON config
{
"place": "Camden, London, UK",
"cell_size_m": 250.0,
"max_travel_time_s": 900.0,
"poi_tags": {"amenity": ["cafe", "restaurant"]},
"poi_travel_time_features": true,
"cache_dir": "./cache/camden"
}
Inspecting feature names
from motac.spatial.substrate import SubstrateBuilder, SubstrateConfig
cfg = SubstrateConfig.from_json("./substrate.json")
sub = SubstrateBuilder(cfg).build()
if sub.poi is None:
raise RuntimeError("POIs disabled or not available")
print(sub.poi.feature_names)
print(sub.poi.x.shape)