Documentation menu

Orbit Mobile Mapping Import

The Mobile mapping generic delivery, with the pose file exactly as Orbit's generic traject export writes it. Pick this template when your panoramas come out of Orbit; the export needs no editing before upload — not the separator, not the header, not the timestamps.

Everything except the pose file is the generic template: the same folders, the same parameters, the same photo matching and tolerance, and the same optional point clouds. This page describes the pose file and points to the generic page for the rest.

Folder layout#

<dataset bucket>/
├── panorama/                  one of three accepted names — see below
│   ├── traject.csv            the Orbit export — exactly one CSV, any name
│   └── jpg/
│       ├── 20260901124146301_360.jpg
│       └── 20260901124146650_360.jpg
└── pointcloud/                optional; see Point cloud generic for details
    └── scan_001.laz

The panorama base folder is looked for under these names, in this order — the first base folder containing any object wins, and candidates below it are then dead:

  1. panorama/
  2. ingest/Panorama1/
  3. Panorama1/

Note the asymmetry that catches people out: once a base folder is chosen, an empty images folder inside it skips this half of the delivery entirely — it does not fall through to the next candidate.

The pointcloud folder is looked for under these names, in this order — the first containing at least one matching file wins:

  1. pointcloud/
  2. Pointcloud/
  3. ingest/Pointcloud/

Each half is optional on its own, but a delivery must contain at least one of them: a bucket with no panorama or pointcloud content is rejected rather than processed into nothing.

Images live in the chosen base's jpg/ subfolder. No panorama folder at all is not an error; the step finishes and only the point clouds are processed. A panorama folder with no CSV is an error.

Every delivered photo is opened and checked, not just listed:

  • Every delivered photo must start with a JPEG marker and end with an end-of-image marker. This catches a file that is not a JPEG whatever its extension says, and the truncated upload — which a size check cannot see, because a truncated file just looks smaller and nothing knows how big it should have been.

The point cloud half follows Point cloud generic exactly, with one difference: here a missing point cloud folder is skipped rather than fatal. Its files must also hold together:

  • The LAS public header of each point cloud file must parse (it is read from the first 64 KiB). A corrupt or truncated header fails the run, naming the file.
  • Point-data record formats 0 and 2 carry no GPS time, so the merged point cloud gets no temporal index and cannot be filtered by capture time. (a warning, not an error)
  • The point records must actually be there: a header can parse while the data behind it is truncated (a half-finished upload or copy). Checked for uncompressed LAS, where the declared point count and record length give an exact expected size; LAZ stores points in variable-size chunks, so the same arithmetic does not apply.

The pose CSV#

Export the trajectory from Orbit as a generic trajectory and upload the file as it comes. It is tab-separated, with the Dutch header row Orbit writes (Fotonaam, X, Y, Z, Heading, Pitch, Roll, DatumTijdFoto), Windows line endings and, optionally, a byte-order mark — all of which are fine. CSVs in subfolders are ignored. If you deliver two, only one is used — so deliver one.

SeparatorTab
PreambleNone — the header row comes first
ColumnsPositional — the header row is required but its names are ignored
Extra columnsIgnored
DecimalsBoth . and , accepted
Photo namesMatched exactly as written, then with .jpg appended, then with .jpeg appended — first hit wins; case-sensitive
Which fileThe alphabetically first .csv directly inside the folder itself
ColumnTypeMeaning
0textFotonaam — photo name without extension, resolved against the real jpg/ listing; see filename matching
1numberX — easting, in the dataset's CRS
2numberY — northing
3numberZ — height
4numberHeading — compass heading, degrees
5numberPitch, degrees
6numberRoll, degrees
7timestampDatumTijdFoto — capture time on the operator's clock, whole seconds; see timestamps

Columns are positional and the header row is only skipped, so the header text does not matter — but a header row must be there, or your first photo is silently dropped. Columns after position 7 are ignored.

Do not re-save the file as comma-separated. A comma-separated file is not read as a slightly different Orbit export; every line becomes a single field and the delivery fails on its first row. The generic template is the one that reads commas.

Timestamps#

timestamp is YYYYMMDDHHMMSS (read as Dutch local time, Europe/Amsterdam).

DatumTijdFoto is the capture time on the recording system's clock, to the second, without a time zone. It is read as Dutch local time (Europe/Amsterdam, so CET or CEST depending on the date). An export from a system running on UTC is currently not supported; tell us if you have one.

Orbit names each photo after the same clock down to the millisecond (20260901124146301_360 is 12:41:46.301). When a photo's name starts with its row's DatumTijdFoto followed by three digits, those digits become the milliseconds of its capture time — which is what keeps photos taken within the same second in order. A photo named differently keeps the whole second.

Filename matching#

Fotonaam has no extension. The name is resolved against the real listing of the jpg/ folder: a name that already ends in .jpg or .jpeg is used as-is, and a bare name is tried with .jpg appended, then .jpeg.

Matching is case-sensitive. Only files directly inside jpg/ are considered — subfolders are not scanned.

Tolerance#

  • Up to 10 % of a recording's CSV rows may reference missing photos. Beyond that the run fails, naming the recording.
  • Photos in the delivery that the CSV does not reference are not indexed (noted, not an error).

The missing-photo allowance exists so one corrupt frame doesn't sink a delivery of 50 000.

Ingest parameters#

KeyRequiredTypeMeaning
anonymisationyesstring — recognised: already_anonymised, auto_anonymiseCompared exactly: already_anonymised marks the photos as already blurred, auto_anonymise queues them for blurring, any other value does neither.
height_above_groundyesnumberCamera height above the road surface, in metres.
set_namenostringThe set the indexed photos are grouped under. Default: 1.
tile_pointcloudsnoflag — anything except missing, null, false or "no" enables itGrid-tile the point clouds; the tiles, not your source files, are then indexed.

Both required keys really are required — a dataset created with no parameters at all fails at this step.

Coordinate reference system#

Nothing is reprojected. Export from Orbit in the dataset's CRS. Positions are stamped with the dataset's 3D SRID, point cloud boundaries with its 2D SRID. See Coordinates are not reprojected.

Heading is a compass heading (north is 0°, clockwise), which is what Orbit writes; Pitch and Roll follow. See Rotation angles.

What you get back#

  • Indexed panorama records with positions and orientations.
  • A tilepack (.tpc) per photo. Omnibase tenants view the JPEG; DZP is not generated at ingest.
  • Blurred derivatives, if anonymisation is auto_anonymise.
  • Indexed point clouds plus a merged COPC, if point clouds were delivered.
  • Grid-tiled point clouds under pointcloud_tiles/, if tile_pointclouds is enabled — in which case the tiles, not your source files, are what gets indexed.

Common failures#

SymptomCause
"row 1: missing column 1"The file was re-saved as comma-separated; upload the tab-separated Orbit export
"row N: cannot parse timestamp"DatumTijdFoto is not YYYYMMDDHHMMSS, or the time falls in the repeated hour of the autumn clock change
"the delivery has no panorama or pointcloud content"Nothing was uploaded, or everything was uploaded under folder names this template does not look in
"no CSV file found under …"The base folder exists but has no CSV directly inside it
First photo missingYour CSV has no header row, so row 1 was consumed as one
"missing required key height_above_ground"The dataset was created with no ingest parameters
More than 10 % of photos missingFilename case mismatch, or images in a subfolder of jpg/ rather than directly inside it