Validation of a CityJSON file

Table of contents

  1. Schema validation (is the syntax of the file OK?)
  2. Geometry (are the geometric primitives valid?)

Validation of a CityJSON dataset means that one must ensure that it respects the standardised specifications and definitions as given in the specifications.

Schema validation (is the syntax of the file OK?)

The JSON schemas of CityJSON can be downloaded, for each version, at These are based on the JSON Schema project.

To validate a given file you can use any software listed here. However, it is rather tricky to stitch all the schemas together, and the handling of Extensions will not work.

The “official validator” for CityJSON is cjval, which is available as a web-app and with cjio.

To validate the file, simply drag it to

Or alternatively type cjio validate

Observe that not only the schema was tested, but also the internal consistency of the file was tested. The following were tested:

  1. JSON syntax
  2. CityJSON schemas
  3. Extension schemas
  4. parent_children_consistency
  5. wrong_vertex_index
  6. semantics_array
  7. extra_root_properties
  8. duplicate_vertices
  9. unused_vertices

It is possible that the validation returns warnings, eg when there are duplicate vertices, those are not considered errors and thus only a warning is raised.

Now download the invalid file, and try to validate it. You should get an error that "CityObjects" is a required property, and that it is missing from the file:

Fixing this is rather easy: remove the space between “City” and “Objects” at line 16 and then the file should be valid.

Geometry (are the geometric primitives valid?)

CityJSON, as is the case for GML, use the ISO 19107 geometric primitives for representing the geometry of its objects: a 0D primitive is a GM_Point, a 1D a GM_Curve, a 2D a GM_Surface, and a 3D a GM_Solid. A d-dimensional primitive is built with (d-1)-dimensional primitives, e.g. a GM_Solid is formed by several GM_Surfaces, which are formed of several GM_Curves, which are themselves formed of GM_Point. While the ISO19107 primitives do not need to be linear or planar, i.e. curves defined by mathematical functions are allowed, CityGML uses a subset of ISO19107, with the following two restrictions: (1) GM_Curves can only be linear (thus only LineStrings and LinearRings are used); (2) GM_Surfaces can only be planar (thus Polygons are used).

Geometric primitives can be combined into either aggregates or composites. An aggregate is an arbitrary collection of primitives of the same dimensionality that is simply used to bundle together geometries, it does not prescribe any topological relationships between the primitives. The Multi* in CityGML are an example. A composite of dimension d is a collection of d-dimensional primitives that form a d-manifold, which is a topological space that is locally like a d-dimensional Euclidean space. The most relevant example is CompositeSurface: it is a 2-manifold, or, in other words, a surface embedded in 3D space.

A valid primitive of dimension 3 means that all the lower-dimensional primitives used to represent the primitives are also valid.

To validate the geometric primitives in a CityJSON file, we recommend using val3dity, which is ISO 19017 compliant, free, and open-source.

It suffices to download its latest binary, open a console/terminal/shell and type:

val3dity myfile.json

This will read the file and validate one-by-one each of the geometric primitives in the file and produce a summary. If the file is used, then the following should be obtained:

It can be seen that one of the 2 buildings is not valid, because it has duplicate vertices. To know the details, you can produce a report (called myreport.json):

val3dity myfile.json --report myreport.json

Drag this file to the online report browser, and we obtain: