_ _ _
__ _ ___ ___ ___ ___(_)_ _ _ __ ___ | |_(_) | ___ _ __
/ _ |/ _ \ / __/ _ \/ __| | | | | '_ _ \| __| | |/ _ \ '__|
| (_| | (_) | (_| __/\__ \ | |_| | | | | | | |_| | | __/ |
\__, |\___/ \___\___||___/_|\__,_|_| |_| |_|\__|_|_|\___|_|
__| | A Cesium Point Cloud tile generator written in golang
|___/
gocesiumtiler is a tool to convert point cloud stored as LAS files to Cesium.js 3D tiles ready to be streamed, automatically generating the appropriate level of details and including additional information for each point such as color, laser intensity and classification.
gocesiumtiler V2.0.0 has been released introducing several important improvements over V1. Please refer to the changelog for a full list of changes.
This release is backward incompatible compared to V1 and also deprecates several options, most of which were not of much interest. Some of these might be added in future minor updates of V2.
gocesiumtiler V2 offers the following features:
New from v2.0.0-gamma: Convertion between EGM and WGS84 elevations is now delegated to Proj. Just make sure to specify the correct input vertical datum and make sure the share
folder contains the required vertical grids. These are not included but can be downloaded from the Proj CDN
The currently tool uses the version 9.5.0 of the well-known Proj.4 library to handle coordinate conversion. The input CRS specified by just providing the relative EPSG code, a Proj4 string or WKT text, or letting the library figure it out automatically from the LAS metadata.
Speed is a major concern for this tool, thus it has been chosen to store the data completely in memory. If you don't have enough memory the tool will fail, so if you have really big LAS files and not enough RAM it is advised to split the LAS in smaller chunks to be processed separately.
Information on point intensity and classification is stored in the output tileset Batch Table under the
propeties named INTENSITY
and CLASSIFICATION
.
You can preview a couple of tilesets generated from this tool at this website
GOCESIUMTILER_WORKDIR
has been deprecatedNote: The final V2.0.0 version significantly differs from "pre-release" versions V2.0.0 alpha, beta and gamma. The V2.0.0 final changelog consolidates all changes from V1.
Along with the source code a prebuilt binary for Windows x64 and Linux x64 is provided for each release of the tool in the github page. Binaries for other systems at the moment are not provided.
Please note that the development setup has changed considerably from V2.0.0 gamma and now leverages Docker for reproducible builds.
In general local development requires:
Please refer to the DEVELOPMENT.md file for further info on how to setup a local development environment in both Windows and Linux.
share
folder is. share
folder. To run just execute the binary tool with the appropriate flags.
To show the help run:
gocesiumtiler -help
There are two commands, file
and folder
:
gocesiumtiler file { flags } myfile.las
: Converts myfile.las
into a Cesium 3D point cloud using the flags passed in input (see below).gocesiumtiler folder { flags } myfolder
: Finds all LAS files into myfolder
and convers them into one or more Cesium 3D Point clouds using the flags passed as input (see below).SThese flags are applicable to both the file
and the folder
commands
--out value, -o value full path of the output folder where to save the resulting Cesium tilesets
--crs value, --epsg value, -e value String representing the input CRS. For example, and EPSG code like EPSG:4326 or EPSG:28355+5773 or a generic Proj4 or WKT string. Bare numbers will be interpreted as EPSG codes. If empty the system will attempt to autodetect the CRS from the LAS metadata. In case of multiple LAS files, the CRS must be consistent else an error will be thrown.
--resolution value, -r value minimum resolution of the 3d tiles, in meters. approximately represets the maximum sampling distance between any two points at the lowest level of detail (default: 20)
--z-offset value, -z value z offset to apply to the point, in meters. only use it if the input elevation is referred to the WGS84 ellipsoid or geoid (default: 0)
--depth value, -d value maximum depth of the output tree. (default: 10)
--min-points-per-tile value, -m value minimum number of points to enforce in each 3D tile (default: 5000)
--8-bit set to interpret the input points color as part of a 8bit color space (default: false)
--subsample value Approximate percent of points to keep in the final point cloud, between 0.01 (1%) and 1 (100%) (default: 1)
--help, -h show help
These commands are specific to the folder
command:
--join, -j merge the input LAS files in the folder into a single cloud. The LAS files must have the same properties (CRS etc) (default: false)
Previous releases of gocesiumtiler had a dedicated flag for EGM to WGS84 ellipsoid elevation conversion. This has been deprecated and now the vertical datum conversion is fully delegated to Proj. This means that to convert the vertical coordinates in case they are not referred to the WGS84 ellipsoid the input CRS definition needs to include the definition for the vertical datum.
If the LAS file includes a 3D CRS definition or separate Horizontal and Vertical CRS definitions gocesiumtiler will attempt to use those info automatically. Else if a vertical definition is not included,
or the tool fails to detect the correct CRS, the right definition can be provided manually via the --crs
flag.
This can be achieved for example by providing a composite CRS EPSG code.
For example, if a LAS file contains coordinates in the EPSG:32633
CRS with elevations referred to the EGM2008 (EPSG:3855
), run the command with:
--crs EPSG:32633+3855
NOTE: This might require to install extra grid files in the share
folder. In case of issues please make sure please to download the Proj Data grids from the Proj CDN and save them in the share
folder.
Convert all LAS files in folder C:\las
, write output tilesets in folder C:\out
, assume LAS input coordinates expressed
in EPSG:32633, with elevations referred to the EGM2008 (EPSG 3855). Use a resolution of 10 meters, create tiles with minimum 1000 points
and enforce a maximum tree depth of 12:
gocesiumtiler folder -out C:\out -crs EPSG:32633+3855 -resolution 10 -min-points-per-tile 1000 -depth 12 C:\las
or, using the shorthand notation:
gocesiumtiler folder -o C:\out -e EPSG:32633+3855 -r 10 -m 1000 -d 12 C:\las
Like Example 1 but merge all LAS files in C:\las
into a single 3D Tileset
gocesiumtiler folder -out C:\out -crs EPSG:32633+3855 -resolution 10 -min-points-per-tile 1000 -depth 12 -join C:\las
or, using the shorthand notation:
gocesiumtiler folder -o C:\out -e EPSG:32633+3855 -r 10 -m 1000 -d 12 -j C:\las
Convert a single LAS file at C:\las\file.las
, write the output tileset in the folder C:\out
, use the system defaults and let gocesiumtiler extract the CRS metadata from the LAS.
gocesiumtiler file -out C:\out C:\las\file.las
or, using the shorthand notation:
gocesiumtiler file -o C:\out -e 32633 C:\las\file.las
To use the tiler in other go programs just:
go get github.com/mfbonfigli/gocesiumtiler/v2
Then instantiate a tiler object and launch it either via ProcessFiles
or ProcessFolder
passing in the desired processing options.
A mnimal example is:
package main
import (
"context"
"log"
"github.com/mfbonfigli/gocesiumtiler/v2/tiler"
)
func main() {
t, err := tiler.NewGoCesiumTiler()
if err != nil {
log.Fatal(err)
}
ctx := context.TODO()
err = t.ProcessFiles([]string{"myinput.las"}, "/tmp/myoutput", "EPSG:32632", tiler.NewTilerOptions(
tiler.WithEightBitColors(true),
tiler.WithWorkerNumber(2),
tiler.WithMaxDepth(5),
), ctx)
if err != nil {
log.Fatal(err)
}
}
Note that you will require to use cgo
for the compilation, for how to setup the build environment please refer to the DEVELOPMENT.md.
gocesiumtiler from version 2.0.0 final offers the concept of mutators. Mutators are implementations of the mutator.Mutator
interface
and can be used to manipulate or discard input points.
The library vends a ZOffset
mutator to perform vertical traslation of point clouds and a Subsampler
mutator to thin down the points in the output.
Other possible uses of mutators (not yet built in into the library) could be, for example:
To use the mutators just pass them to the tiler options:
mut := []mutator.Mutator{
mutator.NewZOffset(10),
mutator.NewSubsampler(0.5),
}
err = t.ProcessFiles([]string{"myinput.las"}, "/tmp/myoutput", "EPSG:32632", tiler.NewTilerOptions(
tiler.WithEightBitColors(true),
tiler.WithWorkerNumber(2),
tiler.WithMaxDepth(5),
tiler.WithMutators(mut),
), ctx)
To implement a custom mutator, implement the mutator interface:
Mutate(p model.Point, t model.Transform) (model.Point, bool)
The Mutate function receives as input the original point and a Transform object that can be used to trasform from the local CRS to the global EPSG 4978 CRS and back. The output of the Mutate function is the, eventually manipulated, point and a boolean which should be true if the point should appear in the final point cloud, false otherwise.
Note: mutators must be goroutine safe.
type ClassBasedColorMutator struct {}
func (m *ClassBasedColorMutator) Mutate(pt model.Point, localToGlobal model.Transform) (model.Point, bool) {
switch pt.Classification {
case 2:
// ground > brown
pt.R, pt.G, pt.B = 128, 0, 0
case 3:
// low vegetation > dark green
pt.R, pt.G, pt.B = 0, 60, 0
case 4:
// medium vegetation > green
pt.R, pt.G, pt.B = 0, 130, 0
case 5:
// high vegetation > light green
pt.R, pt.G, pt.B = 30, 170, 30
case 6:
// building > orange
pt.R, pt.G, pt.B = 200, 100, 0
case 9:
// water > blue
pt.R, pt.G, pt.B = 5, 170, 200
default:
// all other classes > grey
pt.R, pt.G, pt.B = 30, 30, 30
}
return pt, true
}
The sampling occurs using a hybrid, lazy octree data structure. The algorithm works as follows:
Along with the source code, a prebuilt binary for both Linux and Windows x64 is provided for each release of the tool in the github page.
Further work needs to be done, such as:
Contributors and their ideas are welcome.
If you have questions you can contact me at m.federico.bonfigli@gmail.com
This library uses SemVer for versioning. For the versions available, see the tags on this repository.
Massimo Federico Bonfigli - Github
This project is licensed under the Mozilla Public License 2.0 - see the LICENSE.md file for details.
The software uses third party code and libraries. Their licenses can be found in LICENSE-3RD-PARTIES.md file.
Lhe library is released under the Mozilla Public License Version 2.0. See the LICENSE.md file for further info.