Point-to-Source Images

Check index readiness and find the original photos that visibly observe a clicked model point.

Point-to-source-image lookup connects a georeferenced 3D model point to the original input photos that can see it. The browser sends one WGS84 coordinate; it does not upload model vertices, triangles, or image metadata for each lookup. PixService queries compact camera records and immutable geometry sidecars that were prepared asynchronously by BackgroundJobs.

Availability

Check the model capability before enabling a point picker:

GET /v1/spatial/bundles/{modelBundleId}/point-source-images/capability
Authorization: Bearer <token>

Use available as the decision. A ready response also identifies the exact sourceBundleId, advertises coordinateFrame: "wgs84", and reports the index version, indexed image count, usable camera count, and result quality. Do not infer readiness from the presence of input photos alone.

Indexing is optional and low priority. Upload and pipeline success do not wait for it. A model can remain unavailable when source photos contain no useful metadata, the model has no supported georeference, the geometry encoding is not supported, or indexing is still pending. reasonCode is the stable value for client behavior; status is a compact lifecycle label.

Public-share sessions cannot use these routes because source-image identities are protected separately from the shared rendered model.

Lookup

Send the coordinate produced by the active model viewer:

POST /v1/spatial/bundles/{modelBundleId}/point-source-images/lookup
Authorization: Bearer <token>
Content-Type: application/json

{
  "coordinateFrame": "wgs84",
  "latitude": 48.595527,
  "longitude": 9.241882,
  "altitudeMetres": 346.0,
  "limit": 20
}

The point must be on or close to the indexed model surface. PixService snaps it to current indexed geometry, projects it into candidate cameras, tests the shortlist for occlusion, and returns visible photos in server rank order. Each match includes its source artifact and bundle identity, display fields, score, camera distance, projected pixel position, and visibility quality. Use the existing bundle-file thumbnail and content routes to display the returned artifacts.

An empty matches array is a successful lookup with no visible source photo. An HTTP 422 response means the request could not be evaluated safely; inspect the problem response's reasonCode, such as point_off_surface, lookup_limit_exceeded, or lookup_timed_out. Never fall back to sending the whole model from the browser.

Source metadata progress

The source bundle exposes its independent metadata-index state:

GET /v1/spatial/bundles/{sourceBundleId}/metadata-index
Authorization: Bearer <token>

The response provides lifecycle and progress counts plus the sourceImageMetadata capability. Missing EXIF/XMP is a supported terminal outcome, not an upload failure. A metadata-free bundle is represented by one compact skippedNoMetadata result rather than thousands of per-file missing records.

Clients should keep the ordinary All original photos experience available while hiding or disabling point mode whenever the point capability is not available.

Model overview previews

Outputs created from the same input bundle can share one overview image. Bundle metadata exposes representativeImageArtifactId on that input bundle when a representative photo has been selected. Follow the model's previousBundleId lineage to the input Upload bundle rather than grouping by display name.

GET /v1/spatial/bundles/{inputBundleId}/preview?size=tiny
Authorization: Bearer <token>

The response contains a presigned url, expiresAt and fileName. Request tiny (128px) for the initial view and optionally upgrade visible cards to small (256px). medium (1024px) is also supported. No original image is returned.

For a model list, combine visible cache misses into one lookup instead of a GET per card. Send 1–32 distinct, nonempty input bundle IDs:

POST /v1/spatial/bundles/previews/resolve
Authorization: Bearer <token>
Content-Type: application/json

{"bundleIds":["11111111-1111-1111-1111-111111111111"],"size":"tiny"}

The response contains an items entry per requested bundleId. ready includes a presigned link (url, expiresAt, fileName) and resolvedSize. pending has no link and includes retryAfterSeconds; retry only while the card remains visible. unavailable covers missing, unauthorized, or absent representative images without revealing which case applies. Authorization uses LocationBundles for each location, including when IDs from different locations are combined.

Batch reads never generate images or substitute the original or a larger size. Load tiny previews first, then request small thumbnails only for cards still visible. Cancel lookups when cards leave the viewport and cache expiring links by input bundle and size. Malformed IDs/counts or sizes return HTTP 400.

The first supported model index chooses a source photo using camera pose and estimated coverage of the model. The choice is saved once per input dataset and reused by later outputs. It is a framing estimate; an input photo cannot always show the entire model or avoid all obstructions. Missing metadata or unsupported geometry leaves the preview unavailable. Suitable existing completed indexes are automatically backfilled in small background batches after deployment, using their stored geometry and camera poses without regenerating models. Existing preview choices are preserved. Models without linked input photos cannot receive a photo-based preview.

This endpoint requires current LocationBundles=Read for the input bundle. An unavailable or not-yet-generated preview returns HTTP 204; keep a model icon in that case. Preview reads never trigger generation and public model-share sessions do not grant access to input previews.

Custom model thumbnails

A model group can use an uploaded JPEG, PNG or WebP image up to 25 MiB, including imported models that have no input photos. Use the root bundle ID displayed by the grouped model card for both requests:

  1. POST /v1/spatial/bundles/{bundleId}/thumbnail/upload with fileName, contentType, sizeBytes and optional checksumSha256.
  2. PUT the image bytes to the returned uploadUrl with its image Content-Type.
  3. POST /v1/spatial/bundles/{bundleId}/thumbnail/complete with the issued bucket and objectKey, plus originalFileName, contentType, sizeBytes and checksumSha256 (an empty string is allowed when unavailable).

Both API calls require current LocationBundles=Write. The upload reserves and commits Document storage. The image remains separate from reconstruction inputs, the document library and bundle downloads. Completion returns artifactId and optimizationStatus: processing; it does not wait for image conversion.

Refresh bundle metadata and invalidate cached preview links for the bundle after completion. Use the existing viewport batch resolver to load tiny previews before small thumbnails, retrying pending generation only while visible. The custom choice replaces representativeImageArtifactId; automatic selection/backfill preserves it. Replacing it never removes an original input photo. Old custom sources are cleaned after the new choice commits, and model deletion also includes custom sources in durable storage cleanup. Concurrent changes return a conflict; repeating a completed upload does not change a newer selection.

Manual selection of an existing linked input photo is a planned follow-up; there is no selection endpoint or picker in this release.

On this page