Java bindings to use PDAL on JVM (supports PDAL >= 2.0). macOS users can experience some issues with bindings that were build against a different PDAL version, so try to use a consistent PDAL version.
It is released independently from PDAL itself as of PDAL 1.7.
See https://pdal.io/java.html for more info.
You can use pdal-native dep published into maven central in case you don't have installed JNI bindings and to avoid steps described below.
Dependency contains bindings for arm64-darwin, and x86_64-linux, other versions are not supported yet. We dropped x86_64-darwin as of the PDAL Java 2.8.0 release.
Given a {major}.{minor}.{patch} version:
{major}.{minor}- matches the PDAL version it is published for- e.g. pdal-java of version
2.6.1is suitable for all PDAL versions2.6.x(2.6.0, ...,2.6.3, etc) major =2, minor =6
- e.g. pdal-java of version
{patch}- this portion of the version corresponds to updates within pdal-java and should remain compatible with PDAL library{major}.{minor}versions- This implies that there may be multiple pdal-java releases for the same PDAL library version. All releases are compatible with the matching PDAL library
{major}.{minor}version. Thus, higher patch versions are to be preferred.
- This implies that there may be multiple pdal-java releases for the same PDAL library version. All releases are compatible with the matching PDAL library
// pdal is published to maven central, the snapshot repository can be added in addition
resolvers += Resolver.sonatypeCentralSnapshots // for snaphots
// `<latest version>` refers to the version indicated by the badge above
libraryDependencies ++= Seq(
"io.pdal" %% "pdal" % "<latest version>", // core library
"io.pdal" % "pdal-native" % "<latest version>" // jni bindings
)If you would like to use your own bindings, it is necessary to set java.library.path:
// macOS X example with manual JNI installation
// cp -f native/target/resource_managed/main/native/arm64-darwin/libpdaljni.2.8.dylib /usr/local/lib/libpdaljni.2.8.dylib
// place built binary into /usr/local/lib, and pass java.library.path to your JVM
javaOptions += "-Djava.library.path=/usr/local/lib"Scala API allows to build pipeline expressions instead of writing a raw JSON.
// `<latest version>` refers to the version indicated by the badge above
libraryDependencies ++= Seq(
"io.pdal" %% "pdal-scala" % "<latest version>", // scala core library
"io.pdal" % "pdal-native" % "<latest version>" // jni bindings
)Scala API covers PDAL 2.0.x, to use any custom DSL that is not covered by the
current Scala API you can use RawExpr type to build Pipeline Expression.
JNI bindings basic usage examples can be found here.
import io.pdal._
// pipeline definition
val json =
"""
|{
| "pipeline" : [
| {
| "filename" : "/path/to/las",
| "type" : "readers.las"
| },
| {
| "type" : "filters.crop"
| },
| {
| "filename" : "/path/to/new/las",
| "type" : "writers.las"
| }
| ]
|}
""".stripMargin
val pipeline = Pipeline(json, LogLevel.Debug5) // initialize and make it really noisy
pipeline.execute() // execute the pipeline
val metadata = pipeline.getMetadata() // retrieve metadata
val pvs = pipeline.getPointViews() // iterator over PointViews
val pv = pvs.next() // let's take the first PointView
// load all points into JVM memory
// PointCloud provides operations on PDAL points that
// are loaded in this case into JVM memory as a single Array[Byte]
val pointCloud = pv.getPointCloud()
val x = pointCloud.getDouble(0, DimType.X) // get a point with PointId = 0 and only a single dimensions
// in some cases it is not neccesary to load everything into JVM memory
// so it is possible to get only required points directly from the PointView
val y = pv.getDouble(0, DimType.Y)
// it is also possible to get access to the triangular mesh generated via PDAL
val mesh = pv.getTriangularMesh()
// the output is an Array of Triangles
// Each Triangle contains PointIds from the PDAL point table
val triangles = mesh.asArray
pv.close()
pvs.close()
pipeline.close()import io.pdal.*;
// pipeline definition
String json =
"""
{
"pipeline" : [
{
"filename" : "/path/to/las",
"type" : "readers.las"
},
{
"type" : "filters.crop"
},
{
"filename" : "/path/to/new/las",
"type" : "writers.las"
}
]
}
""";
var pipeline = new Pipeline(json, LogLevel.Debug5()); // initialize and make it really noisy
pipeline.execute(); // execute the pipeline
var metadata = pipeline.getMetadata(); // retrieve metadata
var pvs = pipeline.getPointViews(); // iterator over PointViews
var pv = pvs.next(); // let's take the first PointView
// load all points into JVM memory
// PointCloud provides operations on PDAL points that
// are loaded in this case into JVM memory as a single Array[Byte]
var pointCloud = pv.getPointCloud();
var x = pointCloud.getDouble(0, DimType.X()); // get a point with PointId = 0 and only a single dimensions
// in some cases it is not neccesary to load everything into JVM memory
// so it is possible to get only required points directly from the PointView
var y = pv.getDouble(0, DimType.Y());
// it is also possible to get access to the triangular mesh generated via PDAL
var mesh = pv.getTriangularMesh();
// the output is an Array of Triangles
// Each Triangle contains PointIds from the PDAL point table
var triangles = mesh.asArray();
pv.close();
pvs.close();
pipeline.close();import io.pdal._
import io.pdal.pipeline._
// To construct the expected json
val expected =
"""
|{
| "pipeline" : [
| {
| "filename" : "/path/to/las",
| "type" : "readers.las"
| },
| {
| "type" : "filters.crop"
| },
| {
| "filename" : "/path/to/new/las",
| "type" : "writers.las"
| }
| ]
|}
""".stripMargin
// The same, but using scala DSL
val pc = ReadLas("/path/to/las") ~ FilterCrop() ~ WriteLas("/path/to/new/las")
// The same, but using RawExpr, to support not implemented PDAL Pipeline API features
// RawExpr accepts a circe.Json type, which can be a json object of any desired complexity
val pcWithRawExpr = ReadLas("/path/to/las") ~ RawExpr(Map("type" -> "filters.crop").asJson) ~ WriteLas("/path/to/new/las")
// Create Pipelines from the constructed expressions
val pipeline = pc.toPipeline
val pipelineRaw = pcWithRawExpr.toPiplineDevelopment purposes (including binaries) compilation:
- Install PDAL (using brew / package managers (unix) / build from sources / Conda / etc)
- Install sbt (using brew / package managers (unix)) (only after
v2.4.x) - Build native libs
sbt native/nativeCompile(optionally, binaries would be built during tests run) orsbt native/publishLocalfor the built jar only - Run
sbt core/testto run PDAL tests
Only Java development purposes compilation:
- Provide
$LD_LIBRARY_PATHor$DYLD_FALLBACK_LIBRARY_PATH - If you don't want to provide global variable you can pass
-Djava.library.path=<path>into sbt:./sbt -Djava.library.path=<path> - Set
PDAL_DEPEND_ON_NATIVE=false(to disablenativeproject build) - Run
PDAL_DEPEND_ON_NATIVE=false sbtFinally the possible command to launch and build PDAL JNI bindings could be:
# Including binaries build
sbt# Java side development without binaries build
PDAL_DEPEND_ON_NATIVE=false sbt -Djava.library.path=<path>- In case of not installed as global PDAL change this line to:
set(CMAKE_CXX_FLAGS "$ENV{PDAL_LD_FLAGS} $ENV{PDAL_CXX_FLAGS} -std=c++11")In this case sbt launch would be the following:
PDAL_LD_FLAGS=`pdal-config --libs` PDAL_CXX_FLAGS=`pdal-config --includes` sbtthe quick workaround would be to replace this line to:
set(CMAKE_CXX_FLAGS "-L<path to dynamic libs> -std=c++11")-
Here the PDAL conda guide
-
Just run
brew install pdal -
Follow the official guide
- When using the Maven Central JARs on macOS, I get Library not loaded: @rpath/libpdalcpp.16.dylib error
If you are sure PDAL is correctly installed, you can run pdal-config --libs and take the path after the -L argument
and assign it to the DYLD_FALLBACK_LIBRARY_PATH:
❯ pdal-config --libs
-L/opt/homebrew/Cellar/pdal/2.6.3/lib -lpdalcpp
❯ export DYLD_FALLBACK_LIBRARY_PATH=/opt/homebrew/Cellar/pdal/2.6.3/lib
❯ java -jar my-pdal-proj.jar
All the instructions related to the local / maven release process are documented in the HOWTORELEASE.txt file.
For the local publish it is possible to use the following commands:
scripts/publish-local.sh- to publish Scala artifactsscripts/publish-local-native.sh- to compile and publish artifact with native binaries For the additional information checkout the HOWTORELEASE.txt file and the scripts directory.