你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
在 iOS SDK 中添加热度地图层(预览)
注意
Azure Maps iOS SDK 停用
适用于 iOS 的 Azure Maps 本机 SDK 现已弃用,将于 2025 年 3 月 31 日停用。 为了避免服务中断,请在 2025 年 3 月 31 日之前迁移到 Azure Maps Web SDK。 有关详细信息,请参阅 Azure Maps iOS SDK 迁移指南。
热度地图也称为点密度地图,是一种数据可视化效果。 它们用于通过一系列颜色表示数据密度,并在地图上显示数据“热点”。 热度地图是呈现包含大量点的数据集的极佳方式。
以符号形式呈现数以万计的点可能会覆盖大部分地图区域。 而这种情况可能会导致许多符号相互叠加, 因而难以更好地了解数据。 但是,将此数据集可视化为热度地图可以轻松观察密度,以及每个数据点的相对密度。
可以在许多不同的方案中使用热度地图,其中包括:
- 温度数据:提供两个数据点之间的温度近似值。
- 噪声传感器数据:不仅显示传感器所在位置的噪声强度,而且还可提供一段距离内的消散情况见解。 任何一个场地的噪声级别可能不高。 如果多个传感器的噪声覆盖区域重叠,则此重叠区域可能会出现更高的噪声级别。 因此,重叠区域将在热度地图中可见。
- GPS 轨迹:将速度包含为加权高度地图,其中每个数据点的强度基于速度。 例如,使用此功能可以查看车辆的加速位置。
提示
默认情况下,热度地图层将呈现数据源中所有几何图形的坐标。 若要限制层以便仅呈现点几何图形功能,请将层的 filter
选项设置为 NSPredicate(format: "%@ == \"Point\"", NSExpression.geometryTypeAZMVariable)
。 如果还想要包含 MultiPoint 功能,请使用 NSCompoundPredicate
。
物联网展示 - Azure Maps 中的热量地图和图像覆盖
先决条件
请务必完成快速入门:创建 iOS 应用文档中的步骤。 可以将本文中的代码块插入到 ViewController
的 viewDidLoad
函数。
添加热度地图层
若要将点数据源呈现为热度地图,请将数据源传递到 HeatMapLayer
类的实例中,并将其添加到地图。
以下代码示例加载了过去一周地址的 GeoJSON 源,并以热度地图的形式进行呈现。 每个数据点都以所有缩放范围的 10 个数据点半径形式呈现。 为确保提供更好的用户体验,热度地图位于标签层之下,以便标签保持清晰可见。 此示例中的数据摘自 USGS 地震危害应对计划。
// Create a data source.
let source = DataSource()
// Import the geojson data and add it to the data source.
let url = URL(string: "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_week.geojson")!
source.importData(fromURL: url)
// Add data source to the map.
map.sources.add(source)
// Create a heat map layer.
let layer = HeatMapLayer(
source: source,
options: [
.heatmapRadius(10),
.heatmapOpacity(0.8)
]
)
// Add the layer to the map, below the labels.
map.layers.insertLayer(layer, below: "labels")
以下屏幕截图显示了使用上述代码加载热度地图的地图。
自定义热度地图层
前面的示例通过设置半径和不透明度选项来自定义热度地图。 热度地图层提供多个选项用于自定义,其中包括:
heatmapRadius
:定义要呈现每个数据点的数据点半径。 可将半径设置为固定数字或表达式。 使用表达式可以根据缩放级别来缩放半径,并在地图上表示一个一致的空间区域(例如,5 英里半径)。heatmapColor
:指定如何为热度地图赋色。 颜色渐变是热度地图的常用功能。 可以使用NSExpression(forAZMInterpolating:curveType:parameters:stops:)
表达式来实现该效果。 还可以使用NSExpression(forAZMStepping:from:stops:)
表达式为热度地图赋色,直观地将密度分解到类似于等高线或雷达式地图的范围中。 这些调色板定义了从最小到最大密度值的颜色。将热度地图的颜色值指定为基于
NSExpression.heatmapDensityAZMVariable
值的表达式。 “内插”表达式的索引 0 处定义了没有数据的颜色区域,或“递阶”表达式的默认颜色。 可以使用此值来定义背景色。 通常此值设置为“透明”,或“半透明的黑色”。下面是颜色表达式示例:
// Interpolated color expression
NSExpression(
forAZMInterpolating: .heatmapDensityAZMVariable,
curveType: .linear,
parameters: nil,
stops: NSExpression(forConstantValue: [
0: UIColor.magenta.withAlphaComponent(0),
0.01: UIColor.magenta,
0.5: UIColor(red: 251/255, green: 0, blue: 251/255, alpha: 1),
1: UIColor(red: 0, green: 195/255, blue: 1, alpha: 1)
])
)
// Stepped color expression
NSExpression(
forAZMStepping: .heatmapDensityAZMVariable,
from: NSExpression(forConstantValue: UIColor.clear),
stops: NSExpression(forConstantValue: [
0.01: UIColor(red: 0, green: 0, blue: 128/255, alpha: 1),
0.25: UIColor.cyan,
0.5: UIColor.green,
0.75: UIColor.yellow,
1: UIColor.red
])
)
heatmapOpacity
:指定热度地图层的不透明度或透明度。heatmapIntensity
:对每个数据点的权重应用乘数,以增加热度地图的整体强度。 这会导致数据点的权重出现差异,使其更易于可视化。heatmapWeight
:默认情况下,所有数据点的权重均为 1,并且是平均加权的。 权重选项充当乘数,可以设置为数字或表达式。 如果将某个数字设置为权重,则这相当于将每个数据点置于地图上两次。 例如,如果权重为2
,则密度会加倍。 将权重选项设置为一个数字,以类似于使用强度选项的方式来呈现热度地图。但是,如果使用表达式,则每个数据点的权重可以基于每个数据点的属性。 例如,假设每个数据点表示地震。 震级值是每个地震数据点的重要指标。 地震时时刻刻都在发生,但大多数震级都很低,以致于感觉不到。 在表达式中使用震级值可将权重分配到每个数据点。 使用震级值分配权重可以更好地在热度地图中表示地震的严重程度。
minZoom
和maxZoom
:应显示层的缩放级别范围。filter
:用于限制从源检索并在层中呈现的筛选器谓词。sourceLayer
如果连接到层的数据源是矢量图块源,那么必须指定矢量图块中的源层。visible
:隐藏或显示层。
以下示例演示了一个热度地图,它使用了线性内插表达式来创建平滑颜色渐变。 数据中定义的 mag
属性与指数内插结合使用来设置每个数据点的权重或相关性。
let layer = HeatMapLayer(source: source, options: [
.heatmapRadius(10),
// A linear interpolation is used to create a smooth color gradient based on the heat map density.
.heatmapColor(
from: NSExpression(
forAZMInterpolating: .heatmapDensityAZMVariable,
curveType: .linear,
parameters: nil,
stops: NSExpression(forConstantValue: [
0: UIColor.black.withAlphaComponent(0),
0.01: UIColor.black,
0.25: UIColor.magenta,
0.5: UIColor.red,
0.75: UIColor.yellow,
1: UIColor.white
])
)
),
// Using an exponential interpolation since earthquake magnitudes are on an exponential scale.
.heatmapWeight(
from: NSExpression(
forAZMInterpolating: NSExpression(forKeyPath: "mag"),
curveType: .exponential,
parameters: NSExpression(forConstantValue: 2),
stops: NSExpression(forConstantValue: [
0: 0,
// Any earthquake above a magnitude of 6 will have a weight of 1
6: 1
])
)
)
])
以下屏幕截图介绍了以上自定义热度地图层,它们使用与之前热度地图中相同的数据。
可一致缩放的热度地图
默认情况下,热度地图层中呈现的数据点半径对所有缩放级别采用固定点半径。 缩放地图时,数据将会聚合,热度地图层将呈现不同的外观。 以下视频介绍了热度地图的默认行为,即在缩放地图时维护数据点半径。
使用 zoom
表达式缩放每个缩放级别的半径,使每个数据点涵盖相同的地图物理区域。 此表达式使热度地图层显得更为静态且一致。 地图的每个缩放级别的垂直和水平点是前一个缩放级别的两倍。
调整半径使其在每个缩放级别中翻倍,会创建一个在所有缩放级别下均保持一致外观的热度地图。 若要应用这种调整,请将 NSExpression.zoomLevelAZMVariable
与以 2 为底的 exponential interpolation
表达式配合使用,并为最小缩放级别设置数据点半径,为最大缩放级别设置标度半径(计算方式为 pow(2, maxZoom - minZoom) * radius
,如以下示例中所示)。 缩放地图,观看热度地图如何根据缩放级别而缩放。
let layer = HeatMapLayer(source: source, options: [
.heatmapOpacity(0.75),
.heatmapRadius(
from: NSExpression(
forAZMInterpolating: .zoomLevelAZMVariable,
curveType: .exponential,
parameters: NSExpression(forConstantValue: 2),
stops: NSExpression(forConstantValue: [
// For zoom level 1 set the radius to 2 points.
1: 2,
// Between zoom level 1 and 19, exponentially scale the radius from 2 points to 2 * 2^(maxZoom - minZoom) points.
19: pow(2, 19 - 1) * 2
])
)
)
])
以下视频展示了运行以上代码的地图,它能在地图缩放的同时缩放半径,从而创建在缩放级别下保持一致外观的热度地图。
提示
在数据源上启用聚类分析时,相邻的点可以作为一个聚类点组合在一起。 可以使用每个聚类的点计数作为热度地图的权重表达式。 这可以大幅减少要呈现的点数。 聚类点计数存储在点特征的 point_count
属性中:
let layer = HeatMapLayer(source: source, options: [
.heatmapWeight(from: NSExpression(forKeyPath: "point_count"))
])
如果聚类分析半径只有几个数据点,那么呈现的视觉差异就很小。 更大的半径可将更多的点分组到每个聚类,从而改善热度地图的性能。
其他信息
有关可向地图添加的更多代码示例,请参阅以下文章: