sobota, 7 maja 2016

JourneyPlanner #7 - Informacja pogodowa

To ostatni obowiązkowy post zdefiniowany przez regulamin. Ale nie ostatni w ogóle. Dzisiaj opiszę jak zrealizowałem dostęp do danych pogodowych. Jest to również ostatni punkt priorytetu MUST. Bardzo dobrze się składa, że wszystkie wymagania z najwyższym priorytetem udało zrealizować się w założonym regulaminowym czasie konkursu. 


Wyświetlanie informacji pogodowej z danego obszaru mapy było jednym z kluczowych funkcji niniejszej aplikacji. Moja wizja interfejsu jest taka, że oprócz pogody będzie jeszcze kilka innych kontrolek odpowiadających za pozostałe funkcje opisane we wspomnianym poście. Przełączając się pomiędzy nimi na zasadzie inputa typu RADIO, będziemy wyświetlać odpowiednie informacje ze wskazanego obszaru mapy. W obecnej formie funkcja pogody nie zadowala mnie (a jakże by inaczej) ale działa! Głównie chodzi (jak za każdym razem) o sposób prezentacji danych czyli wygląd GUI.

Interfejs


Rzeczą, od której zacząłem to sam przycisk uruchamiający funkcję informacji pogodowej. W tym celu w dobrze znanym już widoku mapy w górnej belce utworzyem button:


Już śpieszę z wyjaśnieniami. Samej budowy buttonu nie ma co opisywać. Natomiast kolejne atrybuty jak najbardziej.
  • ng-click - kliknięcie wywołuje metodę z kontrolera z parametrem weather (tutaj w przyszłości dobre byłyby jakieś stałe z ENUMa)
  • ng-class - dzięki temu mogę nadać przyciskowi klasę active co wpływa na jego wygląd. W tym przypadku klasa active jest nadana zawsze poza momentem naciśnięcia wybrania funkcji pogoda. Jaki to wygląd pokażę w screenie po opisaniu kontrolera.


Kontroler


Kontroler to ostatnie miejsce, w którym wprowadziłem zmiany.

Obsługa GUI



Do obsługi GUI wystarczy tylko tyle. Jak widać został dodany nowy atrybut kontrolera informujący o tym jaka operacja na mapie jest obecnie aktywna. Przyjmuje string lub null. Oraz metoda, za pomocą której ten atrybut ustawiamy. To wszystko doprowadza nas do następującego zachowania przycisku. Domyślnie jest on "przygaszony", a po kliknięciu w niego "zapala" się, co informuje nas o aktywowaniu funkcji pogodowej:

Pobieranie informacji pogodowej


Aby funkcja pogodowa zaczęła działać dodałem event click w obszarze mapy, zaraz po jej wywołaniu i metodę uruchamiającą aktywną funkcje programu:


Jak widać sprawdzam czy funkcja pogody jest aktywna, pobieram dane geograficzne zaznaczonego punktu i wykonuję zapytanie do OpenWeather API, które przy bezpłatnym planie daje dość duże możliwości, w postaci ograniczenia 60 zapytań na minutę. W dalszym kodzie przechwytuję odpowiedź, odpowiednio ją przetwarzam i dodaję marker w postaci ikony pogodowej na mapie. Niestety wadą tego rozwiązania jest konieczność dodawania dymków z pogodą, które w aplikacji mobilnej nie są najlepszym pomysłem. Prawdopodobnie w późniejszym etapie dodam wyświetlanie modala z dokładnymi informacjami. W tym momencie jest tylko ikonka, a reszta danych wyświetlana jest w konsoli:


Co dalej?


W dalszym ciągu będę starał się dodawać posty z postępu prac. Bardzo możliwe, że nie tak często jak dotychczas. Muszę przyznać, że jest to dla mnie dość dużym obciążeniem ale również daje mi pewną satysfakcję. Jedno co mogę zagwarantować, że aplikacja będzie rozwijać się dalej nawet jeśli nie uda mi się tych zmian regularnie opisywać.
Kolejne etapy to:
  • Usprawnienie funkcji pogodowej
  • Realizacja priorytetu SHOULD

środa, 4 maja 2016

JourneyPlanner #6.3 - Refaktoryzacja wyników wyszukiwania cz.3

Witam cię drogi czytelniku w trzecim i ostatnim wpisie traktującym o refaktoryzacji funkcji wyszukiwania. Zostaną opisane tutaj zmiany jakie wykonałem aby możliwe było naniesienie wybranych wyników wyszukiwania na mapę. A więc do dzieła!


Widok wyszukiwania

Ostatnim razem zatrzymałem się w momencie, w którym wyszukiwanie odbywa się w osobnym widoku, a jego wyniki prezentowane są pod postacią przyjaznej urządzeniom dotykowym listy. Lista ta nie ma podpiętej póki co żadnej akcji pozwalającej na jakiekolwiek działanie. Należałoby ją w takim razie dodać. Zrealizowałem to poprzez dodanie atrybutu ng-click na elemencie listy. Jako wartość zadałem metodę kontrolera, do której przekazuję wybrany element. A wszystko to oczywiście w pliku szablonu ./lib/home/templates/search-results.html


Posiadając już taką konstrukcję trzeba tę metodę utworzyć. Dylematem był tutaj dla mnie sposób rozwiązania. W poprzedniej wersji wyszukiwania do usługi przekazywałem już gotową lokalizację. Tutaj niestety obiekt, który metoda otrzymuje posiada tylko identfikator. Przekazuje się go do dedykowanej usługi API Google Maps PlacesService aby uzyskać szczegółowe informacje na temat miejsca np. jego lokalizację. Wymagało to zmiany podejścia ponieważ wspomniana usługa Google Maps przyjmuje również w konstruktorze obiekt samej mapy, niedostępny w przestrzeni kontrolera wyszukiwania. Zmodyfikowałem zatem moją usługę wyszukiwania tak aby przyjmowała tylko identyfikator miejsca zamiast jego lokalizacji:


A co za tym idzie w kontrolerze wyszukiwania przekazuję do niej tylko identyfikator i wykonuję przekierowanie na akcję zawierającą mapę.


Widok mapy

Kontroler odpowiadający za wyświetlanie mapy, nie zmienił się zbyt wiele. Jedynie przybyło mu objętości. Inicjalizacja mapy odbywa się tak samo jak dotychczas, po jej wywołaniu dodałem fragment kodu w warunku:


Następuje tutaj wywołanie centrowania mapy na elemencie zawartym w usłudze wyszukiwania (jeśli jest zadany) i dodanie markera. Kod jest żywcem wzięty z przykładu zawartego w dokumentacji API Google Maps i działa bardzo dobrze :)

Rezultat

Rezultat jest bardzo przyjemny, a jego efekty spełniają moje oczekiwania: 
Podsumowując, punkt drugi priorytetu MUST wykonany. Pozostał jeszcze jeden dotyczący nanoszenia na mapę informacji o pogodzie. Dobrze się składa ponieważ okres publikacji postów do konkursu kończy się dla mnie w tym tygodniu. Oczywiście termin ten można przekroczyć, a posty publikować w dalszym ciągu co mam zamiar uczynić. Dumnie muszę powiedzieć, że udawało mi się dotychczas publikować minimum dwa posty tygodniowo. Zgodnie z regulaminem konkursu aby mój blog był rozpatrywany, poza tym postem powinienem do 8 maja opublikować jeszcze jeden wpis. O czym będzie traktował już wspomniałem - punkt trzeci priorytetu MUST czyli "Informacje pogodowe dla wybranego obszaru".