Package: cjio
Python CLI to process and manipulateCityJSONfiles.
The different operators can be chained to perform several processing operations in one step, the
CityJSON model goes through them and different versions of the CityJSON model can be saved as files along the pipeline.Documentationcjio.readthedocs.ioInstallationIt uses Python 3.7+ only.To install the latest release:pip install cjioNoteThe commandsexport,triangulate,reproject, andvalidaterequire extra packages that are not install by default. You can install these packages by specifying the
commands for pip.pip install 'cjio[export,reproject,validate]'To install the development branch, and still develop with it:git checkout develop
virtualenv venv
. venv/bin/activate
pip install --editable '.[develop]'Note for Windows usersIf your installation fails based on apyprojorpyrsistenterror there is a small hack to get around it.
Based on the python version you have installed you can download a wheel (binary of a python package) of the problem package/s.
A good website to use ishere.
You then run:pip install [name of wheel file]You can then continue with:pip install cjioSupported CityJSON versionsCurrently it supportsCityJSON v2.0, but v1.1 and v1.0 files can be upgraded automatically with the operator upgrade`.The operators (cjio--version) expect that your file is using the latest versionCityJSON schema.
If your file uses an earlier version, you can upgrade it with theupgradeoperator:cjio old.json upgrade save newfile.city.jsonUsage of the CLIAfter installation, you have a small program calledcjio, to see its
possibilities:cjio --help

Commands:
  attribute_remove  Remove an attribute.
  attribute_rename  Rename an attribute.
  crs_assign        Assign a (new) CRS (an EPSG).
  crs_reproject     Reproject to a new EPSG.
  crs_translate     Translate the coordinates.
  export            Export to another format.
  info              Output information about the dataset.
  lod_filter        Filter only one LoD for a dataset.
  materials_remove  Remove all materials.
  merge             Merge the current CityJSON with other ones.
  metadata_create   Add the +metadata-extended properties.
  metadata_get      Shows the metadata and +metadata-extended of this...
  metadata_remove   Remove the +metadata-extended properties.
  metadata_update   Update the +metadata-extended.
  print             print the (pretty formatted) JSON to the console.
  save              Save to a CityJSON file.
  subset            Create a subset, City Objects can be selected by: (1)...
  textures_locate   Output the location of the texture files.
  textures_remove   Remove all textures.
  textures_update   Update the location of the texture files.
  triangulate       Triangulate every surface.
  upgrade           Upgrade the CityJSON to the latest version.
  validate          Validate the CityJSON: (1) against its schemas (2)...
  vertices_clean    Remove duplicate vertices + orphan verticesOr see the command-specific help by calling--helpafter a command:Usage: cjio INPUT subset [OPTIONS]

Create a subset, City Objects can be selected by: (1) IDs of City Objects;(2)bbox; (3) City Object type(s); (4) randomly.

These can be combined, except random which overwrites others.

Option '--exclude' excludes the selected objects, or "reverse" the
selection.

Usage examples:

  cjio myfile.city.json subset --bbox 104607 490148 104703 490257 save out.city.json
  cjio myfile.city.json subset --radius 500.0 610.0 50.0 --exclude save out.city.json
  cjio myfile.city.json subset --id house12 save out.city.json
  cjio myfile.city.json subset --random 5 save out.city.json
  cjio myfile.city.json subset --cotype LandUse --cotype Building save out.city.json

Options:
  --id TEXT          The ID of the City Objects; can be used multiple times.
  --bbox FLOAT...    2D bbox: minx miny maxx maxy.
  --radius FLOAT...  x y radius
  --random INTEGER   Number of random City Objects to select.
  --cotype TEXT      The City Object types; can be used multiple times.
  --exclude          Excludes the selection, thus delete the selected
                     object(s).
  --help             Show this message and exit.Pipelines of operatorsThe input 3D city model opened is passed through all the operators, and it gets modified by some operators.
Operators likeinfoandvalidateoutput information in the console and just pass the 3D city model to the next operator.cjio example.city.json subset --id house12 remove_materials save out.city.json
cjio example.city.json remove_textures info
cjio example.city.json upgrade validate save new.city.json
cjio myfile.city.json merge '/home/elvis/temp/*.city.json' save all_merged.city.jsonstdin and stdoutStarting from v0.8, cjio allows to read/write from stdin/stdout (standard input/output streams).For reading, it accepts at this moment onlyCityJSONL (text sequences with CityJSONFeatures).
Instead of putting the file name,stdinmust be used.For writing, both CityJSON files andCityJSONL filescan be piped to stdout.
Instead of putting the file name,stdoutmust be used.
Also, the different operators of cjio output messages/information, and those will get in the stdout stream, to avoid this add the flag--suppress_msgwhen reading the file, as shown below.cat mystream.city.jsonl | cjio --suppress_msg stdin remove_materials save stdout
cjio --suppress_msg myfile.city.json remove_materials export jsonl stdout | less
cat myfile.city.json | cjio --suppress_msg stdin crs_reproject 7415 export jsonl mystream.txtGenerating Binary glTFConvert the CityJSONexample.city.jsonto a glb file/home/elvis/gltfs/example.glbcjio example.json export glb /home/elvis/gltfsConvert the CityJSONexample.city.jsonto a glb file/home/elvis/test.glbcjio example.city.json export glb /home/elvis/test.glbUsage of the APIcjio.readthedocs.io/en/stable/tutorials.htmlDockerIf docker is the tool of your choice, please read the following hints.To run cjio via docker simply call:docker run --rm  -v <local path where your files are>:/data tudelft3d/cjio:latest cjio --helpTo give a simple example for the following lets assume you want to create a geojson which represents
the bounding boxes of the files in your directory. Lets call this scriptgridder.py. It would look like this:fromcjioimportcityjsonimportglobimportntpathimportjsonimportosfromshapely.geometryimportbox,mappingdefpath_leaf(path):head,tail=ntpath.split(path)returntailorntpath.basename(head)files=glob.glob('./*.json')geo_json_dict={"type":"FeatureCollection","features":[]}forfinfiles:cj_file=open(f,'r')cm=cityjson.reader(file=cj_file)theinfo=json.loads(cm.get_info())las_polygon=box(theinfo['bbox'][0],theinfo['bbox'][1],theinfo['bbox'][3],theinfo['bbox'][4])feature={'properties':{'name':path_leaf(f)},'geometry':mapping(las_polygon)}geo_json_dict["features"].append(feature)geo_json_dict["crs"]={"type":"name","properties":{"name":"EPSG:{}".format(theinfo['epsg'])}}geo_json_file=open(os.path.join('./','grid.json'),'w+')geo_json_file.write(json.dumps(geo_json_dict,indent=2))geo_json_file.close()This script will produce for all files with postfix “.json” in the directory a bbox polygon using
cjio and save the complete geojson result in grid.json in place.If you have a python script like this, simply put it inside your
local data and call docker like this:docker run --rm  -v <local path where your files are>:/data tudelft3d/cjio:latest python gridder.pyThis will execute your script in the context of the python environment inside the docker image.Example CityJSON datasetsThere are a fewexample files on the CityJSON webpage.Alternatively, anyCityGMLfile can be
automatically converted to CityJSON with the open-source projectcitygml-tools(based oncitygml4j).AcknowledgementsThe glTF exporter is adapted from Kavisha’sCityJSON2glTF.