Java¶
PDAL provides Java bindings to use PDAL on JVM. It is released independently from PDAL itself as of PDAL 1.7. Native binaries are prebuilt for Linux and MacOS and delivered in a jar, so there is no need in building PDAL with a special flag or building JNI binaries manually.
The project consists of the following modules:
- `pdal-native`_ - with packed OS specific libraries to link PDAL to JNI proxy classes. Dependency contains bindings for `x86_64-darwin`_ and `x86_64-linux`_, other versions are not supported yet.
- `pdal`_ - with the core bindings functionality.
- `pdal-scala`_ - a Scala API package that simplifies PDAL Pipeline construction.
Versions¶
PDAL JNI major version usually follows PDAL versioning i.e. `pdal-java 1.8.x`_ was built and tested against `PDAL 1.8.x`_ and `pdal-java 2.1.x`_ against `PDAL 2.x.x`_.
Using PDAL Java bindings¶
PDAL provides JNI bindings that gives users access to executing pipeline instantiations and capturing the results in Java interfaces. This mode of operation is useful if you are looking to have PDAL simply act as your data format and processing handler.
Users are expected to construct their own PDAL pipeline, execute it, and retrieve points into Java memory:
import io.pdal._
val json =
"""
|{
| "pipeline":[
| {
| "filename":"1.2-with-color.las",
| "spatialreference":"EPSG:2993"
| },
| {
| "type": "filters.reprojection",
| "out_srs": "EPSG:3857"
| },
| {
| "type": "filters.delaunay"
| }
| ]
|}
""".stripMargin
val pipeline = Pipeline(json)
pipeline.validate() // check if our JSON and options were good
pipeline.setLogLevel(8) // make it really noisy
pipeline.execute() // execute the pipeline
val metadata: String = pipeline.getMetadata() // retrieve metadata
val pvs: PointViewIterator = pipeline.getPointViews() // iterator over PointViews
val pv: PointView = 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: PointCloud = pv.getPointCloud()
val x: Double = 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: Double = pv.getDouble(0, DimType.Y)
// it is also possible to get access to the triangular mesh generated via PDAL
val mesh: TriangularMesh = pv.getTriangularMesh()
// the output is an Array of Triangles
// Each Triangle contains PointIds from the PDAL point table
val triangles: Array[Triangle] = mesh.asArray
pv.close()
pipeline.close()
Using PDAL Scala¶
PDAL Scala project introduces a DSL to simplify PDAL Pipeline construction (this is the same pipeline from the section above):
import io.pdal._
import io.pdal.pipeline._
val expression =
ReadLas("1.2-with-color.las", spatialreference = Some("EPSG:2993")) ~
FilterReprojection("EPSG:3857") ~
FilterDelaunay()
val pipeline = expression.toPipeline
pipeline.validate() // check if our JSON and options were good
pipeline.setLogLevel(8) // make it really noisy
pipeline.execute() // execute the pipeline
val metadata: String = pipeline.getMetadata() // retrieve metadata
val pvs: PointViewIterator = pipeline.getPointViews() // iterator over PointViews
val pv: PointView = 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: PointCloud = pv.getPointCloud()
val x: Double = 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: Double = pv.getDouble(0, DimType.Y)
// it is also possible to get access to the triangular mesh generated via PDAL
val mesh: TriangularMesh = pv.getTriangularMesh()
// the output is an Array of Triangles
// Each Triangle contains PointIds from the PDAL point table
val triangles: Array[Triangle] = mesh.asArray
pv.close()
pipeline.close()
It covers PDAL 2.0.x, but to use any custom DSL that is not covered by the current Scala API you can use `RawExpr`_ type to build `Pipeline Expression`_:
import io.pdal._
import io.pdal.pipeline._
import io.circe.syntax._
val pipelineWithRawExpr =
ReadLas("1.2-with-color.las") ~
RawExpr(Map("type" -> "filters.crop").asJson) ~
WriteLas("1.2-with-color-out.las")
Installation¶
PDAL Java artifacts are cross published for `Scala 2.13`_, `2.12`_ and `2.11`_. However, if it is not required, a separate artifact that has no Scala specific artifact postfix is published as well.
// pdal is published to maven central, but you can use following repos in addition
resolvers ++= Seq(
Resolver.sonatypeRepo("releases"),
Resolver.sonatypeRepo("snapshots") // for snaphots
)
libraryDependencies ++= Seq(
"io.pdal" %% "pdal" % "x.x.x", // core library
"io.pdal" % "pdal-native" % "x.x.x", // jni binaries
"io.pdal" %% "pdal-scala" % "x.x.x" // if scala core library (if required)
)
There is also an example SBT PDAL Demo project in the bindings repository, that can be used for a quick start.
Compilation¶
- Development purposes (including binaries) compilation:
- Install PDAL (using brew / package managers (unix) / build from sources / etc)
- Build native libs `./sbt native/nativeCompile`_ (optionally, binaries would be built during tests run)
- Run `./sbt core/test`_ to run PDAL tests
- Only Java development purposes compilation:
- Provide `$LD_LIBRARY_PATH`_ or `$DYLD_LIBRARY_PATH`_
- If you don’t want to provide global variable you can pass `-Djava.library.path=<path>`_ into sbt:
- Set `PDAL_DEPEND_ON_NATIVE=false`_ (to disable native project build)
- Run `PDAL_DEPEND_ON_NATIVE=false ./sbt`_
If you would like to use your own bindings binary, it is necessary to set java.library.path:
// Mac OS X example with manual JNI installation
// cp -f native/target/resource_managed/main/native/x86_64-darwin/libpdaljni.2.1.dylib /usr/local/lib/libpdaljni.2.1.dylib
// place built binary into /usr/local/lib, and pass java.library.path to your JVM
javaOptions += "-Djava.library.path=/usr/local/lib"
You can use pdal-native dep in case you don’t have installed JNI bindings and to avoid steps described above. Dependency contains bindings for `x86_64-darwin`_ and `x86_64-linux`_, other versions are not supported yet.