コンテンツにスキップ

処理とモニタリング

入力ファイルがアップロードされると、プラットフォームは処理済み出力(標準化点群、メッシュHLOD、フォトスフィアなど)を生成できます。このガイドでは、処理オプションの一覧表示、処理の開始、すべての出力が終端状態に達するまでの進捗ポーリングを説明します。

少なくとも1つの完了したアップロードセッションを持つBundleと、read:bundleおよびwrite:bundleスコープを保持していることを前提としています。


処理はfire-and-forgetです。APIは処理ジョブをキューに入れ、すぐに返します。

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
メソッドパススコープ用途
GET/v1/bundles/{bundleId}/processing/optionsread:bundle可能な出力タイプとメタデータの一覧
POST/v1/bundles/{bundleId}/processingwrite:bundle要求された出力の処理開始
GET/v1/bundles/{bundleId}/processingsread:bundle進捗ポーリング用のBundle処理レコードの一覧
GET/v1/site/{siteId}/bundles/{bundleId}read:hierarchy処理済み出力コンポーネント(署名付きリンク)付きBundleの取得

ステップ1:処理オプションの一覧

Section titled “ステップ1:処理オプションの一覧”

開始前に、Bundleが生成できる出力と、それぞれのコストを確認します。

GET {api_url}/v1/bundles/{bundleId}/processing/options?page=1&limit=20&sortBy=type&sortDir=ASC
Authorization: Bearer {access_token}
パラメータ説明
pagenumber1始まりのページインデックス(デフォルト1
limitnumberページサイズ(デフォルト20、最大20
sortBystringtypeまたはcost(デフォルトtype
sortDirstringASCまたはDESC(デフォルトASC

レスポンスはページネーションされたリスト({ items, total })です。各オプションは1つの出力タイプを記述します:

フィールド意味
type処理開始時に渡す出力コンポーネントタイプ(例:StandardizedPointCloudOgcPointCloudHlod
hasProcessingこの出力の処理がすでに開始されている場合はtrue
cost有料出力の処理コスト(バイト単位)。無料ティア出力は0

例:

{
"items": [
{
"type": "StandardizedPointCloud",
"hasProcessing": false,
"cost": 734003200
},
{
"type": "OgcPointCloudHlod",
"hasProcessing": false,
"cost": 734003200
}
],
"total": 2
}

hasProcessingtrueの出力は、再処理する意図がない限りスキップしてください。

パイプラインに生成させたい出力コンポーネントタイプのリストと、合計処理料金を承認するcostフィールドを渡します。サーバーはrequestedComponents内のすべてのタイプについてステップ1のcost値を合計し、承認が一致しない場合はリクエストを拒否します。

コストが受け入れられると、処理は非同期で開始されます。

POST {api_url}/v1/bundles/{bundleId}/processing
Authorization: Bearer {access_token}
Content-Type: application/json
{
"requestedComponents": [
"StandardizedPointCloud",
"OgcPointCloudHlod"
],
"cost": 1468006400
}

上記の例では、costはステップ1のオプションリストからの734003200 + 734003200です。

204 No Content:処理が受け入れられ、キューに入れられました。

処理を開始できない場合、APIは型付きerrorとともに409 Conflictを返します:

error意味
ProcessingCostMismatch送信されたcostが要求された出力の計算合計と一致しない
InsufficientProcessingCapacity組織の処理上限を超える
NoInputDataFoundForProcessingBundleに確定済み入力ファイルがない
FailedToLaunchProcessing予期しない理由でパイプライン送信に失敗

例:

{
"error": "ProcessingCostMismatch"
}

アップロードされたバッチの構造検証(必須タイプ、拡張子、依存関係)は、開始後に処理パイプラインによって適用されます。アップロードセッションが完了したがrequirements契約に違反していた場合、すべてのファイルが正常にアップロードされ開始呼び出しが204を返しても、処理は後で失敗する可能性があります。

成功した開始後、Bundleの処理レコードをポーリングし、すべてが終端状態に達するまで待ちます。

GET {api_url}/v1/bundles/{bundleId}/processings
Authorization: Bearer {access_token}

レスポンスは、Bundleのすべての処理レコードを含むリスト({ items, total })です。クエリパラメータはありません。すべてのレコードが1回の呼び出しで返されます。

各アイテムは1つの処理ジョブを追跡します:

フィールド意味
id処理レコードの識別子
statusパイプラインステータス(下表参照)
progressアクティブ中の完了率(0100
createdAtジョブが作成された日時
updatedAtジョブが最後に状態変更した日時
launchedByIdジョブを開始したユーザーのid、またはnull
knownErrors構造化された失敗。各エントリにerrorCodeと影響を受けるerrorFilepaths(ファイル固有でない場合はnull
ステータス終端?意味
Pendingいいえキューに入れられたが、まだ開始されていない
Processingいいえパイプラインが実行中
Restartedいいえジョブが再起動され、再び実行中
Readyはい出力が正常に生成された
Failedはい非構造化パイプライン失敗
FailedToLaunchはいジョブがパイプラインに入らなかった
KnownErrorはい構造化検証またはフォーマットエラー

すべてのレコードが終端状態(ReadyFailedFailedToLaunch、またはKnownError)になるまでポーリングしてください。

実行中のレスポンス例:

{
"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
}

既知エラーの例:

{
"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
}

処理リストにはレコードごとの出力typeは含まれません。完了した出力をコンポーネントタイプと署名付きリンクにマッピングするには、Bundleのコンポーネントを取得します(処理済み出力の取得を参照)。

  • 間隔: 1〜5分が合理的なデフォルトです。入力サイズによって処理は数分から数時間かかる場合があります。
  • レート制限: Bundleエンドポイントは、他の複数のエンドポイントとレート制限バケットを共有します。1分未満のポーリングは避けてください。

処理レコードがReadyに達したら、Bundleを取得して出力コンポーネントと署名付きダウンロードリンクを取得します。Bundleの詳細は階層エンドポイントにあります:

GET {api_url}/v1/site/{siteId}/bundles/{bundleId}
Authorization: Bearer {access_token}

このエンドポイントにはread:hierarchyスコープが必要で、components配列付きのBundleを返します:

フィールド意味
idBundle id
nameBundle名
components利用可能なコンポーネント(入力と処理済み出力)ごとに1エントリ

各コンポーネントには以下が含まれます:

フィールド意味
idコンポーネント id
typeコンポーネントタイプ(例:StandardizedPointCloudOgcPointCloudHlod
versionコンポーネントバージョン
signedLinkコンポーネントをダウンロードする署名付きURL。認証ヘッダー不要
roots該当する場合、コンポーネント内のエントリポイントパス

例:

{
"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-…"
}
]
}

RealityPlanプロジェクトは、GET /v1/reality-plan/{projectId}/bundles/{bundleId}(スコープread:twin)を通じて同じBundleを公開します。

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")

アップロードされた生入力ファイルを取得する場合(アーカイブ、再処理、監査用)は、入力ファイルのダウンロードを参照してください。