Android Offline Map ohne Google Maps API
Basiert auf: http://ghoshehsoft.wordpress.com/2012/03/09/building-a-map-app-for-android/
Bestandteile:[Bearbeiten]
Klasse TilesManager[Bearbeiten]
- Berechnung welche Tiles benötigt werden
- Längen und Breitengrade in Pixel umrechnen
Klasse Tiles Provider[Bearbeiten]
- Bekommt einen Index-Bereich und holt die passenden Kacheln (Tiles)
- Verwaltet einen Cache um Zeit zu sparen
- Für eine Online Map kann man einfach diese Klasse anpassen
Klasse MapView[Bearbeiten]
- Übergibt Ortsdaten an den TilesManager und bekommt Informationen welche Tiles gerendert werden müssen und an welcher Stelle
- Holt sich vom TilesProvider die passenden Bilder und rendert diese
- Reagiert auf Touch Events
Klasse Tile[Bearbeiten]
- Enthält x und y Koordinaten sowie ein Bitmap
Helfer Klasse PointD[Bearbeiten]
- Enthält einen Punkt in der Form zweier Double Werte
Tiles Manager[Bearbeiten]
Der TilesManager liefert uns Methoden um die richtigen Tiles an der richtigen Stelle zu rendern.
Eingang:
- Position (Longitude / Latitude)
- Zoom Level
Ausgang:
- Rectangle (left, top, right, bottom)
Wichtige Funktionen des TilesManager[Bearbeiten]
calcRatio[Bearbeiten]
public static PointD calcRatio(double longitude, double latitude)
Konvertiere longitude and latitude to ratio values, wobei ein Ratio Wert eine Zahl zwischen 0 und 1.
Dies ist sinnvoll, weil man so leicht berechnen kann welche Kachel bei einer bestimmten Koordinate und einem bestimmten Zoom Level benötigt wird.
Das funktioniert deswegen weil in der Karte die Kacheln oben Links mit (0,0) beginnen und dann der Index nach rechts und unten wächst. Die Berechnung geht dann so:
Die Anzahl der Kacheln in der Karte ist:
count = 2^zoom
KachelIndex auf der x/y Koordinate:
tileX = ratioX * count tileY = ratioY * count
mapSize[Bearbeiten]
Das packen wir in ein paar Funktionen. Die Anzahl der Kacheln berechnet
public int mapSize()
public int mapSize()
{
return (int) Math.pow(2, zoom);
}
calcTileIndices[Bearbeiten]
Mit dieser Information kann uns jetzt die Funktion calcTileIndices Längen- und Breitengradwerte in den passenden index umrechnen.
protected Point calcTileIndices(double longitude, double latitude)
updateVisibleRegion[Bearbeiten]
Jetzt wissen wir welche Kachel für diesen Punkt benötigt wird. Aber eine Karte besteht i.d.R. aus mehreren Kacheln. Deshalb müssen wir auch noch die passenden Nachbar-Kacheln rendern die in unserem MapView sichtbar sein sollen.
Point lonLatToPixelXY(double longitude, double latitude)[Bearbeiten]
Rechnet einen Geografischen Punkt in einen Pixelpunkt auf der Karte um (0,0) ist dabei oben links
public double calcGroundResolution(double latitude)[Bearbeiten]
Wieviele Meter in wirklichkeit entsprechen einem Pixel auf der Karte ?
public PointD pixelXYToLonLat(int pixelX, int pixelY)[Bearbeiten]
Umkehrfunktion zu linLatToPixelXY. Welche geografische Koordinate entspricht einem Pixel auf der Karte ?
TilesProvider[Bearbeiten]
Während der TilesManager uns die mathematische Funktionalität liefert um mit Punkten und den dazu passenden Kacheln zu arbeiten, soll und der TilesProvider die dazu passenden Bilder liefern.
Der TilesProvider holt sie sich aus der Datenbank und liefert sie aus. Dazu soll er zusätzlich einen Cache nutzen, weil die Datenbankoperationen relativ langsam sind.
Klasse Tile[Bearbeiten]
Diese besteht nur aus dem x,y index der Kachel und einem Bitmap
Klasse TileProvider[Bearbeiten]
Die wichtigste Methode hier ist:
public void fetchTiles(Rect rect, int zoom)[Bearbeiten]
Holt die passenden Kacheln aus der Datenbank. An die Funktion wird ein Rechteck mit dem Index-Range und der Zoomlevel übergeben.
Dann wird eine Abfrage auf die sqlite Datenbank gemacht:
xyz(1,3,2) I have to query for x=1 AND y=3 AND z=15
Besonderheit an der Datenbank ist das der Zoomlevel von 17 subtrahiert wird. Will man Zoomlevel 2 muß man nach 17-2 abfragen (s.o.)
Die Ergebniskacheln werden in einer Hashtabelle gespeichert. Ist die Kachel bereits durch die letzte Abfrage vorhanden kann sie direkt aus der alten Hashtabelle entnommen werden und muß nicht aus der Datenbank gezogen werden.
MapView[Bearbeiten]
Dieser View rendert die Karte und manipuliert die Ansicht wenn nötig.
Er enthält zwei GPS Positionen - Das Zentrum der Karte und die aktuelle Position des Nutzers (also die Position die das GPS liefert).
MapActivity bzw. MainActivity[Bearbeiten]
Dies ist die Hauptactivity. Sie erzeugt den MapView und berücksichtigt Status Änderungen des Android Gerätes. Hinweis im Original MapActivity ist es in der webmynet Anwendung die MainActivity
MapViewLocationListener[Bearbeiten]
Ist ein erweiterter LocationListener der mit der MapView zusammen arbeitet.
Der LocationListener implementiert ein Interface das eine Funktion onLocationChanged enthält. Immer wenn eine neue Position vorliegt können wir damit den Marker neu setzen.