ProRail PVR (older deliveries)
The earlier ProRail PVR delivery shape, kept for datasets that were built against it. New deliveries should use ProRail PVR, which takes one layout regardless of supplier and reads photo dimensions from the images instead of requiring them as parameters.
The essential difference: here the folder layout itself differs per supplier,
so supplier selects a different reader rather than just a rotation convention.
Folder layout#
Every directory at the bucket root is one set, named after
the folder. What must be inside it depends on supplier.
supplier = "Volker":
<dataset bucket>/
├── Deel_1/
│ ├── Rapportage/
│ │ └── 20240226_posities.csv exactly one CSV, any name
│ ├── 02_cam/
│ │ ├── 0000001.jpg
│ │ └── 0000002.jpg
│ └── 01_laz/
│ └── tile_001.laz
└── Deel_2/
└── …
supplier = "IGL":
<dataset bucket>/
├── Deel_1/
│ ├── 20240226_posities.csv at the folder root, not in Rapportage/
│ ├── jpg/
│ │ ├── 0000001.jpg
│ │ └── 0000002.jpg
│ └── 01_laz/
│ └── tile_001.laz
└── Deel_2/
└── …
| Volker | IGL | |
|---|---|---|
| CSV location | <folder>/Rapportage/*.csv | <folder>/*.csv |
| Photo folder | <folder>/02_cam/ | <folder>/jpg/ |
| Point clouds | <folder>/01_laz/*.laz | <folder>/01_laz/*.laz |
A folder with no CSV is skipped with a note. For IGL, a folder with no jpg/
subfolder is skipped before the CSV is even looked for.
Photos are .jpg only; point clouds are .laz only.
The position CSV#
Identical to ProRail PVR's — comma-separated, header row required, columns addressed positionally:
| Position | Meaning |
|---|---|
| 0 | Photo filename, without the .jpg extension |
| 1 | X — easting, in the dataset's CRS |
| 3 | Y — northing |
| 5 | Z — height |
| 7 | Omega, degrees |
| 9 | Phi, degrees |
| 11 | Kappa, degrees |
| 13 | Focal length, millimetres |
| 14 | Pixel size, micrometres |
| 16 | Capture time, HHMMSSffffff |
| 17 | Capture date, YYYYMMDD |
For Volker deliveries, a row whose X reads #N/B is skipped — that is the
supplier's marker for a frame with no fix, and it is expected in normal
deliveries.
Rotation angles#
supplier | Applied |
|---|---|
IGL | Angles used as delivered, with +90° added to kappa |
Volker | Angles used exactly as delivered |
Note that this differs from ProRail PVR, where Volker angles are negated. The conventions changed with the delivery format; that is one of the reasons the two templates are separate.
Any other supplier value is a hard error.
Ingest parameters#
| Key | Required | Values | Default |
|---|---|---|---|
supplier | yes | IGL or Volker | — |
photo_width_px | yes | integer | — |
photo_height_px | yes | integer | — |
set_name | no | string — names the merged point cloud only | 1 |
Photo dimensions are required parameters here — they are not read from the images. Every photo in the dataset is recorded at the dimensions you give, so a delivery mixing resolutions cannot be described correctly. That is the main reason to prefer ProRail PVR for anything new.
Coordinate reference system#
Nothing is reprojected. Positions are stamped with the dataset's SRID and point cloud boundaries come from the LAS headers unchanged. See Coordinates are not reprojected.
Each photo gets a fixed 20 m square footprint centred on its capture position.
Tolerance#
- A CSV row whose photo is missing → skipped, with a note. No percentage limit.
- Photos that no CSV row mentions → left unindexed.
- A folder missing its CSV, or (for IGL) its
jpg/subfolder → skipped, and the rest of the delivery continues.
What you get back#
- Indexed photos per folder, with camera geometry and footprints.
- Indexed point clouds per folder from
01_laz/. - A single merged COPC at
copc/pointcloud.copc.lazacross every folder.
Common failures#
| Symptom | Cause |
|---|---|
| A folder missing entirely | Its CSV is in the other supplier's location, or (IGL) it has no jpg/ |
| Nothing indexed | The delivery uses the newer single layout — use ProRail PVR |
| Photos point the wrong way | The wrong supplier, or a delivery in the newer convention |
| Photos render at the wrong scale | photo_width_px / photo_height_px do not match the actual images |
| Fewer rows than expected for Volker | Rows marked #N/B have no position and are skipped by design |