Работа с геометриями | MapGL | 2GIS Documentation
MapGL JS API
Личный кабинет

Работа с геометриями

Для манипуляций с GeoJSON рекомендуется использовать библиотеку turf.js. Ниже описывается использование данной библиотеки в связке с MapGL JS API.

Метод turf.bbox рассчитывает прямоугольную область, в которой находятся заданные объекты или группа объектов.

const line = turf.lineString([
    [34, 40],
    [36, 41],
    [41, 37],
    [48, 42],
    [42, 35],
]);
const bbox = turf.bbox(line); // [minX, minY, maxX, maxY]

Документация на метод: @turf/bbox

Примеры использования

  • Спозиционировать карту так, чтобы все объекты поместились на экран при помощи метода map.fitBounds.

    map.fitBounds({ southWest: bbox.slice(0, 2), northEast: bbox.slice(2, 4) });
    
  • Запросить дополнительные данные к имеющимся. Например, имея полигоны муниципальных районов, запросить близлежащие объекты застройки.

Граничный прямоугольник является наиболее распространенным и быстрым способом определить границы нахождения объектов. Обратной стороной является то, что границы таким образом определяются достаточно грубо. Если нужна большая точность, воспользуйтесь выпуклой оболочкой.


<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Using @turf/bbox with MapGL</title>
        <meta name="description" content="Using @turf/bbox with MapGL" />
        <style>
            html,
            body,
            #container {
                margin: 0;
                width: 100%;
                height: 100%;
                overflow: hidden;
            }
        </style>
    </head>
    <body>
        <div id="container"></div>
        <script src="https://unpkg.com/@turf/turf@6.5.0/turf.min.js"></script>
        <script src="https://mapgl.2gis.com/api/js/v1"></script>
        <script>
            const line = turf.lineString([[34, 40], [36, 41], [41, 37], [48, 42], [42, 35]]);
            const bbox = turf.bbox(line);

            const geojson = turf.featureCollection([line, turf.bboxPolygon(bbox)]);

            const map = new mapgl.Map('container', {
                center: turf.getCoord(turf.center(geojson)),
                zoom: 5,
                key: 'Your API access key',
            });

            new mapgl.GeoJsonSource(map, {
                data: geojson,
                attributes: {
                    foo: 'bar'
                }
            });
            map.on('styleload', () => {
                map.addLayer({
                    id: 'polygons',
                    type: 'polygon',
                    filter: ['==', ['sourceAttr', 'foo'], 'bar'],
                    style: {
                        color: '#00B2DD50'
                    }
                });
                map.addLayer({
                    id: 'lines',
                    type: 'line',
                    filter: ['==', ['sourceAttr', 'foo'], 'bar'],
                    style: {
                        color: '#00B2DDA0',
                        width: 3
                    }
                });
                map.addLayer({
                    id: 'points',
                    type: 'point',
                    filter: ['==', ['sourceAttr', 'foo'], 'bar'],
                    style: {
                        iconImage: 'ent_i',
                        iconWidth: 16,
                        iconPriority: 100
                    }
                });
            })
        </script>
    </body>
</html>

Метод turf.convex принимает на вход объект или группу объектов и создаёт на их основе выпуклую оболочку.

const line = turf.lineString([
    [34, 40],
    [36, 41],
    [41, 37],
    [48, 42],
    [42, 35],
]);
const convexHull = turf.convex(line);

Документация на метод: @turf/convex

Пример использования

Выпуклая оболочка — более точный по сравнению с граничным прямоугольником метод определения границ объекта. Обратной стороной является большая вычислительная сложность данного метода.


