Skip to content

Migrate geographic maps to MapLibre and OpenFreeMap - #344

Draft
ewlarson wants to merge 42 commits into
developfrom
feature/ogm-viewer-resource-page
Draft

ewlarson wants to merge 42 commits into
developfrom
feature/ogm-viewer-resource-page

Conversation

@ewlarson

@ewlarson ewlarson commented Aug 21, 2026 •

Copy link
Copy Markdown
Contributor

What changes

Rebase feature/ogm-viewer-resource-page onto develop and migrate application geographic maps to MapLibre with OpenFreeMap Liberty, Bright, Positron, Dark, and Fiord styles. This includes homepage previews, resource location maps, search results, geographic filters, and country/region/county/H3 exploration. Preserve URL filters, rectangle selection, popups, legends, marker spreading, cooperative gestures, fullscreen, and responsive resizing. Keep the compact layers-button basemap switcher.

Upgrade OGM Viewer from 0.10.0 to pinned 1.6.0, align MapLibre dependencies, and package COG worker/LERC assets. Use the same pinned viewer and OpenFreeMap configuration in backend viewer HTML. Remove Leaflet, GeoBlacklight map code, plugins, and obsolete OpenLayers CSS.

The resource-page Allmaps viewer remains the existing official iframe, as requested. Homepage georeferenced previews use @allmaps/maplibre. IIIF image/document viewers remain supported.

Replace py-staticmaps with a private MapLibre Native renderer using the Ubuntu/software-rendering pattern from OGM API PR #25. Preserve existing database/Redis storage and public routes; no R2 migration. Validate PNGs before publication, introduce new variants/signatures, deduplicate geometry renders, bound concurrency/downloads/time, retain attribution, and preserve successful assets on failures. Add local Compose/Make workflows and public development documentation.

Upstream release: OGM Viewer 1.6.0, verified as latest.

Validation

All GitHub checks passed on e59143c4b860cdab2362dd681442b2762dcfc1b0 (CI run). PR remains draft against develop.

  • Backend make lint-test using the locked Python 3.12 development environment: passed. Full suite: 2,151 passed, 135 skipped, 1 xpassed, 66.09% coverage (50% requirement met).
  • Frontend full unfiltered coverage run: 123 files / 1,333 tests passed. Coverage: 73.48% statements, 68.50% branches, 74.66% functions, 75.19% lines.
  • Frontend lint: passed with zero errors and 12 nonblocking Fast Refresh warnings. Formatting check: passed.
  • Client and SSR production builds: passed. MapLibre worker and LERC WASM emitted correctly. Clean locked frontend dependency resolution passed.
  • Native renderer camera tests: 2 passed. Static-map service/public endpoint tests and MCP viewer tests are included in the passing backend suite.
  • Real browser checks: homepage refresh and production camera offset, compact five-style switcher/selection, search filter and result maps, keyboard result selection, exploration H3 and country switching, resource location, and a real COG preview.
  • Real Celery → renderer → durable storage round trip passed, with immutable hash verification, ETag/304, and cold Redis recovery.
  • Rendered and visually inspected point, line, polygon with holes, multipolygon, dateline, polar, global, and invalid geometry fixtures; campus route produced a valid 640×320 PNG. Concurrent requests produced one PNG and a bounded busy response. Renderer restart followed by application-service rendering passed.

Test reliability and quality fixes

Use locked backend dependencies in CI, scope resource/search mocks, isolate Elasticsearch indices and Redis test state, and add frontend lint/format checks to CI. Correct analytics navigation observation and split behavioral tests from all 19 full-report WCAG audits. Preserve every accessibility rule and report fixture; bound individual large-report audits at 120 seconds after measuring a 66-second audit on shared CPUs. Add a regression proving accessibility violations remain detectable. Replace repeated full-table role queries in the month-switching behavior test with direct heading lookups; the same assertions pass in 1.4 seconds in the complete local run.

Remaining acceptance work

Keep draft. Exhaustive real-service checks for every WMS/WMTS/XYZ/TMS/TileJSON/PMTiles/index-map fixture, the complete touch/dark-mode/failure matrix, and prolonged load/timeout testing are not claimed complete. Deployment-specific configuration belongs in restricted operations documentation and needs maintainer follow-through.

Homepage refresh regression fixes

Match production's 400px eastward offset from [44, -80] at legacy zoom 3 by resolving it into the initial camera [44, -9.6875], without generating a startup pan. Detect user-originated MapLibre camera events instead of counting generic moveend/zoomend events, so load, resize, basemap changes, and featured flights do not reveal Search Here or pause the tour. Preserve original click events from zoom controls; clear the search prompt on Home reset. Normalize viewport search bounds like OGM Discovery.

Validation: 35 homepage/mapping/bbox tests passed, including fresh-load/passive-event/first-input/reset regressions. Targeted lint: zero errors (three existing mapping-module warnings). Client and SSR builds passed. Real browser verified production refresh matches the production hero offset without the button/outline; first zoom and drag reveal both. Embedded Allmaps viewer unchanged.

Production-offset follow-up: 31 homepage/mapping tests and client/SSR builds passed. Visually compared at the reference screenshot viewport; refresh and resize leave Search Here hidden.

Basemap switcher follow-up: expand the options in place like production, eliminating the pointer gap. Offer Liberty, Bright, Positron, Dark, and Fiord; exclude 3D. Focused control/mapping tests: 18 passed. Targeted lint and formatting plus client/SSR builds passed. All five official style endpoints returned valid style JSON; Positron and Fiord rendering and option selection verified in the browser.

Featured carousel animation fix

