UNPKG

@csi-foxbyte/cityjson-to-3d-tiles

Version:

A Node.js library that converts CityJSON files into Cesium 3D Tilesβ€”complete with automatic texture atlas packing, Basis compression, three LOD levels, and customizable threading.

240 lines (168 loc) β€’ 7.94 kB
# cityjson-to-3d-tiles A Node.js library for converting [CityJSON](https://www.cityjson.org/) files into [Cesium 3D Tiles](https://cesium.com/3d-tiles/) with automatic texture packing and Basis compression. Supports generating three levels of detail (LODs) for different distance ranges. ## Table of Contents - [Features](#features) - [Installation](#installation) - [Usage](#usage) - [API](#api) - [Options Overview](#options-overview) - [CLI Wrapper Example](#cli-wrapper-example) - [Docker Job](#docker-job) - [Airflow DAG Example](#airflow-dag-example) - [Building from source](#building-from-source) - [Contributing](#contributing) - [License](#license) <a id="features" /> ## Features - **πŸ™οΈ CityJSON to Tile Database**: Parses CityJSON files and builds a tile database optimized for 3D Tiles generation. πŸ› οΈ - **πŸ—ΊοΈ 3D Tiles Generation**: Converts the tile database into Cesium 3D Tiles, including geometry, textures, and metadata. 🎨 - **πŸ–ΌοΈ Automatic Texture Packing**: Packs textures into atlases and compresses them with [Basis](https://github.com/BinomialLLC/basis_universal) for efficient streaming. ⚑ - **πŸ“ Multiple LODs**: Generates three LODs (LOD0, LOD1, LOD2) to balance detail and performance based on camera distance. πŸ” - **🧡 Customizable Threading**: Control the number of worker threads for CPU-bound tasks. πŸ›‘οΈ <a id="installation" /> ## Installation ```bash npm install @csi-foxbyte/cityjson-to-3d-tiles ``` <a id="usage" /> ## Usage ```js import { generate3DTilesFromTileDatabase } from "cityjson-to-3d-tiles/3dtiles/index.js"; import { generateTileDatabaseFromCityJSON } from "cityjson-to-3d-tiles/cityjson/index.js"; const inputFolder = "D:\\generator_test\\src"; // Folder containing CityJSON files πŸ“‚ const appearance = "rgbTexture"; // Texture appearance (e.g., "rgbTexture", "vertexColor") 🎨 const outputFolder = "D:\\generator_test"; // Base output folder for the tile database and tiles πŸ“ (async () => { // Step 1: Convert CityJSON to an on-disk tile database πŸ—οΈ const { dbFilePath } = await generateTileDatabaseFromCityJSON( inputFolder, // Source folder outputFolder, // Destination folder appearance, // Appearance mode console.log, // Progress callback πŸ“Š { threadCount: 1 }, // Options: number of worker threads 🧡 ); // Step 2: Generate Cesium 3D Tiles from the tile database πŸ› οΈ await generate3DTilesFromTileDatabase( dbFilePath, // Path to the generated tile database "D:\\generator_test\\tiles", // Output folder for 3D Tiles πŸ—‚οΈ console.log, // Progress callback πŸ“ˆ { threadCount: 1 }, // Options: number of worker threads πŸ”§ ); })(); export { generate3DTilesFromTileDatabase, generateTileDatabaseFromCityJSON }; ``` <a id="api" /> ## API ### `generateTileDatabaseFromCityJSON(inputFolder, outputFolder, appearance, progressCallback, options)` - **inputFolder** `(string)` – Path to a directory containing CityJSON files. πŸ“‚ - **outputFolder** `(string)` – Directory where the tile database will be created. πŸ“ - **appearance** `(string)` – Appearance: e.g. `"rgbTexture"` -> which appearence to use. 🌈 - **progressCallback** `(function)` – Function called with log messages or progress updates. πŸ“’ - **options** `(object)`: - `threadCount` `(number)` – Number of worker threads to use (default: number of CPU cores). 🧡 **Returns:** A promise that resolves with an object containing: - `dbFilePath` `(string)` – File path to the generated tile database (.db file). πŸ“œ ### `generate3DTilesFromTileDatabase(dbFilePath, tilesOutputFolder, progressCallback, options)` - **dbFilePath** `(string)` – Path to the tile database generated in the previous step. πŸ“‚ - **tilesOutputFolder** `(string)` – Directory where the Cesium 3D Tiles will be written. πŸ—‚οΈ - **progressCallback** `(function)` – Function called with log messages or progress updates. πŸ”” - **options** `(object)`: - `threadCount` `(number)` – Number of worker threads for tile generation (default: number of CPU cores). 🧡 **Returns:** A promise that resolves when 3D Tiles generation is complete. βœ… <a id="options-overview" /> ## Options Overview | Option | Default | Description | | ------------------- | ------------------ | -------------------------------------------------------------------------- | | `appearance` | `"rgbTexture"` | Which CityGML appearance to use. 🎨 | | `threadCount` | `os.cpus().length` | Number of parallel worker threads. 🧡 | | `simplifyAddresses` | `false` | Whether to simplify addresses or not (From multiple to first address only) | <a id="cli-wrapper-example" /> ## CLI Wrapper Example Wrap the functions in a simple CLI script: ```js #!/usr/bin/env node import path from "path"; import { generateTileDatabaseFromCityJSON } from "cityjson-to-3d-tiles/cityjson/index.js"; import { generate3DTilesFromTileDatabase } from "cityjson-to-3d-tiles/3dtiles/index.js"; const [, , src, out, appearance] = process.argv; (async () => { const { dbFilePath } = await generateTileDatabaseFromCityJSON( path.resolve(src), path.resolve(out), appearance || "rgbTexture", console.log, { threadCount: 4 }, ); await generate3DTilesFromTileDatabase( dbFilePath, path.join(out, "tiles"), console.log, { threadCount: 4 }, ); })(); ``` <a id="docker-job" /> ## Docker Job The repository provides a Docker-based job runner. What it does: - Runs `citygml-tools to-cityjson -o cityjson .` in `/work` (skippable via `SKIP_CONVERSION`) - Converts CityJSON files from `INPUT_DIR` (default: `/work`) - Creates the temporary SQLite DB in container-local storage (`/tmp`) for better performance on Windows mounts - Writes final 3D Tiles to `OUTPUT_DIR` (default: `/work/tiles`) ### Build Image ```bash docker build -t cityjson-to-3d-tiles . ``` ### Run on Windows (PowerShell) Run this from your data folder: ```powershell docker run --rm -v "${PWD}:/work" cityjson-to-3d-tiles ``` ### Run on Linux (bash/zsh) Run this from your data folder: ```bash docker run --rm -v "$(pwd):/work" cityjson-to-3d-tiles ``` ### Optional Environment Variables ```text APPEARANCE=rgbTexture THREAD_COUNT=4 HAS_ALPHA_ENABLED=true SIMPLIFY_ADDRESSES=false SKIP_CONVERSION=false INPUT_DIR=/work OUTPUT_DIR=/work/tiles INTERNAL_DB_DIR=/tmp/cityjson-to-3d-tiles SRC_SRS=<proj string> DEST_SRS=<proj string> SHOW_STACK_TRACE=false ``` Find Proj4 strings: - PROJ documentation: https://proj.org/ - EPSG search (incl. Proj4): https://epsg.io/ Example (PowerShell): ```powershell docker run --rm -v "${PWD}:/work" -e THREAD_COUNT=8 -e APPEARANCE=rgbTexture cityjson-to-3d-tiles ``` Example (Linux): ```bash docker run --rm -v "$(pwd):/work" -e THREAD_COUNT=8 -e APPEARANCE=rgbTexture cityjson-to-3d-tiles ``` <a id="airflow-dag-example" /> ## Airflow DAG Example An example DAG is available in: `examples/airflow/cityjson_to_3d_tiles_dag.py` It uses `DockerOperator`, runs the GHCR image, and mounts one host folder to `/work`. <a id="building-from-source" /> ## Building from source [pnpm](https://pnpm.io/) is required to build this library. ```bash pnpm install pnpm run build ``` <a id="contributing" /> ## Contributing Contributions are welcome! Please open issues or pull requests on the GitHub repository. πŸ™Œ <a id="license" /> ## License This library is licensed under the [GNU Lesser General Public License](https://www.gnu.org/licenses/#LGPL).