Partilhar via


Adicionar uma camada de mapa de calor no SDK do iOS (Pré-visualização)

Nota

Aposentadoria do SDK do iOS do Azure Maps

O SDK nativo do Azure Maps para iOS foi preterido e será desativado em 31/03/25. Para evitar interrupções de serviço, migre para o SDK da Web do Azure Maps até 31/03/25. Para obter mais informações, consulte O guia de migração do SDK do iOS do Azure Maps.

Os mapas de calor, também conhecidos como mapas de densidade de pontos, são um tipo de visualização de dados. Eles são usados para representar a densidade de dados usando um intervalo de cores e mostrar os "pontos quentes" de dados em um mapa. Os mapas de calor são uma ótima maneira de renderizar conjuntos de dados com um grande número de pontos.

Renderizar dezenas de milhares de pontos como símbolos pode cobrir a maior parte da área do mapa. Este caso provavelmente resulta na sobreposição de muitos símbolos. Dificultando uma melhor compreensão dos dados. No entanto, visualizar esse 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 muitos cenários diferentes, incluindo:

  • Dados de temperatura: fornece aproximações para qual é a temperatura entre dois pontos de dados.
  • Dados para sensores de ruído: Mostra não só a intensidade do ruído onde o sensor está, mas também pode fornecer informações sobre a dissipação à distância. O nível de ruído em qualquer local pode não ser alto. Se a área de cobertura de ruído de vários sensores se sobrepuser, é possível que essa área sobreposta tenha níveis de ruído mais altos. Como tal, a área sobreposta seria visível no mapa de calor.
  • Rastreamento GPS: Inclui a velocidade como um mapa de altura ponderada, onde a intensidade de cada ponto de dados é baseada na velocidade. Por exemplo, esta funcionalidade fornece uma forma de ver onde um veículo estava em excesso de velocidade.

Gorjeta

Por padrão, as camadas de mapa de calor renderizam as coordenadas de todas as geometrias em uma fonte de dados. Para limitar a camada para que ela processe apenas recursos de geometria de ponto, defina a filter opção da camada como NSPredicate(format: "%@ == \"Point\"", NSExpression.geometryTypeAZMVariable). Se você quiser incluir recursos do MultiPoint também, use NSCompoundPredicate.

Internet of Things Show - Mapas de calor e sobreposições de imagem no Azure Maps

Pré-requisitos

Certifique-se de concluir as etapas no 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 de ViewController.

Adicionar uma camada de mapa térmico

Para renderizar uma fonte de dados de pontos como um mapa de calor, passe sua fonte de dados para uma instância da HeatMapLayer classe e adicione-a ao mapa.

O exemplo de código a seguir carrega um feed GeoJSON de terremotos da semana passada 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 fica abaixo da camada de etiquetas para que elas permaneçam claramente visíveis. Os dados nesta amostra são do Programa de Riscos de Terremoto do 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.

Mapa com camada de mapa de calor de terremotos recentes.

Personalizar a camada de mapa de calor

O exemplo anterior personalizou o mapa de calor definindo as opções de raio e opacidade. A camada de mapa de calor fornece várias opções de personalização, incluindo:

  • heatmapRadius: Define um raio em pontos nos quais 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 cores é uma característica comum dos mapas de calor. Você pode obter o efeito com uma NSExpression(forAZMInterpolating:curveType:parameters:stops:) expressão. Você também pode usar uma NSExpression(forAZMStepping:from:stops:) expressão para colorir o mapa de calor, dividindo a densidade visualmente em intervalos que se assemelham a um mapa de contorno ou estilo de radar. Essas paletas de cores definem as cores do valor de densidade mínima para máxima.

    Você especifica valores de cor para mapas de calor como uma expressão no NSExpression.heatmapDensityAZMVariable valor. A cor da área onde não há dados é definida no índice 0 da expressão "Interpolação" ou a cor padrão de uma expressão "Escalonada". Você pode usar esse valor para definir uma cor de plano de fundo. Muitas vezes, esse valor é definido como transparente ou um 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 quão opaca ou transparente é a camada do mapa de calor.

  • heatmapIntensity: Aplica um multiplicador ao 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 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 é definido como o peso, é a equivalência de colocar cada ponto de dados no mapa duas vezes. Por exemplo, se o peso é 2, então a densidade dobra. Definir a opção de peso para um número renderiza o mapa de calor de forma semelhante ao uso da opção de intensidade.

    No entanto, se você usar uma expressão, o peso de cada ponto de dados pode ser baseado nas propriedades de cada ponto de dados. Por exemplo, suponha que cada ponto de dados representa um terremoto. O valor da magnitude tem sido uma métrica importante para cada ponto de dados do terremoto. Os terremotos acontecem o tempo todo, mas a maioria tem uma baixa magnitude e não é notada. 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 melhor representação do significado dos terremotos dentro do mapa de calor.

  • minZoom e maxZoom: O intervalo de nível de zoom onde a camada deve ser exibida.

  • filter: Um predicado de filtro usado para limitar o recuperado da fonte e renderizado na camada.

  • sourceLayer: Se a fonte de dados conectada à camada for uma fonte de mosaico vetorial, uma camada de origem dentro dos blocos vetoriais deverá ser especificada.

  • visible: Oculta ou mostra a camada.

O exemplo a seguir demonstra um mapa de calor usando uma expressão de interpolação de linha para criar um gradiente de cor suave. A mag propriedade 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 de mapa de calor personalizada acima usando os mesmos dados do exemplo de mapa de calor anterior.

Mapa com camada de mapa de calor personalizada de terremotos recentes.

Mapa de calor com zoom consistente

Por padrão, os raios dos pontos de dados renderizados na camada de mapa de calor têm um raio de ponto fixo para todos os níveis de zoom. À medida que você amplia o mapa, os dados se agregam e a camada do mapa de calor parece 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.

Animação mostrando um mapa ampliando com uma camada de mapa de calor mostrando um tamanho de ponto consistente.

Use uma zoom expressão 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 de mapa de calor pareça mais estática e consistente. Cada nível de zoom do mapa tem o dobro de pontos vertical e horizontalmente do que o nível de zoom anterior.

Dimensionar o raio para que ele duplique a 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 de base 2 exponential interpolation , com o raio de ponto definido para o nível mínimo de zoom e um raio dimensionado para o nível de zoom máximo calculado conforme pow(2, maxZoom - minZoom) * radius mostrado no exemplo a seguir. Amplie o 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 de mapa de calor em todos os níveis de zoom.

Animação mostrando um mapa ampliando com uma camada de mapa de calor mostrando um tamanho geoespacial consistente.

Gorjeta

Quando você habilita o clustering na fonte de dados, os pontos próximos uns dos outros são agrupados 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 pontos de um cluster é armazenada em uma point_count propriedade do recurso de ponto:

let layer = HeatMapLayer(source: source, options: [
    .heatmapWeight(from: NSExpression(forKeyPath: "point_count"))
])

Se o raio de agrupamento for de apenas alguns pontos, haveria uma pequena diferença visual na renderização. Um raio maior agrupa mais pontos em cada cluster e melhora 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: