Pełną wersje artykułu można pobrać tutaj
Aplikacje wykorzystujące mapy w Adobe Flex
Popularność
serwisów wykorzystujących mapy jako jeden z głównych elementów
interfejsu użytkownika ciągle wzrasta. Od pierwszej wersji API map
Google powstało wiele doskonałych aplikacji opartych o tego typu
rozwiązania. Z punktu widzenia programisty, tematyka ta staje się coraz
bardziej atrakcyjna, a używane technologie są coraz doskonalsze.
Mamy możliwość korzystania z kilku środowisk klienckich (AJAX, Flash, Flex lub w przyszłości Silverlight), jak i interfejsów aplikacji (API). Głównymi dostarczycielami technologii są Google Maps, Yahoo Maps oraz Microsoft Live Search Maps.Dlaczego warto połączyć te technologie z platformą Adobe Flex? Odpowiedź na to pytanie można podzielić na kilka punktów. Po pierwsze – łatwiejsza komunikacja z API dostarczycieli map. Z reguły odbywa się ona za pomocą Web Services SOAP lub REST, które z kolei są mocno osadzone w środowisku Flex. Po drugie – możemy stworzyć rozbudowany interfejs korzystający z dużego modelu danych. Często przy wykorzystaniu technologi AJAX musimy wybrać, ze względu na optymalizację, jedno lub drugie. Korzystając zaś z Flexa – nie musimy rezygnować z ciekawych rozwiązań, wręcz przeciwnie – możemy często dopieścić nawet bardzo skomplikowaną aplikację ciekawym i nietuzinkowym interfejsem. Po trzecie – Flex będąc zbudowanym na Flashu, jest z natury środowiskiem graficznym. Oznacza to, że możemy w łatwy sposób łączyć elementy wizualne z wybraną technologią map.
Istnieje już kilka ciekawych projektów aplikacji internetowych RIA opartych na mapach oraz środowisku Flex. Spektrum zastosowań biznesowych tego typu rozwiązań może być bardzo szerokie. Jeżeli puścimy wodze fantazji projektując aplikację, a dodatkowo skorzystamy z usług agregujących dane gromadzone we wszelkiego rodzaju serwisach, aby pobrać dodatkowe dane, możemy zbudować aplikację realizującą dowolne zadania. Ciekawymi realizacjami są np.:
• Aplikacja do mierzenia własnego postępu podczas biegania lub jeżdżenia na rowerze. Gotowe rozwiązanie możemy znaleść pod adresem http://www.traxmeet.com/traxmeet/ Pozwala nam na regularne mierzenie poczynanych przez nas postępów poprzez integrację z danymi pobieranymi z GPS, a następnie dokładną ich analizę;
• Aplikacja, która umożliwia naniesienie na mapę zdjęć oraz danych geolokalizacyjnych odczytanych z urządzeń zapisujących pozycję GPS. Całość pozwala np. na odtworzenie odbytej przez nas wycieczki, dodatkowo nanosząc wprowadzone przez nas dane. Następnie możemy rozesłać tak przygotowaną mapę do znajomych. Projekt znajdziemy pod adresem http://mapmypix.com/;
• Prosty, ale ciekawy przykład znajdziemy również pod na stronie http://www.earthmeasurements.com/. Jest to rozwiązanie pocoraz doskonalsze.
zwalające na mierzenie odległości pomiędzy kolejnymi punktami przez nas wyznaczonymi. Odległości pomiędzy punktami przedstawione są jako kolejne elementy wykresu;
• HomeLocator jest przykładem aplikacji pozwalającej na zestawienie w ciekawy sposób informacji o sprzedawanych domach, jak i ich lokalizacji geograficznej. Aby zapoznać się z tym przykładem, należy odwiedzić stronę http://www.asfusion.com/apps/homelocator/. Całość została zaopatrzona w intuicyjny i przyjazny interfejs;
• TrailTracer to aplikacja służąca do tworzenia i współdzielenia spersonalizowanych map. Znajdziemy ją pod adresem http://www.trailtracer.com/;
• Oobgolf Course Finder jest narzędziem do przeglądania informacji o wprowadzonych do bazy serwisu polach golfowych. Serwis można pochwalić za jakość wykonania aplikacji, jak i ilość oraz dokładne położenie przeglądanych miejsc. Znajdziemy go pod adresem http://www.oobgolf.com/courses/finder/;
• Często stosowanym rozwiązaniem jest geolokalizacja punktów sprzedaży danej sieci, tak aby klienci mogli znaleźć najlepiej im odpowiadający. Przykładowe rozwiązanie zastosowała firma Rolex. Rozwiązanie znajdziemy pod adresem http://www.rolex.com/
Osobiście jako konsultant i programista Adobe Flex wykonałem kilka ciekawych projektów wykorzystując mechanizm map. Najbardziej interesującym z nich jest aplikacja pozwalająca na śledzenie w czasie rzeczywistym oraz przeglądanie danych historycznych o włamaniach. Jest to ciągle rozwijany projekt, jednak udowodnił on, że Flex jest doskonale sprawdzającym się narzędziem do takich zastosowań. Aplikacja opiera się na danych kilwww.sdjournal.org33kuset do kilkunastu tysięcy obiektów, a do tego obserwacja zgłoszonych zdarzeń w zabezpieczanych budynkach może odbywać się w czasie rzeczywistym. Całość została zaopatrzona w ciekawy i przyjemny dla użytkownika interfejs. Pozwala on na zmianę parametrów aktualnie przeglądanych wydarzeń oraz ich filtrowanie. Projekt jest wykonywany na zlecenie firmy ochroniarskiej pragnącej narzędzia pozwalającego na szybkie i przejrzyste zapoznanie się i analizowanie danych o przestępstwach (Rysunek 1.).
Bardzo ciekawe możliwości daje połączenie platformy Flex, map oraz technologii zdalnego dostępu i wymiany wiadomości BlazeDS lub LiveCycle DS (technologie umożliwiające budowę aplikacji korzystających z logiki biznesowej serwerów Java w czasie rzeczywistym). Możliwości biznesowe takich rozwiązań są bardzo obiecujące. Przykładowo, pozwalają one na współdzielenie w czasie rzeczywistym map przez kilku użytkowników, np. podczas telekonferencji. Tak wykonaną prostą aplikację wraz ze źródłem oraz instrukcjami wykonania znajdziemy pod adresem http://coenraets.org/. Zainteresowanych tematyką koniecznie odsyłam do zapoznania się z przedstawionym rozwiązaniem.
Flex i API gotowych bibliotek
Jak wspomnieliśmy we wstępie podczas projektowania i wykonywania aplikacji do dyspozycji mamy kilka rozwiązań, jak i gotowych do użycia bibliotek. Podczas pracy z platformą Flex najlepiej jest skorzystać z:
• Yahoo Maps (http://developer.yahoo.com/maps/). Rozwiązanie jest wygodne, dostarczone zostało API dla ActionScript w wersjach 2 oraz 3, AJAX i Simple API (usługa niewymagająca umiejętności programowania). Całość jest dobrze udokumentowana, posiada wiele przykładowych zastosowań, jak i instrukcji krok po kroku. Projekt jest również bardzo czynnie wspierany przez środowisko. Wszelakie pytania możemy zadawać na oficjalnym forum http://tech.groups.yahoo.com/group/yws–maps/;
• UMap firmy Advanced Flash Components (http://www.afcomponents.com/components/umap_as3/). Dostarczone API dla ActionScript 3.0 oferuje wiele ciekawych funkcji. Rozwiązaniu temu warto jest się przyjrzeć bliżej, producent oferuje kilka instrukcji wprowadzających do swojego produktu. Ten projekt również posiada mocne wsparcie środowiska, forum znajdziemy pod adresem http://www.afcomponents.com/forum/viewforum.php?f=20. Standardowo użyte mapy mają trochę niższą jakość niż wymienione powyżej Yahoo Maps, ich głównym dostarczycielem jest serwis http://openstreetmap.com/ (możemy go jednak zamienić np. na Google Maps);
• Modest Maps
(http://www.modestmaps.com/). Zespół programistów tworzy rozwiązanie w oparciu o licencję BSD, dając nam do dyspozycji API ActionScriptowe w wersji 2 oraz 3, jak i dla języka Python. Do wyboru mamy kilku dostarczycieli map, możemy skorzystać z zasobów Open Street Map, NASA, Blue Marble, Google, Yahoo oraz Microsoftu. Projekt nie jest rozwijany tak prężnie jak wcześniejsze i nie posiada tak silnego wsparcia jak one.
Najlepszym rozwiązaniem z naszego punktu widzenia są Yahoo Maps. Poza obsługą samych map bezpośrednio z poziomu ActionScript 3.0 mamy do dyspozycji wiele przydatnych Web Services, m.in.:
• Yahoo! Weather (http://developer.yahoo.com/weather/). Umożliwia on połączenie map z danymi pogodowymi dla zadanej lokacji. Przykładowo prognoza pogody dla Krakowa znajduje się pod adresem http://weather.yahooapis.com/forecastrss?p
=PLXX0012;
• Yahoo! Traffic (http://developer.yahoo.com/traffic/). REST API daje nam możliwość dostępu do bieżących danych o natężeniu ruchu ulicznego w żądanej lokalizacji;
• Yahoo! HotJobs
(http://developer.yahoo.com/hotjobs/). Dzięki faktowi, że ogłoszenia pracy w serwisie Yahoo możemy przeglądać wyszukując m.in. po nazwach miast, możliwe jest stworzenie aplikacji łączącej tę usługę wraz z mapami. Rezultat może być
prawdę ciekawy;
• Yahoo! Travel (http://developer.yahoo.com/travel/). REST API pozwala nam na dostęp do danych zawierających informacje o
cieczkach, ciekawych miejscach, możliwych połączeniach lotniczych czy miejscach hotelowych. Aplikacja stworzona w oparciu o takie rozwiązanie może udostępnić użytkownikom nowe, przyjazne podejście do tej tematyki.
Możemy również użyć gotowych bibliotek stworzonych pod ActionScript 3.0
twiających korzystanie z udostępnionych przez Yahoo serwisów. Biblioteka ta
Yahoo! Astra Web Library. Aby się z
zapoznać, należy odwiedzić stronę http://developer.yahoo.com/flash/astra–webapis/. Dzięki niej mamy uproszczony dostęp np. Yahoo! Weather.
Yahoo Maps ActionScript 3.0 API
Stronę projektu znajdziemy pod adresem http://developer.yahoo.com/flash/maps/index.html. Jak już wcześniej wspomnieliśmy, znajdziemy tu dostęp do bardzo dobrej dokumentacji API (http://developer.yahoo.com/flash/maps/classreference/index.html), wprowadzenie do
blioteki (http://developer.yahoo.com/flash/maps/using.html) oraz liczne przykłady użycia jej
nych elementów (http://developer.yahoo.com/flash/maps/examples.html).
Aby móc skorzystać z biblioteki, instalujemy środowisko Flex (do pobrania z http://www.adobe.com/products/flex lub z płyty dołączonej do magazynu). Ze strony http://developer.yahoo.com/flash/maps/index.html
bieramy aktualną wersję komponentu Yahoo Maps for ActionScript 3.0. W pliku .zip znajdziemy m.in. skompilowaną bibliotekę YahooMap.swc (w katalogu Build). Plik ten umieszczamy w katalogu libs tworzonych we Flex Builderze aplikacji. Aby móc w pełni korzystać z serwisu Yahoo Maps będziemy potrzebować jeszcze swój klucz API potrzebny podczas inicjalizacji mapy. Aby go otrzymać,
jestrujemy naszą aplikację pod adresem http://developer.yahoo.com/wsregapp/index.php. Przejdźmy teraz do najprostszego przykładu zastosowania komponentu (Listing 1.). Aby móc umieścić obiekt mapy w naszym projekcie, musimy umieścić go jako element komponentu UIComponent. Dzieje się tak, ponieważ dostarczone przez Yahoo rozwiązanie dziedziczy bezpośrednio po Sprite. Przeanalizujmy przykład z Listingu 1. Po zakończeniu tworzenia aplikacji wywoływana jest funkcja onCreationComplete(). W niej przechwytujemy parametr przekazany do Flexa zawierający nasz klucz API:
var appid:String = Application.application.parameters.appid;
Następnie tworzymy obiekt YahooMap, dodajemy jako odbiorcę zdarzenia zakończenia inicjalizacji tego komponentu funkcję handleMapInitialize()oraz wywołujemy metodę inicjalizującą mapę, przekazując jej nasz klucz oraz rozmiar okna, w którym jest wyświetlana:
_yahooMap = new YahooMap();
_yahooMap.addEventListener(YahooMapEvent .MAP_INITIALIZE, handleMapInitialize);
_yahooMap.init(appid,mapContainer.width,
mapContainer.height);
Kolejne linijki to: dodanie obiektu do wspomnianego UIComponent oraz nasłuchiwanie zdarzenia zmiany rozmiarów komponentu kontenera mapy oraz, w wypadku wystąpienia zdarzenia, wywołanie odpowiedniej funkcji:
mapContainer.addChild(_yahooMap);
mapContainer.addEventListener(ResizeEvent
.RESIZE, onMapContainerResize);
Następne linijki umożliwiają dodanie do obiektu mapy odpowiednich elementów ułatwiających korzystanie z mapy, są to m.in.: Pan Control – element umożliwiający przeciąganie mapy, Type Control – przełączanie pomiędzy typami widoków, Scale Bar – wyświetla aktualną skalę mapy oraz Zoom Widget – pozwala na zmianę przybliżenia:
_yahooMap.addPanControl();
_yahooMap.addZoomWidget();
_yahooMap.addTypeWidget();
_yahooMap.addScaleBar();
Po zakończeniu inicjalizacji mapy możemy wykonać dodawanie do niej elementów, np. wskaźników na mapie (Marker) czy ustalić punkt centralny, na który ustawi się nowo załadowana mapa. W naszym prostym przykładzie wykorzystaliśmy bardzo przydatny element biblioteki Yahoo Map, jaką jest mechanizm dekodujący zapytanie (w postaci obiektu Adress) do konkretnej lokalizacji geograficznej zawierającej dokładne współrzędne oraz zalecany poziom zbliżenia. Zwracany w wyniku zapytania obiekt (GeocoderResult) zawiera również inne dane, np. nazwę państwa, miasta, hrabstwa (w Polsce – powiatu), kod kraju, kod pocztowy itp. Możemy oczywiście wykonać zapytanie o wiele elementów naraz. Pamiętajmy jednak, wykonywane są one asynchronicznie, co wymusza na nas kontrolę odbieranych danych. Przyjrzyjmy się zawartości funkcji handleMapInitialize():
_address = new Address("warszawa");
_address.addEventListener(GeocoderEvent.GEOCODER_SUCCESS, onGeocodeSuccess);
_address.geocode();
Tworzymy obiekt Adress, przekazując do niego treść zapytania. Następnie jako odbiorcę zdarzenia powodzenia zapytania ustalamy funkcję onGeocodeSuccess(). Kolejna linijka wykonuje zapytanie. Przejdźmy więc do funkcji odbierającej wymienione zdarzenie. Po odebraniu rezultatu w postaci zdarzenia, na jego podstawie ustalamy poziom zbliżenia mapy oraz jest punkt centralny (obiekt LatLon):
var result:GeocoderResult = _address.geoco
derResultSet.firstResult;
_yahooMap.zoomLevel = result.zoomLevel;
_yahooMap.centerLatLon = result.latlon;
Ostatnią funkcją jest onMapContainerResize(). Jak już wcześniej wspomnieliśmy, wywoływana ona jest automatycznie po zmianie rozmiaru komponentu zawierającego mapę. Aby zapewnić poprawne wyświetlanie mapy, musimy upewnić się, że nowe wartości zostaną przekazane jej obiektowi1. Spowoduje to przerysowanie elementów składowych (mapa, wskaźniki, elementy interfejsu mapy). W naszym przykładzie sytuacja ta wystąpi w momencie zmiany rozmiarów okna przeglądarki. Zadanie to jest realizowane wywołaniem odpowiedniej metody:
_yahooMap.setSize(mapContainer.width,mapContainer.height); Jak widzimy zastosowanie komponentu
YahooMap jest bardzo proste, a jego stosowanie logiczne.
Dodanie wskaźników do mapy
Wizualizacja danych w aplikacjach wykorzystujących mapy odbywa się poprzez zastosowanie wskaźników (Markers), które zostają umieszczone w odpowiadających im pozycjach. W dalszej części omówimy umieszczanie prostych wskaźników, jak i stworzenie własnych oparte na stworzonych przez nas elementach graficznych.
Zarządzaniem wskaźnikami zajmuje się klasa MarkerManager. Przy użyciu komponentu YahooMap, używając standardowej klasy map, biblioteka sama stworzy dla nas odpowiedni obiekt. Następnie będziemy mogli do niego dodawać wskaźniki, upewniając się, tylko aby miały one poprawne dane geograficzne. Jako wskaźników użyjemy prostych obiektów SimpleMarker. Są one wbudowane w omawianą bibliotekę. Rozszerzmy więc poprzedni przykład. Dodamy wokół punktu centralnego kilka losowo umieszczonych wskaźników. Aby to zrobić, musimy najpierw mieć zwróconą treść zapytania GeoCoderResult. Modyfikujemy funkcję onGeocodeSuccess():
Jest to maksymalnie uproszczony przykład, mający zobrazować zasadę działania tego mechanizmu. Aby stworzyć własny wskaźnik, rozszerzamy klasę Marker. Klasa ta posiada już kilka przydatnych dla nas właściwości, jak np. adres, własne dane geograficzne, referencję do obiektu mapy, na której jest umieszczony, największy i najmniejszy poziom zbliżenia, przy którym wskaźnik jest widoczny, a także charakterystyczny identyfikator grupy wskaźników. Jeżeli chcemy przyporządkować wskaźniki do takiej grupy, będziemy mogli pobierać tablicę zawierającą referencję do wszystkich jej elementów z poziomu obiektu MarkerManager. Przyda się to np. w sytuacji, gdy chcemy szybko ustawić danej grupie pewne właściwości, np. ich widoczność.
Załóżmy, że na potrzeby projektu musimy stworzyć wskaźniki graficzne według projektu graficznego, który nam dostarczono. Najprostszy sposób, w jakim możemy tego dokonać to wykonać odpowiednie grafiki w programie Flash, wyeksportować je do plików SWF, które to z kolei możemy wprowadzić do naszej aplikacji. Zacznijmy więc od początku – tworząc grafikę. Przykład zamieszczony jest na Rysunku 2.
Wygodne jest stworzenie wskaźników w aplikacji Flash, bo tworzonym elementom możemy automatycznie przyporządkować punkt odniesienia. Jest to o tyle ważne, że nie musimy później pamiętać o przesunięciu wskaźników. Sytuacja taka zdarzyłaby się przy użyciu np. grafik .png, które są pozycjonowane w swoim górnym lewym rogu. Aby tego uniknąć, musimy korzystać ze specjalnej klasy, CustomImageMarker.
Mając przygotowany wskaźnik w postaci pliku .swf, przygotujemy klasę dziedziczącą po Movie Clip, który będzie go zawierać. Obrany tu przeze mnie sposób dobrze ilustruje, jak możemy szybko osiągnąć pożądany rezultat. Przy użyciu wielu różnych wskaźników najlepiej jest stworzyć we Flashu odpowiedni plik zawierający, który je zawiera, i napisać metody, które będą zwracały nam odpowiednie obiekty. Całość eksportujemy do Flexa za pomocą narzędzia Flex Component Kit for Flash (http://www.adobe.com/go/flex3_cs3_swfkit). Wracając do omawianego przykładu, napiszmy klasę Movie Clip zawierający plik Flash (Listing 4.). Mając gotowy do użycia symbol graficzny, możemy stworzyć własny wskaźnik. Załóżmy, że chcemy wykorzystać przygotowaną grafikę, a klient dodatkowo żąda od nas wyświetlenia dymku z informacją o danej lokalizacji zawierającego dodatkowo pewną ikonkę. Tworzymy plik CustomMarker.as (Listing 3.).
Omówmy ten przykład. Do konstruktora wskaźnika przekazujemy jego nazwę, pewien adres (pojawi się on w dymku), oraz adres URL obrazka, który chcemy załadować. Nasłuchiwanie zdarzeń związanych z ruchem myszki pozwoli na pokazanie lub ukrycie podpowiedzi. Stworzony wcześniej FlashMarker dodajemy do naszego wskaźnika poprzez (dodajemy do niego również cień):
this.marker = new FlashMarker();
this.marker.filters =
[this.dropShadowFilter];
this.addChild(this.marker);
Funkcja drawToolTip() powinna być doskonale zrozumiała dla osób na co dzień korzystających z aplikacji Flash i języka ActionScript. Ręcznie rysujemy w niej dymek, dodajemy i formatujemy tekst, który ma się w nim ukazać a także ładujemy i wyświetlamy rządany obrazek. Powróćmy do głównego pliku naszej aplikacji i zmodyfikujmy funkcję onGeocodeSuccess() (Listing 5.). Wynik naszej pracy możemy zobaczyć na Rysunku 3.
Możliwości bilioteki Yahoo Maps Actionscript 3.0 API
Większość elementów biblioteki została doskonale omówiona na stronie http://developer.yahoo.com/flash/maps/examples.html. Przedstawione tam przykłady zawierają podgląd źródła, możemy więc zapoznać się krok po kroku z kolejnymi funkcjami tego API. Wstępnie zapoznaliśmy się z możliwością zadawania zapytań o adres, pozycjonowaniem wskaźników, a także z tworzeniem własnych obiektów służących do wyświetlania danych. Przejrzenie przykładów ze wspomnianej strony pozwoli nam na zrozumienie zasad:
• Obsługi kolejnych zdarzeń komponentu YahooMap;
• Rysowania polilinii w przedstawianych mapach (jest to o tyle łatwe, że kolejne wierzchołki możemy definiować za pomocą współrzędnych geograficznych);
• Rysowania tzw. Geodesic Polyline, są to specyficzne krzywe, często wykorzystywane przy aplikacjach wykorzystujących mapy;
• Rysowania na mapach własnych kształtów, są one przechowywane w specjalnej warstwie;
• Korzystania z serwisu Yahoo! Local Search. Umożliwia on znajdowanie obiektów zainteresowań w bazie serwisu Yahoo! i umieszczania ich na prezentowanej mapie;
• Zbudowania serwisu w oparciu o bibliotekę Yahoo Maps oraz ASTRA Web API – korzystającej z danych meteorologicznych.
Zakończenie
Podczas wykonywania tego typu aplikacji pamiętajmy o pewnych ograniczeniach technicznych – spotkamy się z nimi na pewno w aplikacji opierającej się o setki lub tysiące punktów na mapach. Tworzenie zapytań o ich współrzędne geograficzne przy każdym uruchomieniu aplikacji jest dalece niepraktyczne. Zamiast tego upewnijmy się, że dane o punktach przechowywane przez nas w bazie będą miały również współrzędne. Możemy tego dokonać, zapisując każdy punkt w bazie, wywoławszy wcześniej odpowiedni Web Service, np. Geocoding API udostępnione przez Yahoo (http://developer.yahoo.com/maps/rest/V1/geocode.html). Co ważne – posiada on limit 5000 zapytań na dobę.
Zapoznaliśmy się z możliwościami użycia biblioteki Yahoo Maps Actioncript 3.0 API. Wykorzystując ją (lub inne wcześniej wspomniane), możemy budować bardzo ciekawe serwisy, których funkcjonalności były wcześniej trudne do osiągnięcia klasycznymi technikami. Platforma Flex umożliwia nam bardzo łatwą komunikację z dziesiątkami Web Services na świecie, przy wykorzystaniu serwisów typu Yahoo! Pipes (urzeczywistnienia zasady Web As Platform). Nawet trywialne przykłady zastosowania przy użyciu tej technologii, mogą być ciekawie przedstawione – np. ile hoteli znajduje się w promieniu 5 minut jazdy taksówką od centralnego punktu odwiedzanych przeze mnie miast?
WOJCIECH PTAK
Od 2 lat konsultant i programista Adobe Flex oraz Adobe Integrated Runtime (AIR) (przez rok obejmował to stanowisko w norweskiej firmie Making Waves). Wykonał w całości m.in. aplikację Kalkulator Energetyczny Vattenfall, która została wyróżniona w międzynarodowym konkursie Webby Awards 2008. Aktualnie pracuje dla takich klientów jak Adidas, Heineken, Coca–Cola, Schweppes czy British Telecom, dostarczając kompleksowe aplikacje B2B oparte o Adobe Flex oraz AIR.