繁体   English   中英

重新渲染我的地图时,如何更新 Azure Maps 上的弹出窗口?

[英]How do I update popups on Azure Maps when re-rendering my map?

我目前正在为我的公司开发内部 CRM 应用程序。 它使用 Blazor 构建,并使用 Azure Maps javascript SDK。 我正在使用 Azure Maps 来可视化我公司游戏玩家收集的地图项目。 根据 Microsoft 提供的文档,所有地图设置都是在 javascript 中完成的。 该地图有一个用于显示点的符号层和一个用于渲染给定玩家行进路径的线层。 此外,我们正在生成玩家收集统计数据的摘要(速度、距离和收集之间的时间)。 该组件所在的页面有一个 DateRangePicker、一个不同项目类型的下拉菜单和一个运行查询的按钮。 目前,此网页的用户可以更改日期范围和项目类型并重新运行查询。 这会导致摘要以及包含所有点和线的地图被正确重新渲染。 然而,当地图被重新渲染时,附加到点的弹出窗口不再在地图上,或者至少对鼠标事件没有响应。 如果有人对如何在地图渲染中保留和更新我的弹出窗口有任何想法,我们将不胜感激。

在尝试创建和渲染另一个地图之前,我能够解决处理任何地图资源的问题。 这确保了之前地图渲染中的任何 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();
        }       
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM