Skip to content

feat(spp_demo): add geographic demo data for Philippines, Sri Lanka, and Togo#44

Open
jeremi wants to merge 2 commits into19.0from
feat/geographic-demo-data
Open

feat(spp_demo): add geographic demo data for Philippines, Sri Lanka, and Togo#44
jeremi wants to merge 2 commits into19.0from
feat/geographic-demo-data

Conversation

@jeremi
Copy link
Member

@jeremi jeremi commented Feb 17, 2026

Summary

  • Add curated area hierarchies (Region, Province, Municipality) for Philippines, Sri Lanka, and Togo
  • Add GeoJSON boundary shapes for choropleth map visualization
  • Add demo area loader model and wizard for on-demand area data loading
  • Conditionally load GIS shapes when spp_gis is installed
  • Integrate geographic areas into demo story generation

Dependencies

Origin

From openspp-modules-v2 branch claude/global-alliance-policy-basket.

Test plan

  • spp_demo installs with new geographic data
  • Area loader wizard creates areas correctly
  • Demo stories assign geographic areas to registrants
  • GeoJSON shapes load when spp_gis is present

@gemini-code-assist
Copy link

Summary of Changes

Hello @jeremi, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the spp_demo module by incorporating comprehensive geographic data for three new countries: the Philippines, Sri Lanka, and Togo. The primary goal is to provide more realistic and geographically diverse demo environments, particularly for testing and showcasing GIS-related functionalities. This includes not only the hierarchical administrative divisions but also the corresponding GeoJSON shapes for map visualizations. A new wizard and underlying logic have been added to streamline the loading of this data, and the demo data generator now intelligently assigns these geographic areas to generated registrants and groups, ensuring better data integrity and utility for demonstrations.

Highlights

  • Geographic Demo Data: Introduced curated area hierarchies and geographic data for the Philippines (PHL), Sri Lanka (LKA), and Togo (TGO), including regions, provinces, municipalities, and villages.
  • GeoJSON Shape Integration: Added support for loading GeoJSON boundary shapes for choropleth map visualization, with conditional loading if the spp_gis module is installed.
  • Demo Area Loader: Implemented a new spp.demo.area.loader model and wizard to facilitate on-demand loading of geographic area data and shapes for selected countries.
  • Enhanced Demo Story Generation: Integrated geographic area assignment into the demo story generation process, allowing registrants and groups to be associated with specific leaf-level areas for more realistic scenarios and GIS reporting.
  • Module Dependencies and Structure: Updated the module manifest to include spp_area as a dependency and reorganized demo data files into country-specific directories.
