Zum Inhalt springen

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.


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
MethodPathScopePurpose
GET/v1/bundles/{bundleId}/processing/optionsread:bundleMögliche Ausgabetypen und deren Metadaten auflisten
POST/v1/bundles/{bundleId}/processingwrite:bundleVerarbeitung für angeforderte Ausgaben starten
GET/v1/bundles/{bundleId}/processingsread:bundleVerarbeitungsdatensätze des Bundles zum Abfragen des Fortschritts auflisten
GET/v1/site/{siteId}/bundles/{bundleId}read:hierarchyBundle mit seinen verarbeiteten Ausgabe-Komponenten abrufen (signierte Links)

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=ASC
Authorization: Bearer {access_token}
ParameterTypeDescription
pagenumber1-basierter Seitenindex (Standard 1)
limitnumberSeitengröße (Standard 20, Maximum 20)
sortBystringtype oder cost (Standard type)
sortDirstringASC oder DESC (Standard ASC)

Die Antwort ist eine paginierte Liste ({ items, total }). Jede Option beschreibt einen Ausgabetyp:

FieldMeaning
typeAusgabe-Komponententyp beim Start der Verarbeitung (z. B. StandardizedPointCloud, OgcPointCloudHlod)
hasProcessingtrue, wenn für diese Ausgabe bereits eine Verarbeitung gestartet wurde
costVerarbeitungskosten 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.

Ü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}/processing
Authorization: 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.

204 No Content: Die Verarbeitung wurde akzeptiert und eingereiht.

Wenn die Verarbeitung nicht gestartet werden kann, liefert die API 409 Conflict mit einem typisierten error:

error valueMeaning
ProcessingCostMismatchDer übermittelte cost stimmt nicht mit der berechneten Summe für die angeforderten Ausgaben überein
InsufficientProcessingCapacityDas Verarbeitungslimit der Organisation würde überschritten
NoInputDataFoundForProcessingKeine finalisierten Eingabedateien auf dem Bundle verfügbar
FailedToLaunchProcessingPipeline-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.

Nach einem erfolgreichen Start fragen Sie die Verarbeitungsdatensätze des Bundles ab, bis jeder einen Endzustand erreicht.

GET {api_url}/v1/bundles/{bundleId}/processings
Authorization: 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:

FieldMeaning
idKennung des Verarbeitungsdatensatzes
statusPipeline-Status (siehe Tabelle unten)
progressFertigstellungsprozent (0-100) während aktiv
createdAtWann der Job erstellt wurde
updatedAtWann der Job zuletzt den Zustand geändert hat
launchedByIdID des Benutzers, der den Job gestartet hat, oder null
knownErrorsStrukturierte Fehler, jeweils mit errorCode und betroffenen errorFilepaths (null, wenn nicht dateispezifisch)
StatusTerminal?Meaning
PendingnoIn Warteschlange, noch nicht gestartet
ProcessingnoPipeline läuft
RestartednoJob wurde neu gestartet und läuft wieder
ReadyyesAusgabe erfolgreich erzeugt
FailedyesUnstrukturierter Pipeline-Fehler
FailedToLaunchyesJob ist nie in die Pipeline eingetreten
KnownErroryesStrukturierter 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).

  • 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.

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:

FieldMeaning
idBundle-ID
nameBundle-Name
componentsEin Eintrag pro verfügbarer Komponente (Eingaben und verarbeitete Ausgaben)

Jede Komponente enthält:

FieldMeaning
idKomponenten-ID
typeKomponententyp, z. B. StandardizedPointCloud, OgcPointCloudHlod
versionKomponentenversion
signedLinkSignierte URL zum Herunterladen der Komponente; kein Auth-Header erforderlich
rootsEinstiegspfade 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).

import time
import 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 = 15
TIMEOUT_SECONDS = 3600
deadline = 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")

Um die hochgeladenen Roh-Eingabedateien abzurufen (für Archivierung, erneute Verarbeitung oder Audit), siehe Download von Eingabedateien.