Usage scenarios | Urbi Documentation
MapGL JS API

Usage scenarios

If you are using MapGL JS API for the first time, learn about its operation basics and usage scenarios.

On the top level, a map on MapGL JS API does only one task: draws data using styles.

Data is all information that can be drawn on the map: buildings, roads, water objects, borders, and more. Everything that answers the question "What to draw?". In most cases, this information binds to a particular geographic region. In other words, it is geodata.

Styles are the rules of displaying map data that define how, in which order, and in which form to draw it. Everything that answers the question "How to draw?". No data appears on the map if the drawing rules are not defined.

Data and styles can work in two variants:


You can either work with prepared Urbi data or upload your data to enrich information on the map. User data can be uploaded as dynamic objects or as data sources.

The appropriate way of adding user data depends on your goal. If you need to display several objects that change relatively often (for example, for a scenario of building routes), adding dynamic objects is a better solution. If you need to display large amounts of static data that does not change (for example, a heatmap of traffic incidents statistics for a year), a combination of style layers and data sources is recommended.

Below are typical scenarios of working with MapGL JS API that can help you define the first steps of completing your task.

Follow this scenario if you need to add a small set of custom objects to the Urbi map. Example: show spots where new facilities will be opened in the future and set a unique icon for each.

Steps:

  1. Initialize the map.
  2. Add dynamic objects and configure the style of each.
  3. If needed, additionally configure the look of the map underlay in the Style editor.

Example of a map with separately added markers:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>2GIS Map API</title>
        <meta name="description" content="Several markers example" />
        <style>
            html,
            body,
            #container {
                margin: 0;
                width: 100%;
                height: 100%;
                overflow: hidden;
            }
        </style>
    </head>
    <body>
        <div id="container"></div>
        <script src="https://mapgl.2gis.com/api/js/v1"></script>
        <script>
            const map = new mapgl.Map('container', {
                center: [55.31878, 25.23584],
                zoom: 13,
                key: 'Your API access key',
            });
            const coords = [
                [55.27414804174869, 25.257576991034284],
                [55.289254243403306, 25.211614202468652],
                [55.34418588368302, 25.215341562259866],
                [55.35036569359612, 25.26068195798851],
                [55.32976632814914, 25.238324424362062],
            ];
            coords.forEach((coord) => {
                const marker = new mapgl.Marker(map, {
                    coordinates: coord,
                });
            });
        </script>
    </body>
</html>

If standard styles from the editor do not fit your goals, you can create your own style based on them and apply it to the map. Example: show intercity roads only and highlight them with a specific color or configure the light and dark theme for your map.

Steps:

  1. Initialize the map.
  2. Configure the display of required layers in the Style editor.

Example of a map without user data with styles configured for the light and dark themes:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>2GIS Map API</title>
        <meta name="description" content="Style apply in runtime example" />
        <style>
            html,
            body,
            #container {
                margin: 0;
                width: 100%;
                height: 100%;
                overflow: hidden;
                font-family: Helvetica, Arial, sans-serif;
            }

            #dark_theme, #light_theme {
                margin: 0 10px 10px;
                padding: 3px 12px;
                background: #3b3b3b;
                color: #fff;
                border: none;
            }
        </style>
    </head>
    <body>
        <div>
            Click to switch theme:
            <button id="dark_theme">Switch to dark theme 🌙</button>
            <button id="light_theme">Switch to light theme 🌞</button>
        </div>

        <div id="container"></div>
        <script src="https://mapgl.2gis.com/api/js/v1"></script>
        <script>
            const map = new mapgl.Map('container', {
                center: [55.187609, 25.141736],
                styleZoom: 16,
                pitch: 40,
                rotation: -45,
                key: 'Your API access key',
            });

            document.getElementById('dark_theme').addEventListener('click', function() {
                map.setStyleById('e05ac437-fcc2-4845-ad74-b1de9ce07555');
            });
            document.getElementById('light_theme').addEventListener('click', function() {
                map.setStyleById('c080bb6a-8134-4993-93a1-5b4d8c36a59b');
            });
        </script>
    </body>
</html>

Follow this scenario if you need to add a large set of data (thousands or millions of objects) to the map. Example: display the traffic incidents statistics from external data sources as a heatmap.

Steps:

  1. Initialize the map.
  2. Add a data source.
  3. Configure a style layer using the map.addLayer() method and the style specification or create one in the Style editor.

Example of a map with a connected GeoJSON source and its style configured as a heatmap:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>2GIS Map API</title>
        <meta name="description" content="Heatmap layer example" />
        <style>
            html,
            body,
            #container {
                margin: 0;
                width: 100%;
                height: 100%;
                overflow: hidden;
            }
        </style>
    </head>
    <body>
        <div id="container"></div>
        <script src="https://mapgl.2gis.com/api/js/v1"></script>
        <script>
            const map = new mapgl.Map('container', {
                center: [55.26020, 25.17429],
                zoom: 11,
                key: 'Your API access key',
            });

            fetch('/samples/traffic_accidents.csv')
                .then(r => r.text())
                .then(text => {
                    const csv = text.split('\n').map(s => s.split(','));

                    const geojson = {
                        type: 'FeatureCollection',
                        features: []
                    };

                    const count = csv.length - 1;
                    console.log(count);

                    csv
                        .slice(1) // removes the header row
                        .forEach((row) => {
                            if (row.length < 5) {
                                return;
                            }
                            geojson.features.push({
                                type: 'Feature',
                                properties: { customProperty: 900 / count },
                                geometry: {
                                    type: 'Point',
                                    coordinates: [
                                        // Parse coordinates from CSV encoding to number
                                        +JSON.parse(row[4]),
                                        +JSON.parse(row[3])
                                    ],
                                },
                            });
                        });

                    const source = new mapgl.GeoJsonSource(map, {
                        data: geojson,
                        attributes: {
                            purpose: 'heatmap',
                        },
                    });
                });

            
            const layer = {
                id: 'my-heatmap-layer', // Each layer ID must be unique

                // Data filtering logic
                filter: [
                    'match',
                    ['sourceAttr', 'purpose'],
                    ['heatmap'],
                    true, // Result if value of purpose source attribute equals "heatmap"
                    false, // Result if not
                ],

                // Drawing object type
                type: 'heatmap',

                // Style of drawing object
                style: {
                    color: [
                        'interpolate',
                        ['linear'],
                        ['heatmap-density'],
                        0,
                        'rgba(0, 0, 0, 0)',
                        0.2,
                        'rgba(172, 32, 135, 1)',
                        0.4,
                        'rgba(255, 154, 0, 1)',
                        0.6,
                        'rgba(255, 252, 0, 1)',
                        0.8,
                        'rgba(255, 255, 63, 1)',
                        1,
                        'rgba(255, 255, 255, 1)',
                    ],
                    radius: 30,
                    weight: ["get", "customProperty"],
                    intensity: 0.34,
                    opacity: 0.8,
                    downscale: 1,
                },
            };

            map.on('styleload', () => {
                map.addLayer(layer, '70184');
            });
        </script>
    </body>
</html>