<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Using @turf/convex with MapGL</title>
        <meta name="description" content="Using @turf/convex with MapGL" />
        <style>
            html,
            body,
            #container {
                margin: 0;
                width: 100%;
                height: 100%;
                overflow: hidden;
            }
        </style>
    </head>
    <body>
        <div id="container"></div>
        <script src="https://unpkg.com/@turf/turf@6.5.0/turf.min.js"></script>
        <script src="https://mapgl.2gis.com/api/js/v1"></script>
        <script>
            const line = turf.lineString([[34, 40], [36, 41], [41, 37], [48, 42], [42, 35]]);
            const convexHull = turf.convex(line);

            const geojson = turf.featureCollection([line, convexHull]);

            const map = new mapgl.Map('container', {
                center: turf.getCoord(turf.center(geojson)),
                zoom: 5,
                key: 'Your API access key',
            });

            new mapgl.GeoJsonSource(map, {
                data: geojson,
                attributes: {
                    foo: 'bar'
                }
            });
            map.on('styleload', () => {
                map.addLayer({
                    id: 'polygons',
                    type: 'polygon',
                    filter: ['==', ['sourceAttr', 'foo'], 'bar'],
                    style: {
                        color: '#00B2DD50'
                    }
                });
                map.addLayer({
                    id: 'lines',
                    type: 'line',
                    filter: ['==', ['sourceAttr', 'foo'], 'bar'],
                    style: {
                        color: '#00B2DDA0',
                        width: 3
                    }
                });
                map.addLayer({
                    id: 'points',
                    type: 'point',
                    filter: ['==', ['sourceAttr', 'foo'], 'bar'],
                    style: {
                        iconImage: 'ent_i',
                        iconWidth: 16,
                        iconPriority: 100
                    }
                });
            })
        </script>
    </body>
</html>

Метод turf.buffer позволяет пропорционально увеличить или уменьшить объект.

const line = turf.lineString([
    [34, 40],
    [36, 41],
    [41, 37],
    [48, 42],
    [42, 35],
]);
const buffer = turf.buffer(line, 40);

Документация на метод: @turf/buffer

Примеры использования

  • Отобразить различного рода охранные зоны, полосы отчуждения и т.п.

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Using @turf/buffer and MapGL</title>
        <meta name="description" content="Using @turf/buffer and MapGL" />
        <style>
            html,
            body,
            #container {
                margin: 0;
                width: 100%;
                height: 100%;
                overflow: hidden;
            }
        </style>
    </head>
    <body>
        <div id="container"></div>
        <script src="https://unpkg.com/@turf/turf@6.5.0/turf.min.js"></script>
        <script src="https://mapgl.2gis.com/api/js/v1"></script>
        <script>
            const line = turf.lineString([[34, 40], [36, 41], [41, 37], [48, 42], [42, 35]]);
            const buffer = turf.buffer(line, 40);

            const geojson = turf.featureCollection([line, buffer]);

            const map = new mapgl.Map('container', {
                center: turf.getCoord(turf.center(geojson)),
                zoom: 5,
                key: 'Your API access key',
            });

            new mapgl.GeoJsonSource(map, {
                data: geojson,
                attributes: {
                    foo: 'bar'
                }
            });
            map.on('styleload', () => {
                map.addLayer({
                    id: 'polygons',
                    type: 'polygon',
                    filter: ['==', ['sourceAttr', 'foo'], 'bar'],
                    style: {
                        color: '#00B2DD50'
                    }
                });
                map.addLayer({
                    id: 'lines',
                    type: 'line',
                    filter: ['==', ['sourceAttr', 'foo'], 'bar'],
                    style: {
                        color: '#00B2DDA0',
                        width: 3
                    }
                });
                map.addLayer({
                    id: 'points',
                    type: 'point',
                    filter: ['==', ['sourceAttr', 'foo'], 'bar'],
                    style: {
                        iconImage: 'ent_i',
                        iconWidth: 16,
                        iconPriority: 100
                    }
                });
            })
        </script>
    </body>
</html>

  • Показать на карте места, равноудаленные от какого-либо объекта.

    Однако это работает хорошо только на малых расстояниях (до 50-100 м). При расчёте больших расстояний начинает сказываться тот факт, что turf.buffer рассчитывает удалённость чисто геометрически, а в действительности на кратчайшем геометрическом пути обычно содержатся препятствия: дома, реки, заборы, которые требуется обходить/объезжать. В этом случае нужно применять более точный и специализированный инструмент: изохроны.

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Drawing buffers around points with @turf/buffer and MapGL</title>
        <meta name="description" content="Drawing buffers around points with @turf/buffer and MapGL" />
        <style>
            html,
            body,
            #container {
                margin: 0;
                width: 100%;
                height: 100%;
                overflow: hidden;
            }
        </style>
    </head>
    <body>
        <div id="container"></div>
        <script src="https://unpkg.com/@turf/turf@6.5.0/turf.min.js"></script>
        <script src="https://mapgl.2gis.com/api/js/v1"></script>
        <script>
            const points = [
                [33.63825,34.917647],
                [33.638238,34.914459],
                [33.634526,34.912492],
                [33.628846,34.914821],
                [33.628997,34.917202],
                [33.625677,34.916229]
            ];
            const geojson = turf.featureCollection([]);
            for (const pt of points) {
                const feature = turf.point(pt);
                geojson.features.push(feature);
                geojson.features.push(turf.buffer(feature, 0.1));
            }

            const map = new mapgl.Map('container', {
                center: turf.getCoord(turf.center(geojson)),
                zoom: 15.5,
                key: 'Your API access key',
            });

            new mapgl.GeoJsonSource(map, {
                data: geojson,
                attributes: {
                    foo: 'bar'
                }
            });
            map.on('styleload', () => {
                map.addLayer({
                    id: 'polygons',
                    type: 'polygon',
                    filter: ['==', ['sourceAttr', 'foo'], 'bar'],
                    style: {
                        color: '#00B2DD50'
                    }
                });
                map.addLayer({
                    id: 'lines',
                    type: 'line',
                    filter: ['==', ['sourceAttr', 'foo'], 'bar'],
                    style: {
                        color: '#00B2DDA0',
                        width: 3
                    }
                });
                map.addLayer({
                    id: 'points',
                    type: 'point',
                    filter: ['==', ['sourceAttr', 'foo'], 'bar'],
                    style: {
                        iconImage: 'ent_i',
                        iconWidth: 16,
                        iconPriority: 100
                    }
                });
            })
        </script>
    </body>
</html>

Методы turf.center, turf.centroid и turf.centerOfMass позволяют получить тот или иной центр объекта или группы объектов.

const polygon = turf.polygon([
    [
        [34, 40],
        [36, 41],
        [41, 37],
        [48, 42],
        [42, 35],
        [34, 40],
    ],
]);
const center = turf.center(polygon);
const centroid = turf.centroid(polygon);
const centerOfMass = turf.centerOfMass(polygon);

Документация на методы:

Примеры использования

Есть 3 метода получения центра:

  • center получает центр граничного прямоугольника объекта или группы.
  • centroid вычисляет геометрический центр объекта или группы.
  • centerOfMass получает центр масс фигуры.

На правильных и симметричных полигонах между этими методами практически нет разницы. В случае невыпуклых полигонов или других полигонов неправильной формы лучше всего работает centerOfMass.

Эти методы удобны для расстановки подписей объектов.


<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Using @turf/[center,centroid,centerOfMass] and MapGL</title>
        <meta name="description" content="Using @turf/[center,centroid,centerOfMass] and MapGL" />
        <style>
            html,
            body,
            #container {
                margin: 0;
                width: 100%;
                height: 100%;
                overflow: hidden;
            }
        </style>
    </head>
    <body>
        <div id="container"></div>
        <script src="https://unpkg.com/@turf/turf@6.5.0/turf.min.js"></script>
        <script src="https://mapgl.2gis.com/api/js/v1"></script>
        <script>
            const polygon = turf.polygon([[[34, 40], [36, 41], [41, 37], [48, 42], [42, 35], [34, 40]]]);
            const center = turf.center(polygon, { properties: { name: 'Center' } });
            const centroid = turf.centroid(polygon, { properties: { name: 'Centeroid' } });
            const centerOfMass = turf.centerOfMass(polygon, { properties: { name: 'Center of mass' } });

            const geojson = turf.featureCollection([polygon, center, centroid, centerOfMass]);

            const map = new mapgl.Map('container', {
                center: turf.getCoord(turf.center(geojson)),
                zoom: 7.5,
                key: 'Your API access key',
            });

            new mapgl.GeoJsonSource(map, {
                data: geojson,
                attributes: {
                    foo: 'bar'
                }
            });
            map.on('styleload', () => {
                map.addLayer({
                    id: 'polygons',
                    type: 'polygon',
                    filter: ['==', ['sourceAttr', 'foo'], 'bar'],
                    style: {
                        color: '#00B2DD50'
                    }
                });
                map.addLayer({
                    id: 'lines',
                    type: 'line',
                    filter: ['==', ['sourceAttr', 'foo'], 'bar'],
                    style: {
                        color: '#00B2DDA0',
                        width: 3
                    }
                });
                map.addLayer({
                    id: 'points',
                    type: 'point',
                    filter: ['==', ['sourceAttr', 'foo'], 'bar'],
                    style: {
                        iconImage: 'ent_i',
                        iconWidth: 16,
                        iconPriority: 100,
                        textFont: 'Noto_Sans',
                        textFontSize: 12,
                        textField: ['get', 'name'],
                        textPriority: 100
                    }
                });
            })
        </script>
    </body>
</html>

Метод turf.nearestPoint получает ближайшую точку из множества точек.

const line = turf.lineString([
    [34, 40],
    [36, 41],
    [41, 37],
    [48, 42],
    [42, 35],
]);
const target = turf.point([38, 38]);

const points = turf.explode(line);
const nearest = turf.nearestPoint(target, points);

Документация на метод: @turf/nearestPoint

Особенностью метода является работа только с множеством точек. Чтобы преобразовать произвольный объект в множество точек, воспользуйтесь методом @turf/explode.

Пример использования

Найти ближайший к заданному объект.


Метод turf.nearestPointOnLine получает ближайшую к заданной точку на линии или на группе линий.

const line = turf.lineString([
    [34, 40],
    [36, 41],
    [41, 37],
    [48, 42],
    [42, 35],
]);
const target = turf.point([38, 38], { name: 'Target' });

const nearestOnLine = turf.nearestPointOnLine(line, target);

Документация на метод: @turf/nearestPointOnLine

Пример использования

Найти ближайшую точку на маршруте или дороге. Как и в случае с методом turf.buffer, это работает только в самых простых случаях, когда не требуется учитывать препятствия на местности. В остальных случаях воспользуйтесь API маршрутизации.


<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Finding nearest with Turf.js and MapGL</title>
        <meta name="description" content="Finding nearest with Turf.js and MapGL" />
        <style>
            html,
            body,
            #container {
                margin: 0;
                width: 100%;
                height: 100%;
                overflow: hidden;
            }
        </style>
    </head>
    <body>
        <div id="container"></div>
        <script src="https://unpkg.com/@turf/turf@6.5.0/turf.min.js"></script>
        <script src="https://mapgl.2gis.com/api/js/v1"></script>
        <script>
            const line = turf.lineString([[34, 40], [36, 41], [41, 37], [48, 42], [42, 35]]);
            const target = turf.point([38, 38], { name: 'Target' });

            const nearestOnLine = turf.nearestPointOnLine(line, target);
            nearestOnLine.properties = { name: 'Nearest Point On Line' };

            const points = turf.explode(line);
            const nearest = turf.nearestPoint(target, points);
            nearest.properties = { name: 'Nearest Point' };

            const geojson = turf.featureCollection([line, target, nearest, nearestOnLine]);

            const map = new mapgl.Map('container', {
                center: turf.getCoord(turf.center(geojson)),
                zoom: 7,
                key: 'Your API access key',
            });

            new mapgl.GeoJsonSource(map, {
                data: geojson,
                attributes: {
                    foo: 'bar'
                }
            });
            map.on('styleload', () => {
                map.addLayer({
                    id: 'polygons',
                    type: 'polygon',
                    filter: ['==', ['sourceAttr', 'foo'], 'bar'],
                    style: {
                        color: '#00B2DD50'
                    }
                });
                map.addLayer({
                    id: 'lines',
                    type: 'line',
                    filter: ['==', ['sourceAttr', 'foo'], 'bar'],
                    style: {
                        color: '#00B2DDA0',
                        width: 3
                    }
                });
                map.addLayer({
                    id: 'points',
                    type: 'point',
                    filter: ['==', ['sourceAttr', 'foo'], 'bar'],
                    style: {
                        iconImage: 'ent_i',
                        iconWidth: 16,
                        iconPriority: 100,
                        textFont: 'Noto_Sans',
                        textFontSize: 12,
                        textField: ['get', 'name'],
                        textPriority: 100
                    }
                });
            })
        </script>
    </body>
</html>

Метод turf.union объединяет несколько фигур в одну.

const points = [
    [10, 10],
    [12, 10],
];
const circleA = turf.buffer(turf.point([10, 10]), 300);
const circleB = turf.buffer(turf.point([12, 10]), 300);
const united = turf.union(circleA, circleB);

