【问题标题】:Azure Maps SDK popup does not open after initial loadAzure Maps SDK 弹出窗口在初始加载后未打开
【发布时间】:2021-04-12 02:25:38
【问题描述】:

我在使用 JavaScript 互操作的 Blazor 服务器应用程序中使用 Azure Maps SDK。地图运行良好,渲染完美。

在地图组件的初始加载时,单击地图上的图钉时弹出窗口会正确显示。但是,当数据源通过 API 调用 datasource.importDataFromUrl(organisationDataFeed); 更改时,它会正确带回过滤后的数据,但是当我再次单击其中一个引脚时,不会显示弹出窗口。正在调用 click 事件处理程序(用于 pin),但弹出窗口未打开。

(function () {

    var map, datasource, popup;

    // Global export
    window.azuremaps = {
        initMap: function (organisationDataFeed) {
            // Create an instance of the map control and set some options.

            map = new atlas.Map('map', {
                // center: [-97, 39],

                // center: [18.424095, -33.925000],
                center: [26.157981, -29.083937],
                zoom: 4,
                pitch: 50,
                style: 'night',
                view: 'Auto',

                // Add your Azure Maps subscription key to the map SDK. Get an Azure Maps key at https://azure.com/maps
                authOptions: {
                    authType: 'subscriptionKey',
                    subscriptionKey: ''
                }
            });

            map.controls.add([
                new atlas.control.ZoomControl(),
                new atlas.control.CompassControl(),
                new atlas.control.PitchControl(),
                new atlas.control.StyleControl()
            ], {
                position: "top-right"
            });

            // Wait until the map resources are ready.
            map.events.add('ready', function () {

                // Create a data source and add it to the map.
                datasource = new atlas.source.DataSource(null, {
                    //Tell the data source to cluster point data.
                    cluster: true,

                    //The radius in pixels to cluster points together.
                    clusterRadius: 45,

                    // The maximium zoom level in which clustering occurs.
                    // If you zoom in more than this, all points are rendered as symbols.
                    clusterMaxZoom: 15
                });
                map.sources.add(datasource);

                //Create a bubble layer for rendering clustered data points.
                var clusterBubbleLayer = new atlas.layer.BubbleLayer(datasource, null, {
                    //Scale the size of the clustered bubble based on the number of points inthe cluster.
                    radius: [
                        'step',
                        ['get', 'point_count'],
                        20,         //Default of 20 pixel radius.
                        100, 30,    //If point_count >= 100, radius is 30 pixels.
                        750, 40     //If point_count >= 750, radius is 40 pixels.
                    ],

                    //Change the color of the cluster based on the value on the point_cluster property of the cluster.
                    color: [
                        'step',
                        ['get', 'point_count'],
                        'rgba(0,255,0,0.8)',            //Default to green. 
                        100, 'rgba(255,255,0,0.8)',     //If the point_count >= 100, color is yellow.
                        750, 'rgba(255,0,0,0.8)'        //If the point_count >= 100, color is red.
                    ],
                    strokeWidth: 0,
                    filter: ['has', 'point_count'] //Only rendered data points which have a point_count property, which clusters do.
                });

                //Add a click event to the layer so we can zoom in when a user clicks a cluster.
                map.events.add('click', clusterBubbleLayer, clusterClicked);

                //Add mouse events to change the mouse cursor when hovering over a cluster.
                map.events.add('mouseenter', clusterBubbleLayer, function () {
                    map.getCanvasContainer().style.cursor = 'pointer';
                });

                map.events.add('mouseleave', clusterBubbleLayer, function () {
                    map.getCanvasContainer().style.cursor = 'grab';
                });

                // Create a layer to render the individual locations.
                var individualSymbolLayer = new atlas.layer.SymbolLayer(datasource, null, {
                    filter: ['!', ['has', 'point_count']], //Filter out clustered points from this layer.

                    textOptions: {
                        textField: ['get', 'name'],
                        color: "#FFFFFF",
                        offset: [0, -2.2]
                    },
                });

                map.events.add('click', individualSymbolLayer, symbolClicked);

                //Add the clusterBubbleLayer and two additional layers to the map.
                map.layers.add([
                    clusterBubbleLayer,

                    // Create a symbol layer to render the count of locations in a cluster.
                    new atlas.layer.SymbolLayer(datasource, null, {
                        iconOptions: {
                            image: 'none' //Hide the icon image.
                        },
                        textOptions: {
                            textField: ['get', 'point_count_abbreviated'],
                            offset: [0, 0.4]
                        }
                    }),

                    individualSymbolLayer
                    
                ]);

                // Create a popup but leave it closed so we can update it and display it later.
                popup = new atlas.Popup({
                    pixelOffset: [0, -18],
                    closeButton: true
                });

                // Retrieve a GeoJSON data set and add it to the data source. 
                datasource.importDataFromUrl(organisationDataFeed);
            });
        },
    };

    function clusterClicked(e) {
        if (e && e.shapes && e.shapes.length > 0 && e.shapes[0].properties.cluster) {
            // Get the clustered point from the event.
            var cluster = e.shapes[0];

            // Get the cluster expansion zoom level. This is the zoom level at which the cluster starts to break apart.
            datasource.getClusterExpansionZoom(cluster.properties.cluster_id).then(function (zoom) {

                //Update the map camera to be centered over the cluster. 
                map.setCamera({
                    center: cluster.geometry.coordinates,
                    zoom: zoom + 2,
                    type: 'ease',
                    duration: 200
                });
            });
        }
    }

    function symbolClicked(e) {
        // Make sure the event occured on a point feature.
        
        var popupTemplate = '<div class="card border-success" style="visibility: visible"><div class="card-header" style="visibility: visible">{name}</div><div class="card-body text-success" style="visibility: visible"><h5 class="card-title" style="visibility: visible">{description}</h5><p class="card-text" style="visibility: visible">Contact: {contact}</p><p class="card-text">Web: {website}</p></div></div>';

        if (e.shapes && e.shapes.length > 0) {
            var content, coordinate;

            // Check to see if the first value in the shapes array is a Point Shape.
            if (e.shapes[0] instanceof atlas.Shape && e.shapes[0].getType() === 'Point') {
                var properties = e.shapes[0].getProperties();
                content = popupTemplate.replace(/{name}/g, properties.name).replace(/{description}/g, properties.description).replace(/{contact}/g, properties.contact).replace(/{website}/g, properties.website);
                coordinate = e.shapes[0].getCoordinates();
            }
            else if (e.shapes[0].type === 'Feature' && e.shapes[0].geometry.type === 'Point') {

                // Check to see if the feature is a cluster.
                if (e.shapes[0].properties.cluster) {
                    content = '<div style="padding:10px;">Cluster of ' + e.shapes[0].properties.point_count + ' symbols</div>';
                } else {
                    // Feature is likely from a VectorTileSource.
                    content = popupTemplate.replace(/{name}/g, properties.name).replace(/{description}/g, properties.description).replace(/{contact}/g, properties.contact).replace(/{website}/g, properties.website);
                }

                coordinate = e.shapes[0].geometry.coordinates;
            }
            
            if (content && coordinate) {
                // Populate the popupTemplate with data from the clicked point feature.

                console.log("JB content");
                console.log(content);

                console.log("JB coordinate");
                console.log(coordinate);

                popup.setOptions({
                    //Update the content of the popup.
                    content: content,

                    //Update the position of the popup with the symbols coordinate.
                    position: coordinate
                });

                console.log("JB: logging map variable");
                console.log(map);

                popup.open(map);
            }
        }
    }

})();

