Skip to content

Commit 7acf3e7

Browse files
authored
Expose PDAL Mesh API (#27)
* Expose PDAL Mesh API * Make Native Autoclosable * Add CHANGELOG.md, fix codestyle to avoid syntax deprecated in Dotty * Update PDAL-Scala reader types * DSL expressions rename & DSL implicits reorganization * Update PDAL filters up to 2.0.0
1 parent 0add31a commit 7acf3e7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+4438
-361
lines changed

.travis.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
sudo: false
22

3-
matrix:
3+
jobs:
44
include:
55
- os: linux
66
jdk: openjdk8
@@ -20,6 +20,7 @@ matrix:
2020

2121
- os: osx
2222
osx_image: xcode9.3
23+
language: scala
2324
scala:
2425
- 2.13.1
2526
compiler:
@@ -31,6 +32,7 @@ matrix:
3132

3233
- os: osx
3334
osx_image: xcode9.3
35+
language: scala
3436
scala:
3537
- 2.12.10
3638
compiler:

CHANGELOG.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# Changelog
2+
All notable changes to this project will be documented in this file.
3+
4+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6+
7+
## [Unreleased]
8+
9+
## [2.1.2] - 2020-03-02
10+
### Added
11+
- Expose PDAL Mesh API [#27](https://github.com/PDAL/java/pull/27)
12+
- [CHANGELOG](/CHANGELOG.md)
13+
14+
### Changed
15+
- **Breaking change** // Rename Scala DSL case classes [#28](https://github.com/PDAL/java/issues/28)
16+
- **Breaking change** // Renamed dispose method to close [#27](https://github.com/PDAL/java/pull/27)
17+
- Update Scala DSL up to PDAL 2.0 [#29](https://github.com/PDAL/java/issues/29)
18+
19+
## [2.0.0] - 2020-01-14
20+
### Changed
21+
- PDAL 2.0 compatible release.
22+
- Added Scala 2.13 support.
23+
24+
## [1.9.0] - 2019-05-15
25+
### Changed
26+
- Release process improvements.
27+
28+
## [1.8.6] - 2019-04-26
29+
### Changed
30+
- Release process improvements.
31+
32+
## [1.8.5] - 2019-04-15
33+
### Changed
34+
- PDAL JNI Bindings thread safety [#19](https://github.com/PDAL/java/issues/19)
35+
36+
### Fixed
37+
- PythonFilter gives invalid syntax [#9](https://github.com/PDAL/java/issues/9)
38+
- Option in filter.Python seems to be misspelled [#8](https://github.com/PDAL/java/issues/8)
39+
40+
## [1.8.4] - 2019-04-09
41+
### Changed
42+
- Make Exceptions Handling better [#17](https://github.com/PDAL/java/pull/17)
43+
44+
## [1.8.3] - 2019-04-09
45+
### Fixed
46+
- CSV files read issues [#15](https://github.com/PDAL/java/issues/15)
47+
48+
## [1.8.2] - 2019-03-27
49+
### Fixed
50+
- Fix dimName calls to be better, otherwise CSV reads wont work [#14](https://github.com/PDAL/java/pull/14)
51+
52+
## [1.8.1] - 2019-03-25
53+
### Changed
54+
- Update JTS to make it GeoTrellis compatible [#13](https://github.com/PDAL/java/pull/13)
55+
56+
## [1.7.0-RC4] - 2019-01-14
57+
### Changed
58+
- Scala version update up to 2.12.6.
59+
- Update dependencies and base PDAL version.
60+
- Release process improvements.
61+
62+
### Fixed
63+
- Fix matlab reader ReaderType [#10](https://github.com/PDAL/java/pull/10)
64+
- Fix typo in GdalWrite [#11](https://github.com/PDAL/java/pull/11)
65+
66+
## [1.7.0-RC3] - 2018-04-16
67+
### Changed
68+
- Release process improvements.
69+
70+
## [1.7.0-RC2] - 2018-04-15
71+
### Added
72+
- An [examples](https://github.com/PDAL/java/tree/1.7.0-RC2/examples/pdal-jni) project.
73+
74+
### Changed
75+
- Release process improvements.
76+
77+
## [1.7.0-RC1] - 2018-04-15
78+
### Changed
79+
- Moved from the PDAL repo and established own lifecycle.
80+
81+
[Unreleased]: https://github.com/PDAL/java/compare/2.1.2...HEAD
82+
[2.1.2]: https://github.com/PDAL/java/compare/2.0.0...2.1.2
83+
[2.0.0]: https://github.com/PDAL/java/compare/1.9.0...2.0.0
84+
[1.9.0]: https://github.com/PDAL/java/compare/1.8.6...1.9.0
85+
[1.8.6]: https://github.com/PDAL/java/compare/1.8.5...1.8.6
86+
[1.8.5]: https://github.com/PDAL/java/compare/1.8.4...1.8.5
87+
[1.8.4]: https://github.com/PDAL/java/compare/1.8.3...1.8.4
88+
[1.8.3]: https://github.com/PDAL/java/compare/1.8.2...1.8.3
89+
[1.8.2]: https://github.com/PDAL/java/compare/1.8.1...1.8.2
90+
[1.8.1]: https://github.com/PDAL/java/compare/1.7.0-RC4...1.8.1
91+
[1.7.0-RC4]: https://github.com/PDAL/java/compare/1.7.0-RC3...1.7.0-RC4
92+
[1.7.0-RC3]: https://github.com/PDAL/java/compare/1.7.0-RC2...1.7.0-RC3
93+
[1.7.0-RC2]: https://github.com/PDAL/java/compare/1.7.0-RC1...1.7.0-RC2
94+
[1.7.0-RC1]: https://github.com/PDAL/java/compare/1.7.0-RC1...1.7.0-RC1

README.md

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,16 @@ resolvers ++= Seq(
1818
)
1919

2020
libraryDependencies ++= Seq(
21-
"io.pdal" %% "pdal" % "2.0.0", // core library
22-
"io.pdal" % "pdal-native" % "2.0.0" // jni bindings
21+
"io.pdal" %% "pdal" % "2.1.2", // core library
22+
"io.pdal" % "pdal-native" % "2.1.2" // jni bindings
2323
)
2424
```
2525

26-
It's required to have native JNI binary in `java.library.path`:
26+
If you would like to use your own bindings, it is necessary to set `java.library.path`:
2727

2828
```scala
2929
// Mac OS X example with manual JNI installation
30-
// cp -f native/target/resource_managed/main/native/x86_64-darwin/libpdaljni.2.0.dylib /usr/local/lib/libpdaljni.2.0.dylib
30+
// cp -f native/target/resource_managed/main/native/x86_64-darwin/libpdaljni.2.1.dylib /usr/local/lib/libpdaljni.2.1.dylib
3131
// place built binary into /usr/local/lib, and pass java.library.path to your JVM
3232
javaOptions += "-Djava.library.path=/usr/local/lib"
3333
```
@@ -37,18 +37,17 @@ Dependency contains bindings for `x86_64-darwin` and `x86_64-linux`, other versi
3737

3838
## PDAL-Scala
3939

40-
Scala API to build pipeline expressions instead of writing a raw JSON.
40+
Scala API allows to build pipeline expressions instead of writing a raw JSON.
4141

4242
```scala
4343
libraryDependencies ++= Seq(
44-
"io.pdal" %% "pdal-scala" % "2.0.0", // scala core library
45-
"io.pdal" % "pdal-native" % "2.0.0" // jni bindings
44+
"io.pdal" %% "pdal-scala" % "2.1.2", // scala core library
45+
"io.pdal" % "pdal-native" % "2.1.2" // jni bindings
4646
)
4747
```
4848

49-
Scala API covers PDAL 1.8.x but is compatible with PDAL >= 1.4.x, to use any custom DSL
50-
that is not covered by the current Scala API you can use `RawExpr` type to build `Pipeline
51-
Expression`.
49+
Scala API covers PDAL 2.0.x, to use any custom DSL that is not covered by the
50+
current Scala API you can use `RawExpr` type to build `Pipeline Expression`.
5251

5352
### Code examples
5453

@@ -74,11 +73,11 @@ val expected =
7473
""".stripMargin
7574

7675
// The same, but using scala DSL
77-
val pc: PipelineConstructor = LasRead("/path/to/las") ~ CropFilter() ~ LasWrite("/path/to/new/las")
76+
val pc = ReadLas("/path/to/las") ~ FilterCrop() ~ WriteLas("/path/to/new/las")
7877

7978
// The same, but using RawExpr, to support not implemented PDAL Pipeline API features
8079
// RawExpr accepts a circe.Json type, which can be a json object of any desired complexity
81-
val pcWithRawExpr = LasRead("/path/to/las") ~ RawExpr(Map("type" -> "filters.crop").asJson) ~ LasWrite("/path/to/new/las")
80+
val pcWithRawExpr = ReadLas("/path/to/las") ~ RawExpr(Map("type" -> "filters.crop").asJson) ~ WriteLas("/path/to/new/las")
8281
```
8382

8483
### Demo project example
@@ -87,12 +86,12 @@ JNI bindings basic usage examples can be found [here](./examples).
8786

8887
## How to compile
8988

90-
Development purposes (including binaries):
89+
Development purposes (including binaries) compilation:
9190
1. Install PDAL (using brew / package managers (unix) / build from sources / etc)
9291
2. Build native libs `./sbt native/nativeCompile` (optionally, binaries would be built during tests run)
9392
3. Run `./sbt core/test` to run PDAL tests
9493

95-
Only Java development purposes:
94+
Only Java development purposes compilation:
9695
1. Provide `$LD_LIBRARY_PATH` or `$DYLD_LIBRARY_PATH`
9796
2. If you don't want to provide global variable you can pass `-Djava.library.path=<path>` into sbt:
9897
`./sbt -Djava.library.path=<path>`

build.sbt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name := "pdal-jni"
22

33
lazy val commonSettings = Seq(
4-
version := "2.0.0" + Environment.versionSuffix,
4+
version := "2.1.2" + Environment.versionSuffix,
55
scalaVersion := "2.13.1",
66
crossScalaVersions := Seq("2.13.1", "2.12.10", "2.11.12"),
77
organization := "io.pdal",
@@ -57,6 +57,8 @@ lazy val root = (project in file("."))
5757

5858
lazy val `core-scala` = project
5959
.settings(commonSettings: _*)
60+
.settings(Dependencies.macroSettings)
61+
.settings(Dependencies.licenseSettings)
6062
.settings(name := "pdal-scala")
6163
.settings(javah / target := (native / nativeCompile / sourceDirectory).value / "include")
6264
.settings(libraryDependencies ++= Seq(
@@ -67,9 +69,8 @@ lazy val `core-scala` = project
6769
Dependencies.jtsCore,
6870
Dependencies.scalaTest % Test
6971
))
70-
.settings(headerLicense := Some(HeaderLicense.ALv2("2017", "Azavea")))
71-
.settings(licenses := Seq("Apache-2.0" -> url("https://www.apache.org/licenses/LICENSE-2.0.html")))
7272
.dependsOn(core)
73+
.dependsOn(Environment.dependOnNative(native % Runtime): _*)
7374

7475
lazy val core = project
7576
.settings(commonSettings: _*)

core-scala/src/main/scala/io/pdal/pipeline/ExprType.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@
1616

1717
package io.pdal.pipeline
1818

19+
import io.circe.{Decoder, Encoder}
20+
import io.circe.syntax._
21+
import cats.syntax.either._
22+
1923
import scala.util.Try
2024

2125
trait ExprType {
@@ -26,6 +30,11 @@ trait ExprType {
2630
}
2731

2832
object ExprType {
33+
implicit def exprTypeEncoder[T <: ExprType]: Encoder[T] = Encoder.instance { _.toString.asJson }
34+
implicit def exprTypeDecoder[T <: ExprType]: Decoder[T] = Decoder.decodeString.emap { str =>
35+
Either.catchNonFatal(ExprType.fromName(str).asInstanceOf[T]).leftMap(_ => "ExprType")
36+
}
37+
2938
def fromName(name: String): ExprType =
3039
Try(FilterTypes.fromName(name))
3140
.getOrElse(Try(ReaderTypes.fromName(name))

core-scala/src/main/scala/io/pdal/pipeline/FilterTypes.scala

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,24 +20,30 @@ sealed trait FilterType extends ExprType { val `type` = "filters" }
2020

2121
object FilterTypes {
2222
case object approximatecoplanar extends FilterType
23+
case object assign extends FilterType
2324
case object chipper extends FilterType
2425
case object cluster extends FilterType
2526
case object colorinterp extends FilterType
2627
case object colorization extends FilterType
2728
case object computerange extends FilterType
29+
case object covariancefeatures extends FilterType
2830
case object cpd extends FilterType
2931
case object crop extends FilterType
3032
case object decimation extends FilterType
33+
case object dem extends FilterType
34+
case object delaunay extends FilterType
3135
case object divider extends FilterType
3236
case object eigenvalues extends FilterType
3337
case object estimaterank extends FilterType
38+
case object elm extends FilterType
3439
case object ferry extends FilterType
3540
case object greedyprojection extends FilterType
3641
case object gridprojection extends FilterType
3742
case object groupby extends FilterType
3843
case object hag extends FilterType
3944
case object head extends FilterType
4045
case object hexbin extends FilterType
46+
case object info extends FilterType
4147
case object icp extends FilterType
4248
case object iqr extends FilterType
4349
case object kdistance extends FilterType
@@ -49,16 +55,21 @@ object FilterTypes {
4955
case object mongus extends FilterType
5056
case object mortonorder extends FilterType
5157
case object movingleastsquares extends FilterType
58+
case object miniball extends FilterType
59+
case object neighborclassifier extends FilterType
60+
case object nndistance extends FilterType
5261
case object normal extends FilterType
5362
case object overlay extends FilterType
5463
case object outlier extends FilterType
5564
case object pclblock extends FilterType
65+
case object planefit extends FilterType
5666
case object pmf extends FilterType
5767
case object poisson extends FilterType
5868
case object python extends FilterType
5969
case object radialdensity extends FilterType
6070
case object range extends FilterType
6171
case object randomize extends FilterType
72+
case object reciprocity extends FilterType
6273
case object reprojection extends FilterType
6374
case object sample extends FilterType
6475
case object smrf extends FilterType
@@ -72,12 +83,12 @@ object FilterTypes {
7283
case object voxelgrid extends FilterType
7384

7485
lazy val all = List(
75-
approximatecoplanar, chipper, cluster, colorinterp, colorization, computerange, crop,
76-
cpd, decimation, divider, eigenvalues, estimaterank, ferry, greedyprojection, gridprojection, groupby,
77-
hag, head, hexbin, icp, iqr, kdistance, locate, lof, mad, matlab, merge, mongus, mortonorder, movingleastsquares,
78-
normal, outlier, overlay, pclblock, pmf, poisson, python, radialdensity, randomize, range, reprojection,
79-
sample, smrf, sort, splitter, stats, transformation, voxelcenternearestneighbor, voxelcentroidnearestneighbor,
80-
voxelgrid
86+
approximatecoplanar, assign, chipper, cluster, colorinterp, colorization, computerange, covariancefeatures, crop,
87+
cpd, decimation, dem, delaunay, divider, eigenvalues, estimaterank, elm, ferry, greedyprojection, gridprojection, groupby,
88+
hag, head, hexbin, info, icp, iqr, kdistance, locate, lof, mad, matlab, merge, mongus, mortonorder, movingleastsquares,
89+
miniball, neighborclassifier, nndistance, normal, outlier, overlay, pclblock, planefit, pmf, poisson, python, radialdensity,
90+
randomize, reciprocity, range, reprojection, sample, smrf, sort, splitter, stats, transformation, voxelcenternearestneighbor,
91+
voxelcentroidnearestneighbor, voxelgrid
8192
)
8293

8394
def fromName(name: String): FilterType =

core-scala/src/main/scala/io/pdal/pipeline/Implicits.scala

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,10 @@ package io.pdal.pipeline
1919
import io.pdal.PointCloud
2020
import org.locationtech.jts.geom.Coordinate
2121

22-
object Implicits extends Implicits
22+
object Implicits extends Implicits with Serializable
2323

24-
trait Implicits extends Serializable {
24+
trait Implicits {
2525
implicit class withPointCloudMethods(pointCloud: PointCloud) {
26-
def getCoordinate(i: Int) =
27-
new Coordinate(pointCloud.getX(i), pointCloud.getY(i), pointCloud.getZ(i))
26+
def getCoordinate(i: Int) = new Coordinate(pointCloud.getX(i), pointCloud.getY(i), pointCloud.getZ(i))
2827
}
2928
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* Copyright 2020 Azavea
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.pdal.pipeline
18+
19+
import io.pdal.Pipeline
20+
21+
import io.circe.{Decoder, Encoder, Json}
22+
import io.circe.syntax._
23+
24+
case class PipelineConstructor(list: List[PipelineExpr]) {
25+
def ~(e: PipelineExpr): PipelineConstructor =
26+
e match {
27+
case ENil => this
28+
case _ => PipelineConstructor(list :+ e)
29+
}
30+
def ~(e: Option[PipelineExpr]): PipelineConstructor = e.fold(this)(this ~ _)
31+
def map[B](f: PipelineExpr => B): List[B] = list.map(f)
32+
def toPipeline: Pipeline = Pipeline(this.asJson.noSpaces)
33+
}
34+
35+
object PipelineConstructor {
36+
implicit val pipelineConstructorEncoder: Encoder[PipelineConstructor] = Encoder.instance { constructor =>
37+
Json.obj(
38+
"pipeline" -> constructor.list.flatMap {
39+
_.list.flatMap {
40+
case RawExpr(json) => json.asObject
41+
case expr => expr.asJson.asObject
42+
}.map {
43+
_.remove("class_type") // remove type
44+
.filter { case (_, value) => !value.isNull } // cleanup options
45+
}
46+
}.asJson
47+
)
48+
}
49+
implicit val pipelineConstructorDecoder: Decoder[PipelineConstructor] = Decoder.instance {
50+
_.downField("pipeline").as[PipelineConstructor]
51+
}
52+
53+
implicit def pipelineConstructorToJson(expr: PipelineConstructor): Json = expr.asJson
54+
implicit def pipelineConstructorToString(expr: PipelineConstructor): String = expr.asJson.noSpaces
55+
}

0 commit comments

Comments
 (0)