I derived all traffic‑sign annotations from Panoramax, processed them, and plotted them on a map.
Below is the workflow I used. Using the ‘Dutch’ test Panoramax instance (https://nl.panoramax.xyz/) I extracted all photo locations and all traffic‑sign annotations.
Each annotation contains:
-
the traffic‑sign code (e.g., C2), and
-
a bounding box (bbox) of the pixels describing where in the 8000‑pixel panorama the sign appears.
Because the Amsterdam panoramas have a fixed orientation — the center (pixel 4000) is always looking north — the pixel position of the detected sign can be converted into a horizontal viewing direction:
-
0 px → south
-
4000 px → north
-
8000 px → south again
-
values >4000 lean towards west, values <4000 towards east
This makes it possible to determine which direction the camera was facing at the moment the sign was detected. If north is not the middle it is still possible but with a slightly another script.
Processing pipeline
Small Jupyter Notebook to:
- Call the Panoramax API
- Collect all photo metadata and annotations
- Parse them
- Export two CSVs: one for photos, one for annotations
These CSVs were then loaded into PostgreSQL/PostGIS, where I calculated additional attributes such as:
- the viewing direction (in degrees),
- added the geometry point of the camera location.
Here is the SQL I used:
create table panoramax.annotations_with_sign_code_only_test as
select
a.*,
p.lon,
p.lat,
(8000 - bbox_xmax) as bbox_xmax_from_right,
extract(year from p.ts)::int as year,
case
when bbox_xmax > 4000
then 360.0 * (bbox_xmax - 4000)::float / 8000.0
else
360.0 - 360.0 * (4000 - bbox_xmax)::float / 8000.0
end as degree,
st_setsrid(st_makepoint(p.lon, p.lat), 4326)::geometry(Point, 4326) as geom
from panoramax.annotations_with_sign_code_only a
left join panoramax.panoramax_pictures_collections_paginated p
on a.picture_id = p.picture_id;
The resulting table was then visualized in QGIS.
What the map reveals?
The official C2 signs from the NDW traffic‑sign register appear as white filled arrows. Sequence lines (brown) show the original photo trajectory.
On the map each C2 annotation appears at the location where the photo was taken as a coloured arrow. Arrow annotation is colored based on the degree the sign is to see visual better at which traffic sign it is looking. Patterns:
-
- Photos taken west→east appear green,
-
- south→north appear orange,
-
- east→west appear red.
All photo points correctly “see’’ the official C2 sign — except for two points north of the sign.
These two cameras are positioned behind the sign and should only see the backside of the sign, so they should not detect a C2 at all.
But they do.
Looking at the original Panoramax images explains the discrepancy:
A temporary C2 sign had been placed further north.
Because temporary signs are not included in the NDW traffic‑sign database, the photos detect a C2 that the NDW dataset does not list. This neatly explains why those northern points appear inconsistent.
What a possibilities!