Документация на метод: @turf/union

Примеры использования

  • Отобразить на карте область, которую составляют несколько объектов, как один объект.
  • Собрать излишне фрагментированные объекты, что иногда случается при обработке геоданных.

Метод turf.intersect находит фигуру, образованную пересечением заданных фигур.

const points = [
    [10, 10],
    [12, 10],
];
const circleA = turf.buffer(turf.point([10, 10]), 300);
const circleB = turf.buffer(turf.point([12, 10]), 300);
const intersected = turf.intersect(circleA, circleB);

Документация на метод: @turf/intersect

Пример использования

Отобразить на карте область, являющуюся пересечением других областей. Например, бесплатную парковку в пределах заданного радиуса от объекта.


<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Using @turf/union and @turf/intersect with MapGL</title>
        <meta name="description" content="Using @turf/union and @turf/intersect with MapGL" />
        <style>
            html,
            body,
            #container {
                margin: 0;
                width: 100%;
                height: 100%;
                overflow: hidden;
            }
        </style>
    </head>
    <body>
        <div id="container"></div>
        <script src="https://unpkg.com/@turf/turf@6.5.0/turf.min.js"></script>
        <script src="https://mapgl.2gis.com/api/js/v1"></script>
        <script>
            const points = [[10, 10], [12, 10]];
            const circleA = turf.buffer(turf.point([10, 10]), 300);
            const circleB = turf.buffer(turf.point([12, 10]), 300);
            const united = turf.transformTranslate(turf.union(circleA, circleB), 1200, 90);
            const intersected = turf.transformTranslate(turf.intersect(circleA, circleB), 1200, -90);

            const geojson = turf.featureCollection([circleA, circleB, united, intersected]);

            const map = new mapgl.Map('container', {
                center: turf.getCoord(turf.center(geojson)),
                zoom: 5,
                key: 'Your API access key',
            });

            new mapgl.GeoJsonSource(map, {
                data: geojson,
                attributes: {
                    foo: 'bar'
                }
            });
            map.on('styleload', () => {
                map.addLayer({
                    id: 'polygons',
                    type: 'polygon',
                    filter: ['==', ['sourceAttr', 'foo'], 'bar'],
                    style: {
                        color: '#00B2DD50'
                    }
                });
                map.addLayer({
                    id: 'lines',
                    type: 'line',
                    filter: ['==', ['sourceAttr', 'foo'], 'bar'],
                    style: {
                        color: '#00B2DDA0',
                        width: 3
                    }
                });
                map.addLayer({
                    id: 'points',
                    type: 'point',
                    filter: ['==', ['sourceAttr', 'foo'], 'bar'],
                    style: {
                        iconImage: 'ent_i',
                        iconWidth: 16,
                        iconPriority: 100
                    }
                });
            })
        </script>
    </body>
</html>

Метод turf.mask позволяет «вывернуть наизнанку» полигон: превратить остальное пространство вокруг него в полигон.

const poly = turf.polygon([
    [
        [0, 0],
        [0, 2],
        [2, 2],
        [2, 0],
        [0, 0],
    ],
]);
turf.mask(poly);

Документация на метод: @turf/mask

Пример использования

Акцентировать внимание на одной или нескольких областях карты и затенить остальное пространство.


