2012-12-04 1 views
7

내 질문은 오프라인 Phonegap 응용 프로그램에 큰 사용자 정의 맵을 효율적으로 표시하여 이전 모바일 장치를 계속 지원하면서 팬을 부드럽게 확대/축소 할 수있는 방법입니다.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를 통해 이미지를로드 한 다음 표시 할 이미지의 일부를 캔버스에 복사했습니다. 뷰포트의 크기 일 같은

Y는 패닝 의해 승 정의 된 소스 이미지 내의 좌측 상단 x는
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); 

, h는 줌 레벨

결정 소스 이미지 내의 영역 크기

큰 문제는 큰지도 이미지가 품질을 잃고 폐하가있는 동안, (I는 디더링의 결과로 일부 상위 메모리 한계가있다 가정 할 수 있습니다)지도는 응용 프로그램에서 제대로 표시 원인 메모리 : HTML5 캔버스

를 사용하여 벡터로 see here for an example screenshot

3. 표시지도

Google 검색의 한 비트가 HTML5 캔버스에 표시되는 벡터로 아트웍을 내보낼 수있게 해주는 Illustrator 플러그인 인 ai2canvas를 발견하게되었습니다. 내보내기의 결과는 일러스트 레이터의 모든 경로를 베 지어 곡선으로 나타내는 JS 청크가 들어있는 html 파일입니다. 내 4000x2400 맵을 내보내는 결과 벡터 경로가 포함 된 550Kb html 파일이 생성되었습니다. 테스트 응용 프로그램에서 전체지도를 4000x2400 픽셀의 메모리 내 캔버스 (DOM에 연결되지 않음)로 렌더링 한 다음 context.drawImage()를 사용하여 뷰포트 크기의 캔버스에 관련 부분을 in - 메모리 캔버스를 소스로 사용합니다. HTC Wildfire에서 메모리 내 캔버스에 대한 모든 베 지어 곡선의 초기 렌더링에는 약 2000ms가 걸렸지 만 캔버스 간의 복사는 매끄러운 패닝 및 확대/축소가 가능할 정도로 빠릅니다. 문제는 앱의 메모리 사용량을 살펴볼 때 인 - 메모리 캔버스 용으로 120Mb를 사용하는 것이 었습니다.

나는 벡터지도를 사용하여 두 번째 방법을 시도했다. 모든 벡터를 큰 메모리 캔버스로 렌더링하는 대신 각 드래그/핀치 이벤트 중에 현재 팬 위치/줌 레벨에서 뷰포트 내에서 볼 수있는 벡터 경로를 계산하고 뷰 벡터에 표시되는 벡터 만 그리면됩니다 크기가 캔버스. 이로 인해 필요한 메모리 사용량이 10Mb로 줄어들었지만 모든 드래그/핀치 사이클에서 이러한 계산을 수행하는 데 필요한 CPU 사이클을 사용하면 이전 Android 휴대 전화에서 응용 프로그램이 너무 오래 사용되지 않았습니다. 오프라인 타일 map tiler를 사용

를 사용

4. 표시지도, 나는 100 %로 25 %에서 줌 레벨에서 내지도에 대한 PNG 타일을 만들었습니다. 내 테스트 응용 프로그램에서 필자는 HTC Wildfire에서도 메모리 사용량을 줄이고 부드러운 이동/확대/축소를 생성 할 수 있도록 타일을 게으르게로드 할 수있었습니다. 나는 APK의 크기를 살펴볼 때까지 해결책을 찾았다 고 생각했다 : 4000x2400의 4000x2400 맵에 대해 맵 타일러는 4Mb의 타일 이미지를 생성했다. 대부분의 내지도는 약 2000x2000 픽셀이므로 약 2Mb의 타일이 생성됩니다. Phonegap 오버 헤드를 더한 적절한 애플리케이션 코드는 또 다른 2Mb입니다.

제 의도는 Android/Apple 시장에서 사용할 수있는 일련의 앱을 출시하는 것입니다. 각 앱에는 약 10 개의지도 세트가 있지만 각지도의 크기는 1-4Mb 가량이므로 결과 앱이 매우 커집니다 다운로드.

답변

3

다른 사람들에게 관심이있는 경우, pnqnq이라는 도구를 사용하여 256 개의 색상으로 제한된 8 비트 PNG를 만드는 방법으로지도 타일링을 사용하여이 문제를 해결했습니다. 내 4000x2000지도의 타일 세트는 PNG-24의 4Mb와 달리 약 800K 크기였습니다. PNG-24는 Android 및 iOS 애플리케이션의 자산에 적합한 크기였습니다.