Erweitere deine Xamarin.Android-App mit OpenStreetMap
In diesem Artikel zeige ich, wie sich OpenStreetMap-Kartenmaterial in einer Xamarin.Android-App darstellen lässt. Dafür kommt OSMSharp zum Einsatz. Wenn dich die Kombination aus OpenStreetMap, OSMSharp und Xamarin.iOS interessiert, lies unbedingt auch meinen Artikel über OpenStreetMap in Xamarin.iOS.
BlogErweitere deine Xamarin.Android-App mit OpenStreetMap
Für die Integration von OpenStreetMap mit OSMSharp sind die folgenden Schritte nötig:
OpenStreetMap, kurz OSM, ist ein Projekt, bei dem jeder geografisches Material über Straßen, Wälder, Flüsse, Gebäude und vieles mehr sammeln und daraus eine Karte der Welt mitgestalten kann. Mehr über das Projekt erfährst du auf www.openstreetmap.org.
Xamarin.Android mit OSMSharp verbinden
Um den Schritten in diesem Artikel zu folgen, solltest du in Visual Studio ein Xamarin.Android-Projekt anlegen. Anschließend lädst du die in dem zugehörigen Bitbucket-Projekt im Ordner Referenced Assemblies abgelegten Bibliotheken herunter und fügst sie deinem Projekt als Referenz hinzu.
Danach sollte sich das Projekt noch bauen lassen. Leider funktionierte das damals nicht mehr mit den über NuGet verfügbaren Paketen.
Tile-Provider als Quelle für das Kartenmaterial festlegen
Damit OSMSharp geografisches Material in einer Android-App überhaupt darstellen kann, benötigt es eine Quelle für die kleinen Kacheln, die jeweils nur einen Ausschnitt der Karte enthalten. OSM stellt dafür verschiedene Server bereit. Eine Übersicht findest du unter https://wiki.openstreetmap.org/wiki/Tile_servers. Natürlich kannst du auch einen eigenen Tile-Server betreiben, wenn du möchtest.
Wie man an dieser Übersicht erkennen kann, bestimmt die Auswahl des Tile-Providers gleichzeitig auch das Erscheinungsbild der Karte - also Farben, Linienstärken und ähnliche Merkmale. Am besten kopierst du dir die URL direkt heraus, denn im nächsten Schritt brauchen wir sie.
Eine OpenStreetMap darstellen
Eine einfache OSM-Karte lässt sich mit OSMSharp mit wenig Code umsetzen. Zunächst brauchen wir dafür eine MapView-Instanz. Sie repräsentiert den sichtbaren Kartenbereich in unserer App. Da ich die Karte vollständig in der App nutzen wollte, habe ich die Instanz direkt per SetContentView an die Activity übergeben.
Natürlich braucht unsere MapView auch eine Karte. Daher erstelle ich eine Instanz von Map und weise sie MapView.Map zu. Damit überhaupt etwas zu sehen ist, benötigen wir noch die URI des zuvor ausgewählten Tile-Providers. Diese fügen wir der Karteninstanz mit AddLayerTile hinzu. Ab diesem Zeitpunkt übernimmt die Karte selbst alle weiteren Schritte, um Kartendaten darzustellen, etwa beim Verschieben der Ansicht.
Wichtig ist außerdem, dass Native.Initialize(); aufgerufen werden muss, bevor mit OSMSharp gearbeitet wird.
Das Bild links zeigt die Karte im Standardstil von OpenStreetMap. Wie schon unter iOS erhält man durch einen anderen Tile-Server als Quelle rechts eine optisch ansprechendere Variante.
Marker auf der Karte anzeigen
Im vorherigen Schritt wurde die Karte über MapCenter auf den Hauptsitz von Cayas Software zentriert. Damit dieser Ort leichter erkennbar wird, ist es Zeit, einen Marker auf der Karte zu platzieren.
OSMSharp stellt dafür die Klasse MapMarker bereit. Benötigt werden:
die Position, an der der Marker erscheinen soll
ein Bild, das den Marker repräsentiert
Damit ist der Rest nur noch ein kleines Stück Code:
using (var bitmap = BitmapFactory.DecodeResource(Resources, Resource.Drawable.pin))
{
var marker = new MapMarker(this, new GeoCoordinate(52.207767, 8.803513), MapMarkerAlignmentType.CenterBottom, bitmap);
_mapView.AddMarker(marker);
}
Die Pin-Grafik wird dazu einfach in den drawables-Ordner des Projekts gelegt. Das Ergebnis kann sich bereits sehen lassen.
Karten offline verwenden
Einer der Hauptgründe, warum ich mit OSMSharp und OpenStreetMap gearbeitet habe, ist die Möglichkeit, Karten auch in Offline-Szenarien zu nutzen. Um vergleichbar mit dem iOS-Artikel zu bleiben, konzentriere ich mich hier auf MBTiles als Datenquelle.
Damit OSMSharp den Kartenausschnitt aus den mbtiles-Dateien verwenden kann, binde ich sie der Einfachheit halber als Asset in das Android-Projekt ein. Dadurch muss kein Download implementiert werden.
In der App benötigen wir einen Stream auf die Datei und geben dem MBTile-Layer den Namen der Datenbank mit. Mit ein paar Zeilen Code lässt sich das so umsetzen:
using (var mapStream = File.OpenRead("./demo_layers.mbtiles"))
{
_mapView.Map.AddLayer(new LayerMBTile(SQLiteConnection.CreateFrom(mapStream, "map")));
}
Damit der Unterschied zwischen Online- und Offline-Karte klarer wird, habe ich für die Offline-Karte ein dunkles Farbschema gewählt. Wenn der Button Switch to MBTiles gedrückt wird, sieht das Ergebnis so aus:
OpenStreetMap lässt sich mit OSMSharp mindestens so einfach in eigene Xamarin.Android-Projekte integrieren wie Google Maps und ist dank flexibler Datenquellen sogar leichter an individuelle Anforderungen anpassbar. Das Demo-Projekt und alle Dateien findest du auf bitbucket.
FAQ
Mit OSMSharp erstellen Sie eine MapView, initialisieren die Bibliothek über Native.Initialize, binden einen Tile-Provider ein und setzen die Karte anschließend als sichtbare View in Ihrer Activity.
OSMSharp ist eine Bibliothek, mit der sich OpenStreetMap-Daten und Kartenmaterial in .NET- und Xamarin-Projekten verarbeiten und darstellen lassen.
Ja. Kartenmaterial kann über lokale Quellen wie MBTiles bereitgestellt werden. Dafür wird die Datei in das Android-Projekt eingebunden und zur Laufzeit als Layer geladen.
Sebastian Seidel
Als Mobile-Enthusiast und Geschäftsführer der Cayas Software GmbH ist es mir ein großes Anliegen, mein Team und unsere Kunden zu unterstützen, neue potenziale zu entdecken und gemeinsam zu wachsen. Hier schreibe ich vor allem zur Entwicklung von Android und iOS-Apps mit Xamarin und .NET MAUI.
Kartenfunktionen sind im mobilen Bereich ein wichtiges Feature. Kaum eine App gewinnt nicht an Wert, wenn sie Karten darstellen kann. Apple und Google machen mit ihren Map-SDKs vieles richtig, aber manchmal stößt man an Grenzen - sei es aus rechtlichen Gründen oder wegen eines Bugs. In meinem Fall war Letzteres der Auslöser. Ich brauchte außerdem eine Alternative, die auch offline funktioniert.
Spracheingabe macht es möglich, gegessene und getrunkene Lebensmittel intuitiv zu erfassen, ohne ständig auf ein Gerät schauen oder tippen zu müssen. Statt alles mühsam per Hand einzugeben, können Nutzer Mahlzeiten und Snacks einfach per Sprache dokumentieren. Das spart Zeit und senkt die Hürde für eine regelmäßige Erfassung.