使用Phonegap离线显示和导航大型自定义地图

时间:2012-12-04 15:21:08

标签: android cordova maps offline

我的问题是如何在离线Phonegap应用程序中有效地显示大型自定义地图,允许它们在仍然支持旧移动设备的同时平滑地进行平移和缩放?

我正在开发一个移动应用程序,该应用程序涉及使用地理位置来导航偏远地区的步行路线,在这些地方,用户可能没有信号,因此也没有互联网连接。重要的是该应用程序适用于Android 2.2+(因此SVG不是一个选项)以及iOS4 +。

我使用Adobe Illustrator以适合每条路线的分辨率绘制自定义矢量地图,平均值大约为2000x2000像素,其中最大的图像到目前为止会产生4000x2400像素的图像。

我选择使用Phonegap / JQM而不是本机只是因为我来自网络编程背景,它似乎是最快的方式来启动和运行用户界面而不需要过多地钻研本机代码,尽管为了电源和屏幕管理的目的,我已经使用本机代码编写了几个Phonegap插件。

应用程序需要允许用户在地图上平移(通过拖动)并放大/缩小(通过捏合)原始图像大小的大约25%到200%。

我所做的大部分测试都是运行Android 2.3.3的HTC Desire和运行Android 2.2的HTC Wildfire,因为这些可能是应用程序必须运行的最低规格设备

我已经尝试了各种方法来显示地图(详见下文),但到目前为止,每个方法都被证明不适合用途,因为应用程序的内存使用量太大,所需的存储空间使得应用程序太大而无法使用下载或CPU使用率过高导致平移/缩放时出现延迟。

任何建议都非常感谢。提前谢谢。


我试过的方法:

1。使用标记

将地图显示为栅格PNG

这是我尝试的第一种方法。将Illustrator中的4000x2400像素图像导出为128色PNG-8,得到746Kb文件。我通过相对于视口绝对定位图像来平移图像,并通过缩放标记的宽度/高度属性来缩放图像。 这种方法的问题在于,即使在1:1缩放级别,Android应用程序使用60Mb的RAM用于图像,并且放大到200%导致这增加120Mb,导致应用程序在HTC Wildfire上崩溃。

2。使用HTML5画布显示光栅PNG的部分

为了避免放大导致内存使用量成比例增加的问题,我尝试通过JS加载图像,然后将要显示的图像部分复制到视口大小的画布上,如:

var canvas = $(‘canvas#mycanvas’);
canvas.width = $(window).width;
canvas.height = $(window).height;
...
var img = new Image();
img.src = “map.png”;
...
var context = canvas[0].getContext("2d");
context.drawImage(img, x, y, w, h, 0, 0, canvas.width, canvas.height);

其中x,y是平移定义的源图像中的左上角 w,h是源图像中由缩放级别确定的区域大小

这里的问题是大型地图图像在内存中以某种方式失去了质量(我只能假设有一些内存上限导致抖动),导致地图在应用程序中看起来扭曲:see here for an example screenshot

第3。使用HTML5画布将地图显示为矢量

一些谷歌搜索让我发现了ai2canvas,这是一个Illustrator插件,可以将作品导出为HTML5画布中显示的矢量。导出的结果是一个包含一大块JS的html文件,它将illustrator中的所有路径表示为贝塞尔曲线。导出我的4000x2400地图导致包含矢量路径的550Kb html文件。 在我的测试应用程序中,我将整个地图渲染到4000x2400像素的内存中画布(未附加到DOM),然后使用context.drawImage()将其相关部分复制到视口大小的画布中。内存画布作为源。 在HTC Wildfire上,虽然内存画布的所有贝塞尔曲线的初始渲染时间约为2000毫秒,但画布之间的复制速度足够快,可以进行平滑的平移和缩放。问题是当我查看应用程序的内存使用情况时,一旦所有向量都呈现,它就会使用120Mb作为内存中的画布。

我尝试了使用矢量图的第二种方法;而不是将所有向量渲染到大型内存画布,我让应用程序计算在每个拖动/捏合事件期间当前平移位置/缩放级别的视口中哪些矢量路径可见,并且仅将可见向量绘制到视口大小的帆布。虽然这将所需的内存使用量减少到10Mb,但是在每个拖动/捏合周期执行这些计算所需的CPU周期使得应用程序在旧的Android手机上落后很多,而且无法使用。

4。使用离线平铺显示地图

使用map tiler,我为地图创建了PNG图块,缩放级别从25%到100%。在我的测试应用程序中,我可以根据需要延迟加载磁贴,从而减少内存使用量,并在HTC Wildfire上产生平滑的平移/缩放体验。我以为我找到了解决方案,直到我看到APK生成的大小:对于我的4000x2400地图,地图砖工生成了4Mb的平铺图像。我的大多数地图大约是2000x2000像素,因此产生了大约2Mb的图块。我的正确应用程序的代码加上Phonegap开销是另一个2Mb。

我的目的是发布Android / Apple市场上的一系列应用程序,每个应用程序都有一组大约10张地图,但每个地图的平铺重量在1-4Mb之间,因此生成的应用程序变得非常大

1 个答案:

答案 0 :(得分:3)

如果其他人对此感兴趣,我最后使用地图平铺解决了这个问题,使用名为pnqnq的工具创建了约束为256色的8位PNG。我的4000x2000地图的最终图块大小约为800K,而PNG-24则为4Mb,这对于Android和iOS应用程序中的资产而言是可接受的。