initial
This commit is contained in:
151
readme.hints.md
Normal file
151
readme.hints.md
Normal file
@@ -0,0 +1,151 @@
|
||||
# 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
|
||||
```typescript
|
||||
// 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
|
||||
Reference in New Issue
Block a user