如何从谷歌热图中删除绿色边框?

Вла*_*шер 3 android google-maps heatmap

如何从android google heatmap中删除边框颜色?我正在使用此代码绘制:

fun drawPolygons(polygons: Array<NetworkMapPolygonModel>, scale: Float) {
        map?.let { map ->
            val points = ArrayList<WeightedLatLng>()
            polygons.forEach {
                val intensity = ((it.signalStrength - 12) * -1).toDouble()

                points.add(WeightedLatLng(
                    LatLng(it.aLatitude, it.aLongitude), intensity
                ))
            }
            
            val radius = 40
            val provider = HeatmapTileProvider.Builder()
                .weightedData(points)
                .radius(radius)
                .maxIntensity(48.0)
                .build()

            map.addTileOverlay(TileOverlayOptions().tileProvider(provider))
        }
    }
Run Code Online (Sandbox Code Playgroud)

但是谷歌地图给我画了这张地图:

在此处输入图片说明

我想删除外部绿色边框(屏幕截图中的红色方块)。但找不到如何做到这一点。请帮忙!

And*_*ndy 5

为了简单地消除绿色(以及数据的表示),使用 的梯度属性HeatmapFileProvider.Builder将初始颜色从绿色(默认)更改为黄色,并将起始阈值从对应于绿色(默认为 0.2)的阈值更改为大约( 0.4)(你必须试验这个数字——在这个答案的底部,我展示了如何确定这个数字,它是 0.454)。而不是从透明逐渐淡入,我将展示如何以所需的颜色开始完全不透明。

在深入修改之前,请了解有一个未指定使用的默认渐变,它是这样的:

// Create the gradient.
val colors = intArrayOf(
     Color.rgb(120, 225, 0),  // green
    Color.rgb(255, 0, 0) // red
)
val startPoints = floatArrayOf(0.2f, 1f)
val gradient = Gradient(colors, startPoints)

// Create the tile provider.
val provider = HeatmapTileProvider.Builder()
    .data(latLngs)
    .gradient(gradient)
    .build()
Run Code Online (Sandbox Code Playgroud)

在接下来的内容中,修改了颜色数组和 startPoints 以展示每次调整的点。所以在这个片段中,它显示了消除绿色但从透明过渡到黄色(不是你要找的,只是一个例子)。

// Create the gradient.
val colors = intArrayOf(
     Color.rgb(255, 225, 0),  // yellow
    Color.rgb(255, 0, 0) // red
)
val startPoints = floatArrayOf(0.4f, 1f)
val gradient = Gradient(colors, startPoints)
Run Code Online (Sandbox Code Playgroud)

在这个答案中,我使用了我自己的数据来表示萨克雷门托的犯罪统计数据。您很快就会明白为什么绿色是边缘数据的不错选择。

渐变属性由两个控件组成:

  • 颜色
  • 起点(0.0 到 1.0)

默认颜色是 (GREEN,RED),起点是 (0.2, 1.0)。需要注意的一点是,如果第一个起点不为零(如默认值),则从 pts 0.0 到 0.2 的渐变从透明过渡到颜色;否则,它从 pt 0.0 处的第一种颜色开始。

图像 (A) 是我的数据的默认设置。

然后我想看看绿色实际上是从哪里开始的(0.2),而没有从透明过渡到绿色(0.0 - 0.2)。为此,我将渐变修改为透明至接近 2.0 - 然后引入从 close-to-2.0 到 2.0 的边框(黑色),其余为默认值。

// Create the gradient.

val colors = intArrayOf(
     Color.argb(0, 0, 0, 0),  // transparent
     Color.argb(0, 0, 0, 0),  // transparent
     Color.rgb(0, 0, 0),      // black
     Color.rgb(120, 255, 0),    // green
     Color.rgb(255, 0, 0)    // red
)
val startPoints = floatArrayOf(0.0f, 0.15f, 0.18f, 0.2f, 1f)
val gradient = Gradient(colors, startPoints)
Run Code Online (Sandbox Code Playgroud)

图像 (B) 是添加此“边框”以显示纯绿色数据 (2.0+) 的开始位置:

现在来解决去除绿色的问题。默认插值总结如下:0 - 0.2f(透明到绿色)和0.2f - 1.0f(绿色到红色)。所以在那里的某个地方是内插的黄色。对于这个答案,黄色大约是 0.4 的近似值(但我会跟进一个计算来展示如何计算出来)。我再次添加边框以准确显示黄色 (0.4) 的起始位置:

// Create the gradient.
val colors = intArrayOf(
     Color.argb(0, 0, 0, 0),  // transparent
     Color.argb(0, 0, 0, 0),  // transparent
     Color.rgb(0, 0, 0),      // black
     Color.rgb(255, 255, 0),    // yellow
     Color.rgb(255, 0, 0)    // red
)
val startPoints = floatArrayOf(0.0f, 0.35f, 0.38f, 0.4f, 1f)
val gradient = Gradient(colors, startPoints)
Run Code Online (Sandbox Code Playgroud)

这个答案演示了如何控制颜色结果;我无法回答的更相关的问题是您试图传达什么信息:消除“绿色”就是消除数据,而使用默认起点将数据转换为黄色数据的过渡不会消除数据,而只会消除绿色。(我没有发布这样的例子,但值得考虑。)

(一种)

在此处输入图片说明

(乙)

在此处输入图片说明

(C)

在此处输入图片说明


答案的下一部分重点关注颜色;希望不要离主题太远。

同样,在默认渐变中,指定了 2 个百分位数 (0.2, 1.0),一个隐含的从 0.0 开始。同样,这三个的颜色是:(0x0078E100(完全透明的绿色(120,225,0)),0xFF78E100(不透明的绿色),0xFFFF0000(不透明的红色))。

在 OP 中,问题在于颜色(“删除绿色边框”),这导致必须做出假设:删除应该停止到什么程度。我选择假设黄色 - 但由于颜色代表数据的百分位数,所以问题应该用百分位数来表达,以便准确。)但是从颜色方面看数据表示存在一个问题:黄色的数据百分位数在哪里给定默认渐变。

所以为了帮助这个讨论,我创建了一个简单的,TileProvider其目的是在渲染的每个图块中显示颜色的渐变。这是一个示例:

在此处输入图片说明

此图显示了顶部和底部的一个完整图块和两个部分图块;所以这里重点放在中间的一个完整的瓷砖上。

一些关键点:(1) 平铺从完全透明(数据百分位数 0.0)开始,过渡到默认渐变中的第一种颜色,此时绘制一条黑色线段代表第 20 个百分位数。从那里,瓷砖从绿色过渡到默认渐变(红色)中的第二种颜色,代表第 100 个百分位数。在此过程中,为“最接近”“黄色”渐变中的颜色绘制了第二条黑色线段。

为了发现最接近黄色的数据百分位数,需要了解梯度是如何创建的。简而言之,就是将所提供颜色的RGB值中每个颜色段的端点()转换为HSV值。从这些 HSL 值开始和结束点之间的比率应用 HSV 值,然后转换回 RGB。

一旦确定了渐变段内的 RGB 颜色,它就会计算到目标(“tgt”)颜色(黄色)的“距离”并找到最小距离:

int deltaR = Color.red(tgt) - Color.red(ic);
int deltaG = Color.green(tgt) - Color.green(ic);
int deltaB = Color.blue(tgt) - Color.blue(ic);
double d = Math.sqrt(deltaR*0.3F*deltaR*0.3F + deltaG*0.59F*deltaG*0.59F + deltaB*0.11*deltaB*0.11);
Run Code Online (Sandbox Code Playgroud)

事实证明,最接近黄色的数据百分位数是 45.4%。因此,上图 (3) 中的最终图像中显示的数据代表了数据的 54.6%。

参考这里是使用的实现TileProvider。该mColors数组是热图默认生成的 1000 个元素颜色图:

private class MyTileProvider implements TileProvider {

    public MyTileProvider() {
    }

    @Override
    public Tile getTile(int x, int y, int zoom) {

        Bitmap tile = Bitmap.createBitmap(512,512,Bitmap.Config.ARGB_8888);
        tile.setPixels(mColors,0,Math.max(512,mPixelsPerColor),0,0,512,512);

        Log.d(TAG,"Tile gen done: "+x+","+y+" "+zoom);
        return convertBitmap(tile);
    }
}
Run Code Online (Sandbox Code Playgroud)

有关梯度和热图的参考,请使用此答案: Android 中的加权热图

有关计算“颜色距离”的参考:https : //stackoverflow.com/a/1847112/2711811

参考地图 utils 热图实现(andoid-maps-utils 存储库中的一个子目录):https : //github.com/googlemaps/android-maps-utils/tree/ac9684d627905587b020a0eac301e94478804a48/library/src/main/java com/google/maps/android/heatmaps