Зацикленная карта | MapGL | 2GIS Documentation
MapGL JS API

Зацикленная карта

Вы можете управлять режимом зацикленной карты, который позволяет перемещаться через 180-й меридиан (антимеридиан), а также строить геометрии через него. Если режим включен, вы можете бесконечно перемещать карту вдоль экватора. Данная функция доступна для MapGL JS API версии 1.47.0 и выше.

Чтобы активировать режим зацикленной карты, передайте значение true свойству loopWorld в опциях карты MapOptions:

const map = new mapgl.Map('container', {
    center: [55.31878, 25.23584],
    zoom: 2,
    key: 'Your API access key',
    loopWorld: true,
});

Также вы можете включать и отключать режим на лету, используя метод setOption карты:

// Включение зацикленного режима
map.setOption('loopWorld', true);

// Выключение зацикленного режима
map.setOption('loopWorld', false);
<!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="A looped map 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: 2,
                key: 'Your API access key',
                loopWorld: true,
            });
        </script>
    </body>
</html>

При включении режима зацикленности геометрии из пользовательских источников данных (GeoJsonSource, RasterTileSource и т.д.) будут также сразу распространены на все реплики карты за пределами 180-го меридиана.

<!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="A looped data sources on the map 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: [134.42, 2.18],
                zoom: 2,
                key: 'Your API access key',
                loopWorld: true,
            });

            const data = {
                type: 'FeatureCollection',
                features: [
                    {
                        type: 'Feature',
                        properties: {
                            layer: 'line',
                        },
                        geometry: {
                            type: 'LineString',
                            coordinates: [
                                [-225.2508687122533, -26.197140953800826],
                                [-97.63368123845338, 39.02575847482353],
                                [-51.930556221990116, -14.351992564255312],
                                [13.811631238563326, 48.86305468578952],
                                [106.27256872796717, 34.81173148148569],
                                [252.68117844115423, 56.09275343428385],
                            ],
                        },
                    },
                    {
                        type: 'Feature',
                        properties: {
                            layer: 'polygon',
                        },
                        geometry: {
                            type: 'Polygon',
                            coordinates: [
                                [
                                    [87.18727112357627, 44.44853501098232],
                                    [143.37332863083012, 62.289485224316415],
                                    [208.41239108206506, 62.452519937042204],
                                    [222.12332858591037, -18.935185937787594],
                                    [85.01395365634146, -31.01321448953935],
                                    [87.18727112357627, 44.44853501098232],
                                ],
                            ],
                        },
                    },
                    {
                        type: 'Feature',
                        properties: {
                            layer: 'marker',
                            label: 'A marker',
                        },
                        geometry: {
                            type: 'Point',
                            coordinates: [0, 0],
                        },
                    },
                    {
                        type: 'Feature',
                        properties: {
                            layer: 'marker',
                            label: 'Another marker',
                        },
                        geometry: {
                            type: 'Point',
                            coordinates: [220, 0],
                        },
                    },
                ],
            };

            new mapgl.GeoJsonSource(map, {
                data,
                attributes: {
                    type: 'geojson',
                },
            });

            new mapgl.RasterTileSource(map, {
                url: (x, y, zoom) => `https://tile.openstreetmap.org/${zoom}/${x}/${y}.png`,
                attribution:
                    '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
                attributes: { type: 'raster' },
            });

            map.on('styleload', () => {
                map.addLayer({
                    type: 'raster',
                    id: 'my-raster-tile-layer',
                    filter: ['match', ['sourceAttr', 'type'], ['raster'], true, false],
                    style: {
                        opacity: 0.75,
                    },
                });
                map.addLayer({
                    type: 'polygon',
                    id: 'my-polygon',
                    filter: [
                        'all',
                        ['match', ['sourceAttr', 'type'], ['geojson'], true, false],
                        ['match', ['get', 'layer'], ['polygon'], true, false],
                    ],
                    style: {
                        color: '#ff000044',
                    },
                });
                map.addLayer({
                    type: 'line',
                    id: 'my-line',
                    filter: [
                        'all',
                        ['match', ['sourceAttr', 'type'], ['geojson'], true, false],
                        ['match', ['get', 'layer'], ['line'], true, false],
                    ],
                    style: {
                        color: '#ffcd17',
                        width: 7,
                    },
                });
                map.addLayer({
                    type: 'point',
                    id: 'my-marker',
                    filter: [
                        'all',
                        ['match', ['sourceAttr', 'type'], ['geojson'], true, false],
                        ['match', ['get', 'layer'], ['marker'], true, false],
                    ],
                    style: {
                        iconImage: 'ent_i',
                        iconWidth: 25,
                        textField: ['get', 'label'],
                        textFont: ['Noto_Sans'],
                        textColor: '#0098ea',
                        textHaloColor: '#fff',
                        textHaloWidth: 1,
                        iconPriority: 100,
                        textPriority: 100,
                    },
                });
            });
        </script>
    </body>
