Skip to content

Refactor BMI nexus mapping to use adjacency zarr instead of GeoPackage #175

Description

@taddyb

Context

ddr_bmi.py:508-575 (_build_nexus_mapping) reads the GeoPackage via sqlite3 to get the flowpaths table's idtoid mapping for translating ngen nexus IDs to DDR segment indices.

After #172, the toid array will be available in the adjacency zarr. The BMI module should use that instead of the GeoPackage.

Proposal

Refactor _build_nexus_mapping to read the toid array from the adjacency zarr:

# Instead of sqlite3 query on gpkg:
toid_array = self.conus_adjacency["toid"][:]
order_array = self.conus_adjacency["order"][:]
# Build nexus_to_seg mapping from these arrays

The mapping logic:

  • order[i] gives the segment integer ID at index i
  • toid[i] gives the downstream nexus string (e.g., nex-12345) for segment i
  • Invert to get: nexus integer ID → segment array index

Fallback

Keep the sqlite3/gpkg path as a fallback (it already has a try/except that falls back to identity mapping). This ensures backwards compatibility if someone has a gpkg but hasn't rebuilt their zarr.

Files to modify

  • src/ddr/bmi/ddr_bmi.py
  • src/ddr/bmi/config.py (if hydrofabric_gpkg field needs to become optional)

Acceptance criteria

  • BMI initialize() works without a GeoPackage when adjacency zarr has toid
  • BMI initialize() still works with GeoPackage (backwards compatible)
  • Nexus mapping produces identical results from zarr vs gpkg
  • Existing BMI tests pass

Depends on

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions