有关使用GroundOverlay或TileOverlay在GoogleMap中显示大型叠加图像的一些问题

时间:2013-03-05 19:28:26

标签: android google-maps-android-api-2

我有一个应用程序,用户可以在Google地图上加载图像。这是为2.3开发的,所以有一个MapActivity,一个MapView和我的自定义Overlay类来显示图像。 在overlay class draw-method中,我每次都重新计算一次Matrix,因此图像的大小和位置正确。我还有一个校准模式,用户可以通过拖动参考点来调整图像。

我将为应用程序添加一些功能,我想从一些更新开始,比如使用片段。用MapFragment替换MapActivity会带来一些问题,因为似乎没有任何支持你可以自己实现绘图的覆盖。好像我将不得不使用GroundOverlays或TileOverlay。 (如果我错了,请纠正我。)

这些似乎都不支持在叠加后对叠加进行任何修改,因此图像的校准将不起作用。我对该部分的计划是将普通的ImageView放在MapFragment的顶部以进行校准模式。 (这将隐藏所有标记,但在校准期间无关紧要。)为此,我需要两件事: *接收影响校准点的所有触摸事件,并转发其余部分以允许正常变焦等。 *随时检测位置/旋转/缩放级别,以便我可以调整图像。 问题1:我可以期待任何重大问题吗?

然后我必须决定是否更喜欢GroundOverlays或TileOverlay。

的GroundOverlay: 这似乎需要最少的工作,因为它仍将加载整个图像。我也认为它会自动处理屏幕方向变化等事情。 问题2:GroundOverlay能否适用于大图像(最大2000 * 2000像素)?是否涉及复制图像?因为图像太大,所以我在内存中买不到一个以上的副本。

TileOverlay: 在某种程度上,这似乎是一个更专业的解决方案,因为它只使用实际需要的部分,我可以在以后引入支持同时使用多个地图图像源。 我可能需要提前生成切片并为每个切片保存一个单独的文件,将其保存在内存中并按需创建切片可能需要大量内存。 (或许我可以创建一个单独的磁贴服务,但这看起来有点脏。) 问题3:是否可以控制磁贴缓存将使用多少内存?通常的限制是否适用?我不想在应用程序中的其他地方耗尽内存,因为缓存占用了我允许使用的大部分内存。 问题4:文档说“请注意,与其他叠加层不同,如果重新创建地图,则不会自动恢复平铺叠加层,必须手动重新添加”。我想这会在每次屏幕旋转时发生,这意味着必须再次读取文件,导致明显的加载延迟。这有什么好办法吗? 问题5:当调用getTile并且我返回null(因为tile被保存在文件中并且我不想在读取它时阻止ui线程),在再次请求它之前需要多长时间? (似乎没有办法手动加载单个图块。) 问题6:如何确定一个平铺图像的良好图像分辨率(性能和质量)?

1 个答案:

答案 0 :(得分:6)

很多问题。我会尝试解决一些问题。

  1. 通常,请注意Maps API v2比v1更不宽容。这是件好事。 v2具有许多v1没有的内置函数和优化,并且通过限制性API强制您使用其优化。

  2. 例如,如果您使用GroundOverlay显示图像[假设您不需要旋转或扭曲它],则只需指定它的纬度/长度边界,而地图v2将拉伸为你的形象。 2000x2000将是2000x2000x4字节,因此内存为16MBytes。 但是GroundOverlayOptions使用了BitmapDescriptor,因此它可能永远不会将图像完全加载到内存中。 我对GroundOverlay不太熟悉。

    另一种选择是在第一次加载图片时剪切图片并将其保存在本地存储中,然后使用TileOverlay非常简单。您不能直接从2kx2k图像中合理地读取图块,因为它将涉及全部读取(如果压缩,我猜它是)。 如果您需要显示图像的修改版本,请记住在确保它是可变的之后,您只需要在位图上创建一个Canvas。

  3. 我对TileOverlay更熟悉,我经常使用它。瓷砖缓存对我来说看起来很公平,我已经加载了大量的256x256磁贴并始终保持在13M到20M堆之间。我认为它使用与谷歌地图图块相同,在本地存储内存上缓存一些但从不太多,并且在未显示的内存图块中根本不缓存。您可以看到填充时正在重新加载切片。

    您可以通过列出内部存储的文件轻松查看GMaps磁贴缓存策略。你会看到GMaps缓存瓷砖。

  4. 是的,当停止/启动GoogleMap时,会为每个显示磁贴调用getTile(x,y,zoom)。看起来每次调用getTile都有自己的线程,因此加载时间不是问题。如果您的瓷砖已存储在您的设备上,则加载速度非常快。如果您以智能方式存储数据,那真的不是问题。

  5. 我从未返回null。不知道在这种情况下会发生什么。也许它会触发一个被忽略的异常。请注意,GoogleMap调用将忽略任何运行时异常或甚至由g​​etTile中的代码生成的某些java.lang.error ...我已经报告在此处发布,您可能希望应用该补丁来简化您的开发:{{ 3}}

    要回复您的问题,我已经返回了“NO_TILE”对象,然后GMap像任何磁贴一样缓存它。您可以通过调用https://code.google.com/p/gmap...强制重新加载切片。

  6. 我一直在考虑这个问题,但我只使用256x256磁贴,即使在高DPI Nexus 10上看起来也足够好了。我没有更多地调查这个问题,但可能已经是GMaps了根据缩放级别选择最适合显示的图块,前提是256p是非常标准的图块尺寸。