新增熱度圖層次 (Android SDK)

注意

Azure 地圖服務 Android SDK 淘汰

適用於 Android 的 Azure 地圖服務 原生 SDK 現在已被取代,將於 3/31/25 淘汰。 若要避免服務中斷,請透過 3/31/25 移轉至 Azure 地圖服務 Web SDK。 如需詳細資訊,請參閱 Azure 地圖服務 Android SDK 移轉指南

熱度圖也稱為點密度地圖,是一種數據視覺效果。 它們用來代表使用一系列色彩的數據密度,並在地圖上顯示數據「熱點」。 熱度圖是轉譯具有大量點之數據集的絕佳方式。

將數以萬計的點轉譯為符號可以涵蓋大部分的地圖區域。 此案例可能會造成許多符號重疊。 讓您難以進一步了解數據。 不過,將這個與熱度圖相同的數據集可視化,可讓您輕鬆地查看每個數據點的密度和相對密度。

您可以在許多不同的案例中使用熱度圖,包括:

  • 溫度數據:提供兩個數據點之間溫度的近似值。
  • 雜訊感測器的數據:不僅顯示感測器所在雜訊的強度,還可以提供距離內消散的見解。 任何一個月臺的雜訊等級可能不高。 如果來自多個感測器的雜訊涵蓋範圍區域重疊,則此重疊區域可能會遇到較高的雜訊等級。 因此,熱度圖中會顯示重疊的區域。
  • GPS 追蹤:將速度納入加權高度地圖,其中每個數據點的強度是以速度為基礎。 例如,這項功能提供一種方法來查看車輛超速的位置。

提示

熱度圖圖層預設會轉譯數據源中所有幾何的座標。 若要限制圖層,使其只轉譯點幾何特徵,請將圖層的 filter 選項設為 eq(geometryType(), "Point")。 如果還要加上 MultiPoint 特徵,請將圖層的 filter 選項設定為 any(eq(geometryType(), "Point"), eq(geometryType(), "MultiPoint"))


必要條件

務必完成快速入門:建立 Android 應用程式文件中的步驟。 本文中的程式碼區塊可以插入地圖 onReady 事件處理常式中。

新增熱度圖圖層

若要將點的數據源轉譯為熱度圖,請將數據源傳遞至 類別的 HeatMapLayer 實例,並將其新增至地圖。

下列程式代碼範例會從過去一周載入地震的 GeoJSON 摘要,並將其轉譯為熱度圖。 每個數據點都會在所有縮放層級以 10 像素的半徑呈現。 為了確保更好的用戶體驗,熱度圖位於卷標圖層下方,讓標籤保持清晰可見。 此範例中的數據來自 USGS地震災害計劃。 此範例會使用建立數據源檔中所提供的數據匯入公用程式程式代碼區塊,從 Web 載入 GeoJSON 數據。

//Create a data source and add it to the map.
DataSource source = new DataSource();

//Import the geojson data and add it to the data source.
source.importDataFromUrl("https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_week.geojson");

//Add data source to the map.
map.sources.add(source);

//Create a heat map layer.
HeatMapLayer layer = new HeatMapLayer(source,
  heatmapRadius(10f),
  heatmapOpacity(0.8f)
);

//Add the layer to the map, below the labels.
map.layers.add(layer, "labels");
//Create a data source and add it to the map.
val source = DataSource()

//Import the geojson data and add it to the data source.
source.importDataFromUrl("https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_week.geojson")

//Add data source to the map.
map.sources.add(source)

//Create a heat map layer.
val layer = HeatMapLayer(
    source,
    heatmapRadius(10f),
    heatmapOpacity(0.8f)
)

//Add the layer to the map, below the labels.
map.layers.add(layer, "labels")

下列螢幕快照顯示使用上述程式代碼載入熱度圖的地圖。

具有近期地震熱度圖圖層的地圖

自定義熱度圖圖層

