新增熱度圖層 (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 地震災害計畫 (USGS Earthquake Hazards Program)。 此範例使用建立資料來源文件中提供的資料匯入公用程式程式碼區塊,從 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" 運算式的預設色彩。 您可以使用此值來定義背景色彩。 此值通常設定為透明或半透明黑色。以下是色彩運算式的範例:
插補色彩運算式 分階色彩運算式 interpolate(
linear(),
heatmapDensity(),
stop(0, color(Color.TRANSPARENT)),
stop(0.01, color(Color.MAGENTA)),
stop(0.5, color(parseColor("#fb00fb"))),
stop(1, color(parseColor("#00c3ff")))
},step(
heatmapDensity(),
color(Color.TRANSPARENT),
stop(0.01, color(parseColor("#000080"))),
stop(0.25, color(parseColor("#000080"))),
stop(0.5, color(Color.GREEN)),
stop(0.5, color(Color.YELLOW)),
stop(1, color(Color.RED))
/heatmapOpacity
:指定熱度圖層的不透明度或透明度。heatmapIntensity
:對每個資料點的權數套用乘數,以提高熱度圖的整體濃度。 這導致資料點的權數發生差異,在視覺上更明確。heatmapWeight
:所有資料點的權數預設為 1 且公平加權。 加權選項如同乘數,可設定為數字或運算式。 如果權數設定為數字,則相當於每個資料點在地圖上放兩次。 例如,如果權數為2
,則密度加倍。 將加權選項設定為數字所呈現的熱度圖,與使用強度選項呈現的熱度圖相似。不過,如果使用運算式,則每個資料點的權重以每個資料點的屬性為基礎。 例如,假設每個資料點各代表一次地震。 震度值向來是每個地震資料點的重要計量。 地震隨時在發生,但大多震度低,很難察覺。 在運算式中使用震度值,以指定每個資料點的權數。 使用震度值來指派權數,可以在熱度圖內更清楚呈現地震的嚴重性。
minZoom
和maxZoom
:據以顯示圖層的縮放比例範圍。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
並搭配基數 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
運算式只能用於 step
和 interpolate
運算式。 下列運算式可用計算半徑的近似值 (以公尺為單位)。 此運算式會使用預留位置 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"))
)
如果群集半徑只有幾個像素,則呈現時的視覺差異很小。 越大的半徑將越多點聚集到每一個叢集,可提高熱度圖的效能。
下一步
如需更多可新增至地圖的程式碼範例,請參閱下列文章: