Straßenkarten und Satellitenbilder

Als ich damals meinen PKW Führerschein machte, war die Landkarte aus Papier immer noch ein übliches Inventar in jedem Fahrzeug.
Doch spätestens 2010 hatte jeder entweder ein separates Navigationsgerät oder ein Smartphone mit einer entsprechenden App, um sich auf den Straßen orientieren zu können.

Viel interessanter ist aber, wie man solche Karten-Apps selbst schreiben kann.


Während einige kostenpflichtigen Dienste ihr Kartenmaterial verstecken, haben einige große Dienste ihre Weltbilder per HTTP Web Request (auch REST Service genannt) der Öffentlichkeit zur Verfügung gestellt.

Schon vor einigen Jahren habe ich mit

ein paar Experimente gemacht.

Grundsätzlich ist die Sache recht einfach:

  1. Registrierung und Einrichtung eines API-Keys.
  2. Absetzen eines Webrequests mit Längen- und Breitengrad
  3. Empfang eines Bildes und/oder zusätzlicher Metadaten

Der API-Key identifiziert den zugreifenden Dienst (also die App) und dient auch zur Kontrolle der Anfragen. Ist das Angebot kostenlos, hat der API-Key eine bestimmte Anzahl an freien Zugriffen, z.B.: 1000 pro Tag, 100000 pro Jahr. Zusätzliche Zugriffe kann man allerdings per Zahlung nachkaufen.
So wird verhindert, dass man mit einem Key die gesamte Weltkarte herunterladen kann.

(Kein) Google Maps

Die besten Satellitenbilder hatte immer schon Google. Sie sind teils so hochauflösend, dass man Bodenmarkierungen auf Straßen erkennen kann.

Vor 6 Jahren schaltete ich daher mal einen API-Key frei um eine lokale Karte in eine globale von Google einzubetten.

Heute hat Google allerdings die Dienste gesperrt, wenn man keine Bezahlungsverknüpfung in seinem Konto eingerichtet hat … und eher sterbe ich, als dass ich Google Bank- Kreditkarten- oder Paypal-Daten zukommen lasse. Von daher ist Google von meiner Liste der zu implementierenden Kartenprovidern gestrichen.

Damals konnte man aber mit dem API-Key einfach die URL
http://maps.googleapis.com/maps/api/staticmap?center=LAT,LONG&zoom=19&scale=1&size=WIDTHxHEIGHT&maptype=roadmap&key=KEYE&format=png&visual_refresh=true mit entsprechenden Breitengrad- (LAT) und Längengrad- (LONG) Angaben zusammen mit dem API-Key (KEY) und Pixelbreite und -höhe (WIDTH, HEIGHT) aufrufen und erhielt eine Grafik als Download.

Ein bisschen komplex war die Sache mit der Auflösung. Google nutze einen zoom Faktor um die nähere oder entferntere Blickwinkel zum Zentrum (LAT,LONG) darzustellen.

Das Geheimnis war: Google hat alle Karten als 256 x 256 Pixel Teilgrafiken vorberechnet und auf dem niedrigsten Zoom-Faktor 0 findet man auf 256 Pixeln die gesamte Weltkarte wieder. Jeder weitere Zoomfaktor verdoppelt die Auflösung und das geht runter bis 22. Wenn man jetzt weiß, dass der Erdumfang am Äquator 40075160 Meter lang ist, erhält man 40075016 / 256 == 156543.594 Meter pro Pixel am Äquator und mit jedem weiteren Zoomfaktor halbiert sich diese Einheit.
Und da die Weltkarte eine Mercator-Projektion ist, ergeben sich die metrischen Maße um ein Zielpunkt aus der Formel:

metersPerPixel = cos(latitude) * 40075016 / (256 * 2 ^ zoom)

Beim höchstmöglichen Faktor 22 kommt man schon auf eine theoretische Auflösung von 4 cm pro Pixel. Die Kartenbilder sind zwar je nach Umgebung unterschiedlich scharf, aber im städtischen Gebiet ist das echt krass genau.

Bing Maps

Microsoft’s Bing Maps (früher als “Virtual Earth” bekannt) ist nun aber zwangsläufig der Gewinner, da ich nach wie vor ohne Bankdaten mit einem kostenlosen Account Daten davon beziehen kann.

