Übersicht
Base-URL: https://osm.meyer-edv.cloud
Format: JSON (UTF-8) bzw. PNG für Tiles. CORS für alle Origins offen.
Authentifizierung
API-Token sind optional, aber für Abrechnung & Statistik erforderlich. Tokens werden im Admin verwaltet.
Header (empfohlen)
X-API-Token: osm_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Query-Parameter
?token=osm_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Bei ungültigem Token: 401 Unauthorized. Fehler-Antworten (4xx/5xx) werden nicht abgerechnet.
GETKarten-Tiles
/api/tile/{z}/{x}/{y}.png
Slippy-Map-Tiles im Web-Mercator-Schema (256×256, PNG).
| Param | Wert |
|---|---|
z | Zoomstufe 0–20 |
x / y | Tile-Koordinaten |
curl "https://osm.meyer-edv.cloud/api/tile/6/33/21.png" -o tile.pngL.tileLayer('https://osm.meyer-edv.cloud/api/tile/{z}/{x}/{y}.png', { maxZoom: 20, attribution: '© OpenStreetMap contributors' }).addTo(map);
GETForward Geocoding (Adresse → Koordinaten)
/api/geocode?q={query}&limit=5&lang=de
| Param | Default | Beschreibung |
|---|---|---|
q | — | Suchbegriff (Pflicht) |
limit | 5 | Max. Treffer (1–50) |
lang | en | Sprache: de, en, fr, it |
curl "https://osm.meyer-edv.cloud/api/geocode?q=Brandenburger+Tor&lang=de"const r = await fetch( `https://osm.meyer-edv.cloud/api/geocode?q=${encodeURIComponent('Brandenburger Tor')}&lang=de`, { headers: { 'X-API-Token': 'osm_…' } }); const { results } = await r.json();
import requests r = requests.get('https://osm.meyer-edv.cloud/api/geocode', params={'q': 'Brandenburger Tor', 'lang': 'de'}, headers={'X-API-Token': 'osm_…'}) print(r.json()['results'][0])
Antwort
{
"results": [
{
"lat": 52.5163, "lon": 13.3777,
"display_name": "Brandenburger Tor, Pariser Platz, …",
"type": "attraction",
"osm_type": "W", "osm_id": 12345,
"properties": { /* alle Photon-Felder */ }
}
]
}
GETReverse Geocoding (Koordinaten → Adresse)
/api/reverse?lat={lat}&lon={lon}&lang=de
| Param | Default | Beschreibung |
|---|---|---|
lat | — | Breitengrad (Pflicht) |
lon | — | Längengrad (Pflicht) |
lang | en | Sprache |
curl "https://osm.meyer-edv.cloud/api/reverse?lat=52.52&lon=13.41&lang=de"
Antwort
{
"lat": 52.52, "lon": 13.41,
"address": "Alexanderplatz",
"street": "…", "housenumber": "…",
"postcode": "10178", "city": "Berlin",
"country": "Deutschland",
"display_name": "…"
}
POSTRouting (Navigation)
/api/route
Berechnet Route inkl. Distanz, Dauer, Geometrie und Abbiege-Anweisungen.
Request-Body (JSON)
| Feld | Default | Beschreibung |
|---|---|---|
from | — | [lat, lon] |
to | — | [lat, lon] |
vehicle | {"profile":"car_m1"} | Fahrzeugprofil + Parameter (siehe unten) |
mode | — | Legacy: car · pedestrian · bicycle (weiter unterstützt) |
Fahrzeugprofile (GET /api/vehicles liefert die vollständige Liste)
19 rechtlich unterscheidbare Profile — u. a. car_m1, car_with_trailer, van_n1,
truck_3_5_7_5, truck_7_5_12, truck_n3, bus_m2_m3, motorcycle,
moped_l1e_b, epac_25, speed_pedelec, bicycle, cargo_bicycle,
e_kickscooter, light_quadricycle, heavy_quadricycle, mobility_device,
agricultural_vehicle, pedestrian.
Fahrzeugparameter (Lkw/Bus/Gespann; werden gegen OSM-Restriktionen geprüft)
| Feld | Beschreibung |
|---|---|
height_m / width_m / length_m | Maße (bei Gespann: Gesamtwerte) |
weight_t / axle_load_t / axle_count | tatsächliches Gewicht, Achslast, Achszahl |
hazmat | true = Gefahrgut (Tunnelverbote) |
has_trailer + trailer_mass_t | Anhänger (Masse wird aufaddiert) |
type_approved | nur NL-E-Step: Modell ist national typgenehmigt |
curl -X POST https://osm.meyer-edv.cloud/api/route -H "Content-Type: application/json" -d '{ "from":[52.52,13.40], "to":[48.14,11.58], "vehicle":{"profile":"truck_7_5_12","height_m":3.8,"weight_t":11.2,"hazmat":false} }'
Rechtsprüfung
Jede Route enthält einen legal-Block: Profil, betroffene Länder (Start/Ziel, grenznah approximativ),
status (PRIMARY_SOURCE_VERIFIED · GOOD_NATIONAL_SOURCE · COMMISSION_COMPARISON ·
LEGAL_STATUS_UNKNOWN), die angewandten Regeln mit Quelle (z. B. eKFV §10) sowie Warnungen.
Für rechtlich kritische Klassen (E-Tretroller, S-Pedelec, Mobility Device, L7e) in nicht verifizierten Ländern antwortet der
Server 422 — LEGAL_STATUS_UNKNOWN wird nie als Erlaubnis behandelt
(Beispiele: GB private E-Scooter → 422; NL ohne type_approved → 422).
curl -X POST https://osm.meyer-edv.cloud/api/route \ -H "Content-Type: application/json" \ -H "X-API-Token: osm_…" \ -d '{"from":[52.52,13.40],"to":[48.14,11.58],"mode":"car"}'
const r = await fetch('https://osm.meyer-edv.cloud/api/route', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-API-Token': 'osm_…' }, body: JSON.stringify({ from: [52.52, 13.40], to: [48.14, 11.58], mode: 'car' }) }); const route = await r.json(); // L.polyline(route.geometry).addTo(map);
import requests r = requests.post('https://osm.meyer-edv.cloud/api/route', json={'from':[52.52,13.40], 'to':[48.14,11.58], 'mode':'car'}, headers={'X-API-Token': 'osm_…'})
Antwort
{
"distance": 584.2, // km
"duration": 19440, // Sekunden
"distance_unit": "km",
"duration_unit": "seconds",
"geometry": [[52.52,13.40], /* … [lat,lon] Polyline */],
"instructions": [
{ "instruction": "Fahren Sie nach Süden …",
"distance": 0.5, "time": 30,
"street_names": ["Alexanderstraße"] }
]
}
GETOffline-Karten (MBTiles)
Lädt eine Region als .mbtiles-Datei (SQLite) – direkt nutzbar in MapLibre, Leaflet.Offline, Mapbox/MapLibre Mobile SDKs, OsmAnd u.v.m.
1. Größe abschätzen (vor dem Download)
/api/offline/estimate?bbox={minlon,minlat,maxlon,maxlat}&minzoom={z}&maxzoom={z}
curl "https://osm.meyer-edv.cloud/api/offline/estimate?bbox=13.0,52.3,13.8,52.7&minzoom=10&maxzoom=14" → { "tiles": 1639, "est_mb": 20, "max_tiles": 200000, "exceeds_limit": false }
2. Herunterladen
/api/offline?bbox={minlon,minlat,maxlon,maxlat}&minzoom={z}&maxzoom={z}&name={name}
| Param | Default | Beschreibung |
|---|---|---|
bbox | — | minlon,minlat,maxlon,maxlat (Pflicht) |
minzoom | 0 | kleinste Zoomstufe |
maxzoom | 12 | größte Zoomstufe |
name | osm-offline | Dateiname/Layer-Name |
curl "https://osm.meyer-edv.cloud/api/offline?bbox=13.3,52.4,13.6,52.6&minzoom=10&maxzoom=15&name=berlin" \
-o berlin.mbtiles
Response-Header X-Tiles-Stored / X-Tiles-Requested zeigen, wie viele Kacheln enthalten sind.
App-Einbindung (MapLibre GL, Beispiel)
{
"sources": {
"offline": { "type":"raster", "url":"mbtiles://berlin.mbtiles", "tileSize":256 }
},
"layers": [{ "id":"offline", "type":"raster", "source":"offline" }]
}
POSTWLAN-Ortung
Positionsschätzung aus sichtbaren WLAN-Netzen – überbrückt die ~30 s bis der GPS-Fix steht. Eigene Datenbank, keine fremden Dienste.
Beobachtungen melden
/api/wifi/submit
curl -X POST https://osm.meyer-edv.cloud/api/wifi/submit \ -H "Content-Type: application/json" \ -d '{"items":[{"lat":52.5054,"lon":9.4636,"acc":8,"zeit":1786000000000, "aps":[{"mac":"74:83:c2:74:00:ec","rssi":-45}]}]}' → 200 {"stored":2}
Bündel bis 200 Einträge. Position wird je AP als gleitender Mittelwert fortgeschrieben (nie überschrieben). Nur 200 = angekommen – bei jedem anderen Code behält die App ihre Punkte und sendet später erneut.
Ort schätzen
/api/wifi/locate
curl -X POST https://osm.meyer-edv.cloud/api/wifi/locate \ -H "Content-Type: application/json" \ -d '{"aps":[{"mac":"74:83:c2:74:00:ec","rssi":-45}, {"mac":"44:4e:6d:16:30:09","rssi":-48}]}' → 200 {"lat":52.5059,"lon":9.4635,"accuracy":45,"basis":7} → 404 wenn kein Netz bekannt (Normalfall am Start; App wartet auf GPS)
| Feld | Bedeutung |
|---|---|
accuracy | Streuung um den Schwerpunkt in m (min. 50) |
basis | Anzahl der bekannten Netze, die in die Schätzung eingingen |
Signal-gewichteter Schwerpunkt (Gewicht = 10^(rssi/20)); Ausreißer >3 km vom Median entfernt, Netze älter als 1 Jahr ignoriert. Antwortzeit typ. <20 ms.
GETOSM-Rohdaten & Höhen (Streckenimport)
Overpass (OSM-Rohdaten)
/api/overpass?data=<Overpass-QL>
Vollständige Overpass-QL-Abfragen (Seeufer, Wälder, Häuser, Haltestellen …). GET und POST. Timeout 300 s.
curl -G --data-urlencode 'data=[out:json];way(23569785);out geom;' \ https://osm.meyer-edv.cloud/api/overpass
Elevation (Höhendaten, Copernicus GLO-30, 30 m)
/api/elevation?locations=lat,lon|lat,lon|…
Bis 500 Punkte je Anfrage (opentopodata-Format), Abdeckung: ganz Deutschland.
curl 'https://osm.meyer-edv.cloud/api/elevation?locations=53.95,12.245|52.505,9.464' → {"results":[{"elevation":31.5,…},{"elevation":35.9,…}],"status":"OK"}
GETLive-Verkehrslage (Autobahnen)
/api/traffic?bbox=…&type=…&format=geojson
Staus, Sperrungen und Baustellen aller deutschen Autobahnen. Quelle: offene API der
Autobahn GmbH des Bundes; serverseitig alle 5 Minuten aktualisiert und aus dem Cache
ausgeliefert (Antwortfeld age_seconds, bei Ausfall stale: true).
| Param | Beschreibung |
|---|---|
bbox | minlon,minlat,maxlon,maxlat (optional) |
type | warning (Stau) · closure (Sperrung) · roadworks (Baustelle), kommagetrennt |
road | z. B. A2 |
blocked=true | nur Vollsperrungen |
future=true | auch angekündigte (Standard: nur aktive) |
format=geojson | FeatureCollection statt Item-Liste |
limit | Standard 5000, max. 20000 |
curl 'https://osm.meyer-edv.cloud/api/traffic?bbox=9.0,52.0,10.2,52.8&type=warning' → {"updated_at":…,"count":1,"items":[{"road":"A2","type":"warning","title":"A2", "subtitle":"Braunschweig -> Dortmund","delay_min":6,"avg_speed":30, "lat":52.42,"lon":9.83,"geometry":[[lat,lon],…],…}]}
Items enthalten geometry als [lat,lon]-Polylinie (direkt in Leaflet
zeichenbar), delay_min, avg_speed, blocked und die
amtliche Beschreibung. In der Web-Karte per Haken „Verkehrslage" zuschaltbar.
GETHealth-Check
/api/health
curl https://osm.meyer-edv.cloud/api/health
{"status":"ok","services":{ … }}
Komplettes Beispiel: Karte + Suche + Route in HTML
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"> <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script> <div id="map" style="height:500px"></div> <script> const API = 'https://osm.meyer-edv.cloud'; const TOKEN = 'osm_…'; const H = { 'X-API-Token': TOKEN }; const map = L.map('map').setView([51.16, 10.45], 6); L.tileLayer(`${API}/api/tile/{z}/{x}/{y}.png?token=${TOKEN}`, {maxZoom:20}).addTo(map); async function route(a, b) { const r = await fetch(`${API}/api/route`, { method:'POST', headers:{...H, 'Content-Type':'application/json'}, body: JSON.stringify({from:a, to:b, mode:'car'}) }); const d = await r.json(); L.polyline(d.geometry, {color:'#06f', weight:5}).addTo(map); } </script>