Marker & Symbole
Marker lesen
Abschnitt betitelt „Marker lesen“GET /api/rooms/:roomId/markers (token permission: read){ "count": 42, "markers": [ { "id": "marker-…", "latitude": 47.56, "longitude": 7.59, "title": "…" } ] }Einen Marker anlegen
Abschnitt betitelt „Einen Marker anlegen“POST /api/rooms/:roomId/markers (token permission: write)Content-Type: application/jsonSynchron — liefert den angelegten Marker zurück. Pflicht sind nur latitude/longitude.
{ "latitude": 47.5596, "longitude": 7.5886, "title": "Site A", "description": "first visit", "tags": ["survey"] }→ 201 { "success": true, "marker": { "id": "marker-…", ... } }
Optionale Felder: color (Hex), tags (≤ 50), eventDate (Epoch ms), markerIconId,
markerIconSize (8–256), imageKey/thumbnailKey (aus markers/upload-image), embeddedMediaUrl,
mediaSize (sm | md | lg).
Einen Marker lesen
Abschnitt betitelt „Einen Marker lesen“GET /api/rooms/:roomId/markers/:markerId (token permission: read)→ 200 { "success": true, "marker": { … } }, oder 404, wenn er nicht existiert. Anonyme Aufrufer
können einen Marker in einem öffentlichen Raum lesen, genau wie beim Listen-Endpunkt.
Diese Sicht lässt die E-Mail-Adresse der erstellenden Person und die alten Inline-Bild-Blobs weg —
holen Sie Bilder stattdessen über GET /api/rooms/:roomId/markers/image?key=….
Einen Marker aktualisieren
Abschnitt betitelt „Einen Marker aktualisieren“PATCH /api/rooms/:roomId/markers/:markerId (token permission: write)Content-Type: application/jsonSenden Sie nur, was sich ändert; ausgelassene Felder bleiben unangetastet.
curl -X PATCH "$API/api/rooms/$ROOM/markers/$MARKER" -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"title":"Site A (revisited)","description":null,"color":"#ef4444"}'# → 200 { "success": true, "marker": { … } }Akzeptiert dieselben Felder wie das Anlegen. Die Regeln, die man kennen sollte:
nullleert ein Feld;""speichert eine leere Zeichenkette — das ist nicht dasselbe.latitude,longitude,titleundcolorlassen sich ändern, aber nicht leeren — ein Marker braucht alle vier, um gezeichnet zu werden.imageKeyundthumbnailKeygehören zusammen: Senden Sie beide, oder beide alsnull, um das Bild zu entfernen. Sie zu ersetzen verwirft auch die EXIF-Daten des vorherigen Fotos, damit ein neues Bild nie Kamera oder GPS-Herkunft des alten erbt.- Ein leerer Rumpf ergibt
400 empty_update, unbekannte Felder ergeben400 unknown_field:<key>—id,createdBy,createdAtund die Inline-Blob-Felder sind hier also schreibgeschützt. - Titel dürfen keine Zeilenumbrüche enthalten.
Ein Aufrufer mit write, aber ohne read, bekommt nur die von ihm gesendeten Felder zurück, nie den
gespeicherten Marker.
Einen Marker löschen
Abschnitt betitelt „Einen Marker löschen“DELETE /api/rooms/:roomId/markers/:markerId (token permission: write)→ 200 { "success": true, "markerId": "marker-…" }, oder 404, wenn er schon weg ist. Das Löschen
entfernt auch die Bilder des Markers aus dem Speicher, sofern kein anderer Marker sie noch
referenziert.
Verhalten, das man kennen sollte
Abschnitt betitelt „Verhalten, das man kennen sollte“Weitere Statuscodes: 403 unzureichende Berechtigung · 502 die Änderung konnte nicht verteilt
werden · 503 Raumzustand kurzzeitig nicht lesbar, erneut versuchen.
Jede Aktualisierung und Löschung erreicht offene Browser sofort und wird im Verlauf des Raums
festgehalten. Lesevorgänge sind letztlich konsistent — eine Leseanfrage direkt nach einem Schreibvorgang
kann kurz den vorherigen Zustand zeigen; fragen Sie also mehrfach ab, statt einer einzelnen Leseanfrage
zu vertrauen. Aufeinanderfolgende Schreibvorgänge sind unbedenklich. Gleichzeitige Änderungen an einem
Marker werden über den ganzen Marker nach „letzter Schreibvorgang gewinnt“ aufgelöst — ein PATCH kann
also eine Bearbeitung überschreiben, die jemand gerade in der App vornimmt.
Marker massenhaft importieren
Abschnitt betitelt „Marker massenhaft importieren“POST /api/rooms/:roomId/bulk-import (token permission: write)Content-Type: multipart/form-data # field: file = a point FeatureCollectionAsynchron → { "jobId": "bulk-import-…" }; fragen Sie GET /api/jobs/:jobId ab. Die properties jedes
Punkts dürfen title, description, tags, eventDate, imageKey/thumbnailKey, markerIconId und
markerIconSize tragen.
Ein Marker-Foto hochladen
Abschnitt betitelt „Ein Marker-Foto hochladen“POST /api/rooms/:roomId/markers/upload-image (token permission: write)Content-Type: multipart/form-data # fields: image, thumbnail→ { "imageKey": "markers/…jpg", "thumbnailKey": "markers/…_thumb.jpg" }. Die zurückgegebenen Schlüssel
müssen von einem Marker referenziert werden (über dessen properties/Felder), damit sie auf der Karte
erscheinen.
Marker-Symbole
Abschnitt betitelt „Marker-Symbole“GET /api/rooms/:roomId/marker-icons (token permission: read) — list (icon blob omitted)POST /api/rooms/:roomId/marker-icons (token permission: write) — register an SVG/PNG (≤1 MB)Registrieren Sie ein wiederverwendbares Symbol und referenzieren Sie die zurückgegebene iconId dann
über markerIconId aus Markern:
curl -X POST "$API/api/rooms/$ROOM/marker-icons" -H "Authorization: Bearer $TOKEN" \ -F "icon=@tree.svg" -F "name=Tree" -F "size=32"# → 201 { "iconId": "icon-api-…" }
