Moje pytanie brzmi: jak efektywnie wyświetlać duże niestandardowe mapy w aplikacji Phonegap w trybie offline, umożliwiając ich panoramowanie i płynne powiększanie przy jednoczesnym wspieraniu starszych urządzeń mobilnych?Wyświetlanie i nawigacja dużych niestandardowych map offline przy użyciu Phonegap
Pracuję nad aplikacją mobilną, która polega na użyciu geolokalizacji do nawigacji po trasach pieszych w odległych obszarach, gdzie prawdopodobnie użytkownik nie będzie miał sygnału, a zatem połączenie z Internetem. Ważne jest, aby aplikacja działała dobrze z systemem Android 2.2+ (więc nie jest dostępna opcja SVG), a także iOS4 +.
Rysowałem niestandardowe mapy wektorowe za pomocą programu Adobe Illustrator w rozdzielczościach odpowiednich dla każdej trasy, przy czym średnia wynosi około 2000x2000 pikseli, a największa z nich daje jak dotąd obraz o wymiarach 4000 x 2400 pikseli.
Zdecydowałem się na korzystanie z Phonegap/JQM zamiast z wersji natywnej tylko dlatego, że pochodzę z programowania w tle i wydawało mi się najszybszym sposobem na uruchomienie interfejsu użytkownika bez potrzeby zagłębiania się w natywny kod, chociaż napisałem kilka wtyczek Phonegap, używając natywnego kodu do celów zarządzania mocą i ekranem.
Aplikacja musi pozwalać użytkownikowi na przesuwanie mapy (przeciąganie) i powiększanie/pomniejszanie (przez zaciśnięcie) od około 25% do 200% oryginalnego rozmiaru obrazu.
Większość testów zrobiłem w HTC Desire z systemem Android 2.3.3 i HTC Wildfire z systemem Android 2.2, ponieważ są to prawdopodobnie jedne z najniższych urządzeń ze specyfikacją, które będą musiały być uruchamiane przez aplikację na.
Próbowałem różnych sposobów wyświetlania mapy (szczegółowo poniżej), ale jak dotąd każda okazała się nieprzydatna do celu, albo dlatego, że wykorzystanie pamięci aplikacji jest zbyt duże, wymagana przestrzeń do przechowywania powoduje, że aplikacja jest zbyt duża do pobrania lub użycie procesora jest zbyt intensywne, co powoduje opóźnienie podczas panoramowania/powiększania.
Wszelkie sugestie bardzo doceniane. Z góry dziękuję.
Podejścia próbowałem:
1. Wyświetlacz map rastrowych jak PNG wykorzystaniem znacznika
Było to pierwsze podejście próbowałem. Wyeksportowanie obrazu o rozmiarze 4000 x 2400 z programu Illustrator w postaci 128-kolorowego PNG-8 dało plik o wielkości 746 KB. Przesunąłem obraz, absolutnie ustawiając go względem rzutni i powiększając obraz, skalując atrybuty width/height tagu. Problem z tym podejściem polegał na tym, że nawet na poziomie 1: 1, aplikacja Android wykorzystała 60 MB pamięci RAM do zdjęcia, a powiększenie do 200% spowodowało zwiększenie tego poziomu o 120 MB, powodując awarię aplikacji w HTC Wildfire.
2.Pokaż porcje rastrowej PNG wykorzystujące HTML5 canvas
Aby uniknąć problemu powiększania-in powoduje proporcjonalny wzrost zużycia pamięci, próbowałem ładowania obrazu za pomocą JS następnie kopiując część wyświetlanego obrazu na płótnie wielkość widoku, takim jak:
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);
gdzie x, y jest górny lewy róg w obrazie źródłowym określonej przez przesuwanie i w, h jest wielkość obszar w obrazie źródłowym określony przez stopień powiększenia
Problem polegał na tym, że duże obrazy mapy były takie mehow utraty jakości, podczas gdy w pamięci (Mogę tylko przypuszczać, istnieje jakiś górny limit pamięci, który powoduje ditheringu), powodując mapy wyglądać zniekształcone w aplikacji: see here for an example screenshot
3. widoku mapy jako wektor użyciem HTML5 canvas
Trochę Googlingów skłoniło mnie do odkrycia ai2canvas, wtyczki programu Illustrator, która umożliwia eksportowanie kompozycji jako wektorów wyświetlanych w kanwie HTML5. Wynikiem eksportu jest plik html zawierający fragment JS, który reprezentuje wszystkie ścieżki w ilustratorze jako krzywe Beziera. Po wyeksportowaniu mapy 4000 x 2400 uzyskano plik HTML o pojemności 550 KB zawierający ścieżki wektorowe. W mojej aplikacji testowej renderowałem całą mapę do płótna w pamięci (nie dołączonego do DOM) o wymiarach 4000 x 2400 pikseli, a następnie skopiowałem odpowiednie fragmenty na płótnie o rozmiarze widoku za pomocą metody context.drawImage() - płótno pamięci jako źródło. Na HTC Wildfire, chociaż początkowe renderowanie wszystkich krzywych Beziera do płótna w pamięci trwało około 2000ms, kopiowanie między płótnami było wystarczająco szybkie, aby umożliwić płynne przesuwanie i powiększanie. Problem polegał na tym, że gdy przyjrzałem się wykorzystaniu pamięci w aplikacji, wykorzystałem 120Mb dla płótna w pamięci po wyrenderowaniu wszystkich wektorów.
Próbowałem drugie podejście za pomocą mapy wektorowej; zamiast renderowania wszystkich wektorów na duże płótno w pamięci, sprawiłem, że aplikacja obliczyła, które ścieżki wektorowe były widoczne w oknie podglądu w bieżącym położeniu panoramy/powiększenia podczas każdego zdarzenia przeciągania/przycinania i tylko rysuje widoczne wektory do okna podglądu -size płótno. Chociaż zmniejszyło to wymagane zużycie pamięci do 10 Mb, cykle procesora wymagane do wykonania tych obliczeń w każdym cyklu przeciągania/ściskania spowodowały, że aplikacja była tak opóźniona w stosunku do starych telefonów z Androidem, że nie nadawała się do użytku.
4. Wyświetlanie map w trybie offline przy użyciu Dachówka
Korzystanie map tiler, stworzyłem płytek PNG dla moich mapach przy powiększeniach od 25% do 100%. W mojej aplikacji testowej byłem wtedy w stanie leniwie ładować płytki na żądanie, zmniejszając zużycie pamięci i zapewniając płynne działanie panoramy/zoomu nawet w HTC Wildfire. Pomyślałem, że znalazłem rozwiązanie, dopóki nie przyjrzałem się rozmiarowi wyprodukowanego pliku APK: dla mojej mapy 4000x2400, kaflarz map wykonał 4Mb obrazów płytek. Większość moich map ma około 2000x2000 pikseli, co daje około 2Mb płytek. Kod mojej właściwej aplikacji oraz nakładu Phonegap to kolejne 2 MB.
Moim zamiarem jest udostępnienie serii aplikacji dostępnych na rynkach Android/Apple, z których każdy zawiera zestaw około 10 map, ale przy układaniu każdej mapy waży od 1 do 4 MB, więc wynikowa aplikacja staje się bardzo duża. pobieranie.