wtorek, 3 sierpnia 2010

Rysowanie map

Ostatnio pracowałem nad aplikacją która pozwoli na wyznaczenie jakiegoś obszaru na mapie. Dane mapy pobieram za pomocą biblioteki OGDI z VMAP'y, rysowanie odbywa się poprzez OpenGL, obsługa okien dzięki SDL.

To był mój pierwszy kontakt z mapami w formie elektronicznej, tzn. wiem co to googlemaps, ale nigdy wcześniej nie próbowałem wydobyć i wykorzystać takich informacji „własnoręcznie”. Nigdy też nie zastanawiałem się jak to jest robione. Także:
- VMAP to bardzo skomplikowana struktura, mapa Europy i Północnej Azji na poziomie 0, czyli największej skali i najmniejszej precyzji, to 509 megabajtów danych w blisko 4 tysiącach plików !!!
- Nie wyobrażam sobie samemu zrobić obsługę takiego molocha w żadnym sensownym czasie,
- OGDI pozwala na obsługę danych geograficznych podobnie do bazy danych, podajemy kryteria (obszar geograficzny) oraz tabelę (warstwę), w wyniku otrzymujemy zbiór rekordów spełniających zapytanie,
- Dane mogą przyjąć formę punktów (miasta), linii (drogi), obszarów (lasy), bądź tekstu. OGDI dopuszcza jeszcze parę innych, ale ja się z nimi nie spotkałem,
- Obszary to tak naprawdę zamknięte linie i żeby je narysować trzeba najpierw zamienić dane w coś co jest akceptowalne przez OpenGL. Tak, tak, na trójkąty,
- Zamiana obszaru, który nie jest wypukły i ma w sobie otwory, z formy konturów na trójkąty nie jest zadaniem trywialnym,
- Na szczęście istnieje OpenGL ze swoim zestawem funkcji do teselacji (gluBeginPolygon i spółka).


Przetworzenie danych z obszaru Polski na formę, którą można w miarę wydajnie renderować trwa dość długo (parędziesiąt sekund), a aplikacji rysujących mapy będzie jeszcze kilka i wszystkie będą używane naprzemiennie. Nie ma takiej możliwości aby pracowały równocześnie i nie ma takiej możliwości aby włączały się tak długo. Uznałem więc za sensowne opracowanie pomocniczego procesu, który przygotuje te dane raz i udostępni je w formie pamięci współdzielonej. W tym celu wykorzystałem boost::interprocess::shared_memory_object.

Screeny (przedstawiają Łódź):