Major feature batch covering drawing-tool improvements, layer additions,
and offline-first capabilities. Largest changes in MapView.js (+1700),
main.js (+1500), public/sw.js (+367), and new modules under src/.
Drawing & editing toolkit
* Polygon Divide tool — sub-button under Split, divides a polygon into
N equal-area pieces via binary search; user picks the cutting edge
* UPN pick phase after Split and Divide — non-picked pieces have their
identifier fields cleared automatically
* Improved Merge algorithm — vertex-to-edge proximity (5 m tol.) with
hybrid lockstep extension; bold A/B labels on selected polygons
* Persistent vertex highlights — all vertices of the selected polygon
rendered as dots while edit mode is on, without subclassing ol-ext
* Toast notifications for merge/split/divide outcomes
* Shapefile import — addGeoJSONLayer now includes an image style so
Point features render (previously invisible)
Background & overlay layers
* DEAfrica Coastlines v0.4 (WMS) in Biophysical Environment
* DEAfrica Slope (SRTM 30m, style_slope) — semi-transparent background
* Contours hillshade — get_contours_hillshade.php → local SQLite cache
* OSM_roads — get_osm_roads.php → local SQLite cache, casing-stroke
style (black 3.5 px outer, #F0F1F0 1.5 px inner)
* External Source dialog — green + button in LayerSwitcher lets users
add WMS / WFS / XYZ layers at runtime
* Generic addWMSLayer / addXYZLayer with style, opacity, zIndex,
legendUrl, onlineOnly options
* TileWMS replaces ImageWMS (fixes 'Width exceeds 512' WMS errors)
* Legend panel — bottom-right, auto-shown for visible layers that
register a legendUrl
* Default base map setting in Settings, persisted in localStorage;
setBaseMap() on MapView
Offline tile cache (Phase 1 + 2)
* Service worker: per-host tile caches (osm / topo / satellite /
carto-light / carto-dark), counter-based eviction to prevent
iOS Safari memory-pressure reloads, GET_TILE_STATS /
CLEAR_TILE_CACHES message API
* pwa.js helpers: getActiveServiceWorker, onServiceWorkerControllerChange,
getTileCacheStats, clearTileCaches, getStorageEstimate
* Settings: Offline Map Tiles card with per-provider stats + clear
* Phase 2 download dialog: form to pick base map, area (current view /
district / Ghana), zoom range; live tile-count + size estimate;
progress bar with cancel; OfflineTileDownloader class with
concurrency + throttling
Local database management
* osm_roads table + saveOSMRoads / getLocalOSMRoads helpers
* CACHED_LAYER_TABLES allow-list with clearTable / clearAllCachedLayers
* Local Database Tables card: per-row Clear button (cached layers
only) + 'Refresh cached layers' header button with reload prompt
Build & infrastructure
* Shpjs lazy-loaded via dynamic import (saves ~140 kB from initial JS)
* chunkSizeWarningLimit raised to 900 kB (openlayers + sqlite3.wasm
can't be split further)
* Toast notification module (src/toast.js)
* Units module (src/units.js) for metric / imperial conversions
* PDF export module (src/pdf-export.js)
Documentation & SQL
* Topographic_Background_Layers_for_LUPMIS2.docx — research report
* OpenTopography_Workflow.svg/.png — ETL pipeline diagram
* LUPMIS2_Development_Status_Report.docx — April update section
* sql/create_landuse_parcels.sql — PostgreSQL schema for the LUSPA
land-use parcel specification (Feb 2026, revised), with PostGIS
geometry column and standard indices
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
71 lines
2.0 KiB
JavaScript
71 lines
2.0 KiB
JavaScript
/**
|
|
* Vite Configuration
|
|
*
|
|
* Configures:
|
|
* - Cross-origin isolation headers (required for OPFS/SQLite)
|
|
* - Worker bundling
|
|
*/
|
|
|
|
import { defineConfig } from 'vite';
|
|
|
|
export default defineConfig({
|
|
// Development server configuration
|
|
server: {
|
|
headers: {
|
|
// Required for OPFS (Origin Private File System) access
|
|
'Cross-Origin-Opener-Policy': 'same-origin',
|
|
'Cross-Origin-Embedder-Policy': 'require-corp',
|
|
},
|
|
},
|
|
|
|
// Preview server (npm run preview) configuration
|
|
preview: {
|
|
headers: {
|
|
'Cross-Origin-Opener-Policy': 'same-origin',
|
|
'Cross-Origin-Embedder-Policy': 'require-corp',
|
|
},
|
|
},
|
|
|
|
// Build configuration
|
|
build: {
|
|
// Generate source maps for debugging
|
|
sourcemap: true,
|
|
|
|
// Target modern browsers that support OPFS
|
|
target: 'esnext',
|
|
|
|
// Raise the chunk-size warning threshold.
|
|
// Rationale: the two largest chunks are unavoidable —
|
|
// • openlayers (~535 kB / ~152 kB gzipped) — the OL library itself,
|
|
// used app-wide; further splitting just creates more HTTP round-trips
|
|
// • sqlite3.wasm (~856 kB) — a runtime WASM binary, not a JS chunk;
|
|
// code-splitting does not apply
|
|
// 900 kB silences the noise without hiding genuine regressions.
|
|
chunkSizeWarningLimit: 900,
|
|
|
|
rollupOptions: {
|
|
output: {
|
|
manualChunks(id) {
|
|
if (id.includes('node_modules/ol/')) return 'openlayers';
|
|
if (id.includes('node_modules/ol-ext/')) return 'ol-ext';
|
|
if (id.includes('node_modules/bootstrap/')) return 'bootstrap';
|
|
// shpjs (+ its jszip dependency) — dynamically imported at runtime,
|
|
// so this chunk is only fetched when the user imports a shapefile.
|
|
if (id.includes('node_modules/shpjs/') || id.includes('node_modules/jszip/')) return 'shpjs';
|
|
if (id.includes('node_modules/jspdf')) return 'jspdf';
|
|
},
|
|
},
|
|
},
|
|
},
|
|
|
|
// Worker configuration
|
|
worker: {
|
|
format: 'es',
|
|
},
|
|
|
|
// Dependency optimization
|
|
optimizeDeps: {
|
|
exclude: ['sqlocal'],
|
|
},
|
|
});
|