Геометрии | MapGL | 2GIS Documentation

Geometries

There are several base geometry objects (Circle, CircleMarker, Polyline, Polygon) which allows building complex visualizations on the map.

Create a Polyline on the map.

const polyline = new mapgl.Polyline(map, {
    coordinates: [
        [55.28770929, 25.22069944],
        [55.28976922, 25.25656786],
        [55.33096795, 25.22007825],
        [55.33302789, 25.25687836],
    ],
    width: 10,
    color: '#00b7ff',
});

polyline.on('click', () => {
    alert('Polyline click');
});
<!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="Polyline geometry 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 polyline = new mapgl.Polyline(map, {
                coordinates: [
                    [55.28770929, 25.22069944],
                    [55.28976922, 25.25656786],
                    [55.33096795, 25.22007825],
                    [55.33302789, 25.25687836],
                ],
                width: 10,
                color: '#00b7ff',
            });

            polyline.on('click', () => {
                alert('Polyline click');
            });
        </script>
    </body>
</html>

A polyline differ from all other objects in that it doesn't have strokes. Instead, it uses multiple "layers" - a layer drawn behind each other.

So if you want to add strokes you should specify width2 and calculate it like sum of width and doubled stroke.

For example, you want stroke to be 2 pixels (px), and your main width is 10 px. So doubled stroke width would be 4 px plus main width equals 14 px. This is width2.

Same for width3 - sum of width2 and doubled second stroke.

const polyline = new mapgl.Polyline(map, {
    coordinates: [
        [55.28770929, 25.22069944],
        [55.28976922, 25.25656786],
        [55.33096795, 25.22007825],
        [55.33302789, 25.25687836],
    ],
    width: 10,
    color: '#00b7ff',
    width2: 14,
    color2: '#ffffff',
    width3: 16,
    color3: '#000000',
});

polyline.on('click', () => {
    alert('Polyline click');
});
<!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="Polyline geometry with additional width 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 polyline = new mapgl.Polyline(map, {
                coordinates: [
                    [55.28770929, 25.22069944],
                    [55.28976922, 25.25656786],
                    [55.33096795, 25.22007825],
                    [55.33302789, 25.25687836],
                ],
                width: 10,
                color: '#00b7ff',
                width2: 14,
                color2: '#ffffff',
                width3: 16,
                color3: '#000000',
            });

            polyline.on('click', () => {
                alert('Polyline click');
            });
        </script>
    </body>
</html>

Create a Polygon on the map.

Geometry of a polygon is described in two parts. First, you describe all outer edges and then all parts to cut from it. Also, all parts should have the first and the last points the same. See coordinates option in PolygonOptions for more details.

In the example below we describe a square and then cut a rhombus from it:

const polygon = new mapgl.Polygon(map, {
    coordinates: [
        [
            [55.28770929, 25.22069944],
            [55.28976922, 25.25656786],
            [55.33302789, 25.25687836],
            [55.33096795, 25.22007825],
            [55.28770929, 25.22069944],
        ],
        [
            [55.29500489, 25.23979952],
            [55.31285768, 25.25175496],
            [55.32676225, 25.23917843],
            [55.31062608, 25.2279982],
            [55.29500489, 25.23979952],
        ],
    ],
    color: '#990000',
    strokeWidth: 3,
    strokeColor: '#bb0000',
});

polygon.on('click', () => {
    alert('Polygon click');
});
<!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="Polygon geometry 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 polygon = new mapgl.Polygon(map, {
                coordinates: [
                    [
                        [55.28770929, 25.22069944],
                        [55.28976922, 25.25656786],
                        [55.33302789, 25.25687836],
                        [55.33096795, 25.22007825],
                        [55.28770929, 25.22069944],
                    ],
                    [
                        [55.29500489, 25.23979952],
                        [55.31285768, 25.25175496],
                        [55.32676225, 25.23917843],
                        [55.31062608, 25.2279982],
                        [55.29500489, 25.23979952],
                    ],
                ],
                color: '#99000055',
                strokeWidth: 3,
                strokeColor: '#bb0000',
            });

            polygon.on('click', () => {
                alert('Polygon click');
            });
        </script>
    </body>
</html>

Create a Circle on the map. Radius is in meters.

const circle = new mapgl.Circle(map, {
    coordinates: map.getCenter(),
    radius: 2000,
    color: '#ff000055',
    strokeWidth: 2,
    strokeColor: '#ffffff',
});

circle.on('click', () => {
    alert('Circle click');
});
<!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="Circle geometry 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 circle = new mapgl.Circle(map, {
                coordinates: map.getCenter(),
                radius: 2000,
                color: '#ff000055',
                strokeWidth: 2,
                strokeColor: '#ffffff',
            });

            circle.on('click', () => {
                alert('Circle click');
            });
        </script>
    </body>
</html>

