我目前正在为我的公司开发一个内部 CRM 应用程序。它使用 Blazor 构建,并利用 Azure Maps javascript SDK。我正在使用 Azure Maps 来可视化我公司游戏玩家收集的地图项。根据 Microsoft 提供的文档,所有地图设置都是在 javascript 中完成的。该地图有一个用于显示点的符号层,以及一个用于渲染给定玩家行进路径的线层。此外,我们正在生成玩家收集统计数据的摘要(速度、距离和收集之间的时间)。这个组件所在的页面有一个 DateRangePicker、一个不同项目类型的下拉菜单和一个运行查询的按钮。目前,该网页的用户可以更改日期范围和项目类型并重新运行查询。这会导致摘要以及包含所有点和线的地图被正确地重新渲染。但是,当重新渲染地图时,附加到点的弹出窗口不再在地图上,或者至少对鼠标事件没有响应。如果有人对如何在地图渲染中保留和更新我的弹出窗口有任何想法,他们将不胜感激。
2 回答
0
很高兴在这里您解决了您的问题并为其他人发布了答案。一项建议是,尽可能重用地图实例和图层。您可以在您的应用程序中运行一次上面的代码,然后在将来使用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();
}
}
}
于 2020-11-18T23:20:22.807 回答
0
在尝试创建和渲染另一个地图之前,我能够解决处理任何地图资源的问题。这确保了以前地图渲染中的任何 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);
});
}
于 2020-11-18T19:55:58.403 回答