Unter www.bingmapsportal.com kann man sich im Bing Maps Dev Center Account freischalten und unter My Account - My Keys API Keys anlegen. Der Key kombiniert folgende Datenfelder:

  • Application name
  • Applikation URL
  • Key type (z.B.: Basic)
  • Application Type (z.B.: Mobile, Website, Dev, Win-App)

Und schon kann man folgende Requests absetzen, indem man den generierten API-Key in jedem HTTP-Request als key Argument mitschickt.

  • http://dev.virtualearth.net/REST/V1/Imagery/Map/aerial?mapArea=48.2,16.4,48.25,16.45&mapSize=800,600&key=AKPIKEY&mapMetadata=1
    liefert JSON formatierte Daten zur gewählten Lage
  • http://dev.virtualearth.net/REST/V1/Imagery/Map/aerial?mapArea=48.2,16.4,48.25,16.45&mapSize=800,600&key=APIKEY&format=png
    gibt ein PNG Bild als Download zurück.

Bing arbeitet mit Ausschnitten, daher gibt man 4 Parameter als FROM-LATITUDE, FROM-LONGITUDE, TO-LATITUDE, TO-LONGITUDE an. Der JSON-Response gibt “angepasste” Koordinaten zurück, die zur mapSize (also Breite, Höhe) passen und mit eben diesen Daten, kann der PNG Request abgesetzt werden, womit man präzise weiß, was im Bildausschnitt genau gezeigt wird.

Die JSON-Rückgabe sieht in etwas so aus und kann leicht geparset werden:

 1{
 2  "authenticationResultCode":"ValidCredentials",
 3  "brandLogoUri":"http:\/\/dev.virtualearth.net\/Branding\/logo_powered_by.png",
 4  "copyright":"Copyright © 2022 Microsoft and its suppliers.",
 5  "resourceSets":
 6  [
 7    {
 8      "estimatedTotal":1,
 9      "resources":
10      [
11        {
12          "__type":"StaticMapMetadata:http:\/\/schemas.microsoft.com\/search\/local\/ws\/rest\/v1",
13          "bbox":
14          [
15            48.1908100765507,16.3564109802246,
16            48.2593128380802,16.4935684204101
17          ],
18          "imageHeight":"600",
19          "imageWidth":"800",
20          "mapCenter":
21          {
22            "coordinates":["48.2250061054994","16.425"]
23          },
24          "pushpins":[],
25          "zoom":"13"
26        }
27      ]
28    }
29  ],
30  "statusCode":200,
31  "statusDescription":"OK",
32  "traceId":"..."
33}

Fazit

Mit Bing-Maps (oder Google), kann man relativ einfach Landkarten-Grafiken per HTTP anfordern und in der eigenen Anwendung nutzen.
Statt hinterlegten Satellitenbildern, kann man die REST APIs auch auffordern nur Straßenkarten (mit und ohne Häuseradressen) zurückzuliefern.
Und es gibt noch einige weitere Features, wie Routenplanung oder Distanzberechnung, die man ebenso per HTTP-Request anfordern kann.

Und mit ein bisschen Mathe zur Mercator-Projektion, kann man jedem Pixel unter dem Mauszeiger auch seine Geo-Koordinaten zuordnen.

OpenStreetMap steht auf meiner TODO-Liste, doch da dessen API nicht so einfach aussieht und man Koordinaten von Straßen und anderen Objekten zurückbekommt, die man erst selbst auf ein Bild aufmalen muss, wird das wohl noch etwas dauern.

Die freie Nutzung von Geo-Positionierung und Karten ist aber auf jeden Fall ein wichtiges modernes Feature.

Die Anbieter integrieren es gerne mit jeder Menge Javascript Codes in Webseiten und Phone-Apps, aber verschweigen regelrecht, dass man auch ohne Scripts und Werbe-Einblendungen an die Rohdaten gelangen kann.

Man braucht also kein Android- oder Browser-Framework, um Karten in native Anwendungen einbetten zu können … doch leider werden diese Dienste auf diese Weise viel zu selten genutzt.