Java 在Android上向GoogleMap添加大型GeoJson的有效方法
我有一张3公里网格区域的温度图。 也就是说,我有几千个有颜色的多边形 我试图在我的kotlin应用程序中,在android上的谷歌地图上显示它们 问题是我需要在UI线程中添加GeoJson层,这需要8-15秒。也就是说,申请一直处于冻结状态 关于StackOverflow这个问题有很多老的答案,但它们都与我无关:Java 在Android上向GoogleMap添加大型GeoJson的有效方法,java,android,google-maps,geojson,Java,Android,Google Maps,Geojson,我有一张3公里网格区域的温度图。 也就是说,我有几千个有颜色的多边形 我试图在我的kotlin应用程序中,在android上的谷歌地图上显示它们 问题是我需要在UI线程中添加GeoJson层,这需要8-15秒。也就是说,申请一直处于冻结状态 关于StackOverflow这个问题有很多老的答案,但它们都与我无关: 他们建议减少json——我已经用相同的值从附近的正方形创建了集群 他们建议使用MapView和覆盖,但在最新的google map API中,没有MapView和在后台线程中添加覆盖的
我如何处理这个问题?有没有办法从背景线程中的数千个彩色矩形创建地图,然后立即在UI线程中显示它?如果您已经尝试了
addPolygon()
和GroundOverlay
,还有两种可能:
HashMap
等)或文件系统路径。\zoom\u level\x\y\tile.png
中(如果有很多分幅)。当需要显示时,您可以“动态”(在单独的线程中)创建更“详细”的平铺,然后还可以存储它们以备将来使用(如果需要)。当然,您需要定制模块来进行快速GeoJson
读取(类似Jackson)并将其渲染到.png
平铺中。因此,似乎可以为您的案例创建TileProvider
,以优化性能和内存消耗。您可以使用作为第一次迭代
如果选择自定义图形,则应为MapView
覆盖onDraw()
方法,或为MapFragment
覆盖dispatchDraw()
。比如说。在这种情况下,您可以控制整个流程,但这种方式对于实现来说更为复杂
更新:
您可以为onCameraMove()
执行操作,如在answer中(此处使用的GoogleMap
对象的一些复杂传递):
更新#2:
您可以制作多边形当前视图的“屏幕截图”(不完全是屏幕截图,但在位图上创建多边形的图像),并将其移动到onCameraMove()
(而不是重新绘制所有多边形)。然后在onCameraIdle()
中创建并显示新的完整多边形视图。此外,您还可以创建比地图屏幕视图稍大的位图(用于正确缩小和滚动)。或者,您可以“跳过”一些onCameraMove()
调用(例如,每3次调用onCameraMove()
调用一次)
顺便说一句:如果是平铺覆盖,可以“从框中”移动和缩放。您只需要创建一个复杂的TileProvider。整个设备屏幕只需要生成几个磁贴(单个磁贴的大小为256x256)。因此,您可以为当前屏幕、currentZoomLevel-1、currentZoomLevel+1(缩放时)和+2(或3)生成左、右、上和下(滚动时)的分幅。此外,您还可以将生成的磁贴存储在某些缓存(HashMap、LRU等)中,以备将来使用。您可以生成“额外”(当前不可见)在单独的线程中平铺。我建议不要一次创建这几千个多边形,因为这会影响时间和性能,但是您可以使用GoogleMap.OnCameraMoveListener和GoogleMap.onCameradleListener动态创建所示位置附近的多边形 编辑:- “动态显示位置附近的多边形”我的意思是只创建用户当前看到的多边形,即在地图的当前可见区域边界内:-您可以通过
googleMap.projection.visibleRegion.latLngBounds
“GoogleMap.OnCameraMoveListener和GoogleMap.OnCameraDelListenerWhat”,我的意思是这里有两种方法,首先,当用户停止滚动地图“SetOnCameraDelListener”时,用可见边界内的多边形更新地图第二种方法是使用setOnCameraMoveStartedListener,在用户每次开始滚动地图时,使用可见边界内的多边形更新地图
override fun onMapReady(googleMap: GoogleMap?) {
googleMap ?: return
with(googleMap) {
setMinZoomPreference(9f)
setOnCameraIdleListener {
// first approach user stopped scrolling so update the map with polygons within the boundaries
}
setOnCameraMoveStartedListener {
// second approach user started scrolling so update the map with polygons within the boundaries
}
}
这可能会有所帮助:@kalabalik,正如我所描述的,这不是我的问题。我可以在后台准备数据谢谢!从geojson创建不同缩放级别的平铺看起来工作量太大,但我将尝试第二种方法!看起来不错,但是在地图移动时不调用dispatchDraw,所以当我移动或缩放地图时,我的多边形将保留在同一位置map@PavelBernshtam请参阅更新的答案。简单地说:您可以在
public void onCameraMove()
中调用自定义视图的invalidate()
来完成此操作。谢谢,但它的工作非常不平稳。即,在地图更改位置后,我的多边形正在缓慢移动(!)。非常不愉快的用户体验…@PavelBernshtam请参阅更新#2。请解释更多,它是什么意思“在飞行中靠近显示位置的多边形”以及我将如何使用GoogleMap.OnCameraMoveListener和GoogleMap.OnCameraDelListener?请注意,我更新了我的答案。希望能对你有所帮助。我不确定这是否与我的情况有关,因为当所有多边形都应该可见时,我从缩小开始,但我会尝试。非常感谢。
override fun onMapReady(googleMap: GoogleMap?) {
googleMap ?: return
with(googleMap) {
setMinZoomPreference(9f)
setOnCameraIdleListener {
// first approach user stopped scrolling so update the map with polygons within the boundaries
}
setOnCameraMoveStartedListener {
// second approach user started scrolling so update the map with polygons within the boundaries
}
}