使用自定义缩放级别和缩放因子的高效定制平铺地图

我必须在iOS5 / 6(iPhone)上实现一个非常自定义的平铺地图图层/视图,该图层将图块从服务器加载为图像和/或数据(JSON)。 这就像谷歌地图,但在某些特定的点,所以我不能轻易使用一个解决方案,如:

  • 谷歌地图或
  • route-me(由MapBox使用)
  • CATiledLayerUIScrollView结合使用
  • 问题是:由于我的具体规格,没有任何解决方案可以帮助我。 如果你认为,有一个合适的解决方案, 请告诉我!

    如果不:
    帮助我找到最适合我的案例的解决方案!

    “但为什么我不能使用这些美丽的解决方案?”
    有几个限制,必须知道:

  • 我们只使用3个缩放级别(0,1和2)

  • 每个瓦片在下一个缩放级别(=缩放因子3)中具有9个子元素(不像大部分其他套件用4个子元素 =缩放因子2)

  • 第一层的初始大小(以像素/点为单位)是768 * 1024。
    第二层是更宽和更高的三倍(zoomfactor 3 !!!) - > 2304 * 3072
    第三层同样比第二层 - > 6912 * 9216更宽和更高

  • 来自服务器的每个图块都是256x256像素

  • 所以每个子图层的瓦片数量是瓦片数量的9倍(第一层12,第二层108,第三层972)

  • 每个图块都有一个背景图像(大小约为6KB)(作为服务器的图像加载)和前景信息(从服务器的每个图块加载为JSON - 大小为10-15KB)
    - 前景信息JSON包含覆盖图像(例如google中的流量)或本地瓦片信息,以便绘制到本地瓦片坐标空间(如注释,但是每个瓦片)

  • 我想将整个背景图块缓存在磁盘上,因为它们从不改变

  • 我想要在一定时间内缓存每个tile的overlay-tile-images / overlay-tile-information,直到它再次被重新加载

  • 缩放应该是捏和双击

  • 我的一些考虑:

  • 缓存不是问题。 我通过CoreData或类似的方式做到这一点

  • 我想到了一个UIScrollView,以显示平滑的滚动

  • 我想使用捏,所以每次我突破下一个缩放级别时,我必须绘制下一个缩放级别的图块

  • 内容只能在可见区域绘制(对于iPhone 5 320x500)

  • 应该删除不可见的图块,以提高内存效率。 但是,不应该立即删除它们,只有当瓦片距可见中心有一定数量的像素/点时才会被删除。 应该有一个“显示缓存”,以便即时显示刚刚加载和显示的图块。 或者有更好的技术吗?

  • 我可以立即从磁盘或从服务器异步加载背景,因为我知道哪些图块可见。 所以我用瓷砖JSON。 然后,我提取该图块的JSON信息(“是叠加的直接图像或信息,例如城市名称,我必须在该图块中绘制)”并绘制或加载覆盖图(从数据库/光盘或服务器)

  • UIScrollView的效率足以处理平铺视图的最大尺寸

  • 我应该使用CALayer作为子层来绘制它吗? 我应该使用Quartz直接在一个大的“画布”上绘制吗?

  • 现在轮到你了 !!!


    苹果公司有一个例子,显示了放大到一个单一的形象很深。 他们为此使用CATiledLayer。

    该示例可以在这里找到:http://developer.apple.com/library/ios/#samplecode/PhotoScroller/Introduction/Intro.html

    该示例适用于存储在手机中的子物件,但也可能适用于您的问题。


    对于CATiledLayer不支持的这些类型的非标准拼贴问题,我已经使用了我自己的TiledLayer实现(并且由于CATiledLayer仍然存在一些未解决的错误)。

    该实现现在在Github上提供。

    Fab1n:这是我已经通过电子邮件向您发送的相同实现。


    我想出了一个非常漂亮和漂亮的解决方案(自定义TiledLayer实现):

    我不再使用CATiledLayer作为scrollView的contentView。 相反,我向它添加了一个CALayer子类,并将它添加为子图层。 每个图块都包含作为内容的图块位图。 当使用scrollview进行放大时,我会根据当前缩放级别手动切换切片。 那很完美!!!

    如果有人想知道实施的细节 - >没问题,请写一条评论,然后在这里发布。


    编辑

    有关实施的细节:

    实际上的实现非常简单:

  • 将UIScrollView添加到您的视图/控制器视图
  • 添加一个UIView(从现在开始称为tileView )作为contentView到ScrollView - 与ScrollView大小相同(这是完全缩小模式 - 因子1)
  • 激活缩放(我有最小缩放系数1和最大9)
  • 当你现在将一个图像放入tileView ,放大到9级将会给出非常清晰的像素化图像 - 这就是我们想要的(我将解释为什么)
  • 如果您在放大时喜欢清晰的图像,则应该使用addSublayer:添加CALayer实例( tilesaddSublayer: tileView
  • 假设你有一个zoomFactor 3(我有 - 意味着1 瓷砖在0层 - zoomFactor 1将包含3x3 = 9瓷砖层1 - zoomFactor 3
  • 第0层中,您将3x4的瓦片与243x243(3倍的3倍)像素(作为tileView子层) tileView 。 你把你的相同大小的瓷砖图像作为CALayer contents 。 缩放到zoomFactor 3使它们变得模糊(像旧的谷歌地图)
  • 当您点击zoomFactor 3时,从超级图层中移除全部12层,并将其替换为3倍小( 81x81像素 )的图层 。 整体而言,您可以获得9倍以上的图层。
  • 现在你已经有3倍小的图层,诀窍就是CALayer.contents属性。 即使图层为81x81,内容(图像) 仍为全分辨率 ,这意味着如果将243x243像素图像作为81x81像素CALayer图块的内容,则在zoomFactor 3上它看起来像243x243像素图块!
  • 你可以在任何zoomFactor(3,9,12)上进行更深入的研究。 瓷砖越来越小,但将原始图像设置为内容时,瓷砖在放置的确切zoomFactor中看起来会显得清晰锐利。

    如果你喜欢你的瓷砖在zoomFactors之间看起来很锋利,你必须将3倍高的图像设置为.contents 。 然后,在您传递下一个zoomLevel之前,您的瓷砖会变得清脆锐利。

    你必须弄清楚的一件事是,当传递zoomLevel因子时,移除图层上的所有图块效率不高你只需要更新可视区块。

    不是所有解决方案中最好的解决方案,但它是有效的,如果有人设计了精心设计的库,那么这可能是一个干净的解决方案。

    链接地址: http://www.djcxy.com/p/67413.html

    上一篇: Efficient custom tiled maps with custom zoom levels and zoom factors

    下一篇: zoom in Phonegap Android application has no effect