contentcoordinate 填充了值并评估为 true,选项设置正确,但只有最后一行:popup.open(map); 如果数据无效源更改将新数据带回地图。它在初始加载时完美运行。

任何想法我可以做些什么来让它工作?谢谢

【问题讨论】:

  • 你能分享一下完成弹窗绑定的代码吗?
  • @Umair 这是从 Blazor 调用以初始化地图的代码。有用。弹出模板在函数 symbolClicked(e)

标签: javascript blazor azure-maps


【解决方案1】:

有几件事可以尝试:

  • 仔细检查坐标和内容的值。坐标应该是一个带有 [longitude,latitude] 数字的数组(确保它们不是数字的字符串值)。内容应该是 DOMElement(即 div)或字符串。如果是其他任何东西,它可能不会显示任何东西。

  • 再次检查“地图”变量是否为地图。如果由于某种原因引用丢失,该功能将不起作用。

  • 看起来你一直在创建一个新的弹出窗口。通常,应用程序一次只想显示一个弹出窗口。在这种情况下,创建单个弹出窗口并重用它会更有效,如下例所示:https://azuremapscodesamples.azurewebsites.net/index.html?sample=Reusing%20Popup%20with%20Multiple%20Pins

【讨论】:

  • 感谢您的回复。这是非常感谢的。 1. 所以内容是一个 div(请参阅上面我创建弹出模板的更新帖子)。 2. 坐标以数组中的数字形式返回。我检查了浏览器控制台。 3. 是的,地图参考仍然是参考。
  • 我注意到,当我在初始加载后打开弹出窗口,然后在后续加载后再次打开它时,它不会显示。但是,如果我加载地图一次然后更改搜索过滤器并重新加载地图第二次或第三次然后弹出窗口打开。仅当我打开它然后执行地图组件的第二次重新加载/重新渲染时,它才不起作用。
  • 我还注意到弹出窗口仍然在 DOM 中,它看起来是不可见的。所以我在所有 div 元素中添加了一个内联 CSS style="visibility: visible" ,但它仍然没有显示。地图元素是否在关闭弹出窗口时隐藏它?也许它正在将 CSS 样式设置为隐藏在某个地方?如果是这种情况,不知道去哪里看
  • 在你的代码中没有什么特别之处,它看起来很好。您不需要为您的 div 添加可见性。弹出类使用 div 包装您的内容并在那里设置可见性。如果检查 DOM 时弹出的 div 仍然显示隐藏可见性,那么要么没有调用 open 函数,要么在某处调用了 close 函数。目前我唯一能想到的其他事情可能是您的应用程序中的某些 CSS 以某种方式导致了渲染问题。尝试使用浏览器开发工具手动更改可见性以查看是否存在新内容。
  • 好的,谢谢。考虑到您的建议,让我进一步调查。
猜你喜欢
  • 2017-07-20
  • 1970-01-01
  • 1970-01-01
  • 2018-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多