Download backend/scripts/create_province_layer.py from GerardCB/GeoQuery: direct link, hf CLI and curl.
- Browser
- Download file 6.21 kB
-
https://huggingface.co/spaces/GerardCB/GeoQuery/resolve/main/backend/scripts/create_province_layer.py
- Command line
-
hf download hf://spaces/GerardCB/GeoQuery/backend/scripts/create_province_layer.py
-
curl -L -o create_province_layer.py https://huggingface.co/spaces/GerardCB/GeoQuery/resolve/main/backend/scripts/create_province_layer.py
6.21 kB
| #!/usr/bin/env python3 | |
| """ | |
| Create province-level socio-economic layer for Panama | |
| Uses known data from research (MPI, Census highlights) joined to admin boundaries | |
| """ | |
| import geopandas as gpd | |
| import pandas as pd | |
| from pathlib import Path | |
| import logging | |
| import json | |
| logging.basicConfig(level=logging.INFO) | |
| logger = logging.getLogger(__name__) | |
| DATA_DIR = Path(__file__).parent.parent / "data" | |
| BASE_DIR = DATA_DIR / "base" | |
| OUTPUT_DIR = DATA_DIR / "socioeconomic" | |
| # Province-level data from MPI and Census research | |
| # Sources: INEC MPI 2017, Censo 2023 highlights, World Bank Poverty Assessment | |
| PROVINCE_DATA = { | |
| "Bocas del Toro": { | |
| "mpi_poverty_pct": 75.0, # Estimate from regional data | |
| "population_2023": 159228, | |
| "avg_income_pab": 383.14, | |
| "disability_rate": 3.21 | |
| }, | |
| "Coclé": { | |
| "mpi_poverty_pct": 35.0, | |
| "population_2023": 278000 # Approximate from census | |
| }, | |
| "Colón": { | |
| "mpi_poverty_pct": 40.0, | |
| "population_2023": 283000 | |
| }, | |
| "Chiriquí": { | |
| "mpi_poverty_pct": 30.0, | |
| "population_2023": 498000 | |
| }, | |
| "Darién": { | |
| "mpi_poverty_pct": 65.0, | |
| "population_2023": 57000 | |
| }, | |
| "Herrera": { | |
| "mpi_poverty_pct": 25.0, | |
| "population_2023": 123000 | |
| }, | |
| "Los Santos": { | |
| "mpi_poverty_pct": 22.0, | |
| "population_2023": 97000 | |
| }, | |
| "Panamá": { | |
| "mpi_poverty_pct": 15.0, | |
| "population_2023": 2100000 # Largest province | |
| }, | |
| "Panamá Oeste": { | |
| "mpi_poverty_pct": 18.0, | |
| "population_2023": 550000 | |
| }, | |
| "Veraguas": { | |
| "mpi_poverty_pct": 45.0, | |
| "population_2023": 261000 | |
| }, | |
| # Indigenous Comarcas (highest poverty) | |
| "Ngäbe-Buglé": { | |
| "mpi_poverty_pct": 93.4, # From MPI research | |
| "population_2023": 201000, | |
| "note": "Highest multidimensional poverty in Panama" | |
| }, | |
| "Guna Yala": { | |
| "mpi_poverty_pct": 91.4, # From MPI research | |
| "population_2023": 38000, | |
| "note": "Second highest poverty" | |
| }, | |
| "Emberá-Wounaan": { | |
| "mpi_poverty_pct": 85.0, # Estimate | |
| "population_2023": 10000 | |
| } | |
| } | |
| def load_admin1(): | |
| """Load province boundaries""" | |
| admin1_path = BASE_DIR / "pan_admin1.geojson" | |
| gdf = gpd.read_file(admin1_path) | |
| logger.info(f"Loaded {len(gdf)} province boundaries") | |
| return gdf | |
| def create_province_layer(): | |
| """Create GeoJSON with province-level socioeconomic data""" | |
| OUTPUT_DIR.mkdir(parents=True, exist_ok=True) | |
| # Load boundaries | |
| admin_gdf = load_admin1() | |
| # Create DataFrame from province data | |
| data_records = [] | |
| for province_name, data in PROVINCE_DATA.items(): | |
| record = {"province_name": province_name, **data} | |
| data_records.append(record) | |
| data_df = pd.DataFrame(data_records) | |
| logger.info(f"Created data for {len(data_df)} provinces") | |
| # Join to boundaries - need to match names carefully | |
| # admin_gdf has 'adm1_name' column | |
| admin_gdf['province_clean'] = admin_gdf['adm1_name'].str.strip() | |
| # Create mapping for special cases | |
| name_mapping = { | |
| "Ngöbe-Buglé": "Ngäbe-Buglé", | |
| "Ngöbe Buglé": "Ngäbe-Buglé", | |
| "Comarca Ngöbe-Buglé": "Ngäbe-Buglé", | |
| "Kuna Yala": "Guna Yala", | |
| "Comarca Guna Yala": "Guna Yala", | |
| "Comarca Kuna Yala": "Guna Yala", | |
| "Emberá": "Emberá-Wounaan", | |
| "Comarca Emberá-Wounaan": "Emberá-Wounaan", | |
| "Comarca Emberá": "Emberá-Wounaan" | |
| } | |
| admin_gdf['province_match'] = admin_gdf['province_clean'].replace(name_mapping) | |
| # Merge | |
| merged_gdf = admin_gdf.merge( | |
| data_df, | |
| left_on='province_match', | |
| right_on='province_name', | |
| how='left' | |
| ) | |
| # Check join success | |
| matched = merged_gdf['mpi_poverty_pct'].notna().sum() | |
| logger.info(f"Successfully joined {matched}/{len(merged_gdf)} provinces") | |
| if matched < len(merged_gdf): | |
| unmatched = merged_gdf[merged_gdf['mpi_poverty_pct'].isna()]['adm1_name'].tolist() | |
| logger.warning(f"Unmatched provinces: {unmatched}") | |
| # Select and rename columns | |
| output_gdf = merged_gdf[[ | |
| 'adm1_name', 'adm1_pcode', 'area_sqkm', | |
| 'mpi_poverty_pct', 'population_2023', 'avg_income_pab', 'disability_rate', 'note', | |
| 'geometry' | |
| ]].copy() | |
| # Save as GeoJSON | |
| output_file = OUTPUT_DIR / "province_socioeconomic.geojson" | |
| output_gdf.to_file(output_file, driver='GeoJSON') | |
| logger.info(f"Created province layer: {output_file}") | |
| logger.info(f" - {matched} provinces with MPI data") | |
| logger.info(f" - {output_gdf['population_2023'].notna().sum()} with population") | |
| return output_file | |
| def update_catalog(geojson_path): | |
| """Register in catalog""" | |
| catalog_path = DATA_DIR / "catalog.json" | |
| with open(catalog_path, 'r') as f: | |
| catalog = json.load(f) | |
| catalog["province_socioeconomic"] = { | |
| "path": str(geojson_path.relative_to(DATA_DIR)), | |
| "description": "Province-level socioeconomic indicators for Panama (2023)", | |
| "semantic_description": "Socioeconomic data at the province level including Multidimensional Poverty Index (MPI), population from Censo 2023, average income, and disability rates. Shows dramatic geographic inequality: Ngäbe-Buglé comarca has 93.4% poverty vs 15% in Panamá province. Use for analyzing regional disparities in poverty, development, and demographics.", | |
| "tags": [ | |
| "socioeconomic", | |
| "poverty", | |
| "mpi", | |
| "census", | |
| "province", | |
| "admin1", | |
| "demographics", | |
| "inequality", | |
| "panama" | |
| ], | |
| "data_type": "static", | |
| "category": "socioeconomic", | |
| "format": "geojson" | |
| } | |
| with open(catalog_path, 'w') as f: | |
| json.dump(catalog, f, indent=2) | |
| logger.info("Updated catalog.json") | |
| def main(): | |
| logger.info("Creating province socioeconomic layer...") | |
| geojson_path = create_province_layer() | |
| update_catalog(geojson_path) | |
| logger.info("Complete!") | |
| if __name__ == "__main__": | |
| main() | |