Adicionar uma camada do mapa de calor no SDK do iOS (visualização)
Observação
Desativação do SDK do iOS no Azure Mapas
O SDK Nativo do Azure Mapas para iOS já foi preterido e será desativado em 31/03/25. Para evitar interrupções de serviço, migre para o SDK da Web do Azure Mapas até 31/03/25. Para obter mais informações, confira O guia de migração do SDK do iOS no Azure Mapas.
Mapas de calor, também conhecidos como mapas de densidade de ponto, são um tipo de visualização de dados. Eles são usados para representar a densidade de dados usando uma gama de cores e mostrar os "pontos de acesso" dos dados em um mapa. Mapas de calor são uma ótima maneira de renderizar conjuntos de valores com um grande número de pontos.
A renderização de dezenas de milhares de pontos como símbolos pode abranger a maior parte da área do mapa. Esse caso provavelmente resultará em muitos símbolos sobrepostos. O que dificulta uma compreensão melhor dos dados. No entanto, a visualização desse mesmo conjunto de dados como um mapa de calor facilita a visualização da densidade e da densidade relativa de cada ponto de dados.
Você pode usar mapas de calor em vários cenários diferentes, incluindo:
- Dados de temperatura: fornece aproximações de qual é a temperatura entre dois pontos de dados.
- Dados para sensores de ruído: mostra não apenas a intensidade do ruído em que o sensor está, mas também pode fornecer informações sobre a dissipação ao longo de uma distância. O nível de ruído em um site pode não estar alto. Se a área de cobertura de ruído de vários sensores se sobrepuser, é possível que essa área sobreposta venha a ter níveis de ruído maiores. Dessa forma, a área sobreposta estaria visível no mapa de calor.
- Rastreamento de GPS: inclui a velocidade como um mapa de altura ponderada, em que a intensidade de cada ponto de dados é baseada na velocidade. Por exemplo, essa funcionalidade fornece uma maneira de ver onde um veículo estava acelerando.
Dica
Por padrão, as camadas do mapa de calor renderizam as coordenadas de todas as geometrias em uma fonte de dados. Para limitar a camada de modo que ela só renderize recursos de geometria de ponto, defina a opção filter
da camada como NSPredicate(format: "%@ == \"Point\"", NSExpression.geometryTypeAZMVariable)
. Se você também quiser incluir recursos do MultiPoint, use NSCompoundPredicate
.
Internet das Coisas Show-Mapas de calor e sobreposições de imagem no Azure Mapas
Pré-requisitos
Conclua as etapas no artigo Guia de Início Rápido: Criar um documento de aplicativo iOS . Os blocos de código neste artigo podem ser inseridos na viewDidLoad
função deViewController
.
Adicionar uma camada do mapa de calor
Para renderizar uma fonte de dados de pontos como mapa de calor, passe sua fonte de dados para uma instância da classe HeatMapLayer
e adicione-a ao mapa.
O exemplo de código a seguir carrega um feed GeoJSON de terremotos da última semana e os renderiza como um mapa de calor. Cada ponto de dados é renderizado com um raio de 10 pontos em todos os níveis de zoom. Para garantir uma melhor experiência do usuário, o mapa de calor está abaixo da camada de rótulo para que os rótulos fiquem claramente visíveis. Os dados neste exemplo são do Programa de riscos de terremoto 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")
A captura de tela a seguir mostra um mapa carregando um mapa de calor usando o código acima.
Personalize a camada do mapa de calor
O exemplo anterior personalizou o mapa de calor, definindo as opções de raio e opacidade. A camada do mapa de calor fornece várias opções de personalização, incluindo:
heatmapRadius
: Define um raio em pontos no qual renderizar cada ponto de dados. Você pode definir o raio como um número fixo ou como uma expressão. Usando uma expressão, você pode dimensionar o raio com base no nível de zoom, e representar uma área espacial consistente no mapa (por exemplo, um raio de 5 milhas).heatmapColor
: Especifica como o mapa de calor é colorido. Um gradiente de cor é um recurso comum dos mapas de calor. Você pode obter o efeito com umaNSExpression(forAZMInterpolating:curveType:parameters:stops:)
expressão. Você também pode usar umaNSExpression(forAZMStepping:from:stops:)
expressão para colorir o mapa de calor, dividindo a densidade visualmente em intervalos que se assemelham a uma contorno ou a um mapa de estilo de radar. Essas paletas de cores definem as cores do valor de densidade mínimo ao máximo.Você especifica valores de cor para mapas de calor como uma expressão sobre o valor
NSExpression.heatmapDensityAZMVariable
. A cor da área em que não há dados é definida no índice 0 da expressão de "interpolação", ou a cor padrão de uma expressão "de nível". Você pode usar esse valor para definir uma cor de plano de fundo. Frequentemente, o valor é definido como transparente ou preto semitransparente.Aqui estão exemplos de expressões de cores:
// 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
: Especifica o quanto opaca ou transparente é a camada do mapa de calor.heatmapIntensity
: Aplica um multiplicador para o peso de cada ponto de dados para aumentar a intensidade geral do mapa de calor. Isso causa uma diferença no peso dos pontos de dados, facilitando a visualização.heatmapWeight
Por padrão, todos os pontos de dados têm um peso de 1, portanto, e são ponderados igualmente. A opção de peso atua como um multiplicador, e você pode defini-la como um número ou uma expressão. Se um número for definido como o peso, é equivalente a colocar cada ponto de dados no mapa duas vezes. Por exemplo, se o peso for2
, a densidade dobrará. Definir a opção de peso para um número renderiza o mapa de calor de maneira semelhante a usar a opção de intensidade.No entanto, se você usar uma expressão, o peso de cada ponto de dados poderá ser baseado nas propriedades de cada ponto de dados. Por exemplo, suponha que cada ponto de dados representa um terremoto. O valor de magnitude tem sido uma métrica importante para cada ponto de dados de terremoto. Terremotos ocorrem o tempo todo, mas a maioria tem uma magnitude baixa e não são percebidos. Use o valor de magnitude em uma expressão para atribuir o peso a cada ponto de dados. Usando o valor de magnitude para atribuir o peso, você obtém uma representação melhor da significância dos terremotos dentro do mapa de calor.
minZoom
emaxZoom
: o intervalo de nível de zoom em que a camada deve ser exibida.filter
: um predicado de filtro usado para limitar o que foi recuperado da origem e renderizado na camada.sourceLayer
: se a fonte de dados conectada à camada for uma fonte de bloco de vetor, uma camada de origem dentro dos blocos de vetor deverá ser especificada.visible
: oculta ou mostra a camada.
O seguinte exemplo demonstra um mapa de calor usando uma expressão de interpolação linear para criar um gradiente de cores suave. A propriedade mag
definida nos dados é usada com uma interpolação exponencial para definir o peso ou a relevância de cada ponto de dados.
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
])
)
)
])
A captura de tela a seguir mostra a camada do mapa de calor personalizada acima usando os mesmos dados do exemplo do mapa de calor anterior.
Mapa de calor com zoom consistente
Por padrão, o raios de pontos de dados renderizados na camada do mapa de calor têm um raio de ponto fixo para todos os níveis de zoom. À medida que você aplica zoom no mapa, os dados são agregados e a camada do mapa de calor fica diferente. O vídeo a seguir mostra o comportamento padrão do mapa de calor onde ele mantém um raio de ponto ao ampliar o mapa.
Use uma expressão zoom
para dimensionar o raio para cada nível de zoom, de modo que cada ponto de dados cubra a mesma área física do mapa. Essa expressão faz com que a camada do mapa de calor pareça mais estática e consistente. Cada nível de zoom do mapa tem duas vezes mais pontos vertical e horizontalmente do que o nível de zoom anterior.
Dimensionar o raio para que ele fique duplo com cada nível de zoom cria um mapa de calor que parece consistente em todos os níveis de zoom. Para aplicar esse dimensionamento, use NSExpression.zoomLevelAZMVariable
com uma expressão base 2 exponential interpolation
, com o conjunto de raio de ponto definido para o nível de zoom mínimo e um raio dimensionado para o nível máximo de zoom calculado como pow(2, maxZoom - minZoom) * radius
, como mostrado no exemplo a seguir. Aplique zoom no mapa para ver como o mapa de calor é dimensionado com o nível de zoom.
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
])
)
)
])
O vídeo a seguir mostra um mapa executando o código acima, que dimensiona o raio enquanto o mapa está sendo ampliado para criar uma renderização consistente do mapa de calor entre níveis de zoom.
Dica
Quando você habilita o clustering na fonte de dados, os pontos próximos uns dos outros são agrupados em conjunto como um ponto clusterizado. Você pode usar a contagem de pontos de cada cluster como a expressão de peso para o mapa de calor. Isso pode reduzir significativamente o número de pontos a serem renderizados. A contagem de ponto de um cluster é armazenada em uma propriedade point_count
do recurso de ponto:
let layer = HeatMapLayer(source: source, options: [
.heatmapWeight(from: NSExpression(forKeyPath: "point_count"))
])
Se o raio de clustering for apenas alguns pontos, haverá uma pequena diferença visual na renderização. Raios maiores agrupam mais pontos nos clusters de cada um, e melhoram o desempenho do mapa de calor.
Informações adicionais
Para obter mais exemplos de código para adicionar aos seus mapas, consulte os seguintes artigos: