(Extensible Cameras Format – yet another cameras database standard)
With that amount of existing POI-database formats, developing another one may not seem to be the best idea. However, most formats are proprietary and non-extensible. ExCam format is free for everyone, and supports conversion from other format. ExCam may be further developed in future; however, all new additions should be fully backward-compatible with previous versions.
ExCam standard is developed specifically for storing databases of road cameras. The main features of this standard are the following:
Important note about reading JSON-structures
All JSON objects may be undocumented fields, which be ignored. Any code working with ExCam format should never fail because of unknown JSON fields
Database files are used to store the cameras themselves. On the top level, database file is a JSON-lines file, encoded with UTF-8, and packed to XZ container (LZMA). The first line contains file metadata. The second and subsequent lines describe cameras, one per line.
Metadata
Metadata is stored on the first line of the file after unpacking (XZ) and decoding (UTF-8).
Metadata line contains a JSON object with only one key: _meta
. The value of the _meta
key is another JSON object, containing the metadata itself. The following fields may be used in metadata:
name
(required) – the name of the databasedate
(required) - the date of the dataset, must follow YYYY-MM-DD formatrevision
(optional) - revision of the dataset within the same day, should be assumed as 0
if not specified in JSONExamples of correct metadata lines
{"_meta": {"date": "2020-01-01", "name": "My cameras database"}}
{"_meta": {"date": "2020-01-01", "name": "My cameras database", "revision": 3}}
Cameras information*
Cameras are stored on the second and subsequent lines of the file after unpacking (XZ) and decoding (UTF-8), up to the end of file.
Each line with camera contains a JSON dictionary with the following keys:
lat
(required) - latitude of the cameralon
(required) - longitude of the cameraflg
(required) - an integer containing information (bitmask) about boolean flags associated with that camera, will be described belowdir
(optional) - a list of controlled padding directions (integers), in degrees, starting from true North, clockwise; null
if unknown; should be treated as null
if omitted in JSON[90, 180]
means that camera watches for cars passing eastbound and southbound)spd
(optional) - speed limit in km/h, if enforced; null
if unknown or not enforced; should be treated as null
if omitted in JSONstr
(optional) - name of the location, where the camera is located; null
if unknown; should be treated as null
if omitted in JSONflg
property contains a bitmask of various flags. The following flags and associated bitmask values are supported now. Bits are counted from lower to higher.
(Bit 0)
- Speed is enforced(Bit 1)
- Red light is enforced(Bit 2)
- Start of average speed enforcement section(Bit 3)
- End of average speed enforcement section (may be combined with the previous flag to indicate a middle camera of section enforcement)(Bit 4)
- Lane is enforced(Bit 5)
- Bus lane is enforced(Bit 6)
- This is a dummy camera(Bit 7)
- Distance is enforced(Bit 8)
- Overtaking is enforced(Bit 9)
- Pedestrian crossing is enforced(Bit 10)
- Height is enforced(Bit 11)
- Weight is enforced(Bit 12)
- Entrance is enforced(Bit 13)
- Camera is tracking license plates of all carsExamples of correct cameras lines
{"lat": 47.23907, "lon": -122.35685, "flg":3, "dir":[179, 90], "spd":32, "str": "54th & 20th"}
{"lat":37.5362, "lon":-121.9985, "flg":2}
Python example of reading the database file
import json
import lzma
with lzma.open(excam_file_path, "rt", encoding="utf-8") as f:
lines = map(json.loads, f)
metadata = next(lines)["_meta"]
print(
f"Dataset {metadata['name']} "
f"from {metadata['date']} "
f"(revision {metadata.get('revision', 0)})"
)
for camera in lines:
print(
f"Camera on {camera['lat']},{camera['lon']}, "
f"flags {camera['flg']:012b}, "
f"controlled directions {camera.get('dir')}, "
f"speed {camera.get('spd')}, "
f"street {camera.get('str')}"
)
The ExCam format has an extension allowing to update database automatically. To achieve this without downloading excessive data, a link to database format is used.
Online format works the following way
The format of the link structure
Link structure is a JSON object with only one key: _link
. The value of the _link
key is another JSON object, containing the link data itself. The following fields may be used in the link data:
date
(required) - the date of the dataset, must follow YYYY-MM-DD formatrevision
(optional) - revision of the dataset within the same day, should be assumed as 0
if not specified in JSONdataUrl
(required) - the URL path to the database fileExamples of correct link responses
{"_link":{"dataUrl": "https://example.com/database_file.excam", "date": "2020-01-01"}}
{"_link":{"dataUrl": "https://example.com/database_file.excam", "date": "2020-01-01", "revision": 3}}