</html>

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

<!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="A looped objects on the map example" />
        <style>
            html,
            body,
            #container {
                margin: 0;
                width: 100%;
                height: 100%;
                overflow: hidden;
            }

            .popup {
                position: absolute;
                transform: translate(-50%, -100%);
                display: flex;
                flex-direction: column;
                min-width: 200px;
            }
            .popup-content {
                padding: 5px;
                border-radius: 4px;
                background: #fff;
                box-shadow: 0 1px 2px 0 rgba(38, 38, 38, 0.2);
            }
            .popup-tip {
                width: 0;
                height: 0;
                align-self: center;
                border-left: 10px solid transparent;
                border-right: 10px solid transparent;
                border-top: 10px solid #fff;
            }
        </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: [180, 0],
                zoom: 2,
                key: 'Your API access key',
                loopWorld: true,
            });

            new mapgl.Polygon(map, {
                coordinates: [[
                    [-218.89441752904858, 70.30565959814733],
                    [-225.925667557824, -45.73328345859119],
                    [-132.76160508486493, -14.81241744766605],
                    [-126.78504256222055, 58.15022232449164],
                    [-218.89441752904858, 70.30565959814733],
                ]],
                color: '#00FF0044',
                strokeColor: '#00ff00',
            });

            new mapgl.Polyline(map, {
                    coordinates: [
                        [-223.46245108836405, -26.918360474783015],
                        [-186.8219637290612, 3.7079820374058414],
                        [-128.74592895322968, 37.040091496754826],
                        [-73.69682609848928, 51.05782228027315],
                        [-12.524951100324575, 57.78845028707578],
                        [56.02973638807563, 61.681423620684775],
                        [160.94514533960353, 63.65208904762537],
                        [259.0310828109286, 65.02205304070272],
                    ],
                    dashLength: 10,
            });

            new mapgl.Marker(map, {
                coordinates: [-235.06629252685886, 57.7772495365397],
                icon: 'https://docs.2gis.com/img/mapgl/marker.svg',
            });

            new mapgl.Marker(map, {
                coordinates: [216.33995744596837, -35.920495472932814],
                label: {
                    text: "The marker's label",
                    offset: [0, 25],
                    relativeAnchor: [0.5, 0],
                    image: {
                        url: 'https://docs.2gis.com/img/mapgl/tooltip-top.svg',
                        size: [100, 50],
                        stretchX: [
                            [10, 40],
                            [60, 90],
                        ],
                        stretchY: [[20, 40]],
                        padding: [20, 10, 10, 10],
                    },
                },
            });

            new mapgl.HtmlMarker(map, {
                coordinates: [170, 0],
                html: `<div class="popup">
                    <div class="popup-content">
                        This is a text of the popup
                    </div>
                    <div class="popup-tip"></div>
                </div>`,
            });
        </script>
    </body>
</html>