Как обновить всплывающие окна на Картах Azure при повторном рендеринге карты?

В настоящее время я работаю над внутренним приложением CRM для своей компании. Он построен с помощью Blazor и использует SDK JavaScript для Azure Maps. Я использую Azure Maps для визуализации элементов карты, собранных игроками игры моей компании. Все настройки карты выполняются на javascript в соответствии с документацией, предоставленной Microsoft. Карта имеет слой символов для отображения точек и линейный слой для отображения пути, пройденного данным игроком. Кроме того, мы генерируем сводную статистику сбора игрока (скорость, расстояние и время между сбором). Страница, на которой находится этот компонент, имеет DateRangePicker, раскрывающееся меню с различными типами элементов и кнопку для выполнения запроса. В настоящее время пользователи этой веб-страницы могут изменить диапазон дат и тип элемента и повторно запустить запрос.Это приводит к правильному повторному отображению сводки, а также карты со всеми точками и линией. Однако при повторном рендеринге карты всплывающие окна, прикрепленные к точкам, больше не отображаются на карте или, по крайней мере, не реагируют на события мыши. Если у кого-нибудь есть идеи о том, как сохранять и обновлять мои всплывающие окна при визуализации карт, они были бы очень признательны.

2 ответа

Мне удалось решить эту проблему, удалив все ресурсы карты, прежде чем пытаться создать и отобразить другую карту. Это гарантирует, что любой HTML из предыдущих отрисовок карты не будет мешать текущей карте.

window.adminMap = (() => {

    let map;
    let datasource;
    let point;
    let popup;

    const setupItemsMap = (subscriptionKey, mapItems) => {

        if (map != null) {
            map.dispose();
        }

        map = new atlas.Map('itemsMap', {
            center: [mapItems[0].coordinate.long, mapItems[0].coordinate.lat],
            centerOffest: [0, 0],
            zoom: 15,
            pitch: 90,
            style: 'road',
            language: 'en-US',
            view: 'Auto',
            authOptions: {
                authType: 'subscriptionKey',
                subscriptionKey: subscriptionKey
            }
        });

        map.events.add('ready', () => {

            //Create a data source and add it to the map.
            datasource = new atlas.source.DataSource(null, {
                lineMetrics: true
            });
            map.sources.add(datasource);

            var points = [];
            mapItems.forEach(function (mapItem) {

                point = new atlas.data.Feature(new atlas.data.Point([mapItem.coordinate.long, mapItem.coordinate.lat]), {
                    collectedAt: mapItem.collectedAt,
                    speed: 0
                });
                points.push(point);
            });

            points.forEach(function (point) {

                let previous;
                let current = points.indexOf(point);

                if (current > 0) {
                    previous = current - 1;
                    point.properties.speed = atlas.math.getSpeedFromFeatures(points[previous], points[current], "collectedAt", "milesPerHour", 1);
                }
                else {
                    point.properties.speed = 0;
                }
            });
            datasource.add(points);

            var line = createLineFrom(points);
            datasource.add(line);

            //Calculate a color gradient expression based on the speed of each data point.
            var speedGradient = calculateGradientExpression(points, line);

            //Create a line layer and pass in a gradient expression for the strokeGradient property.
            map.layers.add(new atlas.layer.LineLayer(datasource, null, {
                strokeWidth: 5,
                strokeGradient: speedGradient
            }));

            //Create a layer to render each data point along the path.
            var pointLayer = new atlas.layer.SymbolLayer(datasource, null, {
                //Only render point data in this layer, not the points of the line.
                filter: ['==', ['geometry-type'], 'Point']
            });

            //Create a popup. *This needs to update with the rest of the map!
            popup = new atlas.Popup();
            popup.open(map);

            map.layers.add(pointLayer);

            map.events.add('click', pointLayer, pointClicked);
        });
    }

Рад, что здесь вы решили свою проблему и опубликовали ответ для других. Одна рекомендация: по возможности лучше повторно использовать экземпляр карты и слои. Вы можете запустить приведенный выше код один раз в своем приложении, а затем в будущем использовать datasource.setShapesи переходите в новые точки. Это автоматически обновит данные на карте. Если всплывающее окно открывается при добавлении новых данных, просто закройте его. Также похоже, что некоторые оптимизации могут быть сделаны вокруг ваших расчетов кода преобразования точки / скорости. Вот измененная версия вашего кода, которая может улучшить производительность.

window.adminMap = (() => {

    let map;
    let datasource;
    let point;
    let popup;
    let lineLayer;

    const setupItemsMap = (subscriptionKey, mapItems) => {

        if (map != null) {
            map.dispose();
        }

        map = new atlas.Map('itemsMap', {
            center: [mapItems[0].coordinate.long, mapItems[0].coordinate.lat],
            centerOffest: [0, 0],
            zoom: 15,
            pitch: 90,
            style: 'road',
            language: 'en-US',
            view: 'Auto',
            authOptions: {
                authType: 'subscriptionKey',
                subscriptionKey: subscriptionKey
            }
        });

        map.events.add('ready', () => {

            //Create a data source and add it to the map.
            datasource = new atlas.source.DataSource(null, {
                lineMetrics: true
            });
            map.sources.add(datasource);
            
            lineLayer = new atlas.layer.LineLayer(datasource, null, {
                strokeWidth: 5,
                //strokeGradient: speedGradient
            });
            
            //Create a line layer and pass in a gradient expression for the strokeGradient property.
            map.layers.add(lineLayer);

            //Create a layer to render each data point along the path.
            var pointLayer = new atlas.layer.SymbolLayer(datasource, null, {
                //Only render point data in this layer, not the points of the line.
                filter: ['==', ['geometry-type'], 'Point']
            });

            //Create a popup. *This needs to update with the rest of the map!
            popup = new atlas.Popup();
            popup.open(map);

            map.layers.add(pointLayer);

            map.events.add('click', pointLayer, pointClicked);

            //Add mapItems to data source.
            setMapItems(mapItems);
        });
    }
    
    const setMapItems = (mapItems) => { 
        let points = [];        
        let previous;
        let point;
        
        for(let i = 0, len = mapItems.length; i < len; i++){
                    
            point = new atlas.data.Feature(new atlas.data.Point([mapItem.coordinate.long, mapItem.coordinate.lat]), {
                collectedAt: mapItem.collectedAt,
                speed: 0
            });
            
            if(previous){
                point.properties.speed = atlas.math.getSpeedFromFeatures(previous, point, "collectedAt", "milesPerHour", 1);
            }
            
            points.push(point);
            
            previous = point;
        }

        var line = createLineFrom(points);          
        
        //Calculate a color gradient expression based on the speed of each data point.
        lineLayer.setOptions({
            strokeGradient: calculateGradientExpression(points, line)
        });
        
        points.push(line);
        
        //Add data to data source using setShapes. This clears and adds the data and only triggers one re-render of the map.
        datasource.setShapes(points);
        
        if(popup){
            popup.close();
        }       
    }
}
Другие вопросы по тегам