|
To pre-process point clouds, you must have the LuciadLightspeed Tiling Engine component installed, or the LuciadFusion product. |
Goal
In this tutorial you will learn how to pre-process your point cloud data into a tiled and multi-leveled version. This allows to:
-
Combine multiple point cloud files into a single data set
-
Allows to visualize huge point cloud data sets by dividing the data into tiles, and providing multiple levels of detail
-
The tiled, multi-leveled version can be streamed using the OGC 3D Tiles protocol, making it suitable to be shown in a web client like LuciadRIA.
Pre-process point cloud data
Pre-processing point cloud data is done by creating a TLfnPointCloudPreprocessor instance.
//Use one or more las files as input files
List<String> sourceNames = Arrays.asList("Data/LAS/terrain_with_buildings.las");
//Create the preprocessor
TLfnPointCloudPreprocessor preprocessor =
TLfnPointCloudPreprocessor.newBuilder()
.sources(sourceNames)
.targetDirectory(new File(System.getProperty("java.io.tmpdir"), "pointCloudStore").getAbsolutePath())
.name("Example Store")
.pointCloudCompression(ELcdOGC3DTilesPointCloudCompressionType.DRACO)
.build();
The pre-processor is created using a Builder class.
Once the pre-processor is created, it can be started using the start() method:
preprocessor.start();
The pre-processor provides a getProgress() method which you can use to query it for its progress.
You can for example call this method periodically, or attach a status listener to it.
In this tutorial, we opt for the listener which we attach to it before calling the start() method:
//Attach a listener to the preprocessor to keep track of the progress
preprocessor.addStatusListener(x -> {
TLfnPointCloudPreprocessor.Progress progress = preprocessor.getProgress();
System.out.println(String.format("Overall progress: %.2f%%", progress.getProgress() * 100));
System.out.println("Details:");
for (String source : sourceNames) {
TLfnPointCloudPreprocessor.Progress.SourceDetails sourceDetails = progress.getSourceDetails(source);
TLfnPointCloudPreprocessor.Progress.SourceDetails.Status status = sourceDetails.getStatus();
System.out.println(String.format("%s: %s", source, status));
}
System.out.println();
});
This outputs
Overall progress: 0.00% Details: Data/LAS/terrain_with_buildings.las: PENDING Overall progress: 95.00% Details: Data/LAS/terrain_with_buildings.las: SKIPPED
Visualizing the pre-processed point cloud
There are multiple options to visualize the pre-processed result:
-
The result is data in the LPC format which can directly be opened in LuciadLightspeed. See the LPC documentation for more information.
-
Use LuciadFusion Studio to serve the data using the OGC 3D Tiles protocol. Both LuciadLightspeed and LuciadRIA can visualize point clouds served using this protocol.
This also allows to visualize the data in third party frameworks like Cesium.
Handling non-georeferenced point clouds
Your data might not have a georeference. Data without a georeference can also be pre-processed into tiled, multi-leveled data.
To process non-georeferenced data, you must provide a Cartesian model reference with distance units on the axes.
You can do so by placing a Well-Known Text (WKT) reference file next to your point cloud data to define the Cartesian reference.
This file must have the same base file name as your point cloud data file, but use a .prj extension.
You can use this template as content for the file:
myReference.prjLOCAL_CS["Generic Cartesian 3D", LOCAL_DATUM["Unknown",0], UNIT["m",1.0], AXIS["x",EAST], AXIS["y",NORTH], AXIS["z",UP]]
It isn’t possible to combine non-georeferenced point cloud data with georeferenced point cloud data.
It isn’t possible either to combine multiple non-georeferenced point cloud files into one data set. To work around this limitation, you can create multiple data sets, with one point cloud per data set. A client then loads each pre-processed data set separately.
Non-georeferenced E57 files with multiple point clouds can’t be processed. You must either provide a reference, or split the file into separate point clouds and process each file individually.
If the data isn’t georeferenced, the client decides how to visualize the resulting data:
-
LuciadLightspeed doesn’t visualize non-georeferenced data.
-
When the data is served through the OGC 3D Tiles protocol, LuciadRIA is capable of visualizing non-georeferenced data. You can set up a Cartesian viewing space, or transform the data client-side, using a topocentric reference for example.
-
Third-party clients might also allow you to visualize non-georeferenced data when using an OGC 3D Tiles service.
Full code
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import com.luciad.format.tiled3d.ogc3dtiles.ELcdOGC3DTilesPointCloudCompressionType;
import com.luciad.fusion.pointcloud.TLfnPointCloudPreprocessor;
public class FusePointCloudTutorial {
public static void main(String[] args) throws IOException {
//Use one or more las files as input files
List<String> sourceNames = Arrays.asList("Data/LAS/terrain_with_buildings.las");
//Create the preprocessor
TLfnPointCloudPreprocessor preprocessor =
TLfnPointCloudPreprocessor.newBuilder()
.sources(sourceNames)
.targetDirectory(new File(System.getProperty("java.io.tmpdir"), "pointCloudStore").getAbsolutePath())
.name("Example Store")
.pointCloudCompression(ELcdOGC3DTilesPointCloudCompressionType.DRACO)
.build();
//Attach a listener to the preprocessor to keep track of the progress
preprocessor.addStatusListener(x -> {
TLfnPointCloudPreprocessor.Progress progress = preprocessor.getProgress();
System.out.println(String.format("Overall progress: %.2f%%", progress.getProgress() * 100));
System.out.println("Details:");
for (String source : sourceNames) {
TLfnPointCloudPreprocessor.Progress.SourceDetails sourceDetails = progress.getSourceDetails(source);
TLfnPointCloudPreprocessor.Progress.SourceDetails.Status status = sourceDetails.getStatus();
System.out.println(String.format("%s: %s", source, status));
}
System.out.println();
});
preprocessor.start();
}
}