Changelog
  • spp_demo/README.rst
    • Updated GitHub repository links to reflect the openspp-modules project.
    • Adjusted table column widths and list formatting for improved readability.
  • spp_demo/manifest.py
    • Added descriptions for geographic demo data and related features.
    • Included spp_area in the list of dependencies.
    • Added wizard/demo_area_loader_view.xml to the data files.
  • spp_demo/data/countries/lka/area_kinds.xml
    • Added XML data defining the administrative hierarchy for Sri Lanka (Province, District, DS Division, GN Division).
  • spp_demo/data/countries/lka/areas.xml
    • Added XML data for curated demo areas within Sri Lanka, focusing on Western, Southern, and Central Provinces.
  • spp_demo/data/countries/phl/area_kinds.xml
    • Added XML data defining the administrative hierarchy for the Philippines (Region, Province, City/Municipality, Barangay).
  • spp_demo/data/countries/phl/areas.xml
    • Added XML data for curated demo areas within the Philippines, focusing on NCR and CALABARZON regions.
  • spp_demo/data/countries/tgo/area_kinds.xml
    • Added XML data defining the administrative hierarchy for Togo (Region, Prefecture, Canton, Village/Quartier).
  • spp_demo/data/countries/tgo/areas.xml
    • Added XML data for curated demo areas within Togo, focusing on Maritime, Plateaux, and Centrale regions.
  • spp_demo/data/shapes/lka_curated.geojson
    • Added Git LFS pointer for Sri Lanka's curated GeoJSON shape data.
  • spp_demo/data/shapes/phl_curated.geojson
    • Added Git LFS pointer for the Philippines' curated GeoJSON shape data.
  • spp_demo/data/shapes/tgo_curated.geojson
    • Added Git LFS pointer for Togo's curated GeoJSON shape data.
  • spp_demo/models/init.py
    • Imported the new demo_area_loader module.
  • spp_demo/models/demo_area_loader.py
    • Added a new transient model spp.demo.area.loader to manage loading of geographic data and GeoJSON shapes.
    • Implemented methods to check for GIS module installation, load XML data, and convert GeoJSON to WKT format.
  • spp_demo/models/demo_data_generator.py
    • Added new fields demo_country and load_geographic_data to the demo data generator settings.
    • Integrated a call to _load_geographic_data before generating demo data.
    • Modified group and individual generation to assign leaf-level geographic areas.
    • Added a method _refresh_gis_reports to refresh GIS reports after data generation.
    • Refactored _get_area_for_profile to support area references, area kinds, and fallback to any available area.
    • Removed direct district field assignment in favor of generic area_id.
  • spp_demo/models/demo_stories.py
    • Updated demo story profiles to use area_ref and area_kind for geographic assignment instead of district.
  • spp_demo/security/ir.model.access.csv
    • Added access control list entries for the new spp.demo.area.loader model.
  • spp_demo/static/description/index.html
    • Updated GitHub repository links and adjusted table column widths.
  • spp_demo/tests/init.py
    • Imported the new test_demo_area_loader module.
  • spp_demo/tests/test_demo_area_loader.py
    • Added a new test file with test cases for the spp.demo.area.loader model, covering country support, area loading, and GeoJSON to WKT conversion.
  • spp_demo/tests/test_demo_data_generator.py
    • Added new test cases to verify that groups and individuals are correctly assigned leaf-level geographic areas during demo data generation.
  • spp_demo/tests/test_demo_stories.py
    • Adjusted an assertion for story count calculation.
  • spp_demo/tests/test_res_config_settings.py
    • Simplified assertions for configuration parameter values.
  • spp_demo/tests/test_res_country.py
    • Simplified assertions for custom country fields.
  • spp_demo/tests/test_res_partner.py
    • Simplified assertions for custom partner fields.
  • spp_demo/views/demo_data_generator_view.xml
    • Added UI fields for demo_country and load_geographic_data to the demo data generator form.
  • spp_demo/wizard/demo_area_loader_view.xml
    • Added a new wizard view for the spp.demo.area.loader model, allowing users to select a country and load geographic data.
Activity
  • The pull request introduces new features and data, as detailed in the highlights and changelog.
  • New test files and test cases have been added to ensure the correct functionality of the new demo area loader and geographic data assignment.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a significant feature by adding geographic demo data for the Philippines, Sri Lanka, and Togo. The changes are well-structured, with a new DemoAreaLoader model to handle data loading, and seamless integration into the existing demo data generator. The inclusion of data files, a new wizard, and comprehensive tests is commendable. I've provided a couple of suggestions to enhance performance and improve robustness in specific areas.

Comment on lines +183 to +188
try:
with open(geojson_path, encoding="utf-8") as f:
geojson_data = json.load(f)
except (OSError, json.JSONDecodeError) as e:
_logger.warning("Could not read GeoJSON file for %s: %s", country_code, e)
return 0

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The current error handling for GeoJSON files might be confusing if the file is a Git LFS pointer, as json.JSONDecodeError doesn't explain the root cause. It would be more user-friendly to explicitly check for an LFS pointer and log a specific warning, guiding the user to run git lfs pull.

        try:
            with open(geojson_path, encoding="utf-8") as f:
                first_line = f.readline()
                if first_line.startswith("version https://git-lfs.github.com/spec/v1"):
                    _logger.warning(
                        "GeoJSON file for %s is a Git LFS pointer. "
                        "Ensure files are checked out with 'git lfs pull' to load shapes.",
                        country_code,
                    )
                    return 0
                f.seek(0)
                geojson_data = json.load(f)
        except (OSError, json.JSONDecodeError) as e:
            _logger.warning("Could not read or parse GeoJSON file for %s: %s", country_code, e)
            return 0

