gpt4 book ai didi

android - 使用 Phonegap 离线显示和导航大型自定义 map

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:06:07 25 4
gpt4 key购买 nike

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

我正在开发一个移动应用程序,它涉及使用地理定位来导航偏远地区的步行路线,在那里用户可能没有信号,因此没有互联网连接。重要的是,该应用程序可以与 Android 2.2+(因此 SVG 不是一个选项)以及 iOS4+ 一起运行良好。

我已经使用 Adob​​e Illustrator 以适合每条路线的分辨率绘制了自定义矢量图,平均约为 2000x2000 像素,迄今为止最大的图像为 4000x2400 像素。

我选择使用 Phonegap/JQM 而不是 native ,仅仅是因为我来自 Web 编程背景,这似乎是启动和运行用户界面的最快方法,而无需过多钻研 native 代码,尽管我已经出于电源和屏幕管理的目的,使用 native 代码编写了几个 Phonegap 插件。

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

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

我尝试了各种方法来显示 map (详情如下),但到目前为止,每种方法都被证明不适合用途,因为应用程序的内存使用量太大,所需的存储空间使应用程序太大而无法下载或CPU 使用率太高导致平移/缩放时滞后。

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

我尝试过的方法:

1. 使用标签 将 map 显示为光栅 PNG

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

2. 使用 HTML5 Canvas 显示光栅 PNG 的部分

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

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 是源图像中由缩放级别确定的区域大小

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

3.使用HTML5 Canvas 将 map 显示为矢量

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

我使用矢量图尝试了第二种方法;我没有将所有矢量渲染到一个大的内存 Canvas ,而是让应用程序计算在每个拖动/捏合事件期间在当前平移位置/缩放级别的视口(viewport)中哪些矢量路径是可见的,并且只将可见矢量绘制到视口(viewport)-大小的 Canvas 。虽然这将所需的内存使用量减少到 10Mb,但在每个拖动/捏合周期执行这些计算所需的 CPU 周期使得应用程序在旧的 android 手机上滞后太多以至于无法使用。

4.使用离线平铺显示 map

使用 map tiler ,我以 25% 到 100% 的缩放级别为我的 map 创建了 PNG 图块。在我的测试应用程序中,即使在 HTC Wildfire 上,我也能够按需延迟加载图块,从而减少内存使用并产生平滑的平移/缩放体验。我以为我找到了解决方案,直到我查看了生成的 APK 的大小:对于我的 4000x2400 map , map 拼贴器生成了 4Mb 的拼贴图像。我的大部分 map 大约为 2000x2000 像素,从而产生大约 2Mb 的图块。我的正确应用程序的代码加上 Phonegap 开销是另外 2Mb。

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

最佳答案

如果其他人对此感兴趣,我最终通过使用 map 平铺解决了这个问题,使用了一个名为 pnqnq 的工具。创建限制为 256 色的 8 位 PNG。生成的 4000x2000 map 的图块集大小约为 800K,而 PNG-24 的大小为 4Mb,这是我的 Android 和 iOS 应用程序中 Assets 可接受的大小。

关于android - 使用 Phonegap 离线显示和导航大型自定义 map ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13706136/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com