<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Using @turf/mask with MapGL</title>
        <meta name="description" content="Using @turf/mask with MapGL" />
        <style>
            html,
            body,
            #container {
                margin: 0;
                width: 100%;
                height: 100%;
                overflow: hidden;
            }
        </style>
    </head>
    <body>
        <div id="container"></div>
        <script src="https://unpkg.com/@turf/turf@6.5.0/turf.min.js"></script>
        <script src="https://mapgl.2gis.com/api/js/v1"></script>
        <script>
            const aPlace = turf.polygon([[
                [105.92429031266958, -5.262701049754213],
                [106.28471551378776, -5.195701693969994],
                [106.64994638418318, -5.214845098030779],
                [107.03920560108905, -5.305768259535483],
                [107.58705190638044, -5.4158151922751046],
                [107.74083332350821, -5.721926046845098],
                [107.8369467063646, -6.371857054158838],
                [107.82252969773305, -6.558086239663282],
                [106.65475205317988, -7.569142136398696],
                [106.01079236773299, -7.5834332864075975],
                [105.86181661939993, -7.535794279073713],
                [105.49178008359819, -7.430970061978684],
                [104.78488126325243, -6.791043334337019],
                [104.8233266147578, -6.456892553102861],
                [105.0299703919453, -6.026947405124446],
                [105.16933480114257, -5.816626441233922],
                [105.30389354084993, -5.644487005567058],
                [105.92429031266958, -5.262701049754213],
            ]]);
            const bbox = turf.bbox(aPlace);

            const map = new mapgl.Map('container', {
                center: turf.getCoord(turf.center(aPlace)),
                zoom: 7.5,
                key: 'Your API access key',
            });

            new mapgl.GeoJsonSource(map, {
                data: turf.mask(aPlace),
                attributes: {
                    foo: 'bar'
                }
            });

            map.on('styleload', () => {
                map.addLayer({
                    id: 'polygons',
                    type: 'polygon',
                    filter: ['==', ['sourceAttr', 'foo'], 'bar'],
                    style: {
                        color: '#00B2DD50'
                    }
                });
            })
        </script>
    </body>
</html>



Метод turf.simplify упрощает геометрию при помощи алгоритма Рамера-Дугласа-Пекера.

const gpsTrack = turf.lineString([
    [0, 0],
    [0, 0.1],
    [0.5, 0.5],
    [1, 0.5],
]);
const simplifiedTrack = turf.simplify(gpsTrack, { tolerance: 0.2 });
// { ... geometry: { ..., coordinates: [[0, 0], [0.5, 0.5], [1, 0.5]] } }

Степень упрощения геометрии определяется параметром tolerance, который обозначает максимальную ошибку, которую может допустить алгоритм при упрощении. Величина tolerance имеет ту же размерность, что и исходные данные. То есть, если геокоординаты указываются в градусах, то и tolerance будет в градусах.

Документация на метод: @turf/simplify

Примеры использования

  • Получить менее сложные геометрии, которые будут отрисовываться быстрее.
  • Отфильтровать данные, когда известно, что их точность не может превышать определённое значение.
  • Отобразить точные данные на большом масштабе: упрощённые геометрии имеют более эстетичный внешний вид и плавные линии без визуального шума.

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Using @turf/simplify with MapGL</title>
        <meta name="description" content="Using @turf/simplify with MapGL" />
        <style>
            html,
            body,
            #container {
                margin: 0;
                width: 100%;
                height: 100%;
                overflow: hidden;
            }
        </style>
    </head>
    <body>
        <div id="container"></div>
        <script src="https://unpkg.com/@turf/turf@6.5.0/turf.min.js"></script>
        <script src="https://mapgl.2gis.com/api/js/v1"></script>
        <script>
            const gpsTrack = turf.lineString([[0, 0], [0, 0.1], [0.5, 0.5], [1, 0.5]]);
            const simplifiedTrack = turf.simplify(gpsTrack, { tolerance: 0.2 });
            simplifiedTrack.properties.simplified = true;
            const bbox = turf.bbox(gpsTrack);

            console.log(gpsTrack, simplifiedTrack);
            const geojson = turf.featureCollection([gpsTrack, simplifiedTrack]);

            const map = new mapgl.Map('container', {
                center: turf.getCoord(turf.center(geojson)),
                zoom: 5,
                key: 'Your API access key',
            });
            map.fitBounds(
                { southWest: bbox.slice(0, 2), northEast: bbox.slice(2, 4) },
                { padding: { left: 20, top: 20, right: 20, bottom: 20 } }
            );

            new mapgl.GeoJsonSource(map, {
                data: geojson,
                attributes: {
                    foo: 'bar'
                }
            });
            map.on('styleload', () => {
                map.addLayer({
                    id: 'lines',
                    type: 'line',
                    filter: ['==', ['sourceAttr', 'foo'], 'bar'],
                    style: {
                        color: ['match', 
                            ['get', 'simplified'], 
                            [true], '#FF9387',
                            '#00B2DDA0'
                        ],
                        width: ['match', 
                            ['get', 'simplified'], 
                            [true], 3,
                            5
                        ]
                    }
                });
            })
        </script>
    </body>
</html>