Comment on lines 373 to 385
Area = self.env["spp.area"]
all_areas = Area.search([])
if not all_areas:
return Area.browse()

# Find the maximum area_level (deepest in hierarchy)
max_level = max(all_areas.mapped("area_level"))

# Get areas at the deepest level
leaf_areas = all_areas.filtered(lambda a: a.area_level == max_level)

# Fallback: if no areas at max level, use all areas
return leaf_areas if leaf_areas else all_areas

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The current implementation of _get_leaf_areas loads all spp.area records into memory to find the maximum level and then filters them. This could be inefficient for large datasets. You can optimize this by using a database query to find the maximum level and then another query to fetch only the leaf areas.

Suggested change
Area = self.env["spp.area"]
all_areas = Area.search([])
if not all_areas:
return Area.browse()
# Find the maximum area_level (deepest in hierarchy)
max_level = max(all_areas.mapped("area_level"))
# Get areas at the deepest level
leaf_areas = all_areas.filtered(lambda a: a.area_level == max_level)
# Fallback: if no areas at max level, use all areas
return leaf_areas if leaf_areas else all_areas
Area = self.env["spp.area"]
# Find the maximum area_level more efficiently
max_level_area = Area.search([], order="area_level desc", limit=1)
if not max_level_area:
return Area.browse()
max_level = max_level_area.area_level
# Get all areas at the deepest level
leaf_areas = Area.search([("area_level", "=", max_level)])
return leaf_areas

@codecov
Copy link

codecov bot commented Feb 18, 2026

Codecov Report

❌ Patch coverage is 66.57143% with 117 lines in your changes missing coverage. Please review.
✅ Project coverage is 41.66%. Comparing base (5ac7496) to head (eca97d2).

Files with missing lines Patch % Lines
spp_demo/models/demo_area_loader.py 43.90% 69 Missing ⚠️
spp_demo/models/demo_data_generator.py 44.28% 39 Missing ⚠️
spp_demo/tests/test_demo_data_generator.py 76.92% 9 Missing ⚠️

❗ There is a different number of reports uploaded between BASE (5ac7496) and HEAD (eca97d2). Click for more details.

HEAD has 7 uploads less than BASE
Flag BASE (5ac7496) HEAD (eca97d2)
fastapi 1 0
endpoint_route_handler 1 0
spp_alerts 1 0
spp_api_v2_cycles 1 0
spp_api_v2_change_request 1 0
spp_api_v2_data 1 0
spp_api_v2 1 0
Additional details and impacted files
@@             Coverage Diff             @@
##             19.0      #44       +/-   ##
===========================================
- Coverage   71.31%   41.66%   -29.66%     
===========================================
  Files         299      163      -136     
  Lines       23618    14591     -9027     
===========================================
- Hits        16844     6079    -10765     
- Misses       6774     8512     +1738     
Flag Coverage Δ
endpoint_route_handler ?
fastapi ?
spp_alerts ?
spp_api_v2 ?
spp_api_v2_change_request ?
spp_api_v2_cycles ?
spp_api_v2_data ?
spp_base_common 92.81% <ø> (ø)
spp_demo 75.19% <66.57%> (?)
spp_grm_demo 0.00% <ø> (?)
spp_mis_demo_v2 0.00% <ø> (?)
spp_programs 49.56% <ø> (ø)
spp_security 51.08% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

…and Togo

- Add curated area hierarchies (region, province, municipality) per country
- Add GeoJSON boundary shapes for choropleth visualization
- Add demo area loader model and wizard for on-demand area data loading
- Conditionally load GIS shapes when spp_gis is installed
- Integrate geographic areas into demo story generation
Replace the Python-level filter over all areas with a direct ORM query
using the domain [('child_ids', '=', False)], which lets the database
find leaf areas in a single SQL query instead of loading all records
into memory.
@jeremi jeremi force-pushed the feat/geographic-demo-data branch from 1ca1ed1 to eca97d2 Compare February 18, 2026 14:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

Comments