Oblique (UltraMap)
For oblique aerial imagery — UltraCam Osprey and similar four-cone systems —
processed through UltraMap and delivered with its exterior orientations
export (.eo). The export is the aerotriangulation result: one adjusted
position and rotation per photo, per cone, plus the camera calibration. That
file is what the photos are indexed from; nothing is read from the pixels.
Photos are indexed per camera cone — Forward, Backward, Left and Right each become their own set.
Folder layout#
<dataset bucket>/
├── O26010_Block.eo exactly one — the UltraMap AT export
├── Block-Footprints.shp / .shx / .dbf exactly one — footprints + capture times
├── ATReport.pdf welcome, not read
├── BINGO/ welcome, not read (adjustment input)
├── Cameracalibratie/ welcome, not read
├── JPG/
│ ├── 91357-Fwd.jpg
│ ├── 91357-Bwd.jpg
│ ├── 91357-Left.jpg
│ └── 91357-Right.jpg
└── pointcloud/ optional
└── tile_001.laz
The .eo and the footprint shapefile sit at the bucket root; the photos sit
directly in JPG/ (the folder name is exact and case-sensitive, and
subfolders are ignored). Extra files at the root — the AT report, the BINGO
project, calibration PDFs — are fine to include and are not read.
At least one photo is required. A delivery may be a clip: an
aerotriangulation usually covers a wider block than what is delivered, so
events in the .eo without a photo, and events with only some of their
four cones, are normal. The report says how many events have photos so
that a partial set is not mistaken for missing data.
Photos#
| Naming | <eventNr>-<cone>.jpg with cone Fwd, Bwd, Left or Right |
| Extensions | .jpg and .jpeg, case-insensitive |
| Dimensions | Taken from the .eo camera block (sensor size ÷ pixel size); not read from the file |
Every photo must have a matching [Events] row in the .eo for its event
number and cone, and every photo is checked to start and end like a JPEG.
Deliver the photos exactly as UltraMap wrote them — do not rotate them.
The orientations in the .eo describe the pixels as exported, in the
sensor's own orientation (for a forward-looking cone the near ground is at
the top of the image). Rotating a photo "upright" without changing its
orientation row places it wrongly in the viewer.
The orientations export#
The .eo is UltraMap's "Exterior Orientations File", FILE_VERSION 4.
What is read:
| Block | Used for |
|---|---|
[PARAMETERS] | EPSG_CODE — must be the dataset's CRS (see below) |
[Cameras] | camera id → cone (Lvl02-Oblique-Left, …), pixel size, sensor size |
[Intrinsics] | principal distance and principal point per camera |
[Events] | camera, event number, projection centre X Y Z, rotations Rot_X Rot_Y Rot_Z |
[Sessions] and [Eccentricities] are ignored — the events already carry
the mount offsets. Rotations are taken exactly as written.
When the footprint shapefile's .shp is delivered and has a polygon for
every photo, those polygons are stored as the photos' footprints — they
come out of the same aerotriangulation, projected onto its terrain. A polygon
must lie within 10 km of its photo's camera position — a shapefile in
another coordinate system fails that and the footprints are projected
instead. The polygons are also compared against footprints we compute from
the .eo: a widespread mismatch is reported as a warning, because it means
the export's rotation convention differs from what this template expects,
and the stored orientations would then be wrong even though the footprints
look right.
Without a complete shapefile, the footprints are projected from the .eo
onto the ground (see below).
Timestamps#
The .eo carries no capture times. They are read from the footprint
shapefile's .dbf:
| Column | |
|---|---|
IMAGE | photo filename without extension (91357-Fwd) — the join key |
Recorded | capture time, YYYY-MM-DD HH:MM:SS |
Recorded is on the GPS time scale, not UTC (it is what the camera's GPS
clock read, without the leap-second correction). The leap_seconds
parameter — 18 since 2017 — is subtracted to get UTC.
Every delivered photo must have a Recorded row.
Coordinate reference system#
This template does not reproject. The .eo header's EPSG_CODE must be
the dataset's coordinate reference system (for a Dutch dataset,
28992); export the adjustment in that CRS. Projection centres are stored
as delivered, footprints are computed in the same CRS.
Ground reference#
Only used when footprints have to be projected (no .shp, or one that does
not cover every photo). Then a footprint is the image frame projected onto
the ground, and the ground comes
from a terrain model on the platform when one covers the delivery in its
CRS (for the Netherlands, AHN), sampled under each photo's footprint. When
no terrain model covers the delivery, the flat plane at ground_height is
used instead, and that parameter must then be set — validation fails
otherwise, so it can be corrected before processing starts. When a terrain
model does cover the delivery, ground_height is ignored.
Point cloud#
Optional. LAZ/LAS tiles in pointcloud/ (or Pointcloud/,
ingest/Pointcloud/) are indexed and merged as for
Point cloud (generic). A delivery without them is
photos-only.
What is checked#
Validation runs when the delivery is handed over, before processing starts, and reports against the sections above:
- Exactly one UltraMap exterior-orientations export (
.eo) at the bucket root. None means nothing to index from; several means we cannot tell which adjustment is final. - The
.eomust be an UltraMapFILE_VERSION 4export with[Cameras],[Intrinsics]and[Events]blocks, and camera types for all four oblique cones (Forward, Backward, Left, Right). - The
.eoheader'sEPSG_CODEmust be the dataset's coordinate reference system. Coordinates are not reprojected: export the adjustment in the dataset's CRS. - Every delivered photo
<eventNr>-<cone>.jpgmust have an[Events]row for that event number and cone in the.eo. The reverse is not required — events without a photo are how a clipped delivery looks. - 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, since nothing knows how big the file should have been.
- Exactly one footprint shapefile
.dbfat the bucket root, withIMAGEandRecordedcolumns. It is the only source of capture times: the.eocarries none. - Every delivered photo must have a row in the footprint
.dbf(matched onIMAGE= the filename without extension) with aRecordedtime. - When the delivered footprint shapefile has a polygon for every photo, those polygons are stored as-is and nothing more is needed. Otherwise the footprints are projected onto the ground, and a terrain model on the platform must cover the delivery's extent in the dataset's CRS, or the
ground_heightparameter must be set. This is checked here so the parameter can be fixed before processing starts. - When a footprint shapefile (
.shp) is delivered, the footprints we compute from the.eoare compared against it. Widespread disagreement means the export's rotation convention or CRS is not what we expect, and the indexed photos would be placed wrongly — worth a look before accepting. (a warning, not an error)
Ingest parameters#
| Key | Required | Type | Meaning |
|---|---|---|---|
dtm | no | string | Name or id of the terrain model to use when more than one covers the delivery. Normally left empty: the newest covering model is used. |
ground_height | no | number | Ground elevation (metres, in the dataset's vertical datum) the footprints are projected onto when no terrain model covers the delivery. Ignored when one does. |
leap_seconds | no | number | GPS − UTC offset, in seconds, subtracted from the footprint shapefile's Recorded times (which are on the GPS time scale). Default: 18. |
What you get back#
- One indexed oblique photo per delivered JPG, with its projection centre, orientation, calibration and ground footprint, in the set named after its cone.
- A tilepack (
.tpc) per photo. For tenants still on Omnibase, an SZI as well. - Coverage per cone.
- The point cloud, when delivered, as for the generic point cloud template.