@2gis/mapgl-terra-draw
v0.4.0
Published
TerraDraw adapter for MapGL JS API
Readme
MapGL TerraDraw Adapter
TerraDraw adapter for MapGL JS API or just a simple drawing tool.

Getting started
Install library
npm install @2gis/mapgl-terra-drawUse ui-helper createTerraDrawWithUI and not forget to plug css:
import { load } from '@2gis/mapgl';
import { createTerraDrawWithUI } from '@2gis/mapgl-terra-draw';
import '@2gis/mapgl-terra-draw/dist/mapgl-terra-draw.css';
load().then((mapgl) => {
const map = new mapgl.Map('map', {
center: [55.31878, 25.23584],
zoom: 13,
key: 'Your MapGL JS API key',
enableTrackResize: true,
});
map.on('styleload', () => {
createTerraDrawWithUI({
map,
mapgl: mapgl as any,
controls: ['color', 'select', 'point', 'polygon', 'circle', 'download', 'clear'],
});
});
});Or directly in HTML via unpkg CDN
<html>
<head>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined" />
<link rel="stylesheet" type="text/css" href="https://unpkg.com/@2gis/[email protected]/dist/mapgl-terra-draw.css" />
<script src="https://mapgl.2gis.com/api/js/v1"></script>
<script src="https://unpkg.com/[email protected]/dist/terra-draw.umd.js"></script>
<script src="https://unpkg.com/@2gis/mapgl-terra-draw/dist/mapgl-terra-draw.umd.cjs"></script>
<style>
html,
body,
#container {
margin: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
</style>
</head>
<body>
<div id="container"></div>
<script>
const map = new mapgl.Map('container', {
center: [55.31878, 25.23584],
zoom: 13,
key: 'bfd8bbca-8abf-11ea-b033-5fa57aae2de7',
enableTrackResize: true,
});
map.on('styleload', () => {
mapglTerraDraw.createTerraDrawWithUI({
map,
mapgl: mapgl,
controls: ['color', 'select', 'point', 'polygon', 'circle', 'download', 'clear'],
});
});
</script>
</body>
</html>Advanced usage
If advanced cases (use your custom drawing mode, customize a very flexible TerraDraw selection behaviour, design a fancy UI, e.g.) you can use TerraDrawMapGlAdapter class directly.
This gives you much more flexibility, but puts a some bunch of work on your side. Here is a simple example:
import { load } from '@2gis/mapgl';
import {
TerraDraw,
TerraDrawPointMode,
TerraDrawPolygonMode,
TerraDrawSelectMode,
} from 'terra-draw';
import { TerraDrawMapGlAdapter } from '@2gis/mapgl-terra-draw';
load().then((mapgl) => {
const map = new mapgl.Map('map', {
center: [55.31878, 25.23584],
zoom: 13,
key: 'Your MapGL JS API key',
enableTrackResize: true,
});
map.on('styleload', () => {
const draw = new TerraDraw({
adapter: new TerraDrawMapGlAdapter({
map,
mapgl,
coordinatePrecision: 9,
}),
modes: [
new TerraDrawSelectMode(),
new TerraDrawPointMode(),
new TerraDrawPolygonMode(),
],
});
const buttons = document.createElement('div');
buttons.style.display = 'flex';
buttons.style.flexDirection = 'column';
buttons.style.gap = '8px';
new mapgl.Control(map, buttons, { position: 'centerLeft' });
const selectButton = document.createElement('button');
selectButton.innerText = 'select';
selectButton.addEventListener('click', () => {
draw.setMode('select');
});
buttons.appendChild(selectButton);
const pointButton = document.createElement('button');
pointButton.innerText = 'point';
pointButton.addEventListener('click', () => {
draw.setMode('point');
});
buttons.appendChild(pointButton);
const polygonButton = document.createElement('button');
polygonButton.innerText = 'polygon';
polygonButton.addEventListener('click', () => {
draw.setMode('polygon');
});
buttons.appendChild(polygonButton);
const clearButton = document.createElement('button');
clearButton.innerText = 'clear';
clearButton.addEventListener('click', () => {
draw.clear();
});
buttons.appendChild(clearButton);
draw.start();
});
});How to get a drawed data
To get drawing data with styling use this code snippet:
const adapter = new TerraDrawMapGlAdapter({
...
});
const { draw } = createTerraDrawWithUI({
adapter,
...
});
const features = draw.getSnapshot();
const { icons, layers } = adapter.addStyling(features);
const featureCollection = {
type: 'FeatureCollection',
icons,
layers,
features,
};Here we obtain a standart GeoJSON FeatureCollection and put icons and layers props in the root (which is permitted by GeoJSON specification).
To display this data, you should add icons and layers to your MapGL map, and add GeoJSON via GeoJsonSource
for (const icon in featureCollection.icons) {
map.addIcon(icon, { url: featureCollection.icons[icon] });
}
for (const layer of featureCollection.layers) {
map.addLayer(layer);
}
const source = new mapgl.GeoJsonSource(map, {
data: featureCollection,
attributes: {
name: 'terra-draw-output',
},
});You can use demo on codepen for reference.
Raw Data
If you want just geojson shapes of drawed feature use a .getSnapshot() method of a TerraDraw.
const { draw } = createTerraDrawWithUI({
...
});
...
draw.getSnapshot();Material Icons
UI relies on Material Icons font to display icons. So you should include following link to your HTML head.
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined" />Deploy
npm run build
npm publish --access=publicLICENSE
MIT