Keep map context, H3 overlays, and featured bounds stable across the 100ms progress ticks. Read viewport bounds and zoom together after camera movement ends so intermediate flight frames do not request new H3 resolutions. Preserve source cleanup and deduplicate paired zoomend/moveend updates.

Validation on 6cbe566b: 56 targeted mapping/homepage/control tests passed, including two new source-stability/settled-camera regressions. Frontend lint (zero errors, 12 existing warnings), formatting, and client/SSR builds passed. Real Chrome production-build carousel check covered successive automatic transitions: flights completed, sources remained stable between transitions, and no script errors occurred. Preview on port 3004 refreshed. Current-head CI is rerunning; the all-green result above refers to the preceding commit. Keep draft.

Hex visibility restoration fix

Use the next MapLibre idle event when a style is temporarily busy instead of waiting for the one-time initial load event. Toggled overlays now return after source updates; removed maps and removed layers cannot install deferred overlays.

Validation on 222037ea: 58 mapping/homepage/control tests passed, including overlay restoration and deferred-callback cleanup regressions. Frontend lint, formatting, and client/SSR builds passed. Chrome completed three hide/show cycles, each restoring 1,253 hex features with no script errors; rendered screenshot inspected. Browser test used the healthy local API directly for H3 responses because the preview proxy returned 429. Fixed preview is running on port 3004. Current-head CI is rerunning; keep draft.

Featured highlight rendering parity

Preserve explicit MapLibre pane priorities: density hexes (400), featured bounds (410), selection (415), and previews (420). Late H3 responses and visibility toggles remain below Allmaps imagery and OGM previews. Draw featured coastal point data using overlapping blue pin symbols and use production blue for routes. Keep the active preview/camera stable as other thumbnail details arrive; guard stale Allmaps cleanup by instance identity.

Readiness now waits only for a loaded style document rather than source-tile completion or idle, which animated Allmaps previews can prevent. Initialize the Home camera from configuration and avoid an unnecessary global high-resolution H3 request during remount.

Validation on d90dbc57: 64 mapping/homepage/control tests passed, including pane ordering, stale cleanup, late details, camera stability, and high-zoom remount regressions. Frontend lint (zero errors, 12 existing warnings), formatting, and client/SSR builds passed. Inspected production-build Chrome screenshots: San Francisco imagery above 14 real API hex features after hide/show; 122 coastal pins rendered above hexes; blue migration routes above hexes; Home removed previews/pins and returned to native zoom 2. No script errors. Local API throttling required replaying a recorded successful San Francisco H3 response during that visual check. Updated homepage architecture documentation. Preview refreshed on port 3004. Current-head CI is rerunning; keep draft.

Zoom-button hex visibility and recovery

Preserve the last successful density data and its H3 resolution through viewport refreshes and temporary failures. Keep its existing MapLibre source installed during loading/error updates. Clear retained results when queries/filters change, coalesce rapid zoom clicks, abort superseded requests, ignore late responses, and retry transient failures at most twice while honoring Retry-After (including upstream epoch reset values). Preserve retry guidance through SSR errors.

Pass the configured server API credential to the local Compose API as well as SSR; the isolated preview was falling back to the anonymous ten-request tier. The API now recognizes its intended authenticated server tier without changing rate-limit rules. Updated public local-development documentation; no credential values committed.

Validation on 1b94a8e7: 97 targeted hook/API/proxy/mapping/homepage/control tests passed, frontend lint (zero errors, 12 existing warnings), formatting, client/SSR builds, and Compose configuration validation passed. Real Chrome against the actual authenticated preview/API (no replayed hex responses): eight zoom-button clicks produced nine successful H3 responses and zero empty-layer samples. Injecting one 429 preserved the layer and recovered with a successful retry; 343 total visibility samples contained no empty layer. No script errors. Preview remains on port 3004. Current-head CI is rerunning; keep draft.

@ewlarson
ewlarson force-pushed the feature/ogm-viewer-resource-page branch from 281583a to dec5202 Compare September 8, 2026 20:56
@ewlarson
ewlarson force-pushed the feature/ogm-viewer-resource-page branch from dec5202 to b7f2ce9 Compare October 28, 2026 21:57
@ewlarson ewlarson changed the title Migrate resource page viewer to ogm-viewer Migrate geographic maps to MapLibre and OpenFreeMap Oct 28, 2026
spec.update(center=center, leafletZoom=zoom)
else:
bounds = service._parse_geometry_to_bbox(geometry)
geojson = service._geometry_to_geojson_dict(geometry)
values = re.findall(r"[-+]?(?:\d*\.)?\d+(?:[eE][-+]?\d+)?", geometry)
if len(values) == 4:
west, east, north, south = map(float, values)
if west > east and -180 <= east < west <= 180:
if (typeof geometry === 'object' && geometry !== null && 'type' in geometry && 'coordinates' in geometry) {
if (
typeof geometry === 'object' &&
geometry !== null &&
if (typeof geometry === 'object' && geometry !== null && 'type' in geometry && 'coordinates' in geometry) {
if (
typeof geometry === 'object' &&
geometry !== null &&
def isolate_redis_pools(monkeypatch):
# Initialization tests mock Redis credentials. Do not retain those pools in
# later tests that exercise the real server.
import app.services.image_service as image_service
@ewlarson
ewlarson force-pushed the feature/ogm-viewer-resource-page branch from 6cdc541 to 1ed9710 Compare October 29, 2026 15:42
parsed = urlsplit(value)
if parsed.scheme in ("http", "https") and parsed.hostname and not parsed.username:
return value
except ValueError:

This branch has not been deployed

No deployments
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