Verarbeitung und Überwachung
Nachdem Eingabedateien hochgeladen wurden, kann die Plattform verarbeitete Ausgaben generieren (standardisierte Punktwolken, Mesh-HLODs, Photosphären und so weiter). Dieser Leitfaden erklärt, wie Sie Verarbeitungsoptionen auflisten, die Verarbeitung starten und den Fortschritt abfragen, bis jede Ausgabe einen Endzustand erreicht.
Es wird vorausgesetzt, dass Sie ein Bundle mit mindestens einer abgeschlossenen Upload-Session haben und über die Scopes read:bundle und write:bundle verfügen.
Funktionsweise
Abschnitt betitelt „Funktionsweise“Die Verarbeitung ist Fire-and-Forget: Die API reiht einen Verarbeitungsjob ein und antwortet sofort.
sequenceDiagram
participant Client as Client
participant RCAPI as RCAPI
Client->>RCAPI: GET processing/options
RCAPI-->>Client: options + metadata
Client->>RCAPI: POST processing
RCAPI-->>Client: accepted or typed error
loop until all terminal
Client->>RCAPI: GET bundle/processings
RCAPI-->>Client: processing records (status, progress)
end
Endpunkte
Abschnitt betitelt „Endpunkte“| Method | Path | Scope | Purpose |
|---|---|---|---|
GET | /v1/bundles/{bundleId}/processing/options | read:bundle | Mögliche Ausgabetypen und deren Metadaten auflisten |
POST | /v1/bundles/{bundleId}/processing | write:bundle | Verarbeitung für angeforderte Ausgaben starten |
GET | /v1/bundles/{bundleId}/processings | read:bundle | Verarbeitungsdatensätze des Bundles zum Abfragen des Fortschritts auflisten |
GET | /v1/site/{siteId}/bundles/{bundleId} | read:hierarchy | Bundle mit seinen verarbeiteten Ausgabe-Komponenten abrufen (signierte Links) |
Schritt 1: Verarbeitungsoptionen auflisten
Abschnitt betitelt „Schritt 1: Verarbeitungsoptionen auflisten“Bevor Sie starten, ermitteln Sie, welche Ausgaben das Bundle erzeugen kann und was jede kostet.
GET {api_url}/v1/bundles/{bundleId}/processing/options?page=1&limit=20&sortBy=type&sortDir=ASCAuthorization: Bearer {access_token}Query-Parameter
Abschnitt betitelt „Query-Parameter“| Parameter | Type | Description |
|---|---|---|
page | number | 1-basierter Seitenindex (Standard 1) |
limit | number | Seitengröße (Standard 20, Maximum 20) |
sortBy | string | type oder cost (Standard type) |
sortDir | string | ASC oder DESC (Standard ASC) |
Die Antwort ist eine paginierte Liste ({ items, total }). Jede Option beschreibt einen Ausgabetyp:
| Field | Meaning |
|---|---|
type | Ausgabe-Komponententyp beim Start der Verarbeitung (z. B. StandardizedPointCloud, OgcPointCloudHlod) |
hasProcessing | true, wenn für diese Ausgabe bereits eine Verarbeitung gestartet wurde |
cost | Verarbeitungskosten in Bytes für kostenpflichtige Ausgaben; 0 für Free-Tier-Ausgaben |
Beispiel:
{ "items": [ { "type": "StandardizedPointCloud", "hasProcessing": false, "cost": 734003200 }, { "type": "OgcPointCloudHlod", "hasProcessing": false, "cost": 734003200 } ], "total": 2}Überspringen Sie Ausgaben, bei denen hasProcessing true ist, es sei denn, Sie beabsichtigen eine erneute Verarbeitung.
Schritt 2: Verarbeitung starten
Abschnitt betitelt „Schritt 2: Verarbeitung starten“Übergeben Sie die Liste der Ausgabe-Komponententypen, die die Pipeline erzeugen soll, plus ein cost-Feld, das die gesamten Verarbeitungskosten bestätigt. Der Server summiert die cost-Werte aus Schritt 1 für jeden Typ in requestedComponents und lehnt die Anfrage ab, wenn Ihre Bestätigung nicht übereinstimmt.
Die Verarbeitung startet asynchron, sobald die Kosten akzeptiert wurden.
POST {api_url}/v1/bundles/{bundleId}/processingAuthorization: Bearer {access_token}Content-Type: application/json
{ "requestedComponents": [ "StandardizedPointCloud", "OgcPointCloudHlod" ], "cost": 1468006400}Im obigen Beispiel ist cost 734003200 + 734003200 aus der Optionsliste in Schritt 1.
Erfolgsantwort
Abschnitt betitelt „Erfolgsantwort“204 No Content: Die Verarbeitung wurde akzeptiert und eingereiht.
Fehlerantwort
Abschnitt betitelt „Fehlerantwort“Wenn die Verarbeitung nicht gestartet werden kann, liefert die API 409 Conflict mit einem typisierten error:
error value | Meaning |
|---|---|
ProcessingCostMismatch | Der übermittelte cost stimmt nicht mit der berechneten Summe für die angeforderten Ausgaben überein |
InsufficientProcessingCapacity | Das Verarbeitungslimit der Organisation würde überschritten |
NoInputDataFoundForProcessing | Keine finalisierten Eingabedateien auf dem Bundle verfügbar |
FailedToLaunchProcessing | Pipeline-Einreichung aus unerwartetem Grund fehlgeschlagen |
Beispiel:
{ "error": "ProcessingCostMismatch"}Die strukturelle Validierung des hochgeladenen Stapels (Pflichttypen, Erweiterungen, Abhängigkeiten) wird nach dem Start durch die Verarbeitungs-Pipeline durchgesetzt. Wenn Ihre Upload-Session abgeschlossen wurde, aber den requirements-Vertrag verletzt hat, kann die Verarbeitung später fehlschlagen, obwohl jede Datei erfolgreich hochgeladen wurde und der Startaufruf 204 zurückgab.
Schritt 3: Fortschritt abfragen
Abschnitt betitelt „Schritt 3: Fortschritt abfragen“Nach einem erfolgreichen Start fragen Sie die Verarbeitungsdatensätze des Bundles ab, bis jeder einen Endzustand erreicht.
GET {api_url}/v1/bundles/{bundleId}/processingsAuthorization: Bearer {access_token}Die Antwort ist eine Liste ({ items, total }) mit jedem Verarbeitungsdatensatz des Bundles. Es gibt keine Query-Parameter; alle Datensätze werden in einem einzigen Aufruf zurückgegeben.
Jedes Element verfolgt einen Verarbeitungsjob:
| Field | Meaning |
|---|---|
id | Kennung des Verarbeitungsdatensatzes |
status | Pipeline-Status (siehe Tabelle unten) |
progress | Fertigstellungsprozent (0-100) während aktiv |
createdAt | Wann der Job erstellt wurde |
updatedAt | Wann der Job zuletzt den Zustand geändert hat |
launchedById | ID des Benutzers, der den Job gestartet hat, oder null |
knownErrors | Strukturierte Fehler, jeweils mit errorCode und betroffenen errorFilepaths (null, wenn nicht dateispezifisch) |
Verarbeitungszustände
Abschnitt betitelt „Verarbeitungszustände“| Status | Terminal? | Meaning |
|---|---|---|
Pending | no | In Warteschlange, noch nicht gestartet |
Processing | no | Pipeline läuft |
Restarted | no | Job wurde neu gestartet und läuft wieder |
Ready | yes | Ausgabe erfolgreich erzeugt |
Failed | yes | Unstrukturierter Pipeline-Fehler |
FailedToLaunch | yes | Job ist nie in die Pipeline eingetreten |
KnownError | yes | Strukturierter Validierungs- oder Formatfehler |
Fragen Sie ab, bis jeder Datensatz in einem Endzustand ist (Ready, Failed, FailedToLaunch oder KnownError).
Beispiel während der Ausführung:
{ "items": [ { "id": "3f2b1c4d-8e7a-4b2c-9d1e-0a1b3c4d4e6f", "status": "Processing", "progress": 42, "createdAt": "2026-06-01T14:05:00Z", "updatedAt": "2026-06-01T14:12:00Z", "launchedById": "b1a2c3d4-5e6f-7a8b-9c0d-1e2f3a2b2c1d", "knownErrors": [] }, { "id": "9c0d1e2f-3a4b-5c6d-7e8f-9a0b2c3d3e4f", "status": "Pending", "progress": 0, "createdAt": "2026-06-01T14:05:00Z", "updatedAt": "2026-06-01T14:05:00Z", "launchedById": "b1a2c3d4-5e6f-7a8b-9c0d-1e2f3a3b1c1d", "knownErrors": [] } ], "total": 2}Beispiel mit bekanntem Fehler:
{ "items": [ { "id": "3f2b1c4d-8e7a-4b2c-9d1e-0a1b3c4d4e5f", "status": "KnownError", "progress": 100, "createdAt": "2026-06-01T14:05:00Z", "updatedAt": "2026-06-01T14:48:00Z", "launchedById": "b1a2c3d4-5e6f-7a8b-1c0d-2e6f3a4b5c6d", "knownErrors": [ { "errorCode": "MissingTrajectory", "errorFilepaths": ["scan.las"] } ] } ], "total": 1}Die Verarbeitungsliste enthält nicht den Ausgabe-type pro Datensatz. Um fertige Ausgaben wieder ihren Komponententypen und signierten Links zuzuordnen, rufen Sie die Komponenten des Bundles ab (siehe Verarbeitete Ausgaben abrufen).
Hinweise zum Abfragen
Abschnitt betitelt „Hinweise zum Abfragen“- Intervall: 1-5 Minuten ist ein vernünftiger Standard. Die Verarbeitung kann je nach Eingabegröße mehrere Minuten bis mehrere Stunden dauern.
- Rate Limits: Die Bundle-Endpunkte teilen sich einen Rate-Limit-Bucket mit mehreren anderen Endpunkten. Vermeiden Sie Abfragen im Sub-Minuten-Takt.
Verarbeitete Ausgaben abrufen
Abschnitt betitelt „Verarbeitete Ausgaben abrufen“Sobald ein Verarbeitungsdatensatz Ready erreicht, rufen Sie das Bundle ab, um seine Ausgabe-Komponenten und deren signierte Download-Links zu erhalten. Bundle-Details liegen auf dem Hierarchie-Endpunkt:
GET {api_url}/v1/site/{siteId}/bundles/{bundleId}Authorization: Bearer {access_token}Dieser Endpunkt erfordert den Scope read:hierarchy und liefert das Bundle mit seinem components-Array:
| Field | Meaning |
|---|---|
id | Bundle-ID |
name | Bundle-Name |
components | Ein Eintrag pro verfügbarer Komponente (Eingaben und verarbeitete Ausgaben) |
Jede Komponente enthält:
| Field | Meaning |
|---|---|
id | Komponenten-ID |
type | Komponententyp, z. B. StandardizedPointCloud, OgcPointCloudHlod |
version | Komponentenversion |
signedLink | Signierte URL zum Herunterladen der Komponente; kein Auth-Header erforderlich |
roots | Einstiegspfade innerhalb der Komponente, falls zutreffend |
Beispiel:
{ "id": "a6f75b3c-f261-4b27-9a2a-9a6cc4178a13", "name": "ZF capture 2026-06-01", "components": [ { "id": "5d6e7f8a-9b0c-1d2e-3f4a-1b3c7d4e8f0a", "type": "StandardizedPointCloud", "version": "1", "signedLink": "https://cdn…/components/…?X-Amz-…" } ]}Ein RealityPlan-Projekt stellt dasselbe Bundle über GET /v1/reality-plan/{projectId}/bundles/{bundleId} bereit (Scope read:twin).
Vollständiges Beispiel
Abschnitt betitelt „Vollständiges Beispiel“import timeimport requests
API_URL = "https://<your-regional-api-url>"TOKEN = "<access_token>"BUNDLE_ID = "<bundleId>"
headers = {"Authorization": f"Bearer {TOKEN}"}base = f"{API_URL}/v1/bundles/{BUNDLE_ID}"
# 1. Discover outputs.options = requests.get( f"{base}/processing/options", headers=headers, params={"page": 1, "limit": 20},).json()
options_by_type = {item["type"]: item for item in options["items"]}to_process = [ item["type"] for item in options["items"] if not item["hasProcessing"]]total_cost = sum(options_by_type[t]["cost"] for t in to_process)print(f"Launching: {to_process} (cost: {total_cost})")
# 2. Start processing.response = requests.post( f"{base}/processing", headers=headers, json={"requestedComponents": to_process, "cost": total_cost},)
if response.status_code == 409: raise RuntimeError( f"Processing failed to start: {response.json().get('error')}" )response.raise_for_status() # expect 204
# 3. Poll until every job is terminal.TERMINAL = {"Ready", "Failed", "FailedToLaunch", "KnownError"}POLL_SECONDS = 15TIMEOUT_SECONDS = 3600deadline = time.time() + TIMEOUT_SECONDS
while time.time() < deadline: listing = requests.get( f"{base}/processings", headers=headers, ).json()
processings = listing.get("items", []) for p in processings: print(f" {p['id']}: {p['status']} ({p['progress']}%)")
if processings and all(p["status"] in TERMINAL for p in processings): break
time.sleep(POLL_SECONDS)else: raise TimeoutError("Processing did not finish within the timeout")Nächster Schritt
Abschnitt betitelt „Nächster Schritt“Um die hochgeladenen Roh-Eingabedateien abzurufen (für Archivierung, erneute Verarbeitung oder Audit), siehe Download von Eingabedateien.