If you want to specify radius in pixels use CircleMarker:

const circleMarker = new mapgl.CircleMarker(map, {
    coordinates: map.getCenter(),
    radius: 80,
    color: '#ff0000',
    strokeWidth: 2,
    strokeColor: '#ffffff',
});

circleMarker.on('click', () => {
    alert('circleMarker click');
});
<!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="CircleMarker geometry 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 circleMarker = new mapgl.CircleMarker(map, {
                coordinates: map.getCenter(),
                radius: 80,
                color: '#ff0000',
                strokeWidth: 2,
                strokeColor: '#ffffff',
            });

            circleMarker.on('click', () => {
                alert('circleMarker click');
            });
        </script>
    </body>
</html>

Now lets build a car route demo.

Start with basic HTML, add a container for the map and load MapGL script:

<!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>
        <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>
    </body>
</html>

Then init the map and prepare the data for our route splitted by segments. Each segment will have different color and array of points. Also, the first and the last point will have a circle marker and a label (A and B):

const map = new mapgl.Map('container', {
    center: [55.30095449435502, 25.26873501453329],
    zoom: 17,
    key: 'Your API access key',
});

const segments = [
    {
        color: '#e84646',
        label: 'A',
        coords: [
            [55.29970489, 25.26853913],
            [55.2994345, 25.26920691],
            [55.29950714, 25.26936478],
        ],
    },
    {
        color: '#e3e340',
        coords: [
            [55.29950714, 25.26936478],
            [55.30124581, 25.26959538],
            [55.30141272, 25.26965618],
            [55.30191503, 25.26896923],
        ],
    },
    {
        color: '#43e843',
        label: 'B',
        coords: [
            [55.30191503, 25.26896923],
            [55.3020634, 25.26892939],
            [55.30233927, 25.26823968],
        ],
    },
];

It's important to add zIndex for each map object, otherwise they will be drawn different sometimes (one behind other and vise versa).

So, iterate over segments and add geometries:

segments.forEach((segment, i) => {
    const zIndex = segments.length - 1 - i;
    new mapgl.Polyline(map, {
        coordinates: segment.coords,
        width: 10,
        color: segment.color,
        width2: 14,
        color2: '#ffffff',
        zIndex,
    });

    if (segment.label) {
        const isFirstPoint = i === 0;
        const lastPointIndex = segment.coords.length - 1;
        const coords = isFirstPoint ? segment.coords[0] : segment.coords[lastPointIndex];

        new mapgl.CircleMarker(map, {
            coordinates: coords,
            radius: 16,
            color: '#0088ff',
            strokeWidth: 2,
            strokeColor: '#ffffff',
            zIndex: isFirstPoint ? 5 : 3,
        });

        new mapgl.Label(map, {
            coordinates: coords,
            text: segment.label,
            fontSize: 14,
            color: '#ffffff',
            zIndex: isFirstPoint ? 6 : 4,
        });
    }
});
<!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="Car route geometry 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.30095449435502, 25.26873501453329],
                zoom: 17,
                key: 'Your API access key',
            });

            const segments = [
                {
                    color: '#e84646',
                    label: 'A',
                    coords: [
                        [55.29970489, 25.26853913],
                        [55.2994345, 25.26920691],
                        [55.29950714, 25.26936478],
                    ],
                },
                {
                    color: '#e3e340',
                    coords: [
                        [55.29950714, 25.26936478],
                        [55.30124581, 25.26959538],
                        [55.30141272, 25.26965618],
                        [55.30191503, 25.26896923],
                    ],
                },
                {
                    color: '#43e843',
                    label: 'B',
                    coords: [
                        [55.30191503, 25.26896923],
                        [55.3020634, 25.26892939],
                        [55.30233927, 25.26823968],
                    ],
                },
            ];

            segments.forEach((segment, i) => {
                const zIndex = segments.length - 1 - i;
                new mapgl.Polyline(map, {
                    coordinates: segment.coords,
                    width: 10,
                    color: segment.color,
                    width2: 14,
                    color2: '#ffffff',
                    zIndex,
                });

                if (segment.label) {
                    const isFirstPoint = i === 0;
                    const lastPointIndex = segment.coords.length - 1;
                    const coords = isFirstPoint
                        ? segment.coords[0]
                        : segment.coords[lastPointIndex];

                    new mapgl.CircleMarker(map, {
                        coordinates: coords,
                        radius: 16,
                        color: '#0088ff',
                        strokeWidth: 2,
                        strokeColor: '#ffffff',
                        zIndex: isFirstPoint ? 5 : 3,
                    });

                    new mapgl.Label(map, {
                        coordinates: coords,
                        text: segment.label,
                        fontSize: 14,
                        color: '#ffffff',
                        zIndex: isFirstPoint ? 6 : 4,
                    });
                }
            });
        </script>
    </body>
</html>