Files
dees-catalog-geo/readme.hints.md
2026-02-05 12:03:22 +00:00

6.5 KiB

Project Hints - dees-catalog-geo

Overview

Geospatial web components library using MapLibre GL JS for map rendering and terra-draw for drawing capabilities.

Key Dependencies

  • maplibre-gl (v5.x): WebGL-based vector map library
  • terra-draw (v1.24.0): Modern drawing library with support for multiple map libraries
  • terra-draw-maplibre-gl-adapter (v1.x): Adapter connecting terra-draw with MapLibre

Component: dees-geo-map

Properties

Property Type Default Description
center [number, number] [0, 0] Map center as [lng, lat]
zoom number 2 Initial zoom level
mapStyle string 'osm' Map style ('osm' or custom URL)
activeTool TDrawTool 'static' Active drawing tool
geoJson GeoJSON.FeatureCollection {...} Initial features
showToolbar boolean true Show/hide drawing toolbar
projection 'mercator' | 'globe' 'mercator' Map projection type
showSearch boolean false Show address search input
showNavigation boolean false Show A-to-B navigation panel
navigationMode 'driving' | 'walking' | 'cycling' 'driving' Transport mode for routing

Drawing Tools (TDrawTool)

  • point - Draw points
  • linestring - Draw lines
  • polygon - Draw polygons
  • rectangle - Draw rectangles
  • circle - Draw circles
  • freehand - Freehand drawing
  • select - Select and edit features
  • static - Pan/zoom only (no drawing)

Events

  • map-ready - Fired when map is initialized
  • map-move - Fired on pan/zoom with center and zoom
  • draw-change - Fired on any feature change
  • draw-finish - Fired when a shape is completed
  • address-selected - Fired when a search result is selected
  • route-calculated - Fired when a navigation route is calculated (includes route, startPoint, endPoint, mode)

Public Methods

  • getFeatures() - Get all drawn features
  • getGeoJson() - Get features as FeatureCollection
  • loadGeoJson(geojson) - Load features from GeoJSON
  • clearAllFeatures() - Remove all features
  • setTool(tool) - Set active drawing tool
  • flyTo(center, zoom?) - Animate to location
  • fitToFeatures(padding?) - Fit view to all features
  • setProjection(projection) - Set map projection ('mercator' or 'globe')
  • getMap() - Get underlying MapLibre instance
  • getTerraDraw() - Get TerraDraw instance
  • calculateRoute() - Calculate route between start and end points
  • setNavigationStart(coords, address?) - Set navigation start point
  • setNavigationEnd(coords, address?) - Set navigation end point
  • clearNavigation() - Clear all navigation state

Context Menu

Right-click on the map to access a context menu with the following options:

  • Drag to Draw - Toggle between drag mode (click-drag for circles/rectangles) and two-click mode
  • Globe View - Toggle between globe (3D sphere) and Mercator (flat) projection
  • Clear All Features - Remove all drawn features from the map
  • Fit to Features - Zoom and pan to show all drawn features

Navigation Feature

The navigation panel (showNavigation={true}) provides A-to-B routing using OSRM (Open Source Routing Machine):

  • Transport modes: Driving, Walking, Cycling
  • Point selection: Type an address or click on the map
  • Route display: Blue line overlay with turn-by-turn directions
  • API: Uses free OSRM API (https://router.project-osrm.org) with fair-use rate limit

Development

  • pnpm install - Install dependencies
  • pnpm watch - Start development server (port 3002)
  • pnpm build - Build for production

File Structure

ts_web/
├── index.ts                           # Main exports
├── 00_commitinfo_data.ts              # Auto-generated
└── elements/
    ├── index.ts                       # Elements barrel
    ├── 00colors.ts                    # Color definitions
    ├── 00componentstyles.ts           # Shared styles
    └── 00group-map/
        ├── index.ts
        └── dees-geo-map/
            ├── index.ts               # Exports main + modules
            ├── dees-geo-map.ts        # Main component (~550 lines)
            ├── dees-geo-map.demo.ts   # Demo function
            ├── geo-map.icons.ts       # Icon SVG definitions (~60 lines)
            ├── geo-map.search.ts      # SearchController class (~180 lines)
            └── geo-map.navigation.ts  # NavigationController class (~530 lines)

Modular Architecture

The component was refactored for better maintainability:

geo-map.icons.ts

Contains all SVG icon definitions as a GEO_MAP_ICONS record and a renderIcon(name) helper function.

geo-map.search.ts

SearchController class encapsulating Nominatim geocoding search:

  • Reusable for standalone search or within navigation
  • Debounced API calls
  • Keyboard navigation support
  • Customizable via ISearchControllerConfig

geo-map.navigation.ts

NavigationController class for A-to-B routing:

  • OSRM routing API integration
  • Start/end point management with markers
  • Map click mode for point selection
  • Turn-by-turn directions rendering
  • Route overlay on map

Usage of Controllers

// SearchController is reusable
const search = new SearchController(
  { placeholder: 'Search...' },
  {
    onResultSelected: (result, coords, zoom) => { /* handle */ },
    onRequestUpdate: () => this.requestUpdate(),
  }
);

// NavigationController manages all navigation state
const nav = new NavigationController({
  onRouteCalculated: (event) => { /* dispatch */ },
  onRequestUpdate: () => this.requestUpdate(),
  getMap: () => this.map,
});

Notes

  • MapLibre CSS is loaded dynamically from CDN
  • Terra-draw requires the separate maplibre-gl-adapter package
  • The component uses Shadow DOM for style encapsulation

Shadow DOM & Terra-Draw Drawing Fix

Terra-draw's event listeners normally intercept map events through MapLibre's canvas element. In Shadow DOM contexts, these events are scoped locally and don't propagate correctly, causing terra-draw handlers to fail while MapLibre's drag handlers continue working.

Solution: Manual drag coordination in setTool():

  • When a drawing tool is active (polygon, rectangle, point, linestring, circle, freehand), MapLibre's dragPan and dragRotate are disabled
  • When static or select mode is active, dragging is re-enabled
  • The TerraDrawMapLibreGLAdapter does NOT accept a lib parameter - only map is required