2012-12-04 6 views
7

私の質問は、オフラインのPhonegapアプリケーションに大きなカスタムマップを効率的に表示し、古いモバイルデバイスをサポートしながらスムーズにパンやズームを行う方法です。Phonegapを使用して大規模なカスタムマップをオフラインで表示してナビゲートする

ジオロケーションを使用して遠隔地の歩行ルートをナビゲートして、ユーザーに信号がないためにインターネット接続がない可能性が高いモバイルアプリケーションを開発しています。このアプリはAndroid 2.2以降(つまりSVGはオプションではありません)とiOS4 +ではうまく動作することが重要です。

Adob​​e Illustratorを使用して各ルートに適した解像度でカスタムベクトルマップを描画しました。その平均は約2000x2000ピクセルで、これまでに最大のものは4000x2400ピクセルの画像になりました。

私はWebプログラミングのバックグラウンドから来ているだけで、ネイティブではなくPhonegap/JQMを使用することにしました。ネイティブコードを掘り下げる必要なく、ユーザーインターフェイスを起動して実行するのが最も速い方法でした。電源と画面の管理のためにネイティブコードを使用してPhonegapプラグインを作成しましたが、

アプリケーションでは、元の画像サイズの約25%〜200%の間でマップをドラッグ(ドラッグ)してズームイン/ズームアウト(ピンチ込み)する必要があります。

私が行ったテストのほとんどは、Android 2.3.3を実行しているHTC Desireと、Android 2.2を実行しているHTC Wildfireにあります。これは、アプリケーションが実行する必要がある最も低い仕様のデバイスの一部である可能性が高いためですに。

マップを表示するにはさまざまな方法を試しましたが(以下で詳しく説明します)、アプリのメモリ使用量が大きすぎたり、必要な記憶領域が大きすぎたりするため、またはCPU使用量が多すぎるため、パン/ズーム時に遅れが生じます。

ご迷惑をおかけして申し訳ございません。前もって感謝します。私が試した


アプローチ:タグ

これを使用して、ラスターPNGなど

1.表示マップは、私が試した最初のアプローチでした。 Illustratorから4000x2400ピクセルイメージを128色PNG-8としてエクスポートすると、746Kbファイルになりました。私は、ビューポートを基準にイメージを絶対配置してイメージをパンし、タグの幅/高さ属性を拡大してイメージを拡大しました。 このアプローチの問題点は、1:1のズームレベルでも、Androidアプリケーションが画像に60MbのRAMを使用し、200%に拡大すると120Mbが増加し、HTC Wildfireでアプリがクラッシュするということでした。

2。HTML5キャンバスを使用してラスターPNGの部分を表示

拡大表示でメモリ使用量が増加する問題を回避するために、JSを介して画像を読み込み、表示する画像の部分をキャンバスにコピーしてみました。ビューポートのサイズ、のようなもの:

xが、yが およびWパニングによって定義されたソース画像内の左上隅であり、hはズームレベル

によって決定ソース画像内の領域のサイズである
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); 

ここの問題は、大きな地図画像がメモリにマップはアプリで歪んで見えるように引き起こして、(私は唯一のディザリングが得られているいくつかのメモリ上限がありますと仮定することができます)しながら、品質を失うmehow:HTML5のキャンバスに

を使用して、ベクターとして​​

3.表示マップ

グーグルでは、アートワークをHTML5キャンバスに表示されるベクターとして書き出すことができるIllustratorプラグイン「ai2canvas」を発見しました。エクスポートの結果は、イラストレーターのすべてのパスをベジェ曲線として表現するJSの塊を含むhtmlファイルです。私の4000x2400マップをエクスポートすると、ベクトルパスを含む550Kbのhtmlファイルが作成されました。 私のテストアプリケーションでは、マップ全体を4000x2400ピクセルのメモリ内キャンバス(DOMには付属していません)にレンダリングし、その中の関連する部分をcontext.drawImage()を使用してビューポートサイズのキャンバスにコピーしました。 - ソースとしてのメモリキャンバス。 HTC Wildfireでは、メモリ内キャンバスへのすべてのベジエ曲線の初期レンダリングに約2000msかかりましたが、キャンバス間のコピーはスムーズなパンおよびズームを可能にするほど速かったです。問題は、アプリケーションのメモリ使用量を見て、すべてのベクトルがレンダリングされたらインメモリキャンバスに120Mbを使用しているときでした。

私はベクトルマップを使用して2番目のアプローチを試みました。すべてのベクトルを大きなメモリ内のキャンバスにレンダリングするのではなく、ドラッグ/ピンチイベントごとに現在のパン位置/ズームレベルでビューポート内でどのベクトルパスが表示されているかを計算し、ビューポートに描画するサイズのキャンバス。これにより必要なメモリ使用量は10Mbに減少しましたが、すべてのドラッグ/ピンチサイクルでこれらの計算を実行するために必要なCPUサイクルは、古いアンドロイド端末ではアプリケーションがそれほど遅れませんでした。オフラインタイリングmap tilerを使用して

を使用して

4.表示マップは、私は100%に25%からズームレベルでマイマップのためのPNGタイルを作成しました。私のテストアプリケーションでは、HTC Wildfireでもメモリ使用量を減らし、スムーズなパン/ズームの操作を行うことができ、必要に応じてタイルを読み込むことができました。私はAPKのサイズを調べるまで解決策を見つけたと思っていました。私の4000x2400マップでは、map tilerが4Mbのタイル画像を生成しました。私の地図のほとんどは2000x2000ピクセルで、タイルは約2Mbになります。私の適切なアプリケーションとPhonegapのオーバーヘッドのコードは別の2Mbです。

私はAndroid/Apple市場で利用可能な一連のアプリをリリースしていますが、それぞれのアプリは約10個の地図がセットされていますが、各地図のタイル張りは1~4Mbですダウンロード。

答えて

3

これは他の人にとって興味深い場合は、pnqnqというツールを使用して256色に制限された8ビットPNGを作成し、最後にマップタイルを使用して解決しました。私の4000x2000マップのタイルセットは、AndroidとiOSアプリケーションの資産の許容サイズであったPNG-24の4Mbではなく、約800Kのサイズでした。

関連する問題