Skip to content

feat: GIS foundations and registrant GPS coordinates#42

Open
jeremi wants to merge 1 commit into19.0from
feat/gis-foundations
Open

feat: GIS foundations and registrant GPS coordinates#42
jeremi wants to merge 1 commit into19.0from
feat/gis-foundations

Conversation

@jeremi
Copy link
Member

@jeremi jeremi commented Feb 17, 2026

Summary

  • spp_gis: Add OGC API support, area boundary handling improvements
  • spp_gis_report: Refactor report model for improved data layer management
  • spp_registrant_gis (new): Adds GPS coordinate fields to registrants for spatial queries

Origin

Cherry-picked from openspp-modules-v2 branch claude/global-alliance-policy-basket.

Test plan

  • Existing GIS field tests pass
  • New spp_registrant_gis installs and tests pass
  • GIS report generation works with refactored model

- Add OGC API support and area boundary handling to spp_gis
- Refactor GIS report model for improved data layer management
- Add new spp_registrant_gis module with GPS coordinates for registrants
@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 introduces significant enhancements to the Geographic Information System (GIS) capabilities within the OpenSPP platform. It provides foundational improvements to the spp_gis module by enabling more robust SQL query generation for spatial operations, particularly when dealing with complex table joins. The spp_gis_report module has been refined to provide more accurate aggregation of data across hierarchical geographic areas. Crucially, a new module, spp_registrant_gis, has been added to integrate GPS coordinates directly into registrant profiles, paving the way for advanced spatial analysis and proximity-based services for individuals and groups.

Highlights

  • Enhanced GIS Query Generation: The spp_gis module now supports table-qualified column names in spatial SQL queries, significantly improving robustness when dealing with complex joins and preventing ambiguous column references.
  • Improved GIS Report Aggregation: The spp_gis_report module's aggregation logic has been refactored to correctly include and roll up data from descendant geographic areas to their base-level ancestors, ensuring more accurate reporting.
  • New Registrant GPS Coordinates Module: A new module, spp_registrant_gis, has been introduced to add GPS coordinate fields to registrant records, enabling spatial querying, mapping, and geographic analysis for individuals and groups.
Changelog
  • spp_gis/fields.py
    • Modified the condition_to_sql method to pass table aliases to GIS operator objects, ensuring proper SQL qualification.
  • spp_gis/operators.py
    • Updated the Operator class constructor to accept an optional table_alias parameter.
    • Added a qualified_field_name property to generate SQL-safe, table-qualified field names.
    • Modified get_postgis_query to utilize the new qualified_field_name for all spatial operations.
  • spp_gis/tests/test_geo_fields.py
    • Added a new test class TestOperatorTableAlias to verify the correct generation of table-qualified column names by the Operator class, both with and without aliases.
  • spp_gis_report/models/gis_report.py
    • Refactored the _compute_base_aggregation method to build a mapping of descendant areas to their base-level ancestors, allowing for accurate aggregation of data from more granular areas.
    • Adjusted the aggregation logic to correctly accumulate raw values, counts, and weights for descendant areas into their respective base areas.
    • Updated the _to_geojson method to handle GeoPolygonField values that might be Shapely geometry objects or WKT/WKB strings.
  • spp_registrant_gis/
    • Introduced a new Odoo module to extend res.partner with a GeoPointField for GPS coordinates.
    • Provided README.rst and DESCRIPTION.md detailing the module's capabilities, UI location, security, and technical details.
    • Integrated the new coordinates field into the individual and group profile forms via res_partner_views.xml.
    • Included comprehensive unit tests (test_registrant_gis.py) to ensure the field's existence, writeability, and default empty state for both individual and group registrants.
Activity
  • Initial development was cherry-picked from the openspp-modules-v2 branch claude/global-alliance-policy-basket.
  • Existing GIS field tests were confirmed to pass.
  • The new spp_registrant_gis module was successfully installed and its tests passed.
  • GIS report generation was verified to function correctly with the refactored model.
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 significant GIS functionality. It adds support for table aliases in GIS operators to prevent ambiguous column names in complex queries, which is a solid improvement. A new module spp_registrant_gis is introduced to store GPS coordinates for registrants, complete with UI additions and tests. The GIS reporting has been refactored to handle hierarchical data by aggregating from descendant administrative areas up to a base level.

While the changes are largely positive, I've identified a critical bug in the report aggregation logic that incorrectly calculates sum, min, and max aggregations. I've also found a significant performance issue (N+1 query) in the same reporting feature. Addressing these issues is crucial for the correctness and scalability of the GIS reports. I've also left a minor comment on a newly added empty security file.

Comment on lines +529 to +531
results[base_id]["raw"] += value * count
results[base_id]["count"] += count
results[base_id]["weight"] += count

Choose a reason for hiding this comment

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

critical

There is a critical bug in the aggregation logic for sum, min, and max methods. The current implementation results[base_id]['raw'] += value * count is only correct when recalculating a weighted average (for the avg method).

  • For sum: value is already the sum for the subgroup. Multiplying it by count will inflate the total sum incorrectly. It should just be added to the total.
  • For min and max: Multiplying by count is meaningless. You should be taking the min of the minimums or max of the maximums across the subgroups.

This logic needs to be branched based on the agg_func.

Suggested change
results[base_id]["raw"] += value * count
results[base_id]["count"] += count
results[base_id]["weight"] += count
if agg_func == "avg":
# For avg, accumulate weighted sum to recalculate later
results[base_id]["raw"] += value * count
elif agg_func == "sum":
results[base_id]["raw"] += value
elif agg_func == "min":
# Initialize if it's the first value for this base_id
if results[base_id]["count"] == 0:
results[base_id]["raw"] = value
else:
results[base_id]["raw"] = min(results[base_id]["raw"], value)
elif agg_func == "max":
# Initialize if it's the first value for this base_id
if results[base_id]["count"] == 0:
results[base_id]["raw"] = value
else:
results[base_id]["raw"] = max(results[base_id]["raw"], value)
results[base_id]["count"] += count
results[base_id]["weight"] += count

Comment on lines +476 to +485
for base_area in base_areas:
child_to_base[base_area.id] = base_area.id
descendants = self.env["spp.area"].search(
[
("id", "child_of", base_area.id),
("id", "!=", base_area.id),
]
)
for desc in descendants:
child_to_base[desc.id] = base_area.id

Choose a reason for hiding this comment

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

high

There is a performance issue here due to an N+1 query problem. The self.env['spp.area'].search(...) call is inside a loop that iterates over base_areas. If there are many base areas, this will result in a large number of database queries, significantly slowing down the report generation.

To improve performance, you should refactor this to avoid making database queries inside a loop. One approach is to fetch all descendant areas at once and then process them in memory to build the child_to_base mapping. This will reduce the number of queries from N (where N is the number of base areas) to a small constant number.

@@ -0,0 +1 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink

Choose a reason for hiding this comment

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

medium

This ir.model.access.csv file contains only a header row. If no specific access rights are needed for this module, this file should be removed to avoid confusion. If access rights are intended, they should be added below the header. An empty or header-only access file can be misleading.

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