diff --git a/transform/sqlmesh_padelnomics/models/foundation/dim_locations.sql b/transform/sqlmesh_padelnomics/models/foundation/dim_locations.sql index 015bb28..b0ddbe3 100644 --- a/transform/sqlmesh_padelnomics/models/foundation/dim_locations.sql +++ b/transform/sqlmesh_padelnomics/models/foundation/dim_locations.sql @@ -215,7 +215,7 @@ SELECT l.location_slug, l.lat, l.lon, - h3_latlng_to_cell(l.lat, l.lon, 4) AS h3_cell_res4, + h3_latlng_to_cell(l.lat, l.lon, 5) AS h3_cell_res5, l.admin1_code, l.admin2_code, l.population, diff --git a/transform/sqlmesh_padelnomics/models/serving/location_profiles.sql b/transform/sqlmesh_padelnomics/models/serving/location_profiles.sql index be5edb3..e91c97d 100644 --- a/transform/sqlmesh_padelnomics/models/serving/location_profiles.sql +++ b/transform/sqlmesh_padelnomics/models/serving/location_profiles.sql @@ -20,7 +20,7 @@ -- "Where should I build a padel court?" -- Computed for ALL locations — zero-court locations score highest on supply gap. -- H3 catchment methodology: addressable market and supply gap use a regional --- H3 catchment (res-4 cell + 6 neighbours, ~462km², ~15-18km radius). +-- H3 catchment (res-5 cell + 6 neighbours, ~24km radius). -- -- 25 pts addressable market — log-scaled catchment population, ceiling 500K -- 20 pts economic power — income PPS, normalised to 35,000 @@ -63,30 +63,30 @@ base AS ( l.padel_venues_per_100k, l.nearest_padel_court_km, l.tennis_courts_within_25km, - l.h3_cell_res4 + l.h3_cell_res5 FROM foundation.dim_locations l ), --- Aggregate population and court counts per H3 cell (res 4, ~10km edge). --- Grouping by cell first (~30-50K distinct cells vs 140K locations) keeps the +-- Aggregate population and court counts per H3 cell (res 5, ~8.5km edge). +-- Grouping by cell first (~50-80K distinct cells vs 140K locations) keeps the -- subsequent lateral join small. hex_stats AS ( SELECT - h3_cell_res4, + h3_cell_res5, SUM(population) AS hex_population, SUM(padel_venue_count) AS hex_padel_courts FROM foundation.dim_locations - GROUP BY h3_cell_res4 + GROUP BY h3_cell_res5 ), -- For each location, sum hex_stats across the cell + 6 neighbours (k_ring=1). --- Effective catchment: ~462km², ~15-18km radius — realistic driving distance. +-- Effective catchment: ~24km radius — realistic driving distance. catchment AS ( SELECT l.geoname_id, SUM(hs.hex_population) AS catchment_population, SUM(hs.hex_padel_courts) AS catchment_padel_courts FROM base l, - LATERAL (SELECT UNNEST(h3_grid_disk(l.h3_cell_res4, 1)) AS cell) ring - JOIN hex_stats hs ON hs.h3_cell_res4 = ring.cell + LATERAL (SELECT UNNEST(h3_grid_disk(l.h3_cell_res5, 1)) AS cell) ring + JOIN hex_stats hs ON hs.h3_cell_res5 = ring.cell GROUP BY l.geoname_id ), -- Match dim_cities via (country_code, geoname_id) to get city_slug + exact venue count.