### Clone Repository and Install Dependencies Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/CONTRIBUTING.md Clone the repository and install project dependencies using pnpm. ```shell git clone git@github.com:watergis/maplibre-gl-terradraw.git cd maplibre-gl-terradraw pnpm i ``` -------------------------------- ### Install Lefthook Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/CONTRIBUTING.md Install the lefthook Git hooks manager after cloning the repository. ```shell pnpm lefthook install ``` -------------------------------- ### Install Playwright Browsers Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/CONTRIBUTING.md Install Playwright browser binaries and dependencies for running tests. ```shell pnpm exec playwright install --with-deps ``` -------------------------------- ### Run Development Server Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/CONTRIBUTING.md Start the local development server to run the project. ```shell pnpm dev ``` -------------------------------- ### Complete MapLibre Valhalla Control Example Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/_autodocs/maplibre-valhalla-control.md A full example demonstrating the initialization and usage of the MaplibreValhallaControl. This includes setting up the map, configuring Valhalla options for routing and isochrones, adding the control to the map, listening for events, and modifying control settings. ```typescript import { MaplibreValhallaControl } from '@watergis/maplibre-gl-terradraw'; import maplibregl from 'maplibre-gl'; const map = new maplibregl.Map({ container: 'map', style: 'https://demotiles.maplibre.org/style.json', center: [-74.5, 40], zoom: 9 }); const valhallaControl = new MaplibreValhallaControl({ modes: ['routing', 'time-isochrone', 'distance-isochrone', 'select'], open: true, valhallaOptions: { url: 'http://valhalla.openstreetmap.de', routingOptions: { costingModel: 'auto', distanceUnit: 'kilometers' }, isochroneOptions: { timeCostingModel: 'auto', distanceCostingModel: 'auto', contours: [ { time: 5, distance: 1, color: '#FF0000' }, { time: 10, distance: 2, color: '#00FF00' }, { time: 15, distance: 3, color: '#0000FF' } ] } } }); map.addControl(valhallaControl, 'top-right'); // Listen for routing changes const terradraw = valhallaControl.getTerraDrawInstance(); terradraw?.on('finish', (id) => { const feature = terradraw.getSnapshotFeature(id); if (feature.properties.mode === 'routing') { console.log('Route calculated:'); console.log('Distance:', feature.properties.distance, feature.properties.distanceUnit); console.log('Time:', feature.properties.time, 'minutes'); } }); // Change routing settings valhallaControl.routingCostingModel = 'bicycle'; valhallaControl.routingDistanceUnit = 'miles'; // Modify isochrone settings valhallaControl.timeIsochroneCostingModel = 'pedestrian'; valhallaControl.isochroneContours = [ { time: 5, distance: 1, color: '#FFAAAA' }, { time: 10, distance: 2, color: '#FFFF99' }, { time: 15, distance: 3, color: '#AAFFAA' }, { time: 20, distance: 4, color: '#AAFFFF' } ]; // Export features with routing results const allFeatures = valhallaControl.getFeatures(); console.log('Total features:', allFeatures.features.length); ``` -------------------------------- ### Install maplibre-gl-terradraw Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/README.md Install the maplibre-gl-terradraw plugin as a development dependency using npm. ```shell npm i -D @watergis/maplibre-gl-terradraw ``` -------------------------------- ### Full MapLibre GL TerraDraw Example Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/_autodocs/quick-start.md A complete application example demonstrating the integration of MapLibre Terradraw, Measure, and Valhalla controls. Includes map initialization, control setup, event handling, and feature export. ```typescript import { MaplibreTerradrawControl, MaplibreMeasureControl, MaplibreValhallaControl } from '@watergis/maplibre-gl-terradraw'; import maplibregl from 'maplibre-gl'; import 'maplibre-gl/dist/maplibre-gl.css'; import '@watergis/maplibre-gl-terradraw/dist/maplibre-gl-terradraw.css'; // Initialize map const map = new maplibregl.Map({ container: 'map', style: 'https://demotiles.maplibre.org/style.json', center: [-74.5, 40], zoom: 9 }); // Initialize controls const drawControl = new MaplibreTerradrawControl({ modes: ['point', 'linestring', 'polygon', 'select', 'delete'], open: true }); const measureControl = new MaplibreMeasureControl({ modes: ['point', 'linestring', 'polygon', 'select', 'delete'], measureUnitType: 'metric', computeElevation: false }); const valhallaControl = new MaplibreValhallaControl({ modes: ['routing', 'time-isochrone', 'distance-isochrone', 'select'], valhallaOptions: { url: 'http://valhalla.openstreetmap.de' } }); // Add controls to map map.addControl(drawControl, 'top-right'); map.addControl(measureControl, 'top-right'); map.addControl(valhallaControl, 'top-right'); // Set up event handlers drawControl.on('feature-deleted', () => { console.log('Features deleted'); }); // Export features button document.getElementById('export-btn')?.addEventListener('click', () => { const features = drawControl.getFeatures(); const dataStr = JSON.stringify(features); const link = document.createElement('a'); link.href = 'data:application/json,' + encodeURIComponent(dataStr); link.download = 'features.geojson'; link.click(); }); // Change units button document.getElementById('toggle-units')?.addEventListener('click', () => { const current = measureControl.measureUnitType; measureControl.measureUnitType = current === 'metric' ? 'imperial' : 'metric'; }); ``` -------------------------------- ### Complete Measurement Control Example Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/_autodocs/configuration.md A comprehensive example demonstrating various configuration options for the MaplibreMeasureControl, including modes, units, elevation, and adapter settings. ```typescript const measureControl = new MaplibreMeasureControl({ modes: ['point', 'linestring', 'polygon', 'select', 'delete'], open: true, showDeleteConfirmation: false, // Measurement unit configuration measureUnitType: 'metric', distancePrecision: 3, distanceUnit: undefined, // Auto-convert areaPrecision: 2, areaUnit: 'hectares', // Always show area in hectares // Elevation configuration computeElevation: true, terrainSource: { type: 'terrarium', url: 'https://s3.amazonaws.com/elevation-tiles-prod/terrarium' }, elevationCacheConfig: { enabled: true, maxSize: 2000, ttl: 7200000 // 2 hours }, // Adapter configuration adapterOptions: { prefixId: 'measure', renderBelowLayerId: 'water' } }); ``` -------------------------------- ### Install MapLibre GL TerraDraw Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/_autodocs/00-START-HERE.md Install the main library and its required peer dependencies using npm. Ensure you install maplibre-gl, terra-draw, and the adapter for maplibre-gl integration. ```bash npm install @watergis/maplibre-gl-terradraw npm install maplibre-gl terra-draw terra-draw-maplibre-gl-adapter ``` -------------------------------- ### Set Protomaps API Key Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/CONTRIBUTING.md Copy the example environment file to set up your Protomaps API key. ```shell cp .env.example .env ``` -------------------------------- ### MapLibre GL TerraDraw Control Integration Example Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/_autodocs/maplibre-terradraw-control.md A complete example demonstrating how to initialize and use the MapLibre GL TerraDraw Control, including adding it to a map, listening to events, retrieving features, and cleaning styles. ```typescript import { MaplibreTerradrawControl } from '@watergis/maplibre-gl-terradraw'; import maplibregl from 'maplibre-gl'; const map = new maplibregl.Map({ container: 'map', style: 'https://demotiles.maplibre.org/style.json', center: [-74.5, 40], zoom: 9 }); const drawControl = new MaplibreTerradrawControl({ modes: ['point', 'linestring', 'polygon', 'select', 'delete'], open: true, showDeleteConfirmation: true }); map.addControl(drawControl, 'top-right'); // Listen to events drawControl.on('mode-changed', (args) => { console.log('Mode changed to:', args.mode); }); drawControl.on('feature-deleted', (args) => { console.log('Features deleted:', args.deletedIds); }); // Get features when needed const features = drawControl.getFeatures(); console.log('Total features:', features.features.length); // Export style without TerraDraw elements const cleanedStyle = drawControl.cleanStyle(map.getStyle(), { excludeTerraDrawLayers: true }); ``` -------------------------------- ### Example ModeOptions Configuration Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/_autodocs/types.md Illustrates how to configure different TerraDraw modes, such as 'select' and 'polygon', with their respective options. ```typescript const modeOptions: ModeOptions = { select: { flags: { allowDelete: true, allowRotate: true, allowScale: true } }, polygon: { snapToGrid: true, snappingPrecision: 0.5 } }; ``` -------------------------------- ### Complete MapLibre Measure Control Example Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/_autodocs/maplibre-measure-control.md A comprehensive example demonstrating the integration and customization of the MapLibre Measure Control with MapLibre GL JS, including terrain support, event handling, and unit/symbol customization. ```typescript import { MaplibreMeasureControl } from '@watergis/maplibre-gl-terradraw'; import maplibregl from 'maplibre-gl'; const map = new maplibregl.Map({ container: 'map', style: 'https://demotiles.maplibre.org/style.json', center: [-74.5, 40], zoom: 9 }); // Add terrain for elevation support map.addSource('terrarium', { type: 'raster-dem', attribution: '© Tilezen Joerd', tiles: ['https://s3.amazonaws.com/elevation-tiles-prod/terrarium/{z}/{x}/{y}.png'], minzoom: 0, maxzoom: 5, tileSize: 256, encoding: 'terrarium' }); map.setTerrain({ source: 'terrarium', exaggeration: 1 }); const measureControl = new MaplibreMeasureControl({ modes: ['point', 'linestring', 'polygon', 'select', 'delete'], measureUnitType: 'metric', distancePrecision: 2, areaPrecision: 2, computeElevation: true, terrainSource: { type: 'terrarium', url: 'https://s3.amazonaws.com/elevation-tiles-prod/terrarium' } }); map.addControl(measureControl, 'top-right'); // Get measured features const terradraw = measureControl.getTerraDrawInstance(); terradraw?.on('finish', (id) => { const feature = terradraw.getSnapshotFeature(id); console.log('Measured feature:', feature); console.log('Properties:', feature.properties); }); // Change units dynamically measureControl.measureUnitType = 'imperial'; measureControl.distanceUnit = 'mile'; // Customize symbols measureControl.measureUnitSymbols = { 'meter': 'm', 'kilometer': 'km', 'foot': 'ft', 'mile': 'mi', 'square meters': 'm²', 'hectares': 'ha', 'acres': 'ac' }; ``` -------------------------------- ### Complete MaplibreMeasureControl Configuration Example Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/_autodocs/constants.md Demonstrates building a custom MaplibreMeasureControl configuration by merging defaults with custom options for modes, units, and terrain. ```typescript import { MaplibreMeasureControl, defaultMeasureControlOptions, defaultMeasureUnitSymbols, AvailableModes, terrainSources, getDefaultModeOptions } from '@watergis/maplibre-gl-terradraw'; // Build custom configuration from defaults const modeOptions = getDefaultModeOptions(); modeOptions['select'].flags = { allowDelete: true, allowRotate: true }; const customSymbols = { ...defaultMeasureUnitSymbols, 'meter': 'm', 'hectares': 'ha' }; const control = new MaplibreMeasureControl({ ...defaultMeasureControlOptions, modes: [ AvailableModes.POINT, AvailableModes.LINESTRING, AvailableModes.POLYGON, AvailableModes.SELECT, AvailableModes.DELETE ], measureUnitType: 'metric', measureUnitSymbols: customSymbols, computeElevation: true, terrainSource: terrainSources['awsTerrarium'], modeOptions }); map.addControl(control, 'top-right'); ``` -------------------------------- ### Install MapLibre GL TerraDraw Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/_autodocs/README.md Installs the MapLibre GL TerraDraw package and its required peer dependencies using npm. ```bash npm install @watergis/maplibre-gl-terradraw # Required peer dependencies npm install maplibre-gl terra-draw terra-draw-maplibre-gl-adapter ``` -------------------------------- ### Generate Authors List Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/CONTRIBUTING.md Update the list of authors, typically after adding a new example page. ```shell pnpm generate:authors ``` -------------------------------- ### Instantiate MaplibreTerradrawControl Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/_autodocs/maplibre-terradraw-control.md Example of creating a new MaplibreTerradrawControl instance with custom modes and initial state, then adding it to a MapLibre map. ```typescript const control = new MaplibreTerradrawControl({ modes: ['point', 'linestring', 'polygon', 'rectangle', 'circle', 'select'], open: false, showDeleteConfirmation: true }); map.addControl(control, 'top-right'); ``` -------------------------------- ### Initialize MapLibre GL JS with TerraDraw Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/src/app.html This snippet demonstrates the basic setup for initializing a MapLibre GL JS map and integrating TerraDraw. Ensure you have the necessary MapLibre GL JS and TerraDraw libraries included in your project. ```javascript (function () { try { var stored = localStorage.getItem('light-dark-mode'); var prefersDark; if (stored) { prefersDark = stored === 'dark'; } else { prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; localStorage.setItem('light-dark-mode', prefersDark ? 'dark' : 'light'); } document.documentElement.setAttribute('data-mode', prefersDark ? 'dark' : 'light'); } catch (e) { var fallback = window.matchMedia('(prefers-color-scheme: dark)').matches; document.documentElement.setAttribute('data-mode', fallback ? 'dark' : 'light'); } })(); ``` -------------------------------- ### activate Method Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/_autodocs/maplibre-terradraw-control.md Activates TerraDraw, enabling the drawing functionality on the map. If TerraDraw is not yet initialized, it will be started. ```APIDOC ## activate Method ```typescript public activate(): void ``` ### Description Initiates or resumes the drawing capabilities provided by TerraDraw. This method should be called when you want to allow users to start drawing or editing features. ### Returns - **void** ``` -------------------------------- ### Initialize MapLibre GL JS Map and Add Terra Draw Control Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/static/assets/maplibre-npm-example.txt This snippet shows the basic setup for a MapLibre GL JS map and how to add the MaplibreTerradrawControl. It includes options for enabling/disabling drawing modes and other control configurations. ```javascript import { Map } from 'maplibre-gl'; import 'maplibre-gl/dist/maplibre-gl.css'; import { MaplibreTerradrawControl } from '@watergis/maplibre-gl-terradraw' import '@watergis/maplibre-gl-terradraw/dist/maplibre-gl-terradraw.css' const map = new Map({ container: 'map', style: '{style}', center: [0, 0], zoom: 1, }); // As default, all Terra Draw modes are enabled, // you can disable options if you don't want to use them. const draw = new MaplibreTerradrawControl({ modes: [{modes}], open: {open}, showDeleteConfirmation: {showDeleteConfirmation}, {control_options} }); map.addControl(draw, 'top-left'); ``` -------------------------------- ### Configure Custom Undo/Redo in Terradraw Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/static/assets/examples/custom-undo-redo-config.htm Configure undo/redo support by passing the `undoRedo` option. Set stack sizes for `modeLevel` and `sessionLevel`. Be mindful of OS/browser-reserved shortcuts and avoid conflicting combinations. Refer to the official TerraDraw guide for details on undo/redo events and configuration. ```javascript const map = new maplibregl.Map({ container: 'map', style: 'https://demotiles.maplibre.org/style.json', center: [0, 0], zoom: 1, maxPitch: 85 }); const drawControl = new MaplibreTerradrawControl.MaplibreTerradrawControl({ modes: ['point', 'linestring', 'polygon', 'select', 'delete', 'undo', 'redo'], open: true, /** * • Configure undo/redo support by passing the `undoRedo` option. * • Set stack sizes: - `modeLevel` stack size -> 10 (for in-progress drawing actions) - `sessionLevel` stack size -> 30 (for committed features) * • Be mindful of OS/browser-reserved shortcuts: - Native shortcuts (e.g. ⌘+Z / Ctrl+Z) cannot be overridden reliably in all environments. - Avoid assigning conflicting combinations that may not trigger consistently. - If needed, provide alternative shortcuts or allow user customization. * • Refer to the official TerraDraw guide for details on undo/redo events and configuration: https://github.com/JamesLMilner/terra-draw/blob/main/guides/6.EVENTS.md#undoredo */ undoRedo: { modeLevel: new terraDraw.TerraDrawModeUndoRedo({ maxStackSize: 40 }), sessionLevel: new terraDraw.TerraDrawSessionUndoRedo({ maxStackSize: 30 }), keyboardShortcuts: new terraDraw.TerraDrawUndoRedoKeyboardShortcuts({ undo: [ { key: 'z', heldKeys: ['meta', 'control'] // meta = command key in MacOS } ], redo: [ { key: 'z', heldKeys: ['shift'] } ] }) } }); map.addControl(drawControl, 'top-left'); ``` -------------------------------- ### Build Project Packages and Documentation Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/CONTRIBUTING.md Build all packages and documentation for the project. ```shell pnpm build ``` -------------------------------- ### Activate and Deactivate Drawing Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/_autodocs/maplibre-terradraw-control.md Code examples for activating and deactivating the TerraDraw drawing functionality through the MaplibreTerradrawControl. Activation starts drawing, while deactivation stops it and cleans up resources. ```typescript control.activate(); ``` ```typescript control.deactivate(); ``` -------------------------------- ### Get GeoJSON Features from TerraDraw Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/_autodocs/maplibre-terradraw-control.md Retrieves GeoJSON features from TerraDraw. Use `onlySelected: true` to get only the currently selected features. ```typescript const allFeatures = control.getFeatures(); const selectedFeatures = control.getFeatures(true); console.log(allFeatures); // Output: // { // type: 'FeatureCollection', // features: [...] // } ``` -------------------------------- ### Initialize MapLibre GL JS Map Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/static/assets/maplibre-cdn-example.txt Sets up a MapLibre GL JS map instance. Ensure the map container and style URL are correctly specified. ```javascript const map = new maplibregl.Map({ container: 'map', style: 'https://demotiles.maplibre.org/style.json', center: [0, 0], zoom: 1 }); ``` -------------------------------- ### Generate Typedoc Documentation Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/CONTRIBUTING.md Generate typedoc documentation files. Use 'pnpm typedoc:serve' to open the documentation on port 3000. ```shell pnpm typedoc ``` ```shell pnpm typedoc:serve ``` -------------------------------- ### Update Dependency Graph Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/CONTRIBUTING.md Update the dependency graph by running the depcruise command. Requires Graphviz to be installed. ```shell pnpm depcruise ``` -------------------------------- ### showDeleteConfirmation Property Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/_autodocs/maplibre-terradraw-control.md Get or set whether a confirmation popup should be displayed before deleting features. Defaults to false. ```APIDOC ## showDeleteConfirmation Property ```typescript get showDeleteConfirmation(): boolean set showDeleteConfirmation(value: boolean) ``` ### Description Determines whether a confirmation dialog appears when a user attempts to delete a feature. The default value is `false`. ### Usage ```typescript // Enable delete confirmation control.showDeleteConfirmation = true; // Disable delete confirmation control.showDeleteConfirmation = false; ``` ``` -------------------------------- ### Initialize MaplibreValhallaControl Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/_autodocs/README.md Instantiate the routing and isochrone control, extending MaplibreTerradrawControl, with Valhalla API options. Add the control to the map. ```typescript import { MaplibreValhallaControl } from '@watergis/maplibre-gl-terradraw'; const control = new MaplibreValhallaControl({ modes: ['routing', 'time-isochrone', 'distance-isochrone'], valhallaOptions: { url: 'http://valhalla.openstreetmap.de' } }); map.addControl(control, 'top-right'); ``` -------------------------------- ### Constructor Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/_autodocs/maplibre-terradraw-control.md Initializes a new instance of MaplibreTerradrawControl. It accepts an optional options object to configure the drawing modes and behavior. ```APIDOC ## Constructor ```typescript constructor(options?: TerradrawControlOptions) ``` ### Parameters #### Options - **options** (TerradrawControlOptions) - Optional - Configuration options for the control. This can include specifying drawing modes, initial visibility, and delete confirmation behavior. ### Example ```typescript const control = new MaplibreTerradrawControl({ modes: ['point', 'linestring', 'polygon', 'rectangle', 'circle', 'select'], open: false, showDeleteConfirmation: true }); map.addControl(control, 'top-right'); ``` ``` -------------------------------- ### Initialize MapLibre GL Map and TerraDraw Control Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/static/assets/examples/coordinate-precision.htm Sets up a MapLibre GL map and adds a TerraDraw control. The adapterOptions allow for customization, such as setting the coordinate precision. ```javascript const map = new maplibregl.Map({ container: 'map', style: 'https://demotiles.maplibre.org/style.json', center: [0, 0], zoom: 1, maxPitch: 85 }); const drawControl = new MaplibreTerradrawControl.MaplibreTerradrawControl({ modes: ['point', 'linestring', 'polygon', 'select', 'delete'], open: true, adapterOptions: { // change coordinate precision to 6 digits instead of 9 coordinatePrecision: 6 } }); map.addControl(drawControl, 'top-left'); ``` -------------------------------- ### Get Default Mode Options Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/_autodocs/constants.md Retrieve the default configuration for all TerraDraw modes. This function returns a ModeOptions object that can be further customized. ```typescript import { getDefaultModeOptions } from '@watergis/maplibre-gl-terradraw'; const modeOptions = getDefaultModeOptions(); // Override specific mode modeOptions['select'] = { flags: { allowDelete: true, allowRotate: true, allowScale: true } }; const control = new MaplibreTerradrawControl({ modeOptions }); ``` -------------------------------- ### Get Features with Measurements Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/_autodocs/README.md Retrieve drawn features and their associated measurements (distance, area) from the measure control. Useful for displaying measurement results to the user. ```typescript const measureControl = new MaplibreMeasureControl({ /* ... */ }); const features = measureControl.getFeatures(); features.features.forEach(f => { if (f.properties.distance !== undefined) { console.log(`Distance: ${f.properties.distance} ${f.properties.distanceUnit}`); } if (f.properties.area !== undefined) { console.log(`Area: ${f.properties.area} ${f.properties.unit}`); } }); ``` -------------------------------- ### isExpanded Property Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/_autodocs/maplibre-terradraw-control.md Get or set the expanded state of the control. Changing this state resets the TerraDraw mode and dispatches either an 'expanded' or 'collapsed' event. ```APIDOC ## isExpanded Property ```typescript get isExpanded(): boolean set isExpanded(value: boolean) ``` ### Description Retrieves or sets the current expanded state of the control. When the state is modified, the TerraDraw mode is reset, and an appropriate event ('expanded' or 'collapsed') is dispatched. ### Usage ```typescript // Get the current state const expanded = control.isExpanded; // Set the state to expanded control.isExpanded = true; ``` ``` -------------------------------- ### Run Tests Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/CONTRIBUTING.md Execute the project's test suite using Playwright. ```shell pnpm test ``` -------------------------------- ### MaplibreValhallaControl Constructor Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/_autodocs/maplibre-valhalla-control.md Initializes a new instance of the MaplibreValhallaControl. It requires Valhalla API configuration, including the URL, and can be customized with various options for routing and isochrone calculations. ```APIDOC ## MaplibreValhallaControl Constructor ### Description Initializes a new instance of the MaplibreValhallaControl. It requires Valhalla API configuration, including the URL, and can be customized with various options for routing and isochrone calculations. ### Signature ```typescript constructor(options?: ValhallaControlOptions) ``` ### Parameters #### Options - **options** (ValhallaControlOptions) - Optional - Configuration options for the Valhalla control. - **options.modes** (string[]) - Optional - Specifies the available modes for the control (e.g., 'routing', 'time-isochrone', 'distance-isochrone', 'select'). - **options.valhallaOptions** (object) - Required - Configuration for the Valhalla API. - **options.valhallaOptions.url** (string) - Required - The URL of the Valhalla API endpoint. ### Throws - Error if `valhallaOptions.url` is not provided. ### Example ```typescript const valhallaControl = new MaplibreValhallaControl({ modes: ['routing', 'time-isochrone', 'distance-isochrone', 'select'], valhallaOptions: { url: 'https://valhalla.example.com' } }); map.addControl(valhallaControl, 'top-right'); ``` ``` -------------------------------- ### Custom Measurement Unit Symbols Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/_autodocs/constants.md Customize measurement unit symbols by extending the default symbols. This example shows how to set Japanese symbols for metric distance. ```typescript import { defaultMeasureUnitSymbols } from '@watergis/maplibre-gl-terradraw'; const customSymbols: MeasureUnitSymbolType = { ...defaultMeasureUnitSymbols, 'meter': 'メートル', // Japanese 'kilometer': 'キロメートル' }; const control = new MaplibreMeasureControl({ measureUnitSymbols: customSymbols }); ``` -------------------------------- ### Configure MaplibreValhallaControl Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/_autodocs/configuration.md Set up the MaplibreValhallaControl with various modes and Valhalla API options. This includes defining routing and isochrone parameters, and adapter configurations. ```typescript const valhallaControl = new MaplibreValhallaControl({ modes: ['routing', 'time-isochrone', 'distance-isochrone', 'select'], open: false, // Valhalla API configuration valhallaOptions: { url: 'http://valhalla.openstreetmap.de', routingOptions: { costingModel: 'auto', distanceUnit: 'kilometers' }, isochroneOptions: { timeCostingModel: 'auto', distanceCostingModel: 'auto', contours: [ { time: 5, distance: 1, color: '#FF6B6B' }, { time: 10, distance: 2, color: '#FFA500' }, { time: 15, distance: 3, color: '#FFD700' }, { time: 20, distance: 4, color: '#90EE90' } ] } }, // Adapter configuration adapterOptions: { prefixId: 'valhalla', renderBelowLayerId: 'water' } }); map.addControl(valhallaControl, 'top-right'); // Dynamically change settings valhallaControl.routingCostingModel = 'pedestrian'; valhallaControl.routingDistanceUnit = 'miles'; valhallaControl.timeIsochroneCostingModel = 'bicycle'; ``` -------------------------------- ### Reset Active Mode Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/_autodocs/maplibre-terradraw-control.md Example of resetting the active drawing mode in MaplibreTerradrawControl back to the default render mode. This synchronizes the control's button states with the current TerraDraw mode. ```typescript control.resetActiveMode(); ``` -------------------------------- ### Interact with TerraDraw Instance via MaplibreTerradrawControl Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/_autodocs/maplibre-terradraw-control.md Shows how to retrieve the underlying TerraDraw instance from the MaplibreTerradrawControl to perform advanced operations like getting a snapshot of features or changing the drawing mode programmatically. ```typescript const terradraw = control.getTerraDrawInstance(); if (terradraw) { const features = terradraw.getSnapshot(); terradraw.setMode('select'); } ``` -------------------------------- ### Initialize MaplibreTerradrawControl Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/_autodocs/README.md Instantiate the core drawing control with specified modes and initial expansion state. Add the control to the map instance. ```typescript import { MaplibreTerradrawControl } from '@watergis/maplibre-gl-terradraw'; const control = new MaplibreTerradrawControl({ modes: ['point', 'linestring', 'polygon', 'select'], open: true }); map.addControl(control, 'top-right'); ``` -------------------------------- ### Create Release Notes with Changeset Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/CONTRIBUTING.md Generate release notes using changeset. Releases are automatically published when the PR is merged to the main branch. ```shell pnpm changeset ``` -------------------------------- ### Instantiate MaplibreTerradrawControl Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/_autodocs/configuration.md Instantiate the MaplibreTerradrawControl with custom configuration options for drawing modes, adapter settings, and mode-specific features. ```typescript const drawControl = new MaplibreTerradrawControl({ modes: ['point', 'linestring', 'polygon', 'select'], open: true, showDeleteConfirmation: true, adapterOptions: { prefixId: 'my-draw', renderBelowLayerId: 'waterways' }, modeOptions: { select: { flags: { allowDelete: true, allowRotate: true } } } }); ``` -------------------------------- ### Initialize MaplibreValhallaControl Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/_autodocs/maplibre-valhalla-control.md Instantiate MaplibreValhallaControl with custom modes and Valhalla API URL. The control is then added to the map. ```typescript const valhallaControl = new MaplibreValhallaControl({ modes: ['routing', 'time-isochrone', 'distance-isochrone', 'select'], valhallaOptions: { url: 'https://valhalla.example.com' } }); map.addControl(valhallaControl, 'top-right'); ``` -------------------------------- ### Add Drawing Control to Map Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/_autodocs/00-START-HERE.md Demonstrates how to initialize and add the MaplibreTerradrawControl to a MapLibre GL JS map. Includes basic setup for drawing points, lines, polygons, and selection modes, and shows how to retrieve features and listen for events. ```typescript import { MaplibreTerradrawControl } from '@watergis/maplibre-gl-terradraw'; import maplibregl from 'maplibre-gl'; import '@watergis/maplibre-gl-terradraw/dist/maplibre-gl-terradraw.css'; // Create map const map = new maplibregl.Map({ container: 'map', style: 'https://demotiles.maplibre.org/style.json', center: [-74.5, 40], zoom: 9 }); // Add drawing control const control = new MaplibreTerradrawControl({ modes: ['point', 'linestring', 'polygon', 'select'], open: true }); map.addControl(control, 'top-right'); // Get features const features = control.getFeatures(); console.log('Features:', features); // Listen to events control.on('feature-deleted', () => { console.log('Features deleted'); }); ``` -------------------------------- ### Format Code with Prettier Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/CONTRIBUTING.md Ensure code adheres to formatting standards by running Prettier. ```shell pnpm format ``` -------------------------------- ### Get GeoJSON Features with Routing and Isochrone Results Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/_autodocs/maplibre-valhalla-control.md Retrieves GeoJSON features that include routing and isochrone computation results. This method combines base TerraDraw features with Valhalla-generated data. Use the `onlySelected` parameter to filter for only selected features. ```typescript public getFeatures(onlySelected?: boolean): FeatureCollection ``` ```typescript const features = valhallaControl.getFeatures(); features.features.forEach(feature => { if (feature.properties.mode === 'routing') { console.log('Route distance:', feature.properties.distance); } else if (feature.properties.mode === 'time-isochrone') { console.log('Time contour:', feature.properties.contour, 'minutes'); } }); ``` -------------------------------- ### Helper Functions - Routing and Isochrone Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/_autodocs/README.md Functions for interacting with Valhalla for route calculation and isochrone generation. ```APIDOC ## Helper Functions - Routing and Isochrone ### `ValhallaRouting.calcRoute(coordinates, costingModel, distanceUnit)` Calculate a route between specified coordinates using Valhalla. ### `ValhallaIsochrone.calcIsochrone(lng, lat, contourType, costingModel, contours)` Calculate an isochrone area from a given point using Valhalla. ``` -------------------------------- ### Initialize Map and Add Controls Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/static/assets/examples/use-both-control.htm Initializes a MapLibre GL map and adds both the standard drawing control and the measure control to specified positions. The standard control is for drawing, and the measure control is for measurements. ```javascript const map = new maplibregl.Map({ container: 'map', style: 'https://demotiles.maplibre.org/style.json', center: [0, 0], zoom: 1, maxPitch: 85 }); // add Default Control to the top-left corner of the map // standard control will add layers with prefix of 'td' const drawControl = new MaplibreTerradrawControl.MaplibreTerradrawControl({ open: true }); map.addControl(drawControl, 'top-left'); // add MeasureControl to the top-right corner of the map // measure control will add layers with prefix of 'td-measure' const measureControl = new MaplibreTerradrawControl.MaplibreMeasureControl({ open: true, computeElevation: true }); map.addControl(measureControl, 'top-right'); ``` -------------------------------- ### Initialize MaplibreMeasureControl Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/_autodocs/maplibre-measure-control.md Instantiate the MaplibreMeasureControl with custom options and add it to the map. This control enables measurement functionalities like drawing points, lines, and polygons. ```typescript const measureControl = new MaplibreMeasureControl({ modes: ['point', 'linestring', 'polygon', 'select', 'delete'], measureUnitType: 'metric', distancePrecision: 2, areaPrecision: 2, computeElevation: false }); map.addControl(measureControl, 'top-right'); ``` -------------------------------- ### Initialize Map and Terra Draw Control Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/static/assets/examples/programmatic-mode-control.htm Initializes a MapLibre GL map and adds the Terra Draw control with a specified set of modes. The 'open: true' option ensures the control is visible on load. ```javascript const map = new maplibregl.Map({ container: 'map', style: 'https://demotiles.maplibre.org/style.json', center: [0, 0], zoom: 1, maxPitch: 85 }); // Initialize Terra Draw control with various modes const drawControl = new MaplibreTerradrawControl.MaplibreTerradrawControl({ modes: [ 'render', 'point', 'linestring', 'polygon', 'rectangle', 'circle', 'select', 'delete', 'download' ], open: true }); map.addControl(drawControl, 'top-left'); ``` -------------------------------- ### Initialize Map and Drawing Control with Custom Options Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/static/assets/examples/drawing-option.htm Initializes a MapLibre GL map and a terradraw control, restricting available modes to 'polygon', 'select', and 'delete'. It also customizes the 'select' mode to disable feature dragging and rotation, while enabling scaling and coordinate manipulation. ```javascript const map = new maplibregl.Map({ container: 'map', style: 'https://demotiles.maplibre.org/style.json', center: [0, 0], zoom: 1, maxPitch: 85 }); const drawControl = new MaplibreTerradrawControl.MaplibreTerradrawControl({ // only show polgyon, select, delete mode. modes: ['polygon', 'select', 'delete'], open: true, modeOptions: { select: new terraDraw.TerraDrawSelectMode({ flags: { polygon: { feature: { draggable: false, rotateable: true, scaleable: true, coordinates: { midpoints: false, draggable: true, deletable: false } } } } }) } }); map.addControl(drawControl, 'top-left'); ``` -------------------------------- ### Helper Functions - Utilities Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/_autodocs/README.md General utility functions for string manipulation, debouncing, coordinate rounding, and more. ```APIDOC ## Helper Functions - Utilities ### `capitalize(str)` Capitalizes the first letter of a string. ### `debounce(func, wait)` Debounces a function, delaying its execution until a certain amount of time has passed without it being called. ### `roundFeatureCoordinates(feature, precision)` Rounds the coordinates of a GeoJSON feature to a specified precision. ### `cleanMaplibreStyle(style, options, sourceIds, prefixId)` Filters and cleans a MapLibre GL style object. ### `MemoryCache(maxSize, ttl)` An in-memory cache implementation with a maximum size and time-to-live (TTL) for entries. ``` -------------------------------- ### ValhallaControlOptions Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/_autodocs/types.md Configuration options for the MaplibreValhallaControl constructor. Extends TerradrawControlOptions and includes specific settings for Valhalla routing and isochrone layers, as well as Valhalla API configuration. ```APIDOC ## ValhallaControlOptions ### Description Configuration options for the MaplibreValhallaControl constructor. Extends TerradrawControlOptions and includes specific settings for Valhalla routing and isochrone layers, as well as Valhalla API configuration. ### Fields - **routingLineLayerNodeLabelSpec** (SymbolLayerSpecification) - Optional - Custom symbol layer for routing line node labels. - **routingLineLayerNodeSpec** (CircleLayerSpecification) - Optional - Custom circle layer for routing line nodes. - **timeIsochronePolygonLayerSpec** (FillLayerSpecification) - Optional - Custom fill layer for time isochrone polygons. - **timeIsochroneLineLayerSpec** (LineLayerSpecification) - Optional - Custom line layer for time isochrone lines. - **timeIsochroneLabelLayerSpec** (SymbolLayerSpecification) - Optional - Custom symbol layer for time isochrone labels. - **distanceIsochronePolygonLayerSpec** (FillLayerSpecification) - Optional - Custom fill layer for distance isochrone polygons. - **distanceIsochroneLineLayerSpec** (LineLayerSpecification) - Optional - Custom line layer for distance isochrone lines. - **distanceIsochroneLabelLayerSpec** (SymbolLayerSpecification) - Optional - Custom symbol layer for distance isochrone labels. - **valhallaOptions** (ValhallaOptions) - Optional - Valhalla API configuration. ### Source `src/lib/interfaces/ValhallaControlOptions.ts` ``` -------------------------------- ### on Method Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/_autodocs/maplibre-terradraw-control.md Registers an event listener to respond to events emitted by the control. Supports custom callbacks for various drawing events. ```APIDOC ## on Method ```typescript public on(event: EventType, callback: (event: EventArgs) => void): void ``` ### Description Allows you to subscribe to events triggered by the `MaplibreTerradrawControl`. This is useful for reacting to changes in drawing modes, feature selections, or feature modifications. ### Parameters #### event - **event** (EventType) - Required - The type of event to listen for (e.g., 'mode-changed', 'feature-deleted'). #### callback - **callback** ((event: EventArgs) => void) - Required - The function to execute when the specified event is triggered. The callback receives an `EventArgs` object containing event-specific data. ### Returns - **void** ### Example ```typescript control.on('mode-changed', (args) => { console.log('Current mode:', args.mode); console.log('Selected features:', args.feature); }); control.on('feature-deleted', (args) => { console.log('Deleted feature IDs:', args.deletedIds); }); ``` ``` -------------------------------- ### Valhalla Costing Model Options Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/_autodocs/constants.md Available costing models for the Valhalla API. Use these to specify routing preferences. ```typescript const costingModelOptions: Array<{ value: costingModelType, label: string }> ``` ```typescript [ { value: 'auto', label: 'Auto' }, { value: 'pedestrian', label: 'Pedestrian' }, { value: 'bicycle', label: 'Bicycle' } ] ``` -------------------------------- ### Initialize Map with Terrain Source and Terradraw Control Source: https://github.com/watergis/maplibre-gl-terradraw/blob/main/static/assets/examples/query-elevation-terrain.htm Sets up the MapLibre GL map with a terrain source and adds the terradraw control with elevation computation enabled. Ensure the 'rwanda-dem' source is correctly configured and accessible. ```javascript const map = new maplibregl.Map({ container: 'map', style: { version: 8, name: 'Rwanda DEM', sources: { bing: { type: 'raster', tiles: [ 'https://ecn.t0.tiles.virtualearth.net/tiles/a{quadkey}.jpeg?g=1', 'https://ecn.t1.tiles.virtualearth.net/tiles/a{quadkey}.jpeg?g=1', 'https://ecn.t2.tiles.virtualearth.net/tiles/a{quadkey}.jpeg?g=1', 'https://ecn.t3.tiles.virtualearth.net/tiles/a{quadkey}.jpeg?g=1', 'https://ecn.t4.tiles.virtualearth.net/tiles/a{quadkey}.jpeg?g=1', 'https://ecn.t5.tiles.virtualearth.net/tiles/a{quadkey}.jpeg?g=1', 'https://ecn.t6.tiles.virtualearth.net/tiles/a{quadkey}.jpeg?g=1', 'https://ecn.t7.tiles.virtualearth.net/tiles/a{quadkey}.jpeg?g=1' ], maxzoom: 18, attribution: 'Map tiles by Microsoft, under Microsoft Bing Maps Platform Terms Of Use' }, 'rwanda-dem': { type: 'raster-dem', attribution: "©WASAC,Ltd.", tiles: ['https://wasac.github.io/rw-terrain-webp/tiles/{z}/{x}/{y}.webp'], tileSize: 512, minzoom: 5, maxzoom: 15, bounds: [28.86, -2.84, 30.9, -1.05] } }, terrain: { source: 'rwanda-dem', exaggeration: 1 }, glyphs: 'https://demotiles.maplibre.org/font/{fontstack}/{range}.pbf', layers: [ { id: 'bingaerial', type: 'raster', source: 'bing', minzoom: 0, layout: { visibility: 'visible' } }, { id: 'hillshade', type: 'hillshade', source: 'rwanda-dem', paint: { 'hillshade-shadow-color': 'hsl(39, 21%, 33%)', 'hillshade-illumination-direction': 315, 'hillshade-exaggeration': 1 } } ] }, center: [29.915923665876335, -2.00623424231469], zoom: 8, maxPitch: 85 }); const drawControl = new MaplibreTerradrawControl.MaplibreMeasureControl({ modes: ['point', 'linestring', 'delete', 'download'], open: true, computeElevation: true, terrainSource: undefined }); map.addControl(drawControl, 'top-left'); map.addControl( new maplibregl.NavigationControl({ visualizePitch: true, showCompass: true }), 'bottom-right' ); map.addControl(new maplibregl.GlobeControl(), 'bottom-right'); map.addControl(new maplibregl.TerrainControl({ source: 'rwanda-dem' }), 'bottom-right'); ```