Aha*_*sir 3 android google-maps heatmap google-maps-api-3 android-studio
我正在尝试为我的 android 应用项目创建一个加权热图。我查看了它的谷歌文档。我不明白如何使用颜色数组和起点数组创建新的渐变。起始数组表示为
每种颜色的起点,以最大强度的百分比形式给出。
这是什么意思?如何将颜色数组与起点数组相关联?
int[] colors = {
Color.GREEN, // green(0-50)
Color.YELLOW, // yellow(51-100)
Color.rgb(255,165,0), //Orange(101-150)
Color.RED, //red(151-200)
Color.rgb(153,50,204), //dark orchid(201-300)
Color.rgb(165,42,42) //brown(301-500)
};
float[] startpoints = {
};
Run Code Online (Sandbox Code Playgroud)
我需要填充这个起点数组。
以下是一些假设:
这是帮助讨论的图表:
首先要了解的是colorMap。这是由渐变构建器生成的。它是一个默认大小为 1000 的“int”数组,但可以在其中一个构造函数中进行自定义 - 在您的示例中推荐 500。所以这个数组中的每个值都是一个颜色值。(大小会影响渐变的分辨率。)
colorMap 中的颜色值受 2 个产生颜色间隔的控件的影响:startPoints 数组和颜色数组。在您的示例中,有 6 个颜色间隔。
颜色间隔定义为起始颜色和结束颜色以及范围内“colorMap”插槽的数量。任何给定区间的所有 colorMap 值都使用该范围的开始/结束颜色进行插值。
如果 startPoints 数组的第一个值是 0,则假定第一个颜色间隔是实心的 - 非零意味着从透明到第一种颜色的过渡,这似乎是最理想的。(参见 startPoints 设置为 0 的示例,并注意外部区域的锯齿状。)
如果 startPoints 数组的第一个值不为 0,则第一个颜色区间定义为从第一个颜色 (colors[0]) 和 colorMapSize * 第一个起点的范围开始,例如 500 * 0.1 = 50 和结束具有相同的颜色。
对于所有剩余的已定义颜色,将生成一个间隔 - 再次使用起始颜色映射槽、起始颜色(即前一个颜色结束)和结束颜色(即表中的当前颜色)和范围。
如果最后一个startingPoint 不是1.0,那么最后一个颜色用于开始和停止。在这个例子中,1.0 可能是最好的。
(不透明度适用于整个图层,只会影响颜色的 Alpha 通道。)
这就是欣赏“强度”和 WeightedLatLng 可以发挥作用的地方。
生成地图时,它将可视区域划分为瓦片 - 瓦片的数量是缩放级别的函数。在缩放级别 0 有 1 个平铺,任意缩放级别平铺计数为 2^n(其中 n 是缩放级别)。
每个瓦片被进一步分成桶。桶的数量是缩放级别和半径(模糊)的函数。每个桶对应于 tile- think rectangle-grid 中的一个地理区域。
当前图块内的点是从数据集中获得的。
对于图块地理边界内的所有点,该点的强度值被添加到其对应的桶中。默认情况下,一个点的强度值为 1。WeightedLatLng 允许您通过将此值从 1 更改为某个数字(较大以增加重要性,较小以降低重要性)来偏置点。因此,结果是桶强度计数会受到仅 LatLngs 的影响。
计算强度桶后,强度值将使用第一部分中确定的颜色映射进行着色。请注意,强度值的范围被缩放到 colorMap 的大小,以便最大强度值映射到最后一种颜色。
然后将存储桶应用于图块,并将图块制成位图并进行渲染。
例如,我使用了一些萨克拉门托犯罪数据。我首先创建了一个非加权热图。然后创建一个加权热图,通过为 NCIC 代码为 2404(车辆盗窃)的犯罪指定 5.0 的强度(与任何点的默认值 1.0)来确定汽车盗窃的重要性。5.0 有点武断,实际上取决于数据和您要传达的内容。
非加权/加权(车辆盗窃)
以及第一个 startPoint[0] 为 0.0 的示例 - 这表明缺少从透明到初始颜色的过渡:
以下是 MapActivity 的相关部分:
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
mMap.getUiSettings().setZoomControlsEnabled(true);
// Add a marker in Sydney and move the camera
LatLng sydney = new LatLng(-34, 151);
mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
addHeatMapWeighted();
//addHeatMap();
}
public void addHeatMapWeighted() {
Gradient gradient = new Gradient(colors,startpoints);
List<WeightedLatLng> wDat = new CrimeData().getWeightedPositions();
HeatmapTileProvider provider = new HeatmapTileProvider.Builder().weightedData(wDat).gradient(gradient).build();
mMap.addTileOverlay(new TileOverlayOptions().tileProvider(provider));
}
public void addHeatMap() {
Gradient gradient = new Gradient(colors,startpoints);
List<LatLng> cDat = new CrimeData().getPositions();
HeatmapTileProvider provider = new HeatmapTileProvider.Builder().data(cDat).gradient(gradient).build();
mMap.addTileOverlay(new TileOverlayOptions().tileProvider(provider));
}
int[] colors = {
Color.GREEN, // green(0-50)
Color.YELLOW, // yellow(51-100)
Color.rgb(255,165,0), //Orange(101-150)
Color.RED, //red(151-200)
Color.rgb(153,50,204), //dark orchid(201-300)
Color.rgb(165,42,42) //brown(301-500)
};
float[] startpoints = {
0.1F, 0.2F, 0.3F, 0.4F, 0.6F, 1.0F
};
Run Code Online (Sandbox Code Playgroud)
好的,所以您可能已经注意到,每个 colorMap 间隔的开始都以一个很好的整数 (0,50,100...) 开始,这与您的要求 (51, 101...301) 不太匹配。我认为您的评论范围不正确,因为这实际上意味着有 501 种可能的颜色,这有点奇怪。但是,如果您真的想要指定的范围,那么您必须进行一些数学计算才能得出一个替代的 startPoints 数组: (51/501,101/501,151/501,201/501,301/501,501/501) = (.101796407,. 201596806,.301397206,.401197605,.600798403, 1.0)
半径值是 HeatMap 的高斯模糊实现的输入。有时一张图片是最好的解释:这是一个动画 Gif,它以 10 的步长循环通过半径 20 到 50 的热图(最模糊的是半径 50)。
由于热图旨在传达信息的含义,因此真正留给数据呈现者来评估什么是最佳半径效应。因此,例如,在犯罪数据的情况下,作为寻找住所的数据消费者,我可能会从一些模糊的数据中获得更多价值。另一方面,如果数据显示的是消防站,那么太多的模糊很可能会让人相信它们被覆盖了,而实际上它们没有被覆盖。
仅使用点(圆圈)就可以讲述比热图更准确的故事,并且在更广泛的缩放级别下,尽管没有颜色,但它在视觉上就像热图一样模糊。例如,这里有两个点渲染,未加权和加权。加权偏差针对毒品犯罪(NCIC 代码 [3500,3600)),这表明毒品犯罪在该领域占主导地位。
从参考书(3):
“热图”一词于 1991 年由软件开发商 Cormac Kinney 注册商标。它随后被 SS&C Technologies, Inc. 收购,但他们没有延长许可证,并于 2006 年被取消。
参考
| 归档时间: |
|
| 查看次数: |
2283 次 |
| 最近记录: |