上一個範例會藉由設定半徑和不透明度選項來自定義熱度圖。 熱度圖層次提供數個選項進行自定義,包括:

  • heatmapRadius:定義圖元半徑,在其中轉譯每個數據點。 您可以將半徑設定為固定數位或表達式。 藉由使用表達式,您可以根據縮放層級來縮放半徑,並代表地圖上一致的空間區域(例如 5 英哩半徑)。

  • heatmapColor:指定熱度圖的著色方式。 色彩漸層是熱度圖的常見特徵。 您可以使用表達式來達成效果 interpolate 。 您也可以使用 step 表達式來著色熱度圖,以視覺方式將密度分成類似輪廓或雷達樣式地圖的範圍。 這些調色盤會定義從最小值到最大密度值的色彩。

    您可以指定熱度圖的 heatmapDensity 色彩值做為值的運算式。 在 「Interpolation」 表示式的索引 0 或 “Stepped” 表達式的預設色彩中,沒有定義任何數據的區域色彩。 您可以使用此值來定義背景色彩。 此值通常設定為透明,或半透明黑色。

    以下是色彩表示式的範例:

    插補色彩表達式 階梯狀色彩表達式
    插補
        linear(),
        heatmapDensity(),
        stop(0, color(Color.TRANSPARENT)),
        stop(0.01, color.MAGENTA)),
        stop(0.5, color(parseColor(“#fb00fb”))),
        stop(1, color(parseColor(“#00c3ff”)) )
    )'
    步驟(
        heatmapDensity(),
        color(Color.TRANSPARENT),
        stop(0.01, color(parseColor(“#000080”))),
        stop(0.25, color(parseColor(“#000080”))),
        stop(0.5, color.GREEN)),
        stop(0.5, color.YELLOW)),
        stop(1, color(Color.RED))
    )
  • heatmapOpacity:指定熱度圖圖層不透明或透明的方式。

  • heatmapIntensity:將乘數套用至每個數據點的加權,以增加熱度圖的整體強度。 這會導致數據點的權數有所差異,讓您更容易可視化。

  • heatmapWeight:根據預設,所有數據點的權數為1,且加權相等。 權數選項可作為乘數,您可以將它設定為數位或表達式。 如果數字設定為權數,則表示將每個數據點放在地圖上兩次的等價。 例如,如果權數為 2,則密度會加倍。 將權數選項設定為數位,會以與使用強度選項類似的方式呈現熱度圖。

    不過,如果您使用表示式,則每個數據點的權數可以根據每個數據點的屬性。 例如,假設每個數據點都代表地震。 震級值是每個地震數據點的重要計量。 地震一直發生,但大多數地震都有較低的震級,而且沒有注意到。 使用運算式中的大小值,將權數指派給每個數據點。 藉由使用震級值來指派權數,您可以更清楚地表示熱度圖內的地震重要性。

  • minZoommaxZoom:應該顯示圖層的縮放層級範圍。

  • filter:篩選表達式,用來限制從來源擷取並轉譯在圖層中的 。

  • sourceLayer:如果連接到圖層的數據源是向量磚來源,則必須指定向量圖格內的來源圖層。

  • visible:隱藏或顯示圖層。

下列代碼段是熱度圖的範例,其中會使用線條插補運算式來建立平滑色彩漸層。 mag數據中定義的屬性會與指數插補搭配使用,以設定每個數據點的權數或相關性。

HeatMapLayer layer = new HeatMapLayer(source,
    heatmapRadius(10f),

    //A linear interpolation is used to create a smooth color gradient based on the heat map density.
    heatmapColor(
        interpolate(
            linear(),
            heatmapDensity(),
            stop(0, color(Color.TRANSPARENT)),
            stop(0.01, color(Color.BLACK)),
            stop(0.25, color(Color.MAGENTA)),
            stop(0.5, color(Color.RED)),
            stop(0.75, color(Color.YELLOW)),
            stop(1, color(Color.WHITE))
        )
    ),

    //Using an exponential interpolation since earthquake magnitudes are on an exponential scale.
    heatmapWeight(
       interpolate(
            exponential(2),
            get("mag"),
            stop(0,0),

            //Any earthquake above a magnitude of 6 will have a weight of 1
            stop(6, 1)
       )
    )
);
val layer = HeatMapLayer(source,
    heatmapRadius(10f),

    //A linear interpolation is used to create a smooth color gradient based on the heat map density.
    heatmapColor(
        interpolate(
            linear(),
            heatmapDensity(),
            stop(0, color(Color.TRANSPARENT)),
            stop(0.01, color(Color.BLACK)),
            stop(0.25, color(Color.MAGENTA)),
            stop(0.5, color(Color.RED)),
            stop(0.75, color(Color.YELLOW)),
            stop(1, color(Color.WHITE))
        )
    ),

    //Using an exponential interpolation since earthquake magnitudes are on an exponential scale.
    heatmapWeight(
       interpolate(
            exponential(2),
            get("mag"),
            stop(0,0),

            //Any earthquake above a magnitude of 6 will have a weight of 1
            stop(6, 1)
       )
    )
)

下列螢幕快照顯示上述自定義熱度圖圖層使用上一個熱度圖範例中的相同數據。

具有最近地震之自定義熱度圖圖層的地圖

一致的可縮放熱度圖

在所有縮放比例中,熱度圖層中呈現的資料點半徑預設有固定像素半徑。 當您縮放地圖時,數據會匯總在一起,而熱度圖圖層看起來會有所不同。 下列影片顯示熱度圖的預設行為,其會在縮放地圖時維持圖元半徑。

顯示地圖縮放的動畫,其中熱度圖圖層顯示一致的圖元大小

zoom使用表達式來縮放每個縮放層級的半徑,讓每個數據點涵蓋地圖的相同實體區域。 此表達式讓熱度圖圖層看起來更靜態且一致。 地圖的每個縮放比例在垂直和水平方向的像素數目是前一縮放比例的兩倍。

縮放半徑,使其與每個縮放層級加倍,會建立在所有縮放層級上看起來一致的熱度圖。 若要套用此縮放比例,請使用 zoom base 2 exponential interpolation 表達式,並將圖元半徑設定為最小縮放層級,以及計算的最大縮放比例半徑,如 2 * Math.pow(2, minZoom - maxZoom) 下列範例所示。 縮放地圖以查看熱度圖如何縮放比例。

HeatMapLayer layer = new HeatMapLayer(source,
  heatmapRadius(
    interpolate(
      exponential(2),
      zoom(),

      //For zoom level 1 set the radius to 2 pixels.
      stop(1, 2f),

      //Between zoom level 1 and 19, exponentially scale the radius from 2 pixels to 2 * (maxZoom - minZoom)^2 pixels.
      stop(19, Math.pow(2, 19 - 1) * 2f)
    )
  ),
  heatmapOpacity(0.75f)
);
val layer = HeatMapLayer(source,
  heatmapRadius(
    interpolate(
      exponential(2),
      zoom(),

      //For zoom level 1 set the radius to 2 pixels.
      stop(1, 2f),

      //Between zoom level 1 and 19, exponentially scale the radius from 2 pixels to 2 * (maxZoom - minZoom)^2 pixels.
      stop(19, Math.pow(2.0, 19 - 1.0) * 2f)
    )
  ),
  heatmapOpacity(0.75f)
)

下列影片顯示執行上述程式代碼的地圖,它會縮放地圖時縮放半徑,以建立跨縮放層級的一致熱度圖呈現。

顯示地圖縮放與熱度圖圖層的動畫,其中顯示一致的地理空間大小

zoom表達式只能在 和 interpolate 表示式中使用step。 下列表達式可用來近似以公尺為單位的半徑。 此表示式會使用佔位元 radiusMeters,您應該將 它取代為所需的半徑。 此表達式會針對縮放層級 0 和 24 計算赤道上縮放層級的近似圖元半徑,並使用 exponential interpolation 運算式來縮放這些值,就像地圖中並排系統的運作方式一樣。

interpolate(
    exponential(2),
    zoom(),
    stop(1, product(radiusMeters, 0.000012776039596366526)),
    stop(24, product(radiusMeters, 214.34637593279402))
)

提示

當您在數據源上啟用叢集時,彼此接近的點會分組為叢集點。 您可以使用每個叢集的點計數作為熱度圖的加權表達式。 這可大幅減少要轉譯的點數。 叢集的點計數會儲存在 point_count 點功能的 屬性中:

HeatMapLayer layer = new HeatMapLayer(dataSource,
   heatmapWeight(get("point_count"))
);

如果叢集半徑只有少數圖元,則呈現會有很小的視覺差異。 較大的半徑會將更多點分組到每個叢集,並改善熱度圖的效能。

interpolate(
    exponential(2),
    zoom(),
    stop(1, product(radiusMeters, 0.000012776039596366526)),
    stop(24, product(radiusMeters, 214.34637593279402))
)

提示

當您在數據源上啟用叢集時,彼此接近的點會分組為叢集點。 您可以使用每個叢集的點計數作為熱度圖的加權表達式。 這可大幅減少要轉譯的點數。 叢集的點計數會儲存在 point_count 點功能的 屬性中:

var layer = new HeatMapLayer(dataSource,
   heatmapWeight(get("point_count"))
)

如果叢集半徑只有少數圖元,則呈現會有很小的視覺差異。 較大的半徑會將更多點分組到每個叢集,並改善熱度圖的效能。

下一步

如需更多可新增至地圖的程式碼範例,請參閱下列文章: