diff --git a/.travis.yml b/.travis.yml index 9fce208..3ce6ca1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ sudo: false -matrix: +jobs: include: - os: linux jdk: openjdk8 @@ -20,6 +20,7 @@ matrix: - os: osx osx_image: xcode9.3 + language: scala scala: - 2.13.1 compiler: @@ -31,6 +32,7 @@ matrix: - os: osx osx_image: xcode9.3 + language: scala scala: - 2.12.10 compiler: diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..ddf5bb9 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,94 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +## [2.1.2] - 2020-03-02 +### Added +- Expose PDAL Mesh API [#27](https://github.com/PDAL/java/pull/27) +- [CHANGELOG](/CHANGELOG.md) + +### Changed +- **Breaking change** // Rename Scala DSL case classes [#28](https://github.com/PDAL/java/issues/28) +- **Breaking change** // Renamed dispose method to close [#27](https://github.com/PDAL/java/pull/27) +- Update Scala DSL up to PDAL 2.0 [#29](https://github.com/PDAL/java/issues/29) + +## [2.0.0] - 2020-01-14 +### Changed +- PDAL 2.0 compatible release. +- Added Scala 2.13 support. + +## [1.9.0] - 2019-05-15 +### Changed +- Release process improvements. + +## [1.8.6] - 2019-04-26 +### Changed +- Release process improvements. + +## [1.8.5] - 2019-04-15 +### Changed +- PDAL JNI Bindings thread safety [#19](https://github.com/PDAL/java/issues/19) + +### Fixed +- PythonFilter gives invalid syntax [#9](https://github.com/PDAL/java/issues/9) +- Option in filter.Python seems to be misspelled [#8](https://github.com/PDAL/java/issues/8) + +## [1.8.4] - 2019-04-09 +### Changed +- Make Exceptions Handling better [#17](https://github.com/PDAL/java/pull/17) + +## [1.8.3] - 2019-04-09 +### Fixed +- CSV files read issues [#15](https://github.com/PDAL/java/issues/15) + +## [1.8.2] - 2019-03-27 +### Fixed +- Fix dimName calls to be better, otherwise CSV reads wont work [#14](https://github.com/PDAL/java/pull/14) + +## [1.8.1] - 2019-03-25 +### Changed +- Update JTS to make it GeoTrellis compatible [#13](https://github.com/PDAL/java/pull/13) + +## [1.7.0-RC4] - 2019-01-14 +### Changed +- Scala version update up to 2.12.6. +- Update dependencies and base PDAL version. +- Release process improvements. + +### Fixed +- Fix matlab reader ReaderType [#10](https://github.com/PDAL/java/pull/10) +- Fix typo in GdalWrite [#11](https://github.com/PDAL/java/pull/11) + +## [1.7.0-RC3] - 2018-04-16 +### Changed +- Release process improvements. + +## [1.7.0-RC2] - 2018-04-15 +### Added +- An [examples](https://github.com/PDAL/java/tree/1.7.0-RC2/examples/pdal-jni) project. + +### Changed +- Release process improvements. + +## [1.7.0-RC1] - 2018-04-15 +### Changed +- Moved from the PDAL repo and established own lifecycle. + +[Unreleased]: https://github.com/PDAL/java/compare/2.1.2...HEAD +[2.1.2]: https://github.com/PDAL/java/compare/2.0.0...2.1.2 +[2.0.0]: https://github.com/PDAL/java/compare/1.9.0...2.0.0 +[1.9.0]: https://github.com/PDAL/java/compare/1.8.6...1.9.0 +[1.8.6]: https://github.com/PDAL/java/compare/1.8.5...1.8.6 +[1.8.5]: https://github.com/PDAL/java/compare/1.8.4...1.8.5 +[1.8.4]: https://github.com/PDAL/java/compare/1.8.3...1.8.4 +[1.8.3]: https://github.com/PDAL/java/compare/1.8.2...1.8.3 +[1.8.2]: https://github.com/PDAL/java/compare/1.8.1...1.8.2 +[1.8.1]: https://github.com/PDAL/java/compare/1.7.0-RC4...1.8.1 +[1.7.0-RC4]: https://github.com/PDAL/java/compare/1.7.0-RC3...1.7.0-RC4 +[1.7.0-RC3]: https://github.com/PDAL/java/compare/1.7.0-RC2...1.7.0-RC3 +[1.7.0-RC2]: https://github.com/PDAL/java/compare/1.7.0-RC1...1.7.0-RC2 +[1.7.0-RC1]: https://github.com/PDAL/java/compare/1.7.0-RC1...1.7.0-RC1 diff --git a/README.md b/README.md index 3a819e0..06976d5 100644 --- a/README.md +++ b/README.md @@ -18,16 +18,16 @@ resolvers ++= Seq( ) libraryDependencies ++= Seq( - "io.pdal" %% "pdal" % "2.0.0", // core library - "io.pdal" % "pdal-native" % "2.0.0" // jni bindings + "io.pdal" %% "pdal" % "2.1.2", // core library + "io.pdal" % "pdal-native" % "2.1.2" // jni bindings ) ``` -It's required to have native JNI binary in `java.library.path`: +If you would like to use your own bindings, it is necessary to set `java.library.path`: ```scala // Mac OS X example with manual JNI installation -// cp -f native/target/resource_managed/main/native/x86_64-darwin/libpdaljni.2.0.dylib /usr/local/lib/libpdaljni.2.0.dylib +// 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" ``` @@ -37,18 +37,17 @@ Dependency contains bindings for `x86_64-darwin` and `x86_64-linux`, other versi ## PDAL-Scala -Scala API to build pipeline expressions instead of writing a raw JSON. +Scala API allows to build pipeline expressions instead of writing a raw JSON. ```scala libraryDependencies ++= Seq( - "io.pdal" %% "pdal-scala" % "2.0.0", // scala core library - "io.pdal" % "pdal-native" % "2.0.0" // jni bindings + "io.pdal" %% "pdal-scala" % "2.1.2", // scala core library + "io.pdal" % "pdal-native" % "2.1.2" // jni bindings ) ``` -Scala API covers PDAL 1.8.x but is compatible with PDAL >= 1.4.x, to use any custom DSL -that is not covered by the current Scala API you can use `RawExpr` type to build `Pipeline -Expression`. +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`. ### Code examples @@ -74,11 +73,11 @@ val expected = """.stripMargin // The same, but using scala DSL -val pc: PipelineConstructor = LasRead("/path/to/las") ~ CropFilter() ~ LasWrite("/path/to/new/las") +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 = LasRead("/path/to/las") ~ RawExpr(Map("type" -> "filters.crop").asJson) ~ LasWrite("/path/to/new/las") +val pcWithRawExpr = ReadLas("/path/to/las") ~ RawExpr(Map("type" -> "filters.crop").asJson) ~ WriteLas("/path/to/new/las") ``` ### Demo project example @@ -87,12 +86,12 @@ JNI bindings basic usage examples can be found [here](./examples). ## How to compile -Development purposes (including binaries): +Development purposes (including binaries) compilation: 1. Install PDAL (using brew / package managers (unix) / build from sources / etc) 2. Build native libs `./sbt native/nativeCompile` (optionally, binaries would be built during tests run) 3. Run `./sbt core/test` to run PDAL tests -Only Java development purposes: +Only Java development purposes compilation: 1. Provide `$LD_LIBRARY_PATH` or `$DYLD_LIBRARY_PATH` 2. If you don't want to provide global variable you can pass `-Djava.library.path=` into sbt: `./sbt -Djava.library.path=` diff --git a/build.sbt b/build.sbt index a28d14e..e12965d 100644 --- a/build.sbt +++ b/build.sbt @@ -1,7 +1,7 @@ name := "pdal-jni" lazy val commonSettings = Seq( - version := "2.0.0" + Environment.versionSuffix, + version := "2.1.2" + Environment.versionSuffix, scalaVersion := "2.13.1", crossScalaVersions := Seq("2.13.1", "2.12.10", "2.11.12"), organization := "io.pdal", @@ -57,6 +57,8 @@ lazy val root = (project in file(".")) lazy val `core-scala` = project .settings(commonSettings: _*) + .settings(Dependencies.macroSettings) + .settings(Dependencies.licenseSettings) .settings(name := "pdal-scala") .settings(javah / target := (native / nativeCompile / sourceDirectory).value / "include") .settings(libraryDependencies ++= Seq( @@ -67,9 +69,8 @@ lazy val `core-scala` = project Dependencies.jtsCore, Dependencies.scalaTest % Test )) - .settings(headerLicense := Some(HeaderLicense.ALv2("2017", "Azavea"))) - .settings(licenses := Seq("Apache-2.0" -> url("https://www.apache.org/licenses/LICENSE-2.0.html"))) .dependsOn(core) + .dependsOn(Environment.dependOnNative(native % Runtime): _*) lazy val core = project .settings(commonSettings: _*) diff --git a/core-scala/src/main/scala/io/pdal/pipeline/ExprType.scala b/core-scala/src/main/scala/io/pdal/pipeline/ExprType.scala index 74d3684..9dd5bcf 100644 --- a/core-scala/src/main/scala/io/pdal/pipeline/ExprType.scala +++ b/core-scala/src/main/scala/io/pdal/pipeline/ExprType.scala @@ -16,6 +16,10 @@ package io.pdal.pipeline +import io.circe.{Decoder, Encoder} +import io.circe.syntax._ +import cats.syntax.either._ + import scala.util.Try trait ExprType { @@ -26,6 +30,11 @@ trait ExprType { } object ExprType { + implicit def exprTypeEncoder[T <: ExprType]: Encoder[T] = Encoder.instance { _.toString.asJson } + implicit def exprTypeDecoder[T <: ExprType]: Decoder[T] = Decoder.decodeString.emap { str => + Either.catchNonFatal(ExprType.fromName(str).asInstanceOf[T]).leftMap(_ => "ExprType") + } + def fromName(name: String): ExprType = Try(FilterTypes.fromName(name)) .getOrElse(Try(ReaderTypes.fromName(name)) diff --git a/core-scala/src/main/scala/io/pdal/pipeline/FilterTypes.scala b/core-scala/src/main/scala/io/pdal/pipeline/FilterTypes.scala index 7c3b401..bef01d7 100644 --- a/core-scala/src/main/scala/io/pdal/pipeline/FilterTypes.scala +++ b/core-scala/src/main/scala/io/pdal/pipeline/FilterTypes.scala @@ -20,17 +20,22 @@ sealed trait FilterType extends ExprType { val `type` = "filters" } object FilterTypes { case object approximatecoplanar extends FilterType + case object assign extends FilterType case object chipper extends FilterType case object cluster extends FilterType case object colorinterp extends FilterType case object colorization extends FilterType case object computerange extends FilterType + case object covariancefeatures extends FilterType case object cpd extends FilterType case object crop extends FilterType case object decimation extends FilterType + case object dem extends FilterType + case object delaunay extends FilterType case object divider extends FilterType case object eigenvalues extends FilterType case object estimaterank extends FilterType + case object elm extends FilterType case object ferry extends FilterType case object greedyprojection extends FilterType case object gridprojection extends FilterType @@ -38,6 +43,7 @@ object FilterTypes { case object hag extends FilterType case object head extends FilterType case object hexbin extends FilterType + case object info extends FilterType case object icp extends FilterType case object iqr extends FilterType case object kdistance extends FilterType @@ -49,16 +55,21 @@ object FilterTypes { case object mongus extends FilterType case object mortonorder extends FilterType case object movingleastsquares extends FilterType + case object miniball extends FilterType + case object neighborclassifier extends FilterType + case object nndistance extends FilterType case object normal extends FilterType case object overlay extends FilterType case object outlier extends FilterType case object pclblock extends FilterType + case object planefit extends FilterType case object pmf extends FilterType case object poisson extends FilterType case object python extends FilterType case object radialdensity extends FilterType case object range extends FilterType case object randomize extends FilterType + case object reciprocity extends FilterType case object reprojection extends FilterType case object sample extends FilterType case object smrf extends FilterType @@ -72,12 +83,12 @@ object FilterTypes { case object voxelgrid extends FilterType lazy val all = List( - approximatecoplanar, chipper, cluster, colorinterp, colorization, computerange, crop, - cpd, decimation, divider, eigenvalues, estimaterank, ferry, greedyprojection, gridprojection, groupby, - hag, head, hexbin, icp, iqr, kdistance, locate, lof, mad, matlab, merge, mongus, mortonorder, movingleastsquares, - normal, outlier, overlay, pclblock, pmf, poisson, python, radialdensity, randomize, range, reprojection, - sample, smrf, sort, splitter, stats, transformation, voxelcenternearestneighbor, voxelcentroidnearestneighbor, - voxelgrid + approximatecoplanar, assign, chipper, cluster, colorinterp, colorization, computerange, covariancefeatures, crop, + cpd, decimation, dem, delaunay, divider, eigenvalues, estimaterank, elm, ferry, greedyprojection, gridprojection, groupby, + hag, head, hexbin, info, icp, iqr, kdistance, locate, lof, mad, matlab, merge, mongus, mortonorder, movingleastsquares, + miniball, neighborclassifier, nndistance, normal, outlier, overlay, pclblock, planefit, pmf, poisson, python, radialdensity, + randomize, reciprocity, range, reprojection, sample, smrf, sort, splitter, stats, transformation, voxelcenternearestneighbor, + voxelcentroidnearestneighbor, voxelgrid ) def fromName(name: String): FilterType = diff --git a/core-scala/src/main/scala/io/pdal/pipeline/Implicits.scala b/core-scala/src/main/scala/io/pdal/pipeline/Implicits.scala index 1802dab..ebc3617 100644 --- a/core-scala/src/main/scala/io/pdal/pipeline/Implicits.scala +++ b/core-scala/src/main/scala/io/pdal/pipeline/Implicits.scala @@ -19,11 +19,10 @@ package io.pdal.pipeline import io.pdal.PointCloud import org.locationtech.jts.geom.Coordinate -object Implicits extends Implicits +object Implicits extends Implicits with Serializable -trait Implicits extends Serializable { +trait Implicits { implicit class withPointCloudMethods(pointCloud: PointCloud) { - def getCoordinate(i: Int) = - new Coordinate(pointCloud.getX(i), pointCloud.getY(i), pointCloud.getZ(i)) + def getCoordinate(i: Int) = new Coordinate(pointCloud.getX(i), pointCloud.getY(i), pointCloud.getZ(i)) } } diff --git a/core-scala/src/main/scala/io/pdal/pipeline/PipelineConstructor.scala b/core-scala/src/main/scala/io/pdal/pipeline/PipelineConstructor.scala new file mode 100644 index 0000000..e19bca7 --- /dev/null +++ b/core-scala/src/main/scala/io/pdal/pipeline/PipelineConstructor.scala @@ -0,0 +1,55 @@ +/* + * Copyright 2020 Azavea + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.pdal.pipeline + +import io.pdal.Pipeline + +import io.circe.{Decoder, Encoder, Json} +import io.circe.syntax._ + +case class PipelineConstructor(list: List[PipelineExpr]) { + def ~(e: PipelineExpr): PipelineConstructor = + e match { + case ENil => this + case _ => PipelineConstructor(list :+ e) + } + def ~(e: Option[PipelineExpr]): PipelineConstructor = e.fold(this)(this ~ _) + def map[B](f: PipelineExpr => B): List[B] = list.map(f) + def toPipeline: Pipeline = Pipeline(this.asJson.noSpaces) +} + +object PipelineConstructor { + implicit val pipelineConstructorEncoder: Encoder[PipelineConstructor] = Encoder.instance { constructor => + Json.obj( + "pipeline" -> constructor.list.flatMap { + _.list.flatMap { + case RawExpr(json) => json.asObject + case expr => expr.asJson.asObject + }.map { + _.remove("class_type") // remove type + .filter { case (_, value) => !value.isNull } // cleanup options + } + }.asJson + ) + } + implicit val pipelineConstructorDecoder: Decoder[PipelineConstructor] = Decoder.instance { + _.downField("pipeline").as[PipelineConstructor] + } + + implicit def pipelineConstructorToJson(expr: PipelineConstructor): Json = expr.asJson + implicit def pipelineConstructorToString(expr: PipelineConstructor): String = expr.asJson.noSpaces +} diff --git a/core-scala/src/main/scala/io/pdal/pipeline/PipelineExpressions.scala b/core-scala/src/main/scala/io/pdal/pipeline/PipelineExpressions.scala index 6e699f6..0b019fd 100644 --- a/core-scala/src/main/scala/io/pdal/pipeline/PipelineExpressions.scala +++ b/core-scala/src/main/scala/io/pdal/pipeline/PipelineExpressions.scala @@ -18,21 +18,36 @@ package io.pdal.pipeline import io.pdal.Pipeline -import io.circe.Json +import io.circe.{Decoder, Encoder, Json} +import io.circe.syntax._ import io.circe.generic.extras.ConfiguredJsonCodec +import cats.syntax.either._ @ConfiguredJsonCodec sealed trait PipelineExpr { - def ~(other: PipelineExpr): PipelineConstructor = this :: other :: Nil - - def ~(other: Option[PipelineExpr]): PipelineConstructor = - other.fold(this :: Nil)(o => this :: o :: Nil) - - def toPipeline: Pipeline = (this :: Nil).toPipeline + def ~(other: PipelineExpr): PipelineConstructor = + other match { + case ENil => toPipelineConstructor + case _ => PipelineConstructor(this :: other :: Nil) + } + def ~(other: Option[PipelineExpr]): PipelineConstructor = other.fold(toPipelineConstructor)(this ~ _) + def toPipelineConstructor: PipelineConstructor = PipelineConstructor(this :: Nil) + def toPipeline: Pipeline = toPipelineConstructor.toPipeline +} +object PipelineExpr { + implicit def pipelineExprToConstructor(expr: PipelineExpr): PipelineConstructor = expr.toPipelineConstructor + implicit def pipelineExprToJson(expr: PipelineExpr): Json = expr.asJson } -@ConfiguredJsonCodec +case object ENil extends PipelineExpr + case class RawExpr(json: Json) extends PipelineExpr +object RawExpr { + implicit val rawExprEncoder: Encoder[RawExpr] = Encoder.instance { _.json } + implicit val rawExprDecoder: Decoder[RawExpr] = Decoder.decodeJson.emap { json => + Either.catchNonFatal(RawExpr(json)).leftMap(_ => "RawExpr") + } +} @ConfiguredJsonCodec case class Read( @@ -43,7 +58,38 @@ case class Read( ) extends PipelineExpr @ConfiguredJsonCodec -case class FauxRead( +case class ReadBpf( + filename: String, + count: Option[Int] = None, + overrideSrs: Option[String] = None, + tag: Option[String] = None, + `type`: ReaderType = ReaderTypes.bpf +) + +@ConfiguredJsonCodec +case class ReadEpt( + filename: String, + spatialreference: Option[String] = None, + bounds: Option[String] = None, + resolution: Option[Double] = None, + addons: Option[Json] = None, + origin: Option[String] = None, + threads: Option[Int] = None, + tag: Option[String] = None, + `type`: ReaderType = ReaderTypes.ept +) + +@ConfiguredJsonCodec +case class ReadE57( + filename: String, + count: Option[Int] = None, + overrideSrs: Option[String] = None, + tag: Option[String] = None, + `type`: ReaderType = ReaderTypes.e57 +) + +@ConfiguredJsonCodec +case class ReadFaux( numPoints: Int, mode: String, // constant | random | ramp | uniform | normal stdevX: Option[Int] = None, // [default: 1] @@ -58,13 +104,13 @@ case class FauxRead( `type`: ReaderType = ReaderTypes.faux ) extends PipelineExpr -object GdalRead { +object ReadGdal { def apply(filename: String, spatialreference: Option[String] = None, tag: Option[String] = None): Read = Read(filename, spatialreference, tag, Some(ReaderTypes.gdal)) } @ConfiguredJsonCodec -case class GeoWaveRead( +case class ReadGeoWave( zookeeperUrl: String, instanceName: String, username: String, @@ -80,21 +126,21 @@ case class GeoWaveRead( ) extends PipelineExpr @ConfiguredJsonCodec -case class GreyhoundRead( - url: String, - bounds: Option[String] = None, // [default: the entire resource] - depthBegin: Option[Int] = None, // [default: 0] - depthEnd: Option[Int] = None, // [default: 0] - tilePath: Option[String] = None, - filter: Option[Json] = None, - threads: Option[Int] = None, // [default: 4] - spatialreference: Option[String] = None, +case class ReadI3s( + filename: String, + count: Option[Int] = None, + overrideSrs: Option[String] = None, + dimensions: Option[String] = None, + bounds: Option[String] = None, + minDensity: Option[Double] = None, + maxDensity: Option[Double] = None, + threads: Option[Int] = None, tag: Option[String] = None, - `type`: ReaderType = ReaderTypes.greyhound -) extends PipelineExpr + `type`: ReaderType = ReaderTypes.i3s +) @ConfiguredJsonCodec -case class Ilvis2Read( +case class ReadIlvis2( filename: String, mapping: Option[String] = None, metadata: Option[String] = None, @@ -104,21 +150,21 @@ case class Ilvis2Read( ) extends PipelineExpr @ConfiguredJsonCodec -case class MatlabRead( +case class ReadMatlab( filename: String, struct: Option[String] = None, // [default: PDAL] `type`: ReaderType = ReaderTypes.matlab ) extends PipelineExpr @ConfiguredJsonCodec -case class MbioRead( +case class ReadMbio( filename: String, format: String, `type`: ReaderType = ReaderTypes.mbio ) extends PipelineExpr @ConfiguredJsonCodec -case class LasRead( +case class ReadLas( filename: String, extraDims: Option[String] = None, compression: Option[String] = None, @@ -128,18 +174,18 @@ case class LasRead( `type`: ReaderType = ReaderTypes.las ) extends PipelineExpr -object MrsidRead { +object ReadMrsid { def apply(filename: String, spatialreference: Option[String] = None, tag: Option[String] = None): Read = Read(filename, spatialreference, tag, Some(ReaderTypes.mrsid)) } -object NitfRead { +object ReadNitf { def apply(filename: String, spatialreference: Option[String] = None, tag: Option[String] = None): Read = Read(filename, spatialreference, tag, Some(ReaderTypes.nitf)) } @ConfiguredJsonCodec -case class NumpyRead( +case class ReadNumpy( filename: String, dimension: Option[String] = None, x: Option[Int] = None, @@ -150,7 +196,7 @@ case class NumpyRead( ) @ConfiguredJsonCodec -case class OciRead( +case class ReadOci( connection: String, query: String, xmlSchemaDump: Option[String] = None, @@ -160,23 +206,23 @@ case class OciRead( `type`: ReaderType = ReaderTypes.oci ) extends PipelineExpr -object OptechRead { +object ReadOptech { def apply(filename: String, spatialreference: Option[String] = None, tag: Option[String] = None): Read = Read(filename, spatialreference, tag, Some(ReaderTypes.optech)) } -object OsgRead { +object ReadOsg { def apply(filename: String, spatialreference: Option[String] = None, tag: Option[String] = None): Read = Read(filename, spatialreference, tag, Some(ReaderTypes.osg)) } -object PcdRead { +object ReadPcd { def apply(filename: String, spatialreference: Option[String] = None, tag: Option[String] = None): Read = Read(filename, spatialreference, tag, Some(ReaderTypes.pcd)) } @ConfiguredJsonCodec -case class PgpointcloudRead( +case class ReadPgpointcloud( connection: String, table: String, schema: Option[String] = None, // [default: public] @@ -186,18 +232,18 @@ case class PgpointcloudRead( `type`: ReaderType = ReaderTypes.pgpointcloud ) extends PipelineExpr -object PlyRead { +object ReadPly { def apply(filename: String, spatialreference: Option[String] = None, tag: Option[String] = None): Read = Read(filename, spatialreference, tag, Some(ReaderTypes.ply)) } -object PtsRead { +object ReadPts { def apply(filename: String, spatialreference: Option[String] = None, tag: Option[String] = None): Read = Read(filename, spatialreference, tag, Some(ReaderTypes.pts)) } @ConfiguredJsonCodec -case class QfitRead( +case class ReadQfit( filename: String, flipCoordinates: Option[Boolean] = None, scaleZ: Option[Double] = None, @@ -207,7 +253,18 @@ case class QfitRead( ) extends PipelineExpr @ConfiguredJsonCodec -case class RxpRead( +case class ReadRdb( + filename: String, + count: Option[Int] = None, + overrideSrs: Option[String] = None, + filter: Option[String] = None, + extras: Option[Boolean] = None, + tag: Option[String] = None, + `type`: ReaderType = ReaderTypes.rdb +) extends PipelineExpr + +@ConfiguredJsonCodec +case class ReadRxp( filename: String, rdtp: Option[Boolean] = None, syncToPps: Option[Boolean] = None, @@ -220,13 +277,26 @@ case class RxpRead( `type`: ReaderType = ReaderTypes.rxp ) extends PipelineExpr -object SbetRead { +object ReadSbet { def apply(filename: String, spatialreference: Option[String] = None, tag: Option[String] = None): Read = Read(filename, spatialreference, tag, Some(ReaderTypes.sbet)) } @ConfiguredJsonCodec -case class SqliteRead( +case class ReadSlpk( + filename: String, + count: Option[Int] = None, + overrideSrs: Option[String] = None, + dimensions: Option[String] = None, + bounds: Option[String] = None, + minDensity: Option[Double] = None, + maxDensity: Option[Double] = None, + tag: Option[String] = None, + `type`: ReaderType = ReaderTypes.slpk +) extends PipelineExpr + +@ConfiguredJsonCodec +case class ReadSqlite( connection: String, query: String, spatialreference: Option[String] = None, @@ -235,7 +305,7 @@ case class SqliteRead( ) extends PipelineExpr @ConfiguredJsonCodec -case class TextRead( +case class ReadText( filename: String, separator: Option[String] = None, spatialreference: Option[String] = None, @@ -246,7 +316,7 @@ case class TextRead( ) extends PipelineExpr @ConfiguredJsonCodec -case class TindexRead( +case class ReadTindex( filename: String, layerName: Option[String] = None, srsColumn: Option[String] = None, @@ -263,18 +333,26 @@ case class TindexRead( `type`: ReaderType = ReaderTypes.tindex ) extends PipelineExpr -object TerrasolidRead { +object ReadTerrasolid { def apply(filename: String, spatialreference: Option[String] = None, tag: Option[String] = None): Read = Read(filename, spatialreference, tag, Some(ReaderTypes.terrasolid)) } -object IceBridgeRead { - def apply(filename: String, spatialreference: Option[String] = None, tag: Option[String] = None): Read = - Read(filename, spatialreference, tag, Some(ReaderTypes.icebridge)) -} +@ConfiguredJsonCodec +case class ReadTiledb( + arrayName: String, + configName: Option[String] = None, + chunkSize: Option[Int] = None, + stats: Option[String] = None, + bbox3d: Option[String] = None, + count: Option[Int] = None, + overrideSrs: Option[String] = None, + tag: Option[String] = None, + `type`: ReaderType = ReaderTypes.tiledb +) extends PipelineExpr @ConfiguredJsonCodec -case class ApproximateCoplanarFilter( +case class FilterApproximateCoplanar( knn: Option[Int] = None, // [default: 8] thresh1: Option[Int] = None, // [default: 25] thresh2: Option[Int] = None, // [default: 6] @@ -282,13 +360,20 @@ case class ApproximateCoplanarFilter( ) extends PipelineExpr @ConfiguredJsonCodec -case class ChipperFilter( +case class FilterAssign( + assignment: Option[String] = None, + condition: Option[String] = None, + `type`: FilterType = FilterTypes.assign +) extends PipelineExpr + +@ConfiguredJsonCodec +case class FilterChipper( capacity: Option[Int] = None, // [default: 5000] `type`: FilterType = FilterTypes.chipper ) extends PipelineExpr @ConfiguredJsonCodec -case class ClusterFilter( +case class FilterCluster( minPoints: Option[Int] = None, // [default: 1] maxPoints: Option[Int] = None, // [default: UINT64_MAX] tolerance: Option[Double] = None, // [default: 1.0] @@ -296,7 +381,7 @@ case class ClusterFilter( ) @ConfiguredJsonCodec -case class ColorinterpFilter( +case class FilterColorinterp( ramp: Option[String] = None, // [default: pestel_shades] dimension: Option[String] = None, // [default: Z] minimum: Option[String] = None, @@ -309,25 +394,34 @@ case class ColorinterpFilter( ) extends PipelineExpr @ConfiguredJsonCodec -case class ColorizationFilter( +case class FilterColorization( raster: String, dimensions: Option[String] = None, `type`: FilterType = FilterTypes.colorization ) extends PipelineExpr @ConfiguredJsonCodec -case class ComputerangeFilter( +case class FilterComputerange( `type`: FilterType = FilterTypes.computerange ) extends PipelineExpr @ConfiguredJsonCodec -case class CpdFilter( +case class FilterCovariancefeatures( + knn: Option[Int] = None, + threads: Option[Int] = None, + featureSet: Option[String] = None, + stride: Option[String] = None, + `type`: FilterType = FilterTypes.covariancefeatures +) extends PipelineExpr + +@ConfiguredJsonCodec +case class FilterCpd( method: Option[String] = None, `type`: FilterType = FilterTypes.cpd ) extends PipelineExpr @ConfiguredJsonCodec -case class CropFilter( +case class FilterCrop( bounds: Option[String] = None, polygon: Option[String] = None, outside: Option[String] = None, @@ -337,7 +431,7 @@ case class CropFilter( ) extends PipelineExpr @ConfiguredJsonCodec -case class DecimationFilter( +case class FilterDecimation( step: Option[Int] = None, offset: Option[Int] = None, limit: Option[Int] = None, @@ -345,7 +439,20 @@ case class DecimationFilter( ) extends PipelineExpr @ConfiguredJsonCodec -case class DividerFilter( +case class FilterDem( + raster: String, + limits: String, + band: Option[Int] = None, + `type`: FilterType = FilterTypes.dem +) extends PipelineExpr + +@ConfiguredJsonCodec +case class FilterDelaunay( + `type`: FilterType = FilterTypes.delaunay +) extends PipelineExpr + +@ConfiguredJsonCodec +case class FilterDivider( mode: Option[String] = None, count: Option[Int] = None, capacity: Option[Int] = None, @@ -353,53 +460,61 @@ case class DividerFilter( ) extends PipelineExpr @ConfiguredJsonCodec -case class EigenValuesFilter( +case class FilterEigenValues( knn: Option[Int] = None, `type`: FilterType = FilterTypes.eigenvalues ) extends PipelineExpr @ConfiguredJsonCodec -case class EstimateRankFilter( +case class FilterEstimateRank( knn: Option[Int] = None, thresh: Option[Double] = None, `type`: FilterType = FilterTypes.estimaterank ) extends PipelineExpr @ConfiguredJsonCodec -case class FerryFilter( +case class FilterElm( + cell: Option[Double] = None, + `class`: Option[Int] = None, + threshold: Option[Double] = None, + `type`: FilterType = FilterTypes.elm +) extends PipelineExpr + +@ConfiguredJsonCodec +case class FilterFerry( dimensions: String, `type`: FilterType = FilterTypes.ferry ) extends PipelineExpr @ConfiguredJsonCodec -case class GreedyProjectionFilter( +case class FilterGreedyProjection( `type`: FilterType = FilterTypes.greedyprojection ) extends PipelineExpr @ConfiguredJsonCodec -case class GridProjectionFilter( +case class FilterGridProjection( `type`: FilterType = FilterTypes.gridprojection ) extends PipelineExpr @ConfiguredJsonCodec -case class GroupByFilter( +case class FilterGroupBy( dimension: String, `type`: FilterType = FilterTypes.groupby ) @ConfiguredJsonCodec -case class HagFilter( +case class FilterHag( `type`: FilterType = FilterTypes.hag ) extends PipelineExpr @ConfiguredJsonCodec -case class HeadFilter( +case class FilterHead( count: Option[Int] = None, // [default: 10] `type`: FilterType = FilterTypes.head ) extends PipelineExpr @ConfiguredJsonCodec -case class HexbinFilter( +case class FilterHexbin( edgeSize: Option[Int] = None, sampleSize: Option[Int] = None, threshold: Option[Int] = None, @@ -408,45 +523,52 @@ case class HexbinFilter( ) extends PipelineExpr @ConfiguredJsonCodec -case class IcpFilter( +case class FilterInfo( + point: Option[String] = None, + query: Option[String] = None, + `type`: FilterType = FilterTypes.info +) extends PipelineExpr + +@ConfiguredJsonCodec +case class FilterIcp( `type`: FilterType = FilterTypes.icp ) extends PipelineExpr @ConfiguredJsonCodec -case class IqrFilter( +case class FilterIqr( dimension: String, k: Option[Double] = None, `type`: FilterType = FilterTypes.iqr ) extends PipelineExpr @ConfiguredJsonCodec -case class KDistanceFilter( +case class FilterKDistance( k: Option[Int] = None, `type`: FilterType = FilterTypes.kdistance ) extends PipelineExpr @ConfiguredJsonCodec -case class LocateFilter( +case class FilterLocate( dimension: String, minmax: String, `type`: FilterType = FilterTypes.locate ) extends PipelineExpr @ConfiguredJsonCodec -case class LofFilter( +case class FilterLof( minpts: Option[Int] = None, `type`: FilterType = FilterTypes.lof ) extends PipelineExpr @ConfiguredJsonCodec -case class MadFilter( +case class FilterMad( dimension: String, k: Option[Double] = None, `type`: FilterType = FilterTypes.mad ) extends PipelineExpr @ConfiguredJsonCodec -case class MatlabFilter( +case class FilterMatlab( script: String, source: String, addDimension: Option[String] = None, @@ -455,14 +577,14 @@ case class MatlabFilter( ) extends PipelineExpr @ConfiguredJsonCodec -case class MergeFilter( +case class FilterMerge( inputs: List[String], tag: Option[String] = None, `type`: FilterType = FilterTypes.merge ) extends PipelineExpr @ConfiguredJsonCodec -case class MongusFilter( +case class FilterMongus( cell: Option[Double] = None, classify: Option[Boolean] = None, extract: Option[Boolean] = None, @@ -472,24 +594,45 @@ case class MongusFilter( ) extends PipelineExpr @ConfiguredJsonCodec -case class MortonOrderFilter( +case class FilterMortonOrder( reverse: Option[String] = None, `type`: FilterType = FilterTypes.mortonorder ) extends PipelineExpr @ConfiguredJsonCodec -case class MovingLeastSquaresFilter( +case class FilterMovingLeastSquares( `type`: FilterType = FilterTypes.movingleastsquares ) extends PipelineExpr @ConfiguredJsonCodec -case class NormalFilter( +case class FilterMiniball( + knn: Option[Int] = None, + `type`: FilterType = FilterTypes.miniball +) extends PipelineExpr + +@ConfiguredJsonCodec +case class FilterNeighborclassifier( + candidate: Option[String] = None, + domain: Option[String] = None, + k: Option[Int] = None, + `type`: FilterType = FilterTypes.neighborclassifier +) extends PipelineExpr + +@ConfiguredJsonCodec +case class FilterNndistance( + mode: Option[String] = None, + k: Option[Int] = None, + `type`: FilterType = FilterTypes.nndistance +) extends PipelineExpr + +@ConfiguredJsonCodec +case class FilterNormal( knn: Option[Int] = None, `type`: FilterType = FilterTypes.normal ) extends PipelineExpr @ConfiguredJsonCodec -case class OutlierFilter( +case class FilterOutlier( method: Option[String] = None, minK: Option[Int] = None, radius: Option[Double] = None, @@ -499,7 +642,7 @@ case class OutlierFilter( ) extends PipelineExpr @ConfiguredJsonCodec -case class OverlayFilter( +case class FilterOverlay( dimension: Option[String] = None, // [default: none] datasource: Option[String] = None, // [default: none] column: Option[String] = None, // [default: none] @@ -509,14 +652,21 @@ case class OverlayFilter( ) extends PipelineExpr @ConfiguredJsonCodec -case class PclBlockFilter( +case class FilterPclBlock( filename: String, methods: Option[List[String]] = None, `type`: FilterType = FilterTypes.pclblock ) extends PipelineExpr @ConfiguredJsonCodec -case class PmfFilter( +case class FilterPlanefit( + knn: Option[Int] = None, + threads: Option[Int] = None, + `type`: FilterType = FilterTypes.planefit +) extends PipelineExpr + +@ConfiguredJsonCodec +case class FilterPmf( maxWindowSize: Option[Int] = None, slope: Option[Double] = None, maxDistance: Option[Double] = None, @@ -527,14 +677,14 @@ case class PmfFilter( ) extends PipelineExpr @ConfiguredJsonCodec -case class PoissonFilter( +case class FilterPoisson( depth: Option[Int] = None, pointWeight: Option[Double] = None, `type`: FilterType = FilterTypes.poisson ) extends PipelineExpr @ConfiguredJsonCodec -case class PythonFilter( +case class FilterPython( module: String, function: String, script: Option[String] = None, @@ -545,24 +695,30 @@ case class PythonFilter( ) extends PipelineExpr @ConfiguredJsonCodec -case class RadialDensityFilter( +case class FilterRadialDensity( radius: Option[Double] = None, `type`: FilterType = FilterTypes.radialdensity ) extends PipelineExpr @ConfiguredJsonCodec -case class RandomizeFilter( +case class FilterRandomize( `type`: FilterType = FilterTypes.randomize ) extends PipelineExpr @ConfiguredJsonCodec -case class RangeFilter( +case class FilterRange( limits: Option[String] = None, `type`: FilterType = FilterTypes.range ) extends PipelineExpr @ConfiguredJsonCodec -case class ReprojectionFilter( +case class FilterReciprocity( + knn: Option[Int] = None, + `type`: FilterType = FilterTypes.reciprocity +) extends PipelineExpr + +@ConfiguredJsonCodec +case class FilterReprojection( outSrs: String, inSrs: Option[String] = None, tag: Option[String] = None, @@ -570,13 +726,13 @@ case class ReprojectionFilter( ) extends PipelineExpr @ConfiguredJsonCodec -case class SampleFilter( +case class FilterSample( radius: Option[Double] = None, `type`: FilterType = FilterTypes.sample ) extends PipelineExpr @ConfiguredJsonCodec -case class SmrfFilter( +case class FilterSmrf( cell: Option[Double] = None, classify: Option[Boolean] = None, cut: Option[Double] = None, @@ -588,13 +744,13 @@ case class SmrfFilter( ) extends PipelineExpr @ConfiguredJsonCodec -case class SortFilter( +case class FilterSort( dimension: String, `type`: FilterType = FilterTypes.sort ) extends PipelineExpr @ConfiguredJsonCodec -case class SplitterFilter( +case class FilterSplitter( length: Option[Int] = None, originX: Option[Double] = None, originY: Option[Double] = None, @@ -602,7 +758,7 @@ case class SplitterFilter( ) extends PipelineExpr @ConfiguredJsonCodec -case class StatsFilter( +case class FilterStats( dimenstions: Option[String] = None, enumerate: Option[String] = None, count: Option[Int] = None, @@ -610,19 +766,19 @@ case class StatsFilter( ) extends PipelineExpr @ConfiguredJsonCodec -case class TailFilter( +case class FilterTail( count: Option[Int] = None, // [default: 10] `type`: FilterType = FilterTypes.tail ) extends PipelineExpr @ConfiguredJsonCodec -case class TransformationFilter( +case class FilterTransformation( matrix: String, `type`: FilterType = FilterTypes.transformation ) extends PipelineExpr @ConfiguredJsonCodec -case class VoxelCenterNearestNeighborFilter( +case class FilterVoxelCenterNearestNeighbor( cell: Option[Double] = None, // [default: 1.0] `type`: FilterType = FilterTypes.voxelcenternearestneighbor ) extends PipelineExpr @@ -634,7 +790,7 @@ case class VoxelCentroidNearestNeighbor( ) extends PipelineExpr @ConfiguredJsonCodec -case class VoxelGridFilter( +case class FilterVoxelGrid( leafX: Option[Double] = None, leafY: Option[Double] = None, leafZ: Option[Double] = None, @@ -648,7 +804,7 @@ case class Write( ) extends PipelineExpr @ConfiguredJsonCodec -case class BpfWrite( +case class WriteBpf( filename: String, compression: Option[Boolean] = None, format: Option[String] = None, @@ -666,7 +822,7 @@ case class BpfWrite( ) extends PipelineExpr @ConfiguredJsonCodec -case class GdalWrite( +case class WriteGdal( filename: String, resolution: Int, radius: Double, @@ -679,7 +835,7 @@ case class GdalWrite( ) extends PipelineExpr @ConfiguredJsonCodec -case class GeoWaveWrite( +case class WriteGeoWave( zookeeperUrl: String, instanceName: String, username: String, @@ -692,7 +848,7 @@ case class GeoWaveWrite( ) extends PipelineExpr @ConfiguredJsonCodec -case class LasWrite( +case class WriteLas( filename: String, forward: Option[String] = None, minorVersion: Option[Int] = None, @@ -717,14 +873,14 @@ case class LasWrite( ) extends PipelineExpr @ConfiguredJsonCodec -case class MatlabWrite( +case class WriteMatlab( filename: String, outputDims: Option[String] = None, `type`: WriterType = WriterTypes.matlab ) extends PipelineExpr @ConfiguredJsonCodec -case class NitfWrite( +case class WriteNitf( filename: String, clevel: Option[String] = None, stype: Option[String] = None, @@ -744,12 +900,12 @@ case class NitfWrite( ) extends PipelineExpr @ConfiguredJsonCodec -case class NullWrite( +case class WriteNull( `type`: WriterType = WriterTypes.`null` ) extends PipelineExpr @ConfiguredJsonCodec -case class OciWrite( +case class WriteOci( connection: String, is3d: Option[Boolean] = None, solid: Option[Boolean] = None, @@ -786,14 +942,14 @@ case class OciWrite( ) extends PipelineExpr @ConfiguredJsonCodec -case class PcdWrite( +case class WritePcd( filename: String, compression: Option[Boolean] = None, `type`: WriterType = WriterTypes.pcd ) extends PipelineExpr @ConfiguredJsonCodec -case class PgpointcloudWrite( +case class WritePgpointcloud( connection: String, table: String, schema: Option[String] = None, @@ -815,14 +971,14 @@ case class PgpointcloudWrite( ) extends PipelineExpr @ConfiguredJsonCodec -case class PlyWrite( +case class WritePly( filename: String, storageMode: Option[String] = None, `type`: WriterType = WriterTypes.ply ) extends PipelineExpr @ConfiguredJsonCodec -case class RialtoWrite( +case class WriteRialto( filename: String, maxLevels: Option[Int] = None, overwrite: Option[Boolean] = None, @@ -830,7 +986,7 @@ case class RialtoWrite( ) extends PipelineExpr @ConfiguredJsonCodec -case class SqliteWrite( +case class WriteSqlite( filename: String, cloudTableName: String, blockTableName: String, @@ -850,7 +1006,7 @@ case class SqliteWrite( ) extends PipelineExpr @ConfiguredJsonCodec -case class TextWrite( +case class WriteText( filename: String, format: Option[String] = None, order: Option[String] = None, diff --git a/core-scala/src/main/scala/io/pdal/pipeline/ReaderTypes.scala b/core-scala/src/main/scala/io/pdal/pipeline/ReaderTypes.scala index f10e0a2..ab3c698 100644 --- a/core-scala/src/main/scala/io/pdal/pipeline/ReaderTypes.scala +++ b/core-scala/src/main/scala/io/pdal/pipeline/ReaderTypes.scala @@ -21,10 +21,12 @@ sealed trait ReaderType extends ExprType { val `type` = "readers" } object ReaderTypes { case object bpf extends ReaderType case object buffer extends ReaderType + case object ept extends ReaderType + case object e57 extends ReaderType case object faux extends ReaderType case object gdal extends ReaderType case object geowave extends ReaderType - case object greyhound extends ReaderType + case object i3s extends ReaderType case object ilvis2 extends ReaderType case object las extends ReaderType case object matlab extends ReaderType @@ -40,18 +42,21 @@ object ReaderTypes { case object ply extends ReaderType case object pts extends ReaderType case object qfit extends ReaderType + case object rdb extends ReaderType case object rxp extends ReaderType case object sbet extends ReaderType + case object slpk extends ReaderType case object sqlite extends ReaderType case object text extends ReaderType + case object tiledb extends ReaderType case object tindex extends ReaderType case object terrasolid extends ReaderType case object icebridge extends ReaderType lazy val all = List( - bpf, buffer, faux, gdal, geowave, greyhound, ilvis2, las, matlab, mbio, mrsid, nitf, - numpy, oci, optech, osg, pcd, pgpointcloud, ply, pts, qfit, rxp, sbet, sqlite, text, - tindex, terrasolid, icebridge + bpf, buffer, ept, faux, gdal, geowave, i3s, ilvis2, las, matlab, mbio, mrsid, nitf, + numpy, oci, optech, osg, pcd, pgpointcloud, ply, pts, qfit, rdb, rxp, sbet, slpk, sqlite, text, + tiledb, tindex, terrasolid, icebridge ) def fromName(name: String): ReaderType = diff --git a/core-scala/src/main/scala/io/pdal/pipeline/json/Implicits.scala b/core-scala/src/main/scala/io/pdal/pipeline/json/Implicits.scala index 7caffe6..c772f0c 100644 --- a/core-scala/src/main/scala/io/pdal/pipeline/json/Implicits.scala +++ b/core-scala/src/main/scala/io/pdal/pipeline/json/Implicits.scala @@ -16,46 +16,14 @@ package io.pdal.pipeline.json -import io.pdal.pipeline._ - -import io.circe.{Decoder, Encoder, Json, Printer} +import io.circe.Printer import io.circe.generic.extras.Configuration -import io.circe.syntax._ -import cats.syntax.either._ -object Implicits extends Implicits +object Implicits extends Implicits with Serializable -trait Implicits extends Serializable { +trait Implicits { implicit val customConfig: Configuration = Configuration.default.withSnakeCaseMemberNames.withDiscriminator("class_type") val pipelinePrettyPrinter: Printer = Printer.spaces2.copy(dropNullValues = true) - - implicit def exprTypeEncoder[T <: ExprType]: Encoder[T] = Encoder.instance { _.toString.asJson } - implicit def exprTypeDecoder[T <: ExprType]: Decoder[T] = Decoder.decodeString.emap { str => - Either.catchNonFatal(ExprType.fromName(str).asInstanceOf[T]).leftMap(_ => "ExprType") - } - - implicit val pipelineConstructorEncoder: Encoder[PipelineConstructor] = Encoder.instance { constructor => - Json.obj( - "pipeline" -> constructor - .flatMap { - _.flatMap { - case RawExpr(json) => json.asObject - case expr => expr.asJson.asObject - }.map { - _.remove("class_type") // remove type - .filter { case (_, value) => !value.isNull } // cleanup options - } - }.asJson - ) - } - implicit val pipelineConstructorDecoder: Decoder[PipelineConstructor] = Decoder.instance { - _.downField("pipeline").as[PipelineConstructor] - } - - implicit val rawExprEncoder: Encoder[RawExpr] = Encoder.instance { _.json } - implicit val rawExprDecoder: Decoder[RawExpr] = Decoder.decodeJson.emap { json => - Either.catchNonFatal(RawExpr(json)).leftMap(_ => "RawExpr") - } } diff --git a/core-scala/src/main/scala/io/pdal/pipeline/package.scala b/core-scala/src/main/scala/io/pdal/pipeline/package.scala index 0242c3e..af52dcd 100644 --- a/core-scala/src/main/scala/io/pdal/pipeline/package.scala +++ b/core-scala/src/main/scala/io/pdal/pipeline/package.scala @@ -16,26 +16,4 @@ package io.pdal -import io.circe.Json -import io.circe.syntax._ - -/** - * There is no implicit PipelineExprToString function to avoid - * implicit casts in places where PipelineConstructor should be used. - */ - -package object pipeline extends json.Implicits with Implicits with Serializable { - type PipelineConstructor = List[PipelineExpr] - - implicit class withPipelineConstructor(list: PipelineConstructor) { - def ~(e: PipelineExpr): PipelineConstructor = list :+ e - def ~(e: Option[PipelineExpr]): PipelineConstructor = e.fold(list)(el => list :+ el) - def map[B](f: PipelineExpr => B): List[B] = list.map(f) - def toPipeline = Pipeline(list.asJson.noSpaces) - } - - implicit def pipelineExprToConstructor[T <: PipelineExpr](expr: T): PipelineConstructor = expr :: Nil - implicit def pipelineExprToJson(expr: PipelineExpr): Json = expr.asJson - implicit def pipelineConstructorToJson(expr: PipelineConstructor): Json = expr.asJson - implicit def pipelineConstructorToString(expr: PipelineConstructor): String = expr.asJson.noSpaces -} +package object pipeline extends json.Implicits with pipeline.Implicits with Serializable diff --git a/core-scala/src/test/scala/io/pdal/pipeline/PipelineExpressionsSpec.scala b/core-scala/src/test/scala/io/pdal/pipeline/PipelineExpressionsSpec.scala index c66f9fa..fe5d8c7 100644 --- a/core-scala/src/test/scala/io/pdal/pipeline/PipelineExpressionsSpec.scala +++ b/core-scala/src/test/scala/io/pdal/pipeline/PipelineExpressionsSpec.scala @@ -16,7 +16,6 @@ package io.pdal.pipeline -import io.circe._ import io.circe.syntax._ import io.circe.parser._ @@ -47,8 +46,8 @@ class PipelineExpressionsSpec extends AnyFunSpec with Matchers with BeforeAndAft """.stripMargin - val pc: PipelineConstructor = LasRead("/path/to/las") ~ CropFilter() ~ LasWrite("/path/to/new/las") - val pipelineJson: Json = LasRead("/path/to/las") ~ CropFilter() ~ LasWrite("/path/to/new/las") + val pc = ReadLas("/path/to/las") ~ FilterCrop() ~ WriteLas("/path/to/new/las") + val pipelineJson = pc.asJson parse(expected) match { case Right(r) => pipelineJson shouldBe r @@ -76,12 +75,28 @@ class PipelineExpressionsSpec extends AnyFunSpec with Matchers with BeforeAndAft |} """.stripMargin - val pipelineJson: Json = LasRead("/path/to/las") ~ RawExpr(Map("type" -> "filters.crop").asJson) ~ LasWrite("/path/to/new/las") + val pipelineJson = ReadLas("/path/to/las") ~ RawExpr(Map("type" -> "filters.crop").asJson) ~ WriteLas("/path/to/new/las") asJson parse(expected) match { case Right(r) => pipelineJson shouldBe r case Left(e) => throw e } } + + it("inductive constructor should work with ENil properly") { + (ReadLas("/path/to/las") ~ ENil asJson) shouldBe (ReadLas("/path/to/las").toPipelineConstructor asJson) + (ReadLas("/path/to/las") ~ FilterCrop() ~ WriteLas("/path/to/new/las") ~ ENil asJson) shouldBe (ReadLas("/path/to/las") ~ FilterCrop() ~ WriteLas("/path/to/new/las") asJson) + } + + it("should execute the pipeline built from the Scala DSL") { + val expression = + ReadLas("./core/src/test/resources/1.2-with-color.las", spatialreference = Some("EPSG:2993")) ~ + FilterReprojection(outSrs = "EPSG:3857") + + val pipeline = expression.toPipeline + pipeline.validate() shouldBe true + pipeline.execute() + pipeline.close() + } } } diff --git a/core/src/main/scala/io/pdal/Native.scala b/core/src/main/scala/io/pdal/Native.scala index 9cb2b5e..2a798bf 100644 --- a/core/src/main/scala/io/pdal/Native.scala +++ b/core/src/main/scala/io/pdal/Native.scala @@ -33,8 +33,8 @@ package io.pdal -trait Native { +trait Native extends AutoCloseable { protected var nativeHandle = 0L // C++ pointer def ptr(): Long = nativeHandle - def dispose(): Unit + def close(): Unit } diff --git a/core/src/main/scala/io/pdal/Pipeline.scala b/core/src/main/scala/io/pdal/Pipeline.scala index d7fce33..c3986d3 100644 --- a/core/src/main/scala/io/pdal/Pipeline.scala +++ b/core/src/main/scala/io/pdal/Pipeline.scala @@ -41,7 +41,7 @@ class Pipeline(val json: String) extends Native { @native def initialize(): Unit @native def execute(): Unit @native def getPointViews(): PointViewIterator - @native def dispose(): Unit + @native def close(): Unit @native def getMetadata(): String @native def getSchema(): String @native def validate(): Boolean @@ -50,7 +50,7 @@ class Pipeline(val json: String) extends Native { @native def getLog(): String } -@nativeLoader("pdaljni.2.0") +@nativeLoader("pdaljni.2.1") object Pipeline { def apply(json: String): Pipeline = { val p = new Pipeline(json); p.initialize(); p } } diff --git a/core/src/main/scala/io/pdal/PointLayout.scala b/core/src/main/scala/io/pdal/PointLayout.scala index f73dd38..c206823 100644 --- a/core/src/main/scala/io/pdal/PointLayout.scala +++ b/core/src/main/scala/io/pdal/PointLayout.scala @@ -63,5 +63,5 @@ class PointLayout extends Native { */ @native def dimPackedOffset(id: String): Long @native def pointSize(): Long - @native def dispose(): Unit + @native def close(): Unit } diff --git a/core/src/main/scala/io/pdal/PointView.scala b/core/src/main/scala/io/pdal/PointView.scala index 5d62256..6debddf 100644 --- a/core/src/main/scala/io/pdal/PointView.scala +++ b/core/src/main/scala/io/pdal/PointView.scala @@ -36,32 +36,32 @@ package io.pdal import java.nio.{ByteBuffer, ByteOrder} class PointView extends Native { - def getPointCloud(idx: Long): PointCloud = getPointCloud(idx, layout.dimTypes()) + def getPointCloud(idx: Long): PointCloud = getPointCloud(idx, layout().dimTypes()) def getPointCloud(idx: Long, dims: Array[DimType]): PointCloud = PointCloud( bytes = getPackedPoint(idx, dims), - dimTypes = layout.toSizedDimTypes(dims) + dimTypes = layout().toSizedDimTypes(dims) ) - def getPointCloud(): PointCloud = getPointCloud(layout.dimTypes()) + def getPointCloud(): PointCloud = getPointCloud(layout().dimTypes()) def getPointCloud(dims: Array[DimType]): PointCloud = PointCloud( bytes = getPackedPoints(dims), - dimTypes = layout.toSizedDimTypes(dims) + dimTypes = layout().toSizedDimTypes(dims) ) - def getPackedPoint(idx: Long): Array[Byte] = getPackedPoint(idx, layout.dimTypes()) - def getPackedPoints(): Array[Byte] = getPackedPoints(layout.dimTypes()) - def findDimType(name: String): DimType = layout.findDimType(name) + def getPackedPoint(idx: Long): Array[Byte] = getPackedPoint(idx, layout().dimTypes()) + def getPackedPoints(): Array[Byte] = getPackedPoints(layout().dimTypes()) + def findDimType(name: String): DimType = layout().findDimType(name) def length(): Int = size() def getCrsWKT(): String = getCrsWKT(pretty = false) /** * Reads a packed point by point id from a set of packed points. */ - def get(idx: Int, packedPoints: Array[Byte]): Array[Byte] = get(idx, packedPoints, layout.dimTypes()) + def get(idx: Int, packedPoints: Array[Byte]): Array[Byte] = get(idx, packedPoints, layout().dimTypes()) def get(idx: Int, packedPoints: Array[Byte], dims: Array[DimType]): Array[Byte] = { - val pointSize = dims.map(layout.dimSize(_)).sum.toInt + val pointSize = dims.map(layout().dimSize(_)).sum.toInt val from = idx * pointSize val result = new Array[Byte](pointSize) var j = 0 @@ -76,8 +76,8 @@ class PointView extends Native { * Reads dim from a packed point, point should contain all layout dims. */ def get(packedPoint: Array[Byte], dim: DimType): ByteBuffer = { - val from = layout.dimPackedOffset(dim).toInt - val dimSize = layout.dimSize(dim).toInt + val from = layout().dimPackedOffset(dim).toInt + val dimSize = layout().dimSize(dim).toInt val result = new Array[Byte](dimSize) var j = 0 while(j < dimSize) { @@ -152,5 +152,6 @@ class PointView extends Native { @native def getCrsWKT(pretty: Boolean): String @native def getPackedPoint(idx: Long, dims: Array[DimType]): Array[Byte] @native def getPackedPoints(dims: Array[DimType]): Array[Byte] - @native def dispose(): Unit + @native def getTriangularMesh(name: String = ""): TriangularMesh + @native def close(): Unit } diff --git a/core/src/main/scala/io/pdal/PointViewIterator.scala b/core/src/main/scala/io/pdal/PointViewIterator.scala index 3b2a2ce..300d5ff 100644 --- a/core/src/main/scala/io/pdal/PointViewIterator.scala +++ b/core/src/main/scala/io/pdal/PointViewIterator.scala @@ -38,5 +38,5 @@ import java.util class PointViewIterator extends util.Iterator[PointView] with Native { @native def hasNext: Boolean @native def next(): PointView - @native def dispose(): Unit + @native def close(): Unit } diff --git a/core/src/main/scala/io/pdal/Triangle.scala b/core/src/main/scala/io/pdal/Triangle.scala new file mode 100644 index 0000000..095f76b --- /dev/null +++ b/core/src/main/scala/io/pdal/Triangle.scala @@ -0,0 +1,46 @@ +/****************************************************************************** + * Copyright (c) 2020, hobu Inc. (info@hobu.co) + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following + * conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Hobu, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + ****************************************************************************/ + +package io.pdal + +/** Triangles with PointIds that correspond to PointIds from the original PDAL PointCloud table. */ +case class Triangle(a: Int, b: Int, c: Int) extends Product3[Int, Int, Int] { + def _1: Int = a + def _2: Int = b + def _3: Int = c +} + +object Triangle { + implicit def tupToTriangle(tup: (Int, Int, Int)): Triangle = Triangle(tup._1, tup._2, tup._3) + implicit def triangleToTup(triangle: Triangle): (Int, Int, Int) = (triangle.a, triangle.b, triangle.c) +} diff --git a/core/src/main/scala/io/pdal/TriangularMesh.scala b/core/src/main/scala/io/pdal/TriangularMesh.scala new file mode 100644 index 0000000..346424d --- /dev/null +++ b/core/src/main/scala/io/pdal/TriangularMesh.scala @@ -0,0 +1,45 @@ +/****************************************************************************** + * Copyright (c) 2020, hobu Inc. (info@hobu.co) + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following + * conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Hobu, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + ****************************************************************************/ + +package io.pdal + +import java.util + +class TriangularMesh extends util.Iterator[Triangle] with Native { + @native def size(): Int + @native def get(idx: Long): Triangle + @native def hasNext: Boolean + @native def next(): Triangle + @native def asArray(): Array[Triangle] + @native def close(): Unit +} diff --git a/core/src/test/resources/delaunay.ply b/core/src/test/resources/delaunay.ply new file mode 100644 index 0000000..555cea1 --- /dev/null +++ b/core/src/test/resources/delaunay.ply @@ -0,0 +1,3202 @@ +ply +format ascii 1.0 +comment Generated by PDAL +element vertex 1065 +property float64 x +property float64 y +property float64 z +property uint16 intensity +property uint8 returnnumber +property uint8 numberofreturns +property uint8 scandirectionflag +property uint8 edgeofflightline +property uint8 classification +property float32 scananglerank +property uint8 userdata +property uint16 pointsourceid +property float64 gpstime +property uint16 red +property uint16 green +property uint16 blue +element face 2114 +property list uint8 uint32 vertex_indices +end_header +637012 849028 431.66 143 1 1 1 0 1 -9 132 7326 245381 68 77 88 +636896 849088 446.39 18 1 2 1 0 1 -11 128 7326 245381 54 66 68 +636785 849107 426.71 118 1 1 0 0 1 -10 122 7326 245382 112 97 114 +636699 848991 425.39 100 1 1 0 0 1 -6 124 7326 245383 178 138 162 +636602 849019 425.1 124 1 1 1 0 1 -4 126 7326 245383 134 104 134 +636452 849251 435.17 48 1 1 0 0 1 -9 122 7326 245384 99 85 95 +636327 849372 408.6 3 1 1 1 0 2 -12 128 7326 245384 90 95 106 +636268 849261 427.92 207 1 1 1 0 1 -9 128 7326 245385 106 100 125 +636199 849238 428.05 142 1 1 1 0 1 -9 126 7326 245385 106 95 124 +636146 849170 428.15 124 1 1 1 0 1 -6 124 7326 245386 100 94 122 +636038 849338 423.06 147 1 1 0 0 2 -9 124 7326 245386 64 70 74 +636044 849006 427.95 75 1 1 0 0 1 -1 124 7326 245386 152 108 134 +635883 849391 423.69 63 1 1 0 0 1 -11 124 7326 245387 71 73 93 +635869 849206 444.46 1 1 2 1 0 1 -9 126 7326 245387 51 61 65 +635795 849310 426.61 146 1 1 0 0 1 -9 126 7326 245387 101 94 121 +635752 849347 426.25 91 1 1 0 0 1 -10 124 7326 245388 98 82 114 +635792 848992 428.58 134 1 1 1 0 1 -4 124 7326 245388 142 102 137 +635718 849050 428.67 167 1 1 0 0 1 -7 124 7326 245388 163 118 150 +635674 849017 428.02 153 1 1 0 0 1 -7 126 7326 245389 146 104 140 +635620 850064 447.01 1 1 2 0 0 1 15 125 7327 246092 52 65 68 +635640 849759 422.74 25 1 1 1 0 1 6 124 7327 246093 39 57 56 +635742 850053 424.64 188 1 1 0 0 1 12 128 7327 246093 95 89 113 +635761 849985 425.72 4 3 3 1 0 1 11 126 7327 246093 80 83 102 +635684 849494 407.12 48 1 1 0 0 1 1 126 7327 246093 78 88 94 +635681 849363 421.56 58 2 2 0 0 2 -1 126 7327 246093 64 73 78 +635791 849751 413.42 77 1 1 1 0 1 7 122 7327 246094 72 78 90 +635873 850003 424.44 33 1 1 0 0 1 13 126 7327 246094 98 104 118 +635817 849587 407.32 224 1 1 1 0 1 4 124 7327 246094 76 88 93 +635816 849427 447.57 4 1 3 0 0 1 1 126 7327 246094 52 66 66 +635823 849299 426.61 179 1 1 0 0 2 -1 126 7327 246094 116 101 133 +635852 849271 428.54 181 1 1 1 0 1 -1 124 7327 246094 128 112 142 +635948 849589 407.25 182 1 1 1 0 1 5 124 7327 246095 75 86 90 +635980 849609 407.22 2 1 1 1 0 2 5 122 7327 246095 103 98 112 +635961 849380 438.02 2 1 2 1 0 1 0 122 7327 246095 73 76 92 +635979 849336 424.28 98 1 1 1 0 1 0 122 7327 246095 99 89 113 +636075 849719 410.47 63 1 1 1 0 1 7 122 7327 246095 114 90 112 +636046 849442 406.59 23 1 1 0 0 1 1 128 7327 246095 79 89 95 +635994 849048 427.95 120 1 1 0 0 1 -7 124 7327 246095 145 108 139 +636052 849248 427.99 154 1 1 1 0 1 -3 122 7327 246096 170 123 153 +636052 849107 427.99 116 1 1 1 0 1 -6 124 7327 246096 174 126 154 +636087 849150 427.95 118 1 1 1 0 2 -5 122 7327 246096 168 126 152 +636272 850050 425.2 57 2 2 0 0 1 13 128 7327 246096 50 57 60 +636145 849152 428.02 115 1 1 0 0 2 -5 126 7327 246096 102 94 124 +636216 849401 407.97 4 1 1 1 0 1 0 124 7327 246096 104 104 114 +636341 849987 494.03 2 1 3 1 0 1 11 127 7327 246097 77 79 93 +636301 849613 409.12 186 1 1 1 0 1 2 124 7327 246097 102 85 97 +636216 849010 428.12 67 1 1 0 0 1 -10 126 7327 246097 113 97 123 +636238 849008 428.15 93 1 1 1 0 1 -10 121 7327 246097 104 93 120 +636340 849452 409.06 95 1 1 1 0 1 -1 122 7327 246097 99 95 102 +636460 849996 426.05 0 3 3 0 0 2 9 128 7327 246097 80 80 96 +636407 849568 410.27 142 1 1 1 0 1 0 122 7327 246097 102 92 102 +636525 850058 445.96 17 3 3 1 0 1 10 124 7327 246098 62 72 80 +636541 849980 426.61 108 1 1 0 0 1 8 124 7327 246098 84 89 105 +636551 849845 414.93 2 2 2 1 0 2 5 124 7327 246098 57 66 73 +636598 849903 487.83 98 1 1 1 0 1 7 124 7327 246098 76 86 88 +636451 849039 428.61 183 1 1 1 0 1 -10 124 7327 246098 120 100 128 +636642 849804 417.55 159 1 1 0 0 1 6 126 7327 246098 44 68 61 +636726 850063 447.21 137 1 1 1 0 2 12 124 7327 246098 92 93 118 +636645 849592 411.19 139 1 1 1 0 2 1 120 7327 246099 73 84 90 +636770 850056 447.01 136 1 1 0 0 1 10 124 7327 246099 56 75 74 +636739 849828 500.26 1 1 2 1 0 1 5 122 7327 246099 84 94 99 +636579 849032 428.15 98 1 1 1 0 1 -11 124 7327 246099 227 209 223 +636607 849054 425.89 153 1 1 1 0 2 -10 126 7327 246099 143 106 134 +636672 849236 411.98 11 1 1 1 0 1 -6 124 7327 246099 82 80 91 +636703 849271 411.15 37 1 1 1 0 2 -5 124 7327 246099 70 82 84 +636896 850024 455.41 6 1 2 1 0 1 11 124 7327 246100 66 77 80 +636873 849839 531.2 10 1 2 1 0 1 7 124 7327 246100 60 75 77 +636699 848972 425.62 96 1 1 0 0 2 -10 124 7327 246100 207 177 196 +636952 850014 495.44 8 1 1 0 0 1 11 124 7327 246100 80 88 100 +636757 849035 426.48 171 1 1 1 0 1 -9 126 7327 246100 156 121 150 +636782 849043 426.41 157 1 1 1 0 2 -8 124 7327 246100 140 104 132 +636785 848950 424.25 35 1 1 1 0 1 -10 126 7327 246100 160 125 148 +636987 849803 423.36 27 2 2 1 0 1 8 124 7327 246100 48 66 64 +637030 849908 451.38 11 1 2 0 0 1 10 126 7327 246101 84 86 98 +637049 849878 480.05 5 1 2 1 0 1 9 124 7327 246101 95 95 116 +637099 849985 422.6 125 2 2 0 0 1 10 128 7327 246101 105 105 125 +637134 849995 422.38 6 1 1 1 0 1 9 128 7327 246101 52 66 68 +636966 849045 428.51 154 1 1 1 0 2 -11 124 7327 246101 102 102 126 +637156 849779 425.66 83 1 1 1 0 2 3 126 7327 246101 58 71 74 +637184 849717 425.95 158 1 1 1 0 1 2 128 7327 246101 97 96 117 +637089 848954 430.41 151 1 1 0 0 1 -12 128 7327 246102 140 112 142 +637203 850169 427.43 27 3 3 0 0 2 -3 132 7328 246501 79 83 90 +637176 850114 482.28 57 1 2 1 0 1 -2 126 7328 246501 70 82 88 +637136 850143 421.56 3 1 1 1 0 2 -1 124 7328 246501 54 64 66 +637059 850454 426.18 56 1 1 1 0 1 -6 124 7328 246502 119 99 133 +637053 850335 427.33 81 2 2 0 0 1 -3 130 7328 246502 106 101 124 +637122 849678 425.59 82 2 2 0 0 1 9 134 7328 246502 80 82 96 +637001 850346 465.16 10 2 3 0 0 1 -4 135 7328 246502 59 69 72 +637078 849622 466.04 1 2 3 1 0 1 10 128 7328 246502 52 71 67 +636936 850369 441.14 146 1 1 1 0 2 -6 126 7328 246502 78 88 96 +636942 850105 498.62 5 1 2 0 0 1 -1 134 7328 246502 102 101 124 +636865 850375 441.57 142 1 1 1 0 2 -8 126 7328 246503 127 99 134 +636946 849676 456.2 5 2 3 0 0 1 6 135 7328 246503 53 70 66 +636907 849720 551.31 105 1 2 0 0 1 6 132 7328 246503 69 84 83 +636904 849568 411.09 7 1 1 0 0 2 9 130 7328 246503 74 88 94 +636843 849772 419.46 188 1 1 0 0 1 6 132 7328 246503 54 66 69 +636794 849874 425.82 24 1 1 1 0 1 4 128 7328 246503 103 112 119 +636767 849829 521.19 27 1 2 0 0 1 4 135 7328 246504 57 74 70 +636753 849714 482.55 2 1 3 0 0 1 5 134 7328 246504 58 80 72 +636699 849829 420.8 216 1 1 0 0 1 2 135 7328 246504 50 65 65 +636661 849854 424.9 233 1 1 0 0 1 2 136 7328 246504 92 100 110 +636568 850179 441.8 165 1 1 0 0 2 -4 128 7328 246504 122 106 127 +636555 850040 499.11 7 1 2 0 0 1 -2 132 7328 246505 58 70 74 +636521 850039 470.73 3 2 3 0 0 1 -2 137 7328 246505 47 65 64 +636495 850001 497.83 0 2 2 1 0 1 -2 128 7328 246505 52 58 66 +636453 850061 450.66 0 4 4 0 0 1 -3 133 7328 246505 46 60 60 +636421 850059 524.67 228 1 1 0 0 1 -2 135 7328 246505 84 86 101 +636341 850366 433.69 156 1 1 0 0 1 -8 128 7328 246506 129 102 135 +636376 849926 428.12 239 1 1 0 0 1 1 134 7328 246506 79 83 101 +636335 849954 428.22 217 1 1 0 0 1 0 135 7328 246506 80 82 98 +636291 849991 464.6 127 2 2 1 0 1 0 126 7328 246506 98 97 104 +636299 849676 409.09 1 1 1 0 0 2 7 132 7328 246506 110 92 109 +636218 849996 440.62 38 1 2 1 0 1 1 126 7328 246506 87 93 111 +636269 849489 408.5 2 1 1 0 0 2 11 133 7328 246507 109 97 110 +636142 850134 426.84 150 1 1 1 0 1 -1 124 7328 246507 48 65 62 +636113 850147 426.57 124 1 1 1 0 1 -2 124 7328 246507 106 99 114 +636123 849913 489.11 2 1 3 0 0 1 2 132 7328 246507 103 101 118 +636087 849982 424.7 43 3 3 1 0 2 0 126 7328 246508 62 74 74 +636024 850179 426.38 158 1 1 1 0 2 -5 124 7328 246508 136 105 138 +635957 850336 426.67 97 1 1 1 0 1 -8 122 7328 246508 141 106 141 +635969 849937 462.01 12 2 2 0 0 1 0 130 7328 246508 53 64 68 +635956 849717 479.82 2 1 2 0 0 1 5 128 7328 246508 56 73 72 +635787 850497 439.73 22 1 1 1 0 1 -10 124 7328 246509 71 61 81 +635823 849938 407.22 74 1 1 0 0 2 1 128 7328 246509 98 102 114 +635765 849961 536.58 12 1 3 1 0 1 2 124 7328 246509 46 60 60 +635673 850158 435.73 70 1 1 1 0 1 0 124 7328 246509 228 220 231 +635699 849416 423.92 2 1 1 1 0 1 15 128 7328 246509 101 95 119 +635651 850244 424.93 33 1 1 1 0 2 -11 126 7329 247176 109 104 122 +635712 850237 437.34 51 2 2 0 0 1 -10 124 7329 247176 164 136 154 +635769 850249 475.85 0 2 2 1 0 1 -8 129 7329 247176 56 71 68 +635878 850414 426.41 128 1 1 0 0 1 -4 124 7329 247177 133 104 130 +635872 850110 424.54 143 1 1 0 0 1 -11 122 7329 247177 58 62 64 +635944 850107 425.43 159 1 1 1 0 1 -13 127 7329 247177 64 72 82 +636083 850430 425.75 22 1 1 1 0 2 -7 124 7329 247178 127 97 130 +636079 850168 426.51 158 1 1 0 0 2 -12 124 7329 247178 132 100 135 +636158 850361 424.31 1 1 1 1 0 2 -7 124 7329 247179 152 110 148 +636145 850255 426.02 63 1 1 1 0 1 -8 126 7329 247179 134 106 140 +636159 850173 427 136 1 1 0 0 2 -10 126 7329 247179 48 66 62 +636229 850320 424.57 141 1 1 0 0 2 -8 126 7329 247179 62 80 80 +636213 850174 426.38 83 2 2 1 0 1 -11 128 7329 247180 60 76 75 +636222 850125 512.27 9 2 2 0 0 1 -13 126 7329 247180 56 67 70 +636232 850078 460.33 15 2 3 1 0 1 -14 128 7329 247180 102 104 116 +636251 850045 425.92 133 1 1 0 0 1 -14 126 7329 247180 88 89 105 +636327 850120 458.79 21 1 1 0 0 1 -13 126 7329 247181 60 74 80 +636411 850211 434.48 127 1 1 0 0 2 -14 124 7329 247181 118 96 126 +636439 850105 480.05 24 1 1 0 0 1 -18 122 7329 247181 65 74 80 +636473 850067 440.91 13 2 2 1 0 1 -19 126 7329 247182 79 86 96 +636579 850318 437.47 141 1 1 1 0 2 -12 126 7329 247182 130 102 130 +636553 850068 445.67 153 1 1 1 0 2 -15 126 7329 247182 91 89 105 +636677 850308 440.49 104 1 1 0 0 1 -8 124 7329 247183 130 90 120 +636673 850076 465.91 109 1 1 1 0 1 -11 124 7329 247183 78 65 86 +636764 850157 444.59 133 1 1 1 0 2 -10 124 7329 247183 132 107 142 +636796 850061 446.62 64 2 2 1 0 1 -12 127 7329 247184 57 70 74 +636824 850017 432.15 2 2 2 0 0 1 -11 126 7329 247184 101 100 122 +636940 850317 442.62 114 1 1 1 0 2 -4 124 7329 247184 58 72 74 +636989 850330 442.36 0 3 3 0 0 2 -5 124 7329 247185 54 69 69 +636973 850109 496.39 28 1 1 1 0 1 -11 128 7329 247185 96 98 114 +637093 850373 440.16 1 2 2 1 0 1 -7 128 7329 247185 100 94 115 +637129 850319 426.54 7 2 2 1 0 1 -8 128 7329 247185 58 66 77 +637124 850106 423.49 56 1 1 1 0 1 -11 130 7329 247185 69 78 86 +637184 850060 429.92 104 1 1 1 0 1 -10 130 7329 247186 52 64 66 +638807 849256 424.9 125 1 1 1 0 1 -11 124 7326 245370 183 137 169 +638774 849164 424.74 149 1 1 1 0 1 -9 124 7326 245371 177 130 163 +638703 849285 423.72 151 1 1 0 0 1 -11 124 7326 245371 156 125 152 +638647 849336 423.72 120 1 1 1 0 1 -12 124 7326 245371 120 113 142 +638596 849263 423.82 167 1 1 0 0 1 -9 126 7326 245372 181 132 162 +638553 849130 424.67 144 1 1 1 0 1 -7 124 7326 245372 170 125 152 +638510 848980 423.39 33 1 1 1 0 1 -4 124 7326 245372 146 120 142 +638386 849355 425.23 134 1 1 0 0 2 -13 126 7326 245373 163 120 148 +638386 849130 534.81 8 1 3 0 0 1 -10 128 7326 245373 69 84 82 +638324 849189 429.63 169 1 1 1 0 1 -12 126 7326 245373 118 122 149 +638278 849186 425.79 190 1 1 0 0 2 -11 130 7326 245373 116 113 140 +638218 849312 429.53 16 1 1 0 0 1 -13 130 7326 245374 70 84 80 +638205 849186 425.26 43 1 1 0 0 1 -9 128 7326 245374 98 94 100 +638136 849348 449.64 70 1 2 0 0 1 -11 126 7326 245374 100 106 124 +638116 849266 448.33 1 1 2 1 0 1 -9 128 7326 245374 83 96 98 +638093 849225 538.65 33 2 3 0 0 1 -9 128 7326 245374 104 104 120 +638039 849298 468.67 26 1 2 0 0 1 -10 135 7326 245375 74 84 87 +637997 849325 424.57 18 1 1 0 0 1 -10 131 7326 245375 96 104 108 +637992 849233 538.75 4 1 3 0 0 1 -9 130 7326 245375 65 78 78 +637990 849063 428.28 4 1 1 1 0 1 -5 128 7326 245375 57 81 75 +637934 849148 466.57 8 1 2 1 0 1 -7 130 7326 245375 96 100 113 +637931 848955 413.02 216 1 1 1 0 1 -3 127 7326 245376 78 95 92 +637811 849127 411.78 2 1 1 0 0 2 -7 126 7326 245376 178 142 169 +637635 849207 411.48 1 1 1 0 0 2 -9 126 7326 245377 108 92 106 +637338 848956 422.54 20 2 2 1 0 1 -8 133 7326 245379 54 64 70 +637240 849979 424.8 59 2 2 1 0 1 7 126 7327 246101 70 72 84 +637187 849495 411.35 225 1 1 1 0 2 -1 126 7327 246102 74 86 93 +637272 849755 507.51 1 2 3 0 0 1 4 126 7327 246102 82 90 94 +637332 849888 520.83 54 1 2 0 0 1 8 128 7327 246102 97 106 115 +637399 850034 428.28 91 2 2 1 0 1 11 126 7327 246102 108 114 126 +637181 848943 452.99 1 1 2 1 0 1 -11 126 7327 246102 82 71 84 +637257 849162 411.09 5 1 1 0 0 2 -7 124 7327 246102 80 88 95 +637461 849916 425.75 68 1 1 0 0 1 8 126 7327 246103 67 66 79 +637449 849747 428.08 173 1 1 0 0 2 4 126 7327 246103 140 106 134 +637433 849568 420.28 25 3 3 0 0 2 0 124 7327 246103 52 66 65 +637342 849088 411.58 23 1 1 0 0 1 -10 126 7327 246103 78 88 92 +637562 849886 427.13 78 1 1 1 0 1 6 124 7327 246103 110 80 112 +637614 849997 426.18 123 1 1 0 0 1 9 126 7327 246104 104 98 133 +637568 849748 429.33 146 1 1 1 0 2 4 126 7327 246104 63 70 70 +637459 849262 411.19 11 1 1 0 0 2 -5 124 7327 246104 79 87 87 +637636 849924 426.64 96 1 1 0 0 1 9 122 7327 246104 108 96 124 +637531 849441 411.29 12 1 1 0 0 2 0 121 7327 246104 71 85 88 +637620 849728 429.72 171 1 1 1 0 1 5 126 7327 246104 62 71 71 +637635 849709 472.24 11 1 2 0 0 1 4 122 7327 246105 84 72 76 +637718 849956 464.6 1 1 2 0 0 1 9 122 7327 246105 77 89 86 +637738 849953 442.19 7 1 2 1 0 1 8 128 7327 246105 74 80 85 +637584 849231 411.61 204 1 1 0 0 1 -7 124 7327 246105 72 78 80 +637756 849840 429.59 49 2 2 1 0 1 5 126 7327 246105 65 78 81 +637784 849881 428.54 138 1 1 1 0 1 6 126 7327 246105 52 61 65 +637728 849561 429.49 180 1 1 0 0 1 0 128 7327 246106 102 79 95 +637738 849493 522.54 2 1 3 1 0 1 0 129 7327 246106 68 76 84 +637796 849649 429.82 96 1 1 0 0 2 3 126 7327 246106 65 71 72 +637879 849902 427.23 135 1 1 1 0 2 9 125 7327 246106 141 105 135 +637879 849790 428.61 163 1 1 1 0 1 7 127 7327 246106 159 118 148 +637877 849663 429.23 141 1 1 1 0 1 5 126 7327 246106 140 133 155 +637938 849793 428.84 136 1 1 1 0 1 7 126 7327 246107 160 118 148 +637821 849149 412.66 62 1 1 1 0 1 -6 130 7327 246107 139 112 141 +637965 849662 429.17 152 1 1 1 0 1 4 128 7327 246107 148 118 136 +637910 849287 522.44 5 1 2 0 0 1 -4 124 7327 246107 72 84 83 +637983 849492 440.81 46 1 2 1 0 1 0 130 7327 246107 84 88 106 +638069 849755 427.62 67 1 1 1 0 1 5 128 7327 246108 91 82 91 +638072 849651 428.41 131 1 1 0 0 1 4 126 7327 246108 168 129 155 +638013 849281 424.21 0 4 4 0 0 1 -3 128 7327 246108 118 112 133 +638036 849271 422.9 0 4 4 1 0 2 -4 134 7327 246108 113 113 133 +638033 849162 414.4 160 1 1 0 0 1 -6 130 7327 246108 80 96 94 +638091 849294 446.33 1 1 2 0 0 1 -2 128 7327 246108 77 86 98 +638215 849724 443.34 41 1 2 1 0 1 7 130 7327 246108 88 83 110 +638113 849172 536.81 1 1 3 0 0 1 -2 128 7327 246108 90 92 106 +638233 849619 447.11 28 1 1 1 0 1 8 131 7327 246109 103 107 125 +638179 849262 530.61 6 1 3 1 0 1 1 132 7327 246109 80 90 96 +638160 849091 418.67 58 2 2 1 0 1 0 135 7327 246109 99 109 113 +638210 849254 428.54 0 3 3 0 0 2 3 128 7327 246109 84 94 104 +638273 849482 426.35 203 1 1 1 0 1 8 132 7327 246109 133 113 127 +638214 849068 542.91 29 1 3 1 0 1 0 135 7327 246109 58 74 72 +638281 849337 429.63 113 1 1 0 0 2 5 128 7327 246109 146 124 146 +638222 848909 414.7 55 1 1 0 0 1 -3 128 7327 246109 121 106 117 +638277 849054 462.73 28 1 3 1 0 1 -1 132 7327 246110 100 102 112 +638469 849984 425.72 28 2 2 1 0 2 18 131 7327 246110 103 100 124 +638502 849993 426.35 169 1 1 0 0 2 18 127 7327 246110 86 80 100 +638485 849687 417.32 28 1 1 0 0 1 12 131 7327 246110 82 97 95 +638442 849251 426.97 179 1 1 0 0 1 3 128 7327 246110 181 130 164 +638487 849360 424.61 177 1 1 0 0 2 5 129 7327 246111 114 104 132 +638475 849135 483.3 5 1 2 0 0 1 0 126 7327 246111 97 105 114 +638507 849178 425.75 175 1 1 1 0 2 0 128 7327 246111 162 126 156 +638496 848922 434.88 19 2 3 0 0 1 -6 124 7327 246111 102 104 119 +638536 848900 419.03 176 1 1 1 0 2 -7 128 7327 246111 108 114 124 +638720 849658 417.36 38 1 1 0 0 1 7 130 7327 246112 77 98 95 +638659 849043 445.54 36 1 1 1 0 1 -5 128 7327 246112 62 88 84 +638822 849710 417.13 8 1 1 1 0 2 8 126 7327 246112 77 93 96 +638836 849544 417.26 21 1 1 0 0 2 5 128 7327 246112 56 80 71 +638875 849335 424.34 130 1 1 1 0 1 1 124 7327 246113 176 140 160 +638886 850064 420.34 80 2 2 1 0 1 -2 126 7328 246490 90 105 106 +638826 850069 437.8 2 1 2 1 0 1 -2 126 7328 246491 58 79 72 +638746 850184 417.75 91 1 1 0 0 1 -5 126 7328 246491 99 103 121 +638837 849381 422.18 174 1 1 1 0 2 11 126 7328 246491 175 131 156 +638650 850164 417.95 2 2 2 0 0 2 -5 127 7328 246491 98 98 114 +638644 849996 417.16 39 1 1 1 0 2 -1 128 7328 246491 86 90 94 +638587 850046 437.14 17 1 2 1 0 1 -2 124 7328 246492 66 80 84 +638505 850149 447.8 69 1 2 0 0 1 -5 126 7328 246492 109 107 128 +638513 849784 417.22 11 1 1 0 0 1 1 126 7328 246492 83 94 94 +638381 850269 425.82 140 1 1 0 0 1 -9 126 7328 246492 104 105 112 +638362 850165 439.8 11 1 2 1 0 1 -7 126 7328 246493 124 122 146 +638333 850130 446.23 60 1 2 0 0 1 -7 126 7328 246493 105 105 126 +638329 849956 441.57 14 1 2 1 0 1 -3 124 7328 246493 98 100 120 +638228 850308 425.69 128 1 1 1 0 2 -11 124 7328 246493 115 105 121 +638290 849777 438.85 60 1 1 0 0 1 0 128 7328 246493 95 102 117 +638317 849479 423.92 68 1 1 1 0 2 6 126 7328 246494 147 103 123 +638165 850205 443.31 1 1 2 0 0 1 -8 128 7328 246494 116 122 142 +638220 849771 442.68 70 1 2 0 0 1 1 128 7328 246494 88 89 114 +638234 849570 444.46 7 1 1 1 0 1 4 128 7328 246494 58 78 76 +638134 849987 426.31 128 1 1 0 0 1 -4 126 7328 246494 146 125 152 +638028 850417 424.7 119 1 1 0 0 2 -14 126 7328 246494 135 110 132 +638072 850010 427.26 170 1 1 0 0 1 -5 126 7328 246494 138 110 136 +638150 849415 428.28 33 2 2 1 0 2 6 128 7328 246495 102 109 128 +638104 849512 428.31 38 2 2 1 0 2 5 124 7328 246495 102 107 124 +637972 850102 427.3 124 1 1 1 0 2 -5 127 7328 246495 150 117 149 +637985 849882 427.95 118 1 1 1 0 2 0 126 7328 246495 94 92 104 +638063 849325 463.98 1 1 2 1 0 1 14 126 7328 246495 100 106 123 +638018 849423 427.53 131 1 1 1 0 2 13 126 7328 246495 101 101 125 +637830 850283 425.85 113 1 1 1 0 2 -3 126 7328 246495 102 104 124 +637962 849453 428.05 79 2 2 1 0 1 13 129 7328 246496 104 108 128 +637870 849828 428.35 209 1 1 0 0 2 5 128 7328 246496 66 71 75 +637801 850091 458.27 2 1 2 1 0 1 0 128 7328 246496 71 76 78 +637729 850340 428.18 113 1 1 0 0 1 -5 124 7328 246496 88 80 92 +637824 849786 458.43 120 1 1 0 0 1 6 126 7328 246496 56 66 68 +637701 850260 421.56 7 3 3 1 0 2 -3 128 7328 246496 70 86 90 +637878 849385 502.33 2 2 3 0 0 1 15 128 7328 246497 114 117 134 +637832 849486 429.3 194 1 1 0 0 1 13 128 7328 246497 97 96 112 +637636 850225 425.46 102 1 1 1 0 2 -2 124 7328 246497 83 88 100 +637798 849430 530.48 32 1 3 0 0 1 15 130 7328 246497 74 86 88 +637618 850088 446.98 64 1 1 0 0 1 0 126 7328 246497 68 80 88 +637722 849575 440.81 13 2 2 1 0 1 12 124 7328 246497 76 78 82 +637573 850154 426.02 150 1 1 1 0 1 0 126 7328 246497 61 69 70 +637496 850438 424.51 113 1 1 1 0 1 -5 126 7328 246498 129 102 124 +637584 850033 426.12 141 1 1 1 0 1 4 126 7328 246498 123 109 146 +637717 849433 415.94 62 2 2 1 0 1 17 128 7328 246498 50 68 65 +637497 850371 425.75 119 1 1 0 0 1 -2 126 7328 246498 145 104 131 +637700 849460 421.23 90 1 1 0 0 1 15 128 7328 246498 46 68 63 +637473 850445 424.05 129 1 1 1 0 2 -6 126 7328 246498 135 107 133 +637666 849507 426.38 42 1 1 0 0 1 11 130 7328 246499 100 102 116 +637569 849854 427.26 167 1 1 0 0 2 4 128 7328 246499 136 102 136 +637423 850445 424.51 146 1 1 0 0 1 -6 126 7328 246499 162 121 148 +637503 849979 425.26 133 1 1 0 0 1 3 126 7328 246499 60 70 74 +637571 849550 454.72 25 1 2 1 0 1 11 126 7328 246499 69 75 82 +637385 850379 460.1 7 2 2 1 0 1 -7 128 7328 246499 64 74 78 +637516 849540 471.42 12 1 2 1 0 1 10 126 7328 246500 57 70 71 +637477 849600 424.97 19 1 1 1 0 2 9 125 7328 246500 83 86 98 +637332 850260 425.85 187 1 1 0 0 1 -3 128 7328 246500 51 65 68 +637433 849534 489.9 3 1 1 1 0 1 11 127 7328 246500 67 79 82 +637265 850365 528.84 11 1 2 0 0 1 -5 130 7328 246500 64 77 80 +637322 849877 443.41 18 1 2 1 0 1 4 128 7328 246500 52 61 63 +637276 850001 444.09 16 1 2 1 0 1 1 128 7328 246500 106 110 126 +637271 849895 429.36 205 1 1 0 0 1 3 132 7328 246501 96 101 110 +637279 849717 424.18 37 1 1 1 0 1 6 126 7328 246501 136 109 126 +637243 849790 530.81 23 1 2 0 0 1 4 132 7328 246501 50 68 64 +637231 849592 416.04 1 3 3 0 0 1 9 133 7328 246501 72 74 88 +637276 850397 430.91 49 2 2 1 0 1 -3 130 7329 247186 75 83 93 +637230 850060 427.59 182 1 1 0 0 1 -10 128 7329 247186 50 62 68 +637348 850294 435.27 10 1 1 0 0 1 -6 126 7329 247186 48 67 63 +637352 850067 469.88 33 1 2 1 0 1 -14 126 7329 247187 69 75 83 +637428 850119 453.71 14 1 3 0 0 1 -14 126 7329 247187 52 63 68 +637466 850009 447.64 1 2 2 1 0 1 -16 125 7329 247187 73 79 85 +637547 850098 459.45 157 1 1 1 0 1 -13 126 7329 247188 86 78 94 +637623 850211 425.66 143 1 1 1 0 1 -11 124 7329 247188 74 80 89 +637653 850057 435.79 36 1 1 1 0 1 -9 124 7329 247188 99 92 115 +637712 850058 426.51 181 1 1 0 0 2 -8 126 7329 247189 168 114 146 +637766 850017 426.71 191 1 1 1 0 1 -9 124 7329 247189 138 108 130 +637861 850307 443.04 2 1 2 0 0 1 -2 126 7329 247189 71 81 87 +637863 850045 493.73 6 1 3 0 0 1 -7 130 7329 247190 56 68 68 +637888 850041 420.08 80 2 2 1 0 1 -6 126 7329 247190 125 126 146 +637962 850287 462.66 51 1 2 0 0 1 -3 130 7329 247190 125 120 148 +637978 850077 426.94 185 1 1 0 0 2 -11 130 7329 247191 112 106 124 +638045 850046 437.6 26 1 1 1 0 1 -16 129 7329 247191 135 112 147 +638103 849974 449.34 3 1 2 0 0 1 -16 126 7329 247191 123 119 136 +638217 850124 449.21 3 1 2 0 0 1 -11 126 7329 247192 122 125 152 +638333 850282 425.23 165 1 1 1 0 1 -9 128 7329 247192 118 113 138 +638382 850270 426.05 124 1 1 0 0 1 -11 126 7329 247192 97 98 105 +638406 850123 426.38 41 2 2 1 0 1 -13 128 7329 247192 97 98 120 +638448 850136 428.9 103 2 2 0 0 1 -12 124 7329 247193 97 102 118 +638484 850184 450.43 45 2 3 1 0 1 -10 130 7329 247193 137 126 152 +638506 850077 428.15 0 2 2 0 0 2 -10 126 7329 247193 52 81 74 +638548 850049 449.61 55 1 1 1 0 1 -9 130 7329 247194 70 82 89 +638626 850254 418.18 39 2 2 0 0 1 -4 129 7329 247194 117 113 135 +638723 850374 430.22 4 1 2 0 0 1 -2 126 7329 247194 70 86 84 +638787 850148 426.02 1 1 1 1 0 1 -8 133 7329 247195 59 78 74 +638865 850273 423.59 94 1 1 0 0 1 -5 126 7329 247195 73 84 90 +638904 850229 426.61 15 2 2 0 0 1 -6 128 7329 247195 119 113 139 +637150 850711 451.57 2 1 2 0 0 1 -13 126 7328 246500 77 90 96 +637114 850613 425.46 153 1 1 0 0 1 -12 128 7328 246501 66 74 84 +637031 850633 426.61 190 1 1 0 0 1 -10 128 7328 246502 126 112 146 +636941 850529 436.88 163 1 1 0 0 2 -9 128 7328 246502 123 95 120 +636821 850477 436.84 70 1 1 1 0 2 -10 126 7328 246503 144 102 128 +636680 850626 434.19 139 1 1 1 0 1 -11 126 7328 246503 171 123 166 +636564 850640 433.37 133 1 1 0 0 1 -13 128 7328 246504 140 108 146 +636463 850566 432.61 128 1 1 0 0 1 -13 128 7328 246505 167 122 159 +636356 850530 432.68 171 1 1 0 0 2 -12 128 7328 246505 148 114 146 +636228 850592 428.67 133 1 1 0 0 1 -12 128 7328 246506 140 105 132 +636115 850574 423.92 123 1 1 1 0 1 -10 124 7328 246507 155 114 145 +636015 850670 424.77 149 1 1 1 0 1 -13 124 7328 246507 176 128 165 +635926 850603 425.82 21 1 1 1 0 2 -14 122 7328 246508 139 122 133 +635760 850676 424.67 144 1 1 1 0 1 -14 124 7328 246509 147 114 150 +635679 851351 436.45 6 2 2 0 0 1 10 126 7329 247174 76 87 92 +635704 851161 417.95 16 1 1 0 0 1 9 126 7329 247175 51 71 63 +635793 851286 418.21 137 1 1 0 0 2 12 124 7329 247175 92 80 94 +635847 851295 419.36 129 1 1 0 0 1 11 124 7329 247175 140 105 138 +635889 851265 418.86 118 1 1 1 0 2 10 124 7329 247175 180 130 161 +635945 851319 419.39 80 1 1 0 0 1 11 124 7329 247176 177 129 155 +635759 850517 425.07 175 1 1 1 0 2 -5 126 7329 247176 115 96 128 +636008 851287 419.26 98 1 1 0 0 1 12 125 7329 247176 181 126 161 +635931 850902 423.46 12 2 2 1 0 2 4 124 7329 247176 116 108 126 +635914 850730 424.77 151 1 1 0 0 2 1 124 7329 247176 180 128 165 +635976 850832 424.7 156 1 1 0 0 1 4 124 7329 247177 173 123 159 +635970 850687 424.48 164 1 1 1 0 1 1 126 7329 247177 167 120 153 +636090 851016 422.41 114 1 1 1 0 1 7 122 7329 247177 114 105 116 +636109 850940 422.87 114 1 1 1 0 2 4 124 7329 247177 104 98 122 +636081 850687 424.28 155 1 1 1 0 2 -1 124 7329 247177 156 114 144 +636175 850940 423.52 15 1 1 0 0 2 3 122 7329 247178 158 124 149 +636114 850570 423.88 122 1 1 1 0 2 -4 124 7329 247178 153 112 142 +636260 851042 425.03 131 1 1 1 0 2 5 124 7329 247178 72 81 89 +636218 850734 425.56 34 1 1 1 0 2 0 124 7329 247178 160 134 151 +636381 851312 418.31 109 1 1 0 0 2 12 125 7329 247178 138 108 142 +636370 851220 417.26 94 1 1 0 0 1 11 126 7329 247179 82 82 80 +636396 851300 417.52 16 1 1 1 0 1 13 124 7329 247179 174 145 166 +636398 851266 497.64 11 1 2 0 0 1 13 126 7329 247179 69 74 78 +636417 851252 418.14 86 2 2 0 0 1 12 126 7329 247179 81 90 97 +636384 851020 470.57 33 2 2 0 0 1 7 126 7329 247179 63 72 76 +636485 851335 419.55 110 1 1 0 0 1 13 126 7329 247179 191 135 168 +636457 851144 415.78 143 1 1 1 0 1 8 124 7329 247180 164 114 147 +636322 850549 430.64 147 1 1 1 0 2 -4 126 7329 247180 128 102 135 +636429 850894 438.32 21 1 1 0 0 1 3 125 7329 247180 64 65 72 +636532 851215 419 169 1 1 1 0 2 9 126 7329 247180 176 138 166 +636583 851326 419.91 124 1 1 1 0 1 12 124 7329 247180 190 136 168 +636491 850854 446.39 0 2 3 0 0 1 2 124 7329 247181 100 90 106 +636577 851021 426.51 168 1 1 1 0 2 4 126 7329 247181 84 86 102 +636608 850980 431.86 35 1 1 0 0 1 2 124 7329 247181 136 110 134 +636736 851317 434.61 117 1 1 1 0 1 7 124 7329 247181 114 96 112 +636725 851142 430.25 4 1 1 1 0 1 3 124 7329 247181 83 82 95 +636768 851182 418.67 32 1 1 0 0 1 4 124 7329 247182 138 122 138 +636799 851177 446.95 5 1 2 0 0 1 5 124 7329 247182 66 72 82 +636790 851027 432.12 83 1 1 0 0 1 3 122 7329 247182 162 114 145 +636682 850506 435.99 111 1 1 1 0 1 -6 124 7329 247182 132 92 124 +636903 851163 427.17 178 1 1 1 0 1 9 124 7329 247183 160 110 136 +636978 851292 417.91 62 1 1 1 0 1 13 124 7329 247183 178 130 160 +636947 851037 426.31 136 1 1 0 0 1 8 122 7329 247183 110 89 110 +636964 850957 427.13 158 1 1 0 0 2 6 124 7329 247183 177 139 163 +637005 850981 425.95 131 1 1 0 0 2 6 124 7329 247183 166 117 146 +636953 850660 486.84 25 1 2 1 0 1 0 124 7329 247184 87 92 102 +637025 850829 424.25 35 1 1 1 0 1 5 124 7329 247184 142 118 130 +637086 850962 424.34 111 1 1 1 0 2 9 122 7329 247184 187 133 163 +637145 851045 422.18 124 1 1 0 0 2 11 124 7329 247184 165 120 147 +637160 850885 420.96 174 1 1 1 0 2 5 125 7329 247185 180 126 158 +637181 850594 454.43 21 1 2 0 0 1 -2 126 7329 247185 106 104 123 +637223 851574 452 111 1 1 0 0 1 -4 130 7330 247566 232 216 227 +637127 851792 475.52 128 1 1 0 0 1 -11 122 7330 247566 78 88 87 +637084 851828 478.02 143 1 1 0 0 1 -12 124 7330 247566 185 168 186 +637030 851930 484.48 149 1 1 1 0 1 -14 126 7330 247566 64 77 75 +637081 851504 425.52 28 1 1 0 0 2 -4 126 7330 247567 151 132 142 +637157 850968 422.9 168 1 1 0 0 1 7 122 7330 247567 169 128 148 +637061 851347 424.31 40 1 1 0 0 2 0 124 7330 247567 162 134 156 +637005 851489 425.46 98 1 1 0 0 2 -3 124 7330 247567 229 219 227 +636946 851661 423.33 48 1 1 0 0 2 -7 124 7330 247567 185 164 177 +636976 851339 423.33 90 1 1 1 0 1 -1 128 7330 247567 207 173 201 +637035 850878 424.61 85 1 1 0 0 1 7 124 7330 247567 159 116 140 +636827 851881 470.64 12 1 1 0 0 1 -13 124 7330 247568 152 149 154 +636984 850904 425.26 110 1 1 1 0 1 6 122 7330 247568 144 114 142 +636855 851482 422.38 20 1 1 0 0 2 -6 122 7330 247568 152 128 146 +636821 851540 426.31 89 1 1 1 0 1 -8 126 7330 247568 165 142 156 +636917 850897 428.44 105 1 1 1 0 2 4 122 7330 247568 136 112 137 +636925 850725 454 1 2 3 1 0 1 8 122 7330 247568 70 74 83 +636819 851177 436.84 1 1 2 1 0 1 0 124 7330 247568 106 98 122 +636704 851663 448.1 45 1 1 1 0 1 -10 122 7330 247569 249 239 249 +636865 850683 435.3 150 1 1 0 0 1 11 124 7330 247569 66 74 72 +636718 851320 419.62 104 1 1 0 0 2 0 124 7330 247569 144 110 130 +636574 851906 490.75 10 1 1 0 0 1 -12 124 7330 247569 128 130 136 +636619 851498 417.49 38 1 1 1 0 1 -4 126 7330 247569 173 148 165 +636645 851187 411.84 33 1 1 1 0 1 2 126 7330 247569 180 142 164 +636542 851554 416.63 18 1 1 1 0 2 -6 124 7330 247569 191 168 183 +636526 851477 418.14 169 1 1 1 0 2 -5 124 7330 247570 69 81 74 +636600 850969 431.99 30 1 1 0 0 1 5 126 7330 247570 136 117 140 +636383 851938 414.7 68 1 1 1 0 2 -14 124 7330 247570 64 76 75 +636581 850850 433.79 102 1 1 0 0 1 8 124 7330 247570 152 112 143 +636418 851574 417.75 144 1 1 1 0 2 -6 124 7330 247570 138 108 146 +636393 851614 416.96 59 1 1 0 0 1 -7 124 7330 247570 177 149 173 +636498 851015 423.26 83 2 2 0 0 1 5 124 7330 247570 74 84 89 +636509 850867 450.79 19 1 2 0 0 1 9 124 7330 247570 107 104 118 +636492 850845 432.35 5 2 2 1 0 2 10 126 7330 247571 155 134 150 +636375 851305 426.94 41 1 1 1 0 1 0 126 7330 247571 150 120 150 +636258 851772 415.68 41 1 1 1 0 2 -8 126 7330 247571 164 134 154 +636235 851759 415.55 60 1 1 0 0 1 -7 126 7330 247571 154 131 154 +636279 851393 419.23 86 1 1 0 0 1 1 124 7330 247571 162 122 158 +636292 851176 417.26 143 1 1 0 0 1 6 125 7330 247571 189 136 166 +636332 850812 445.67 69 1 1 0 0 1 14 124 7330 247571 112 108 135 +636317 850755 427.85 135 1 1 1 0 1 15 124 7330 247571 148 114 144 +636135 851635 416.83 36 1 1 1 0 1 -3 124 7330 247572 162 136 160 +636064 851914 416.04 209 1 1 0 0 1 -9 123 7330 247572 177 150 172 +636134 851372 420.41 160 1 1 0 0 2 0 126 7330 247572 141 112 144 +636172 851005 440.45 82 1 1 0 0 1 7 126 7330 247572 64 76 75 +636190 850746 424.44 199 1 1 1 0 1 12 126 7330 247572 137 107 140 +635984 851796 416.4 51 1 1 1 0 1 -9 126 7330 247572 126 105 116 +635945 851851 416.54 139 1 1 1 0 1 -9 128 7330 247572 106 100 120 +636109 850721 423 100 1 1 1 0 1 14 124 7330 247573 191 139 174 +636036 850999 423.06 164 1 1 1 0 1 8 126 7330 247573 136 112 139 +636050 850756 423.56 154 1 1 1 0 1 13 124 7330 247573 84 80 84 +635981 851022 460.93 15 2 3 1 0 1 8 126 7330 247573 108 108 124 +635857 851623 415.32 146 1 1 1 0 1 -3 125 7330 247573 162 111 146 +635978 850779 424.44 129 1 1 0 0 1 13 124 7330 247573 148 102 136 +635807 851648 416.7 154 1 1 1 0 2 -4 124 7330 247573 154 117 151 +635949 850720 424.9 132 1 1 1 0 1 15 124 7330 247573 187 130 170 +635773 851581 412.66 139 1 1 1 0 2 -3 124 7330 247574 165 130 155 +635718 851746 418.86 11 3 3 0 0 2 -7 124 7330 247574 72 82 86 +635863 850833 424.15 150 1 1 0 0 1 11 122 7330 247574 164 119 150 +635700 851554 414.86 159 1 1 1 0 2 -4 126 7330 247574 52 68 73 +635737 851232 476.21 7 1 2 0 0 1 1 124 7330 247574 78 83 95 +635681 851384 419 99 2 2 1 0 2 -3 130 7330 247574 81 84 95 +635771 850812 423.92 201 1 1 1 0 1 7 126 7330 247574 163 119 152 +635709 850802 423.39 143 1 1 0 0 1 8 124 7330 247575 185 136 170 +635710 852538 420.41 13 1 1 1 0 1 10 124 7331 248278 168 150 162 +635752 852432 420.24 95 1 1 1 0 1 6 122 7331 248278 156 128 158 +635720 852154 415.91 24 3 3 1 0 2 0 126 7331 248279 119 108 135 +635818 852439 415.68 112 1 1 1 0 2 6 122 7331 248279 152 122 144 +635834 852403 416.11 145 1 1 0 0 1 6 124 7331 248279 93 91 120 +635718 851814 417.13 133 1 1 0 0 1 -5 124 7331 248279 76 81 90 +635886 852431 415.65 111 1 1 1 0 2 7 126 7331 248279 109 104 128 +635887 852353 416.6 132 1 1 1 0 1 6 124 7331 248279 95 97 121 +635961 852610 463.85 116 1 1 0 0 1 11 126 7331 248280 64 76 78 +635888 852214 415.29 149 1 1 0 0 1 3 124 7331 248280 96 92 116 +635733 851454 419.03 9 2 2 1 0 2 -13 128 7331 248280 106 102 126 +635773 851557 416.9 85 1 1 0 0 1 -10 124 7331 248280 100 97 119 +635770 851465 422.28 81 1 1 1 0 1 -12 126 7331 248280 105 85 114 +635966 852266 416.21 204 1 1 1 0 2 4 124 7331 248280 100 100 123 +635791 851378 419.29 143 1 1 0 0 2 -14 124 7331 248280 166 130 166 +635816 851375 419.23 115 1 1 1 0 1 -14 124 7331 248280 188 130 172 +635838 851369 419.13 162 1 1 1 0 1 -14 126 7331 248280 196 140 176 +636009 852064 414.17 127 1 1 1 0 2 0 126 7331 248281 139 137 153 +635958 851726 416.37 53 1 1 0 0 2 -7 125 7331 248281 130 114 131 +636152 852559 420.64 23 1 1 1 0 1 10 124 7331 248281 170 134 156 +636112 852258 416.47 160 1 1 0 0 1 5 124 7331 248281 89 93 117 +636011 851650 417.85 97 1 1 0 0 1 -5 124 7331 248281 162 128 160 +636143 852178 415.94 183 1 1 1 0 1 7 124 7331 248281 86 92 112 +636236 852536 421.46 26 1 1 0 0 2 14 122 7331 248281 163 137 155 +636203 852288 417.26 140 1 1 0 0 2 9 122 7331 248282 90 93 115 +636019 851329 419.19 39 1 1 0 0 1 -12 124 7331 248282 180 137 161 +636245 852312 417.81 158 1 1 1 0 2 6 122 7331 248282 88 96 116 +636317 852545 421.59 25 1 1 1 0 1 10 122 7331 248282 164 143 155 +636340 852553 421.33 14 1 1 1 0 1 10 122 7331 248282 159 130 149 +636315 852337 417.81 95 1 1 1 0 1 6 122 7331 248282 92 94 118 +636266 852026 415.09 177 1 1 1 0 2 0 124 7331 248282 96 100 121 +636226 851759 416.11 58 1 1 1 0 1 -4 126 7331 248283 115 101 123 +636215 851617 416.8 54 1 1 0 0 1 -7 124 7331 248283 125 113 120 +636397 852308 417.85 112 1 1 0 0 1 8 122 7331 248283 89 92 117 +636366 852073 415.72 102 1 1 0 0 2 4 122 7331 248283 95 100 118 +636276 851566 417.06 90 1 1 1 0 1 -6 124 7331 248283 82 78 91 +636444 852150 416.37 159 1 1 0 0 1 5 124 7331 248283 87 97 117 +636455 852070 424.15 147 1 1 1 0 2 2 122 7331 248283 110 101 110 +636575 852457 419.06 173 1 1 0 0 1 10 124 7331 248284 140 114 142 +636419 851675 419.19 183 1 1 1 0 1 -7 126 7331 248284 122 108 124 +636637 852512 438.62 6 1 2 0 0 1 10 126 7331 248284 129 112 125 +636509 851882 506.53 24 1 1 0 0 1 -3 125 7331 248284 123 125 133 +636625 852300 417.75 82 1 1 0 0 2 5 126 7331 248284 131 110 127 +636695 852534 422.34 107 1 1 1 0 1 10 126 7331 248284 175 151 166 +636644 852229 427.2 170 1 1 1 0 1 3 126 7331 248284 90 92 96 +636585 851875 500.59 15 1 1 1 0 1 -4 126 7331 248284 123 130 137 +636717 852344 418.08 17 1 1 1 0 1 5 124 7331 248285 156 132 148 +636755 852397 419.95 15 1 1 0 0 1 6 124 7331 248285 106 88 102 +636669 851912 477.13 15 1 1 0 0 1 -4 124 7331 248285 132 128 137 +636611 851566 426.57 127 1 1 0 0 1 -12 126 7331 248285 105 102 131 +636666 851737 472.83 17 1 1 1 0 1 -9 126 7331 248285 158 151 158 +636816 852309 419.62 19 1 1 0 0 1 3 124 7331 248285 171 151 164 +636596 851332 419.95 131 1 1 0 0 2 -17 126 7331 248285 205 150 182 +636749 851913 467.88 16 1 1 1 0 1 -4 124 7331 248286 136 134 140 +636934 852588 420.93 46 1 1 0 0 2 9 122 7331 248286 199 162 185 +636818 852041 461.84 77 1 1 0 0 1 -1 124 7331 248286 215 208 218 +636678 851408 418.86 120 1 1 0 0 1 -14 124 7331 248286 189 134 169 +636790 851739 488.62 16 1 1 1 0 1 -7 126 7331 248286 136 138 144 +636898 852036 425.16 97 1 1 1 0 2 0 126 7331 248286 228 218 229 +636965 852171 423.39 102 1 1 1 0 2 2 126 7331 248286 200 184 200 +637097 852553 423.2 34 1 1 1 0 1 10 124 7331 248287 172 148 162 +637031 852202 432.02 143 1 1 0 0 2 3 124 7331 248287 92 90 98 +636890 851572 422.93 24 1 1 0 0 1 -9 126 7331 248287 144 127 138 +636915 851562 422.77 19 1 1 1 0 1 -9 124 7331 248287 150 133 142 +637138 852298 434.02 20 1 1 1 0 2 6 122 7331 248287 145 129 141 +637224 852523 422.97 33 1 1 0 0 2 11 122 7331 248287 178 157 171 +637087 851920 454.17 91 1 1 0 0 1 -2 122 7331 248287 198 188 196 +637010 851522 425.36 158 1 1 1 0 1 -10 124 7331 248288 126 102 126 +637191 852074 426.35 237 1 1 0 0 1 2 126 7331 248288 158 142 157 +637064 851407 425.56 72 1 1 1 0 1 -10 124 7331 248288 225 209 220 +637147 851495 431.56 123 1 1 0 0 1 -7 122 7331 248288 124 106 132 +637240 851500 444.06 90 1 1 1 0 1 -10 126 7331 248289 224 210 222 +637255 852487 424.25 69 1 1 1 0 2 0 124 7332 248679 199 175 193 +637222 852366 425.07 24 1 1 1 0 1 1 126 7332 248680 152 134 144 +637089 852823 422.18 16 1 1 1 0 1 -8 117 7332 248680 151 133 146 +637075 852697 420.9 145 1 1 0 0 1 -4 122 7332 248680 147 114 150 +637096 852378 423.62 24 1 1 1 0 1 2 124 7332 248680 154 135 145 +637021 852621 423.1 7 2 2 1 0 2 -1 120 7332 248680 74 80 86 +636939 852906 437.89 24 1 1 1 0 1 -7 122 7332 248681 136 120 131 +636916 852865 433.5 3 1 1 1 0 1 -6 118 7332 248681 89 77 89 +637022 852143 442.26 86 1 1 1 0 2 9 120 7332 248681 87 92 100 +637028 851960 489.01 93 1 1 0 0 1 14 120 7332 248681 61 73 74 +636986 852000 444.19 82 1 1 1 0 2 14 120 7332 248681 80 88 95 +636932 852147 431.69 176 1 1 1 0 1 11 124 7332 248682 177 169 180 +636810 852675 420.54 138 1 1 1 0 1 0 124 7332 248682 119 107 130 +636816 852584 422.87 66 1 1 0 0 1 0 126 7332 248682 208 176 196 +636868 852239 433.3 13 1 1 0 0 1 6 128 7332 248682 143 138 142 +636849 852231 437.2 78 1 1 1 0 1 5 126 7332 248682 212 206 214 +636827 852256 437.37 54 1 1 1 0 1 5 124 7332 248682 207 192 204 +636856 852003 460.96 40 1 1 0 0 1 12 128 7332 248683 141 130 149 +636665 852786 421.19 15 1 1 1 0 1 -4 126 7332 248683 163 141 155 +636621 852810 421.03 5 1 1 0 0 2 -7 122 7332 248683 181 168 177 +636702 852193 461.65 69 1 1 1 0 1 5 124 7332 248683 197 183 196 +636684 852089 462.04 75 1 1 1 0 1 9 124 7332 248683 208 196 206 +636514 852775 421.26 24 1 1 1 0 1 -3 124 7332 248684 161 142 155 +636636 852032 441.14 27 1 2 1 0 1 13 124 7332 248684 115 104 113 +636590 852117 418.54 85 1 1 1 0 1 11 124 7332 248684 165 151 161 +636506 852397 418.9 163 1 1 1 0 2 4 124 7332 248684 112 110 128 +636531 852160 416.83 24 1 1 0 0 1 8 126 7332 248684 192 145 182 +636386 852788 468.41 10 1 3 1 0 1 -6 126 7332 248684 64 76 77 +636491 852162 416.47 81 1 1 0 0 1 7 126 7332 248685 94 94 108 +636480 852113 422.08 181 1 1 1 0 2 8 124 7332 248685 116 107 124 +636293 852933 423.46 158 1 1 1 0 1 -7 124 7332 248685 168 144 163 +636327 852631 419.72 92 1 1 1 0 1 0 120 7332 248685 138 112 142 +636404 852107 416.01 157 1 1 0 0 1 12 124 7332 248685 94 96 118 +636299 852442 416.21 127 1 1 1 0 2 6 120 7332 248685 128 116 134 +636248 852494 420.77 31 2 2 0 0 1 3 122 7332 248686 108 102 110 +636314 851958 414.8 93 1 1 0 0 1 11 124 7332 248686 175 126 141 +636151 852633 419.69 98 1 1 0 0 1 -4 122 7332 248686 96 80 98 +636112 852669 419.36 109 1 1 0 0 1 -5 122 7332 248686 142 106 136 +636202 851998 414.5 96 1 1 1 0 2 9 123 7332 248686 155 110 133 +636102 852390 415.65 162 1 1 1 0 1 1 124 7332 248687 92 95 116 +635976 852938 418.34 204 1 1 1 0 1 -8 126 7332 248687 114 100 124 +636104 852120 415.35 116 1 1 1 0 2 11 123 7332 248687 93 97 120 +636110 851990 426.15 33 1 1 1 0 1 15 122 7332 248687 165 137 165 +636096 851963 416.11 137 1 1 0 0 1 16 124 7332 248687 185 162 178 +636073 851986 418.47 89 1 1 1 0 1 15 122 7332 248687 138 118 132 +636053 851982 415.42 45 1 1 1 0 1 13 123 7332 248688 172 150 162 +635870 852869 416.8 108 2 2 1 0 1 -6 126 7332 248688 94 94 106 +635910 852515 420.54 37 1 1 1 0 1 0 126 7332 248688 153 132 146 +635963 851998 415.91 23 1 1 1 0 1 10 124 7332 248688 179 156 176 +635803 852739 418.9 139 1 1 0 0 1 -4 124 7332 248688 65 72 70 +635746 852852 412.47 20 2 2 1 0 2 -5 128 7332 248688 58 77 70 +635832 852057 416.5 29 1 1 1 0 2 11 126 7332 248689 154 131 144 +635753 852265 416.77 38 1 1 0 0 1 7 126 7332 248689 154 136 146 +635685 852165 421.75 109 1 1 1 0 1 7 126 7332 248689 64 73 78 +635746 852828 471.95 64 1 2 0 0 1 -10 124 7333 249387 62 75 74 +635745 852632 417.98 93 1 1 0 0 2 -18 120 7333 249388 70 77 74 +635883 852881 489.47 3 1 3 1 0 1 -14 128 7333 249388 103 94 113 +635964 852937 418.31 139 1 1 1 0 1 -13 124 7333 249388 113 105 127 +635994 852704 418.18 152 1 1 1 0 1 -11 124 7333 249389 124 109 134 +636108 852823 447.18 2 1 3 1 0 1 -8 128 7333 249389 77 82 92 +636160 852814 420.67 138 1 1 1 0 2 -10 124 7333 249390 111 98 126 +636186 852685 419.59 102 1 1 0 0 2 -11 120 7333 249390 136 108 134 +636302 852874 421.95 113 1 1 0 0 2 -7 125 7333 249390 152 126 148 +636374 852863 420.18 0 3 3 0 0 2 -9 126 7333 249391 62 73 71 +636437 852892 465.94 21 1 2 1 0 1 -8 124 7333 249391 86 91 99 +636476 852800 438.75 4 1 2 1 0 1 -10 124 7333 249391 118 110 137 +636570 852894 420.47 35 1 1 0 0 2 -6 124 7333 249392 100 88 96 +636649 852910 477.36 118 1 1 0 0 1 -7 124 7333 249392 72 80 86 +636656 852609 419.98 146 1 1 0 0 1 -13 126 7333 249392 86 91 102 +636720 852603 446.62 2 1 2 1 0 1 -10 124 7333 249393 77 94 94 +636805 852922 423.2 139 1 1 0 0 2 -9 122 7333 249393 154 122 145 +636865 852790 421.59 148 1 1 0 0 2 -13 122 7333 249394 120 105 137 +637013 852874 422.05 35 1 1 0 0 1 -8 126 7333 249394 182 164 176 +637074 852615 421.75 127 1 1 0 0 1 -11 122 7333 249394 99 98 121 +637173 852701 420.9 149 1 1 1 0 2 -13 122 7333 249395 152 114 152 +637262 852787 422.77 18 1 1 0 0 1 -12 124 7333 249395 156 134 154 +638909 850558 437.24 18 1 1 1 0 1 -9 132 7328 246489 108 110 126 +638826 850604 423.65 157 1 1 0 0 1 -12 128 7328 246490 68 86 85 +638749 850577 417.68 56 2 2 1 0 1 -12 126 7328 246490 109 113 126 +638672 850484 418.08 151 1 1 1 0 1 -11 126 7328 246491 79 88 84 +638588 850482 470.34 1 1 2 0 0 1 -12 130 7328 246491 116 112 130 +638472 850511 426.31 29 1 1 1 0 1 -12 126 7328 246492 166 126 155 +638349 850504 427.95 10 2 2 1 0 2 -14 128 7328 246492 118 107 124 +638250 850506 423.95 28 1 1 1 0 1 -15 126 7328 246493 199 159 183 +638124 850610 424.97 23 1 1 0 0 2 -17 126 7328 246493 188 138 162 +638029 850636 423.62 26 1 1 1 0 1 -17 128 7328 246494 106 88 100 +637944 850554 422.83 84 2 2 1 0 2 -16 128 7328 246495 112 118 129 +637845 850559 424.18 187 1 1 1 0 2 -12 124 7328 246495 126 109 130 +637758 850627 525.98 1 1 3 1 0 1 -11 128 7328 246496 53 64 68 +637685 850649 446.23 44 1 2 0 0 1 -11 126 7328 246496 74 83 90 +637644 850531 434.88 3 2 2 1 0 1 -9 128 7328 246496 56 64 70 +637532 850447 424.15 139 1 1 1 0 1 -6 126 7328 246497 77 75 79 +637452 850601 466.08 7 1 3 0 0 1 -7 126 7328 246498 94 95 115 +637456 850527 421.33 168 1 1 1 0 1 -7 126 7328 246498 119 116 127 +637418 850516 421.46 96 1 1 0 0 1 -8 126 7328 246499 101 92 124 +637383 850510 439.04 3 2 2 0 0 1 -8 124 7328 246499 65 76 84 +637322 850531 419.46 34 1 1 1 0 1 -10 128 7328 246500 74 82 88 +637264 850571 421.52 75 2 2 1 0 1 -9 131 7328 246500 82 82 100 +637236 851037 442.16 9 1 2 0 0 1 8 124 7329 247185 69 76 84 +637380 851215 423.56 33 1 1 1 0 1 10 124 7329 247185 183 158 176 +637270 850648 427.17 192 1 1 0 0 1 0 128 7329 247185 98 96 116 +637306 850627 468.04 7 1 2 0 0 1 1 128 7329 247186 92 90 108 +637391 850808 421 155 1 1 1 0 2 5 128 7329 247186 81 84 94 +637349 850509 501.71 0 2 2 1 0 1 -1 128 7329 247186 53 66 66 +637431 850671 417.22 43 1 1 0 0 1 1 128 7329 247186 74 84 86 +637569 851035 421.36 204 1 1 0 0 1 7 128 7329 247186 182 153 172 +637504 850588 420.57 90 1 1 0 0 2 -3 128 7329 247187 103 89 105 +637637 850956 421.82 170 1 1 1 0 1 3 126 7329 247187 180 156 171 +637695 851052 421.19 53 1 1 1 0 1 5 126 7329 247187 168 144 158 +637629 850624 440.39 16 1 2 1 0 1 -2 126 7329 247187 53 64 65 +637660 850632 421.56 68 3 3 1 0 2 -1 126 7329 247187 101 102 116 +637819 851241 420.8 36 1 1 0 0 1 10 128 7329 247188 172 139 163 +637802 851047 419.06 26 1 1 1 0 1 6 126 7329 247188 174 152 165 +637760 850737 423 120 1 1 1 0 1 2 124 7329 247188 61 75 74 +637810 850927 421.52 23 1 1 1 0 1 9 124 7329 247188 176 149 166 +637771 850596 487.11 2 1 2 0 0 1 3 130 7329 247188 100 94 116 +637891 851233 420.34 21 1 1 0 0 1 15 130 7329 247189 171 144 162 +637812 850463 423.88 140 1 1 1 0 1 0 126 7329 247189 88 82 110 +637956 851265 420.9 60 1 1 0 0 1 16 130 7329 247189 194 150 175 +637975 851129 420.7 82 1 1 0 0 1 14 130 7329 247189 184 141 169 +638004 851055 420.8 22 1 1 1 0 2 13 124 7329 247189 203 163 185 +638037 851067 420.93 24 1 1 0 0 1 14 132 7329 247190 181 151 170 +638092 851228 421.36 31 1 1 0 0 1 18 130 7329 247190 178 150 165 +638005 850587 422.87 33 1 1 1 0 1 3 126 7329 247190 186 156 176 +638038 850611 423.72 42 1 1 0 0 2 2 134 7329 247190 110 100 104 +638158 850989 421.49 54 1 1 0 0 1 7 132 7329 247191 176 152 167 +638229 851100 420.28 27 1 1 1 0 1 6 128 7329 247191 178 149 166 +638181 850652 424.84 21 1 1 1 0 1 -4 124 7329 247191 176 124 146 +638250 850750 429.49 133 1 1 0 0 1 0 133 7329 247191 136 116 130 +638405 851263 421.39 30 1 1 0 0 1 12 130 7329 247191 178 153 167 +638354 850673 425.69 218 1 1 0 0 1 0 132 7329 247192 158 116 135 +638407 850643 425.26 121 1 1 1 0 1 -2 126 7329 247192 197 148 172 +638434 850599 426.31 101 1 1 1 0 1 -4 126 7329 247192 144 118 150 +638552 851083 420.47 26 1 1 1 0 1 6 124 7329 247192 172 149 164 +638514 850640 424.21 118 1 1 1 0 1 -2 122 7329 247193 189 143 165 +638556 850757 426.05 174 1 1 0 0 1 1 130 7329 247193 129 116 142 +638600 850913 421.59 53 1 1 1 0 2 5 126 7329 247193 185 156 174 +638617 850875 419.98 15 1 1 1 0 1 6 124 7329 247193 192 154 174 +638681 851174 421.72 33 1 1 0 0 1 13 126 7329 247193 91 93 96 +638705 851197 422.31 56 1 1 1 0 1 14 129 7329 247194 100 98 111 +638732 851197 424.18 62 2 2 0 0 1 15 130 7329 247194 91 96 103 +638745 851028 422.57 45 1 1 1 0 1 11 126 7329 247194 166 140 158 +638732 850557 418.21 36 2 2 0 0 1 1 126 7329 247194 99 101 119 +638774 850552 416.83 143 1 1 1 0 1 0 128 7329 247194 97 104 110 +638868 851125 425.66 250 1 1 0 0 1 12 134 7329 247194 148 119 147 +638844 850445 422.93 143 1 1 0 0 1 -2 126 7329 247195 71 81 89 +638909 850687 423.16 8 2 2 0 0 1 2 130 7329 247195 80 88 107 +638931 851721 465.88 0 2 3 1 0 1 -10 126 7330 247556 132 123 157 +638920 851652 425.2 123 2 2 1 0 2 -9 128 7330 247556 72 82 89 +638912 851580 426.28 53 3 3 1 0 1 -6 128 7330 247557 77 86 99 +638885 851599 425.52 22 2 2 1 0 1 -6 131 7330 247557 122 126 147 +638879 851374 459.15 33 2 3 0 0 1 -2 135 7330 247557 104 111 126 +638808 851616 470.28 3 3 4 0 0 1 -8 130 7330 247557 94 96 107 +638897 850807 433.17 106 1 2 1 0 1 7 130 7330 247557 108 108 128 +638805 851265 428.77 1 2 2 1 0 1 -2 135 7330 247557 82 93 102 +638693 851899 423.06 161 1 1 0 0 1 -15 133 7330 247557 118 115 147 +638813 850941 430.48 0 3 3 1 0 1 4 133 7330 247558 103 107 119 +638742 851310 420.41 122 1 1 0 0 2 -3 126 7330 247558 106 102 108 +638778 850932 423.2 41 1 1 0 0 2 4 126 7330 247558 71 92 86 +638679 851532 469.85 4 3 4 1 0 1 -7 128 7330 247558 116 116 140 +638677 851409 497.11 37 1 3 1 0 1 -4 126 7330 247558 99 106 114 +638721 850927 417.32 88 1 1 0 0 2 5 126 7330 247558 66 84 82 +638672 851082 420.67 41 1 1 1 0 1 3 130 7330 247558 74 94 88 +638599 851445 422.15 30 1 1 1 0 1 -4 128 7330 247558 69 90 84 +638519 851908 477.13 66 1 1 0 0 1 -13 130 7330 247558 127 122 142 +638595 850955 421.62 82 1 1 0 0 2 6 128 7330 247559 202 168 186 +638592 850703 424.57 160 1 1 0 0 2 11 126 7330 247559 106 99 106 +638561 850716 425.89 118 1 1 0 0 2 11 126 7330 247559 172 130 154 +638432 851821 424.15 54 1 1 1 0 1 -12 130 7330 247559 167 159 165 +638494 850773 422.05 128 1 1 0 0 1 8 124 7330 247559 174 135 160 +638368 851889 421.19 43 1 1 1 0 2 -14 133 7330 247559 83 95 91 +638441 850659 424.84 22 1 1 0 0 2 10 126 7330 247559 205 153 180 +638304 851888 421.03 34 1 1 1 0 1 -14 132 7330 247560 172 142 158 +638372 850719 429.43 52 1 1 1 0 1 10 134 7330 247560 144 104 123 +638344 850652 429.33 54 1 1 1 0 1 12 139 7330 247560 142 110 126 +638272 851081 419.42 70 1 1 1 0 2 4 141 7330 247560 180 152 166 +638221 851313 420.83 43 1 1 1 0 1 0 139 7330 247560 178 152 166 +638170 851532 423.13 63 1 1 1 0 1 -5 139 7330 247560 175 147 163 +638101 851910 425.33 7 1 1 0 0 2 -13 135 7330 247560 182 154 169 +638185 850835 423.69 254 1 1 0 0 2 8 130 7330 247561 174 136 161 +638061 851802 426.15 233 1 1 0 0 2 -11 130 7330 247561 156 122 150 +638130 851000 421.52 60 1 1 1 0 1 5 130 7330 247561 175 150 164 +638002 851892 425.72 75 1 1 0 0 1 -11 134 7330 247561 150 134 141 +638124 850747 425.89 145 1 1 0 0 1 12 134 7330 247561 150 125 136 +637999 851541 423.46 28 1 1 1 0 2 -3 131 7330 247561 192 162 182 +638084 850764 423.65 22 1 1 0 0 2 12 130 7330 247561 174 147 164 +637881 851910 427.33 51 1 1 1 0 1 -11 139 7330 247562 86 87 88 +637980 851058 420.51 63 1 1 0 0 1 5 132 7330 247562 181 154 169 +637836 851741 427.23 118 1 1 0 0 1 -9 128 7330 247562 182 174 176 +637827 851607 427.3 152 1 1 1 0 1 -7 133 7330 247562 222 194 213 +637973 850657 422.9 17 1 1 1 0 1 11 126 7330 247562 168 154 158 +637857 851159 419.65 20 1 1 0 0 2 1 136 7330 247562 180 147 170 +637727 851718 439.07 169 1 1 0 0 2 -9 128 7330 247562 109 107 128 +637694 851772 451.77 17 1 1 0 0 1 -9 126 7330 247563 92 100 103 +637750 851359 423.26 5 1 1 0 0 1 0 126 7330 247563 168 146 162 +637653 851706 490.03 92 1 1 0 0 1 -6 124 7330 247563 154 152 158 +637665 851549 426.02 32 1 1 0 0 1 -2 128 7330 247563 175 149 172 +637835 850632 444.23 0 2 3 0 0 1 17 124 7330 247563 67 76 80 +637624 851653 451.31 13 1 1 1 0 2 -4 124 7330 247563 156 134 151 +637809 850648 448.52 16 1 3 0 0 1 16 128 7330 247563 87 88 102 +637553 851936 417.36 19 1 1 1 0 2 -10 126 7330 247563 189 133 182 +637534 851942 417.62 35 1 1 1 0 1 -10 124 7330 247564 152 124 156 +637577 851602 451.71 176 1 1 1 0 1 -4 126 7330 247564 148 122 140 +637628 851196 421.65 37 1 1 1 0 2 4 126 7330 247564 168 138 157 +637534 851591 521.16 105 1 1 0 0 1 -4 126 7330 247564 154 134 146 +637675 850645 422.51 60 2 2 1 0 1 15 126 7330 247564 60 73 72 +637431 851955 417.68 28 1 1 1 0 2 -12 124 7330 247564 132 110 139 +637485 851515 445.18 23 1 1 0 0 2 -4 126 7330 247564 154 135 157 +637435 851677 583.73 249 1 1 1 0 1 -8 128 7330 247564 241 234 243 +637594 850633 420.83 75 2 2 0 0 1 12 126 7330 247565 74 78 83 +637433 851418 425.2 17 1 1 1 0 1 -3 124 7330 247565 146 122 139 +637538 850683 488.55 15 1 2 1 0 1 11 126 7330 247565 104 90 116 +637364 851513 450.3 24 1 1 0 0 1 -5 128 7330 247565 162 138 157 +637324 851556 586.38 169 1 1 0 0 1 -4 124 7330 247565 228 211 221 +637340 851289 424.9 77 1 1 1 0 1 3 122 7330 247565 224 212 221 +637415 850660 420.14 75 1 1 0 0 1 15 124 7330 247566 118 106 124 +637298 851020 419.59 150 1 1 0 0 1 5 124 7330 247566 184 136 162 +637311 850675 420.37 25 1 1 1 0 1 11 124 7330 247566 121 110 132 +637291 852549 423.56 35 1 1 0 0 1 11 124 7331 248288 176 151 166 +637316 852265 475.43 13 1 1 0 0 2 9 124 7331 248288 141 124 135 +637371 852250 520.6 20 1 1 1 0 1 8 124 7331 248288 127 116 126 +637440 852356 442.42 190 1 1 0 0 1 8 126 7331 248289 109 104 128 +637432 852204 482.12 21 1 1 1 0 1 4 124 7331 248289 134 122 134 +637304 851523 451.9 81 1 1 0 0 2 -10 124 7331 248289 184 166 179 +637457 852094 439.76 76 1 1 1 0 1 2 122 7331 248289 138 126 138 +637478 852098 444.59 133 1 1 0 0 1 2 124 7331 248289 137 127 136 +637362 851484 446.06 155 1 1 1 0 1 -10 122 7331 248289 116 99 125 +637621 852568 424.05 26 1 1 0 0 1 13 124 7331 248289 168 144 162 +637396 851449 433.33 140 1 1 0 0 1 -9 122 7331 248290 122 109 135 +637588 852228 477.53 166 1 1 1 0 1 8 124 7331 248290 140 140 143 +637542 851892 418.27 42 1 1 0 0 1 2 124 7331 248290 158 102 146 +637567 851891 417.22 28 1 1 1 0 1 2 122 7331 248290 168 152 174 +637613 851996 432.45 48 1 1 0 0 1 4 122 7331 248290 124 120 129 +637497 851387 426.08 180 1 1 1 0 2 -9 125 7331 248290 147 117 140 +637691 852163 451.57 148 1 1 1 0 1 6 119 7331 248290 125 114 140 +637783 852472 437.47 2 1 2 0 0 1 12 124 7331 248291 136 114 132 +637661 851854 454.3 114 1 1 0 0 1 -2 124 7331 248291 64 80 78 +637551 851279 423.56 22 1 1 1 0 1 -14 126 7331 248291 170 150 163 +637757 852097 433.6 17 1 1 1 0 1 2 122 7331 248291 124 108 144 +637846 852383 424.05 39 1 1 0 0 2 8 126 7331 248291 146 137 144 +637747 851854 481.04 76 1 1 0 0 1 -2 126 7331 248291 220 210 220 +637644 851305 423.2 16 1 1 0 0 1 -13 124 7331 248291 170 149 164 +637826 852025 426.71 159 1 1 1 0 2 1 124 7331 248291 130 112 133 +637963 852551 424.21 43 1 1 0 0 1 13 128 7331 248292 176 152 168 +637825 851832 426.25 133 1 1 0 0 1 -1 130 7331 248292 230 222 231 +637745 851367 423.69 64 1 1 1 0 1 -11 132 7331 248292 165 141 157 +638022 852520 438.29 16 1 2 1 0 1 12 132 7331 248292 148 136 156 +637918 851952 440.12 163 1 1 0 0 1 0 133 7331 248292 220 212 218 +637996 852202 422.93 29 1 1 1 0 1 6 134 7331 248292 157 129 145 +637820 851329 422.34 48 1 1 0 0 1 -11 131 7331 248292 145 128 139 +638060 852291 420.21 1 1 1 1 0 2 9 128 7331 248293 179 163 171 +637885 851440 422.93 49 1 1 1 0 1 -8 134 7331 248293 164 136 156 +637866 851265 420.47 54 1 1 0 0 1 -12 132 7331 248293 176 154 169 +637905 851332 421.19 55 1 1 1 0 1 -11 141 7331 248293 184 152 176 +637917 851288 420.83 41 1 1 0 0 2 -13 137 7331 248293 174 144 161 +637993 851502 423.06 58 1 1 0 0 1 -10 143 7331 248293 192 160 180 +638160 852094 420.6 3 1 1 0 0 2 1 145 7331 248294 166 144 158 +638289 852538 424.11 132 2 2 1 0 1 10 147 7331 248294 142 128 150 +638208 852121 420.31 5 1 1 1 0 2 1 147 7331 248294 191 156 174 +638283 852352 423.69 125 1 1 1 0 1 6 143 7331 248294 182 146 165 +638117 851598 424.08 31 1 1 1 0 1 -9 143 7331 248294 194 162 177 +638182 851771 424.57 72 1 1 1 0 1 -6 145 7331 248294 187 152 170 +638148 851541 423 52 1 1 1 0 2 -12 147 7331 248294 171 140 157 +638204 851668 459.58 19 1 3 0 0 1 -10 137 7331 248295 160 130 154 +638412 852342 420.47 5 1 1 1 0 1 3 149 7331 248295 179 150 166 +638183 851375 421.49 56 1 1 1 0 1 -17 137 7331 248295 176 144 163 +638500 852439 419.09 17 1 1 0 0 1 6 129 7331 248295 176 144 160 +638230 851359 421.23 69 1 1 1 0 1 -17 143 7331 248295 185 157 172 +638352 851711 425.03 48 1 1 0 0 1 -10 139 7331 248295 179 155 169 +638557 852347 419.69 65 1 1 0 0 1 3 149 7331 248295 177 150 166 +638331 851459 422.31 27 1 1 1 0 1 -14 139 7331 248296 177 148 166 +638543 852107 421.95 59 1 1 1 0 2 0 136 7331 248296 146 132 144 +638391 851476 422.44 53 1 1 1 0 1 -12 137 7331 248296 184 148 166 +638649 852304 418.54 29 3 3 0 0 1 6 128 7331 248296 103 106 120 +638611 852076 427.13 32 1 1 0 0 1 2 126 7331 248296 82 100 94 +638626 852024 427.17 83 1 1 0 0 1 1 128 7331 248296 64 82 80 +638771 852454 422.67 69 2 2 0 0 2 11 128 7331 248296 51 73 66 +638532 851427 421.72 39 1 1 1 0 1 -10 145 7331 248297 78 90 89 +638742 852144 418.11 180 1 1 1 0 1 4 134 7331 248297 130 117 136 +638765 852172 469.69 109 2 3 0 0 1 5 135 7331 248297 103 102 112 +638823 852342 424.15 59 1 1 1 0 1 8 135 7331 248297 60 84 74 +638732 851912 423.33 191 1 1 0 0 1 0 132 7331 248297 170 132 160 +638817 852211 468.83 47 1 3 1 0 1 5 136 7331 248297 116 110 143 +638786 852018 422.54 40 2 2 0 0 1 1 133 7331 248297 95 100 116 +638801 852033 513.65 36 1 3 1 0 1 1 137 7331 248297 104 112 124 +638887 852336 452.3 4 3 4 0 0 1 8 126 7331 248297 90 96 104 +638708 851498 461.84 40 1 2 1 0 1 -10 133 7331 248297 132 126 155 +638922 852382 517.65 2 1 3 0 0 1 9 124 7331 248298 113 112 128 +638941 852402 495.96 19 3 4 1 0 1 10 128 7331 248298 106 108 124 +638962 852424 463.16 4 1 1 1 0 1 10 128 7331 248298 98 104 118 +638960 852337 416.67 0 4 4 0 0 1 9 126 7331 248298 116 116 134 +638941 852174 425.3 85 1 1 1 0 2 6 130 7331 248298 71 81 87 +638786 851367 472.9 18 2 3 0 0 1 -10 128 7331 248298 105 105 124 +638794 851256 420.14 0 2 2 1 0 2 -12 129 7331 248298 98 104 116 +638895 851562 471.98 1 1 2 1 0 1 -7 128 7331 248298 67 80 92 +638918 851383 465.42 26 1 2 0 0 1 -12 128 7331 248299 96 101 118 +638972 852466 442.32 1 2 3 0 0 1 0 126 7332 248668 116 118 138 +638922 852509 419.06 78 2 2 1 0 1 0 128 7332 248669 98 106 118 +638833 852772 431.92 17 2 2 0 0 1 -4 130 7332 248669 103 105 125 +638864 852547 419.09 0 2 2 0 0 1 0 130 7332 248669 70 82 86 +638774 852794 447.15 74 1 2 0 0 1 -3 134 7332 248669 72 86 86 +638945 852002 424.11 49 1 1 0 0 1 13 135 7332 248669 152 138 146 +638762 852621 421.49 137 1 1 0 0 1 0 128 7332 248670 86 91 100 +638861 852115 453.15 16 2 3 0 0 1 11 128 7332 248670 64 86 80 +638840 852111 484.48 7 1 2 0 0 1 11 130 7332 248670 104 104 120 +638822 852100 424.25 95 1 1 1 0 1 11 126 7332 248670 82 88 97 +638811 852070 425.59 65 2 2 0 0 1 11 130 7332 248670 103 105 120 +638608 852820 420.93 125 1 1 0 0 2 -4 127 7332 248670 158 127 145 +638787 851992 477.53 2 2 4 1 0 1 13 126 7332 248670 96 101 117 +638786 851902 423.79 59 1 1 0 0 1 14 130 7332 248671 139 119 134 +638558 852781 420.96 182 1 1 0 0 1 -4 128 7332 248671 189 142 168 +638551 852665 421.52 110 1 1 1 0 1 -1 126 7332 248671 186 136 164 +638583 852336 420.37 36 1 1 0 0 1 5 130 7332 248671 178 146 162 +638636 851916 425 146 1 1 1 0 1 14 128 7332 248671 86 94 98 +638412 852771 418.9 32 1 1 1 0 1 -4 126 7332 248672 157 139 152 +638473 852327 419.29 26 1 1 1 0 1 4 129 7332 248672 177 142 162 +638450 852286 419.42 35 1 1 1 0 2 4 128 7332 248672 183 146 164 +638509 851861 458.33 3 1 2 0 0 1 13 129 7332 248672 114 112 136 +638371 852414 417.55 20 1 1 1 0 2 1 126 7332 248672 183 148 169 +638375 852292 420.18 1 1 1 0 0 2 3 130 7332 248672 174 149 164 +638425 851892 421.1 17 1 1 0 0 1 11 128 7332 248673 73 90 85 +638239 852699 422.24 60 1 1 0 0 1 -4 130 7332 248673 179 153 167 +638355 851890 421.26 27 1 1 0 0 1 13 130 7332 248673 100 111 106 +638200 852486 422.38 45 1 1 1 0 2 2 126 7332 248673 170 148 159 +638253 851978 420.83 21 1 1 1 0 1 13 124 7332 248674 181 152 167 +638225 851911 421.46 15 1 1 1 0 1 13 126 7332 248674 180 149 166 +638083 852479 422.01 44 1 1 0 0 1 0 133 7332 248674 176 149 164 +638096 852150 420.11 1 1 1 0 0 2 6 130 7332 248674 172 141 158 +638082 851969 425.39 21 1 1 1 0 2 10 126 7332 248674 180 150 167 +638038 851998 423.88 189 1 1 1 0 2 10 128 7332 248675 152 128 153 +638006 851961 424.67 45 1 1 1 0 2 11 128 7332 248675 153 136 144 +637957 852003 425.52 37 1 1 1 0 1 10 129 7332 248675 159 138 148 +637928 851937 440.22 77 1 1 1 0 1 11 126 7332 248675 219 208 220 +637882 851961 427.23 31 1 1 1 0 2 10 128 7332 248675 117 107 107 +637812 852121 425.52 174 1 1 0 0 2 7 128 7332 248676 124 110 128 +637711 852486 424.84 108 1 1 0 0 2 0 128 7332 248676 230 216 228 +637648 852693 422.97 54 1 1 0 0 1 -4 126 7332 248676 108 100 108 +637583 852894 424.31 195 1 1 1 0 1 -8 126 7332 248676 126 111 130 +637583 852740 423.36 0 2 2 1 0 2 -6 124 7332 248676 176 160 168 +637583 852596 423.06 41 1 1 1 0 1 -2 124 7332 248677 106 100 110 +637537 852690 425.13 103 1 1 1 0 1 -3 126 7332 248677 138 128 139 +637480 852874 423.79 75 1 1 0 0 1 -6 124 7332 248677 110 106 118 +637664 851991 452.46 218 1 1 0 0 1 13 126 7332 248677 110 115 118 +637630 852067 459.15 139 1 1 1 0 1 10 124 7332 248677 109 108 116 +637526 852397 424.21 109 1 1 1 0 1 2 128 7332 248678 224 206 218 +637403 852854 422.64 17 1 1 0 0 1 -7 122 7332 248678 152 133 144 +637472 852416 424.28 86 1 1 1 0 2 3 126 7332 248678 214 194 213 +637402 852635 425 125 1 1 1 0 2 0 126 7332 248678 96 88 106 +637323 852899 421.49 20 1 1 1 0 1 -5 124 7332 248678 120 111 126 +637361 852595 422.87 72 1 1 0 0 1 0 126 7332 248678 155 140 151 +637348 852521 423.65 58 1 1 0 0 1 1 124 7332 248679 188 162 180 +637363 852289 478.84 203 1 1 1 0 1 5 124 7332 248679 72 87 82 +637313 852286 473.75 172 1 1 1 0 1 5 124 7332 248679 136 121 134 +637309 851927 417.72 19 1 1 1 0 1 10 124 7332 248680 124 102 132 +637283 852557 423.23 43 1 1 1 0 1 -14 126 7333 249396 180 159 170 +637373 852612 423.88 147 1 1 1 0 2 -16 124 7333 249396 125 112 131 +637471 852624 425.66 65 2 2 0 0 2 -18 124 7333 249397 118 105 126 +637617 852866 423.56 33 1 1 0 0 2 -9 124 7333 249397 150 130 144 +637701 852745 423.23 134 1 1 0 0 2 -8 124 7333 249398 93 86 92 +637797 852577 424.21 28 1 1 0 0 1 -15 124 7333 249398 163 146 158 +637927 852786 425.1 58 1 1 1 0 2 -9 124 7333 249399 134 114 138 +637978 852566 424.15 36 1 1 1 0 2 -14 124 7333 249399 169 148 160 +638066 852648 422.47 31 1 1 1 0 2 -14 124 7333 249399 144 128 141 +638133 852599 424.02 31 1 1 0 0 2 -12 124 7333 249400 141 130 139 +638214 852554 424.18 37 1 1 1 0 1 -12 128 7333 249400 161 139 155 +638314 852794 419.65 39 1 1 0 0 2 -7 124 7333 249401 164 140 153 +638352 852539 440.62 4 1 2 0 0 1 -12 128 7333 249401 142 130 153 +638444 852655 421.69 69 1 1 0 0 2 -12 124 7333 249402 186 140 166 +638511 852504 437.73 1 1 2 1 0 1 -18 124 7333 249402 150 126 150 +638650 852770 421.75 131 1 1 0 0 2 -9 125 7333 249402 84 96 88 +638707 852620 422.77 186 1 1 1 0 1 -10 128 7333 249403 88 100 98 +638753 852541 423.1 172 1 1 1 0 2 -13 128 7333 249403 72 88 82 +638808 852534 474.61 7 1 2 0 0 1 -17 124 7333 249403 82 93 98 +638905 852669 422.7 40 2 2 0 0 2 -15 126 7333 249404 120 120 140 +638946 852513 465.62 67 1 3 1 0 1 -18 126 7333 249404 117 116 140 +637282 852938 455.74 180 1 1 0 0 1 -7 126 7332 248679 80 88 83 +637154 853205 423.46 80 1 1 0 0 1 -13 124 7332 248679 210 182 204 +637119 852967 444.06 26 1 1 0 0 1 -11 122 7332 248680 154 139 148 +636985 853190 437.3 218 1 1 0 0 1 -15 122 7332 248680 138 110 123 +636902 853239 434.35 179 1 1 1 0 1 -14 120 7332 248680 215 201 213 +636874 852993 438.29 12 1 1 1 0 1 -8 118 7332 248681 74 80 78 +636796 852956 422.83 17 1 1 0 0 1 -5 122 7332 248681 122 111 124 +636710 853167 455.87 9 1 3 0 0 1 -10 124 7332 248682 76 83 91 +636688 853133 421.52 139 1 1 0 0 1 -12 126 7332 248682 121 110 132 +636668 853046 462.34 23 1 2 1 0 1 -11 126 7332 248682 94 89 100 +636568 853230 420.11 28 1 1 0 0 1 -14 124 7332 248683 82 79 82 +636484 853170 418.14 168 1 1 0 0 2 -14 127 7332 248683 178 146 172 +636422 853109 446.62 3 1 2 0 0 1 -9 124 7332 248684 101 98 118 +636352 853133 466.77 14 1 2 1 0 1 -11 124 7332 248684 75 73 86 +636297 853183 454.36 11 1 2 1 0 1 -14 126 7332 248684 115 114 133 +636250 853209 417.16 99 1 1 0 0 1 -13 126 7332 248685 106 98 121 +636182 853234 415.68 23 1 1 1 0 1 -12 122 7332 248685 68 82 78 +636097 853164 417.19 21 2 2 1 0 2 -11 125 7332 248686 70 74 78 +636020 853218 434.91 1 1 2 1 0 1 -16 126 7332 248686 122 108 127 +635981 853089 436.88 0 2 3 0 0 1 -13 122 7332 248686 87 90 97 +635918 853135 451.87 1 1 3 1 0 1 -10 128 7332 248687 126 118 142 +635868 853134 432.58 6 1 2 1 0 1 -7 126 7332 248687 66 82 76 +635843 853057 428.67 30 2 3 1 0 1 -9 128 7332 248688 63 73 80 +635783 853017 416.24 7 2 2 1 0 1 -10 130 7332 248688 106 104 125 +635814 853487 425.2 120 1 1 0 0 1 5 118 7333 249387 149 122 137 +635823 853230 419.72 39 1 1 1 0 2 0 128 7333 249387 141 125 137 +635825 852997 455.51 14 1 2 0 0 1 -9 120 7333 249388 75 88 87 +635899 853017 415.49 80 2 2 1 0 2 -11 126 7333 249388 94 100 112 +636006 853181 413.62 140 1 1 1 0 2 -8 122 7333 249388 177 137 163 +636102 853270 414.11 113 2 2 1 0 1 -2 122 7333 249389 132 111 139 +636200 853412 417.85 127 1 1 1 0 1 5 124 7333 249389 100 107 116 +636275 853491 414.27 103 1 1 1 0 2 5 124 7333 249389 117 97 122 +636298 853462 413.98 15 2 2 0 0 1 3 127 7333 249390 136 119 136 +636276 853209 483.23 1 1 2 1 0 1 -2 120 7333 249390 104 102 122 +636325 853187 418.31 111 2 2 0 0 2 0 126 7333 249390 118 113 135 +636371 853101 449.97 11 1 2 1 0 1 -2 128 7333 249390 122 109 140 +636471 853249 419.32 169 1 1 1 0 1 0 123 7333 249391 129 114 136 +636479 853019 420.01 25 1 1 1 0 2 -5 124 7333 249391 150 131 149 +636577 853225 420.21 27 1 1 1 0 1 -1 124 7333 249391 78 80 78 +636592 853045 452.46 27 1 2 1 0 1 -3 128 7333 249392 94 90 109 +636704 853340 481.82 122 1 1 1 0 1 2 122 7333 249392 116 106 118 +636711 853139 421.39 72 2 2 1 0 1 -2 124 7333 249392 136 114 140 +636734 852997 421.49 156 1 1 1 0 1 -5 126 7333 249393 175 128 156 +636816 853250 421.19 22 1 1 1 0 2 3 124 7333 249393 185 172 180 +636875 853356 481 114 1 1 0 0 1 0 124 7333 249393 88 98 102 +636934 853323 446.62 49 1 1 1 0 1 -2 120 7333 249394 110 106 112 +637065 853483 420.18 70 2 2 0 0 1 2 124 7333 249394 110 102 116 +637177 853454 470.01 16 1 2 0 0 1 5 126 7333 249394 92 93 107 +637196 853029 424.57 130 1 1 1 0 2 -4 124 7333 249395 162 139 164 +637296 853286 429.17 53 1 1 1 0 1 10 124 7334 249773 69 78 84 +637276 853222 479.1 1 1 3 0 0 1 13 124 7334 249774 62 76 72 +637206 853272 423.23 135 1 1 1 0 1 10 124 7334 249774 121 108 136 +637140 853182 423.06 1 2 2 1 0 2 12 126 7334 249775 94 84 94 +637017 853282 421.92 27 1 1 0 0 1 12 124 7334 249775 154 134 146 +636940 853204 422.21 142 1 1 0 0 1 15 122 7334 249776 216 202 213 +636893 853238 434.74 232 1 1 1 0 1 12 124 7334 249776 208 196 206 +636845 853259 421.23 34 1 1 1 0 1 10 124 7334 249777 168 161 166 +636737 853445 461.06 27 1 1 0 0 1 6 118 7334 249777 102 102 116 +636686 853301 420.6 25 1 1 1 0 2 9 124 7334 249778 176 171 184 +636621 853297 420.6 32 1 1 1 0 2 12 124 7334 249778 153 124 138 +636542 853338 483.66 115 1 1 0 0 1 14 131 7334 249778 80 92 96 +636471 853325 417.65 206 1 1 0 0 2 14 126 7334 249779 74 92 86 +636356 853502 419.65 83 1 1 0 0 2 10 123 7334 249779 180 144 172 +636379 853237 418.57 179 1 1 1 0 1 14 126 7334 249780 142 117 148 +636288 853491 414.44 200 1 1 1 0 1 10 135 7334 249780 120 99 121 +636260 853420 414.04 25 2 2 1 0 1 8 128 7334 249781 100 100 116 +636199 853390 409.65 104 1 1 1 0 2 3 126 7334 249781 105 105 123 +636078 853477 419.39 36 1 1 1 0 2 4 126 7334 249782 174 146 160 +636007 853294 410.93 72 1 1 0 0 1 5 122 7334 249782 79 86 92 +635879 853461 435.01 178 1 1 1 0 1 4 120 7334 249783 216 204 214 +635776 853535 423.82 25 1 1 1 0 2 5 126 7334 249783 140 133 140 +638983 853132 456.92 56 1 1 0 0 1 -13 128 7332 248667 120 111 124 +638894 853120 447.24 4 1 2 0 0 1 -13 128 7332 248668 187 167 179 +638867 852935 423.59 2 1 1 0 0 2 -10 122 7332 248668 88 96 92 +638816 852877 465.81 10 1 3 0 0 1 -7 132 7332 248669 106 109 123 +638749 852904 422.38 9 1 1 1 0 1 -6 128 7332 248669 72 90 86 +638644 853100 417.19 126 1 1 1 0 1 -9 128 7332 248669 117 117 136 +638635 852938 421.33 124 1 1 0 0 1 -6 126 7332 248670 72 86 84 +638608 852908 421.75 99 1 1 1 0 2 -6 128 7332 248670 104 110 111 +638530 853083 491.44 0 1 2 1 0 1 -10 128 7332 248670 80 92 92 +638490 853075 419.75 153 1 1 1 0 2 -10 128 7332 248671 76 84 83 +638380 853193 419.03 92 1 1 1 0 1 -12 126 7332 248671 63 84 75 +638343 852961 417.78 124 1 1 1 0 1 -8 125 7332 248672 192 148 174 +638228 853175 422.97 164 1 1 0 0 2 -14 128 7332 248672 164 123 152 +638229 852920 420.64 21 1 1 1 0 1 -9 126 7332 248673 187 149 174 +638104 853160 424.48 197 1 1 0 0 1 -12 132 7332 248673 80 92 88 +638029 853088 424.28 161 1 1 1 0 1 -9 124 7332 248674 184 134 156 +637963 853056 445.87 74 1 1 1 0 1 -12 128 7332 248674 224 222 225 +637872 853004 425.16 49 1 1 1 0 1 -10 133 7332 248675 159 137 150 +637721 853205 424.77 140 1 1 0 0 1 -15 128 7332 248675 175 126 152 +637627 853134 449.41 70 1 1 0 0 1 -14 133 7332 248676 182 186 196 +637573 853042 457.41 68 1 1 0 0 1 -12 126 7332 248676 236 226 236 +637490 853100 444.42 53 1 1 1 0 1 -13 126 7332 248677 225 222 228 +637468 852921 423.33 46 1 1 1 0 1 -6 128 7332 248677 153 130 144 +637386 853078 440.88 72 1 1 0 0 1 -11 124 7332 248677 116 104 115 +637319 853111 423.29 139 1 1 0 0 1 -11 124 7332 248678 80 86 94 +637379 853416 409.19 11 1 1 0 0 2 1 122 7333 249395 100 98 116 +637415 853304 422.77 167 1 1 1 0 2 0 122 7333 249395 116 104 131 +637461 853298 422.57 141 1 1 0 0 1 1 122 7333 249396 139 108 133 +637522 853314 431.89 137 1 1 0 0 1 0 126 7333 249396 118 114 136 +637570 853213 424.34 165 1 1 0 0 2 -5 124 7333 249397 176 128 155 +637630 853153 446.69 66 1 1 1 0 1 -6 126 7333 249397 178 181 190 +637709 853240 423.43 116 1 1 1 0 2 0 124 7333 249397 145 118 140 +637796 853223 424.31 197 1 1 0 0 2 1 124 7333 249398 179 131 161 +637920 853300 421.98 144 1 1 1 0 2 0 124 7333 249398 150 116 138 +637957 853068 424.93 94 1 1 1 0 2 -3 122 7333 249398 225 221 226 +638083 853360 416.08 69 1 1 1 0 1 3 122 7333 249399 128 116 146 +638126 853200 423.85 61 1 1 1 0 1 -2 122 7333 249399 73 94 85 +638186 853294 434.09 52 1 2 0 0 1 0 124 7333 249400 98 108 113 +638257 853424 425.52 27 1 1 1 0 1 5 124 7333 249400 128 108 122 +638308 853303 419.78 158 1 1 1 0 2 3 123 7333 249400 186 130 162 +638386 853400 412.63 158 1 1 1 0 1 6 124 7333 249401 129 117 140 +638432 853167 418.54 55 1 1 0 0 1 0 126 7333 249401 66 83 79 +638477 853013 418.47 61 1 1 0 0 2 -2 126 7333 249401 139 115 132 +638553 853169 419.39 0 4 4 1 0 1 -2 122 7333 249402 107 104 123 +638660 853325 438.12 17 1 1 1 0 1 0 124 7333 249402 79 92 96 +638666 853027 468.24 1 1 2 1 0 1 -5 126 7333 249402 124 118 144 +638727 853060 438.98 8 1 2 1 0 1 -1 124 7333 249403 111 103 118 +638780 853008 444.55 20 1 1 0 0 1 -1 126 7333 249403 161 146 156 +638894 853280 429.56 142 1 1 0 0 1 2 124 7333 249403 112 106 136 +638927 853029 447.47 17 1 1 0 0 1 -7 124 7333 249404 157 153 157 +638973 853327 439.44 0 2 3 0 0 1 8 124 7334 249765 91 99 115 +638912 853317 470.21 41 1 2 1 0 1 9 130 7334 249765 68 77 84 +638836 853307 440.68 27 1 2 1 0 1 7 131 7334 249765 94 98 112 +638735 853326 439.44 5 1 2 0 0 1 6 126 7334 249766 99 107 120 +638642 853328 440.75 1 1 1 0 0 1 7 126 7334 249766 89 100 106 +638542 853355 415.16 101 1 1 1 0 1 1 131 7334 249767 79 91 98 +638507 853171 458.73 4 1 2 1 0 1 4 127 7334 249767 118 118 134 +638435 853170 418.64 14 1 1 1 0 1 6 128 7334 249767 72 90 84 +638297 853409 418.41 71 1 1 0 0 1 0 125 7334 249768 86 90 106 +638233 853311 461.68 134 1 1 1 0 1 1 126 7334 249768 76 88 89 +638142 853454 421.1 161 1 1 0 0 1 1 126 7334 249769 171 129 155 +638080 853406 409.74 1 1 1 0 0 2 3 126 7334 249769 99 106 116 +638049 853232 423.59 95 1 1 1 0 1 10 125 7334 249770 174 138 155 +637918 853429 418.11 91 1 1 1 0 1 8 124 7334 249770 122 102 132 +637843 853349 427.99 17 1 1 0 0 1 9 126 7334 249771 86 82 100 +637739 853335 421.06 105 2 2 0 0 1 7 124 7334 249771 99 103 116 +637652 853197 427.2 58 1 1 1 0 1 13 124 7334 249772 225 222 229 +637502 853376 417.52 43 1 1 0 0 1 11 124 7334 249772 100 96 120 +637433 853231 424.08 31 1 1 0 0 1 11 125 7334 249773 176 138 164 +637343 853240 423.92 116 1 1 1 0 1 9 124 7334 249773 138 107 136 +3 782 763 648 +3 648 786 782 +3 782 759 763 +3 759 777 763 +3 782 756 759 +3 745 790 794 +3 786 790 782 +3 648 752 786 +3 777 775 763 +3 759 756 777 +3 786 752 790 +3 777 756 761 +3 775 761 772 +3 777 761 775 +3 775 772 548 +3 756 753 757 +3 761 762 772 +3 775 548 763 +3 762 413 772 +3 648 654 752 +3 761 756 757 +3 782 790 745 +3 756 782 745 +3 752 660 790 +3 654 657 752 +3 790 743 794 +3 648 765 654 +3 763 647 648 +3 548 547 419 +3 753 751 757 +3 756 751 753 +3 743 798 800 +3 648 647 765 +3 756 745 751 +3 752 657 660 +3 548 413 547 +3 772 413 548 +3 761 757 762 +3 763 548 419 +3 800 798 802 +3 790 660 743 +3 762 757 413 +3 743 660 798 +3 763 419 410 +3 647 410 418 +3 763 410 647 +3 657 656 663 +3 654 656 657 +3 765 651 654 +3 647 418 765 +3 547 546 419 +3 751 747 757 +3 745 747 751 +3 794 743 800 +3 547 417 546 +3 413 417 547 +3 660 801 798 +3 657 740 660 +3 803 801 665 +3 660 740 665 +3 765 418 411 +3 419 403 410 +3 657 661 740 +3 798 801 802 +3 660 665 801 +3 747 744 757 +3 745 741 747 +3 745 794 800 +3 745 800 738 +3 410 403 402 +3 546 422 419 +3 417 420 546 +3 419 422 403 +3 802 803 667 +3 801 803 802 +3 740 668 665 +3 546 420 422 +3 413 414 417 +3 757 414 413 +3 420 544 540 +3 417 544 420 +3 418 409 411 +3 410 409 418 +3 745 738 741 +3 656 651 760 +3 654 651 656 +3 765 411 651 +3 744 741 742 +3 747 741 744 +3 802 667 804 +3 665 667 803 +3 661 663 736 +3 800 802 804 +3 740 661 736 +3 657 663 661 +3 744 742 785 +3 738 737 741 +3 780 744 785 +3 409 406 423 +3 410 406 409 +3 410 402 404 +3 422 426 396 +3 420 540 426 +3 665 668 667 +3 410 404 406 +3 411 423 408 +3 409 423 411 +3 404 405 406 +3 738 800 733 +3 800 804 733 +3 668 669 670 +3 417 414 421 +3 668 736 669 +3 740 736 668 +3 406 405 425 +3 402 430 400 +3 422 420 426 +3 417 421 544 +3 741 737 793 +3 757 744 779 +3 741 793 742 +3 757 779 755 +3 744 780 779 +3 406 425 423 +3 738 733 737 +3 671 668 670 +3 671 667 668 +3 663 669 736 +3 544 421 540 +3 403 422 396 +3 421 539 540 +3 540 539 426 +3 663 656 662 +3 656 760 662 +3 411 766 651 +3 651 653 760 +3 425 408 423 +3 411 408 348 +3 785 789 891 +3 742 789 785 +3 733 809 729 +3 651 766 764 +3 814 667 671 +3 746 739 748 +3 400 430 399 +3 403 430 402 +3 400 404 402 +3 428 405 404 +3 653 764 641 +3 651 764 653 +3 414 415 421 +3 757 902 414 +3 414 902 543 +3 780 749 779 +3 748 739 662 +3 779 749 750 +3 785 891 780 +3 779 750 755 +3 804 667 814 +3 411 348 766 +3 425 405 428 +3 403 396 430 +3 789 793 735 +3 742 793 789 +3 757 755 902 +3 408 428 429 +3 425 428 408 +3 539 427 426 +3 421 534 539 +3 415 543 416 +3 426 427 533 +3 766 649 650 +3 348 649 766 +3 760 758 754 +3 653 641 760 +3 766 650 764 +3 764 650 641 +3 348 412 649 +3 399 398 397 +3 430 396 399 +3 760 638 662 +3 760 754 638 +3 758 760 655 +3 760 641 655 +3 758 658 754 +3 754 659 638 +3 658 659 754 +3 404 400 428 +3 398 396 433 +3 399 396 398 +3 758 655 639 +3 650 646 645 +3 299 294 642 +3 424 415 416 +3 414 543 415 +3 755 773 902 +3 749 781 750 +3 780 781 749 +3 774 781 892 +3 774 750 781 +3 398 433 436 +3 426 533 396 +3 780 891 781 +3 399 397 400 +3 737 733 729 +3 804 811 733 +3 731 737 729 +3 659 637 638 +3 658 639 659 +3 638 637 662 +3 662 637 748 +3 804 814 811 +3 670 730 675 +3 733 811 809 +3 669 663 734 +3 641 650 645 +3 649 646 650 +3 408 429 350 +3 675 730 674 +3 669 730 670 +3 649 412 646 +3 441 395 439 +3 791 735 882 +3 559 416 558 +3 902 545 543 +3 348 349 412 +3 811 726 809 +3 814 726 811 +3 809 726 812 +3 658 758 639 +3 641 642 655 +3 348 408 350 +3 397 436 394 +3 663 662 739 +3 637 664 748 +3 659 664 637 +3 433 533 529 +3 396 533 433 +3 421 415 424 +3 748 664 746 +3 641 645 644 +3 412 317 646 +3 349 84 412 +3 814 725 816 +3 671 725 814 +3 671 670 675 +3 663 739 734 +3 427 539 534 +3 543 558 416 +3 641 643 642 +3 642 643 299 +3 84 350 351 +3 348 350 349 +3 427 534 431 +3 814 816 819 +3 671 675 725 +3 641 644 643 +3 755 750 774 +3 891 892 781 +3 789 735 791 +3 659 639 664 +3 644 302 643 +3 891 789 791 +3 793 737 731 +3 645 652 644 +3 646 317 645 +3 902 773 545 +3 735 793 731 +3 755 774 773 +3 735 881 796 +3 429 407 350 +3 400 397 395 +3 351 407 432 +3 429 428 432 +3 398 436 397 +3 882 796 880 +3 735 796 882 +3 735 731 881 +3 678 675 724 +3 881 731 879 +3 543 545 558 +3 774 892 778 +3 891 791 787 +3 881 879 880 +3 533 427 435 +3 427 431 526 +3 416 559 424 +3 730 669 734 +3 664 636 746 +3 639 666 664 +3 728 730 734 +3 674 730 728 +3 534 421 424 +3 545 557 558 +3 746 636 635 +3 350 407 351 +3 429 432 407 +3 729 809 810 +3 809 812 810 +3 814 819 726 +3 533 435 529 +3 534 424 530 +3 433 529 436 +3 639 655 640 +3 655 642 640 +3 652 302 644 +3 645 317 652 +3 643 302 299 +3 639 640 284 +3 725 675 678 +3 674 724 675 +3 816 725 678 +3 892 787 783 +3 891 787 892 +3 796 881 880 +3 529 392 436 +3 435 438 529 +3 436 392 391 +3 642 294 640 +3 302 305 297 +3 791 882 880 +3 729 727 731 +3 791 880 883 +3 674 728 724 +3 739 634 734 +3 427 526 435 +3 534 527 431 +3 435 526 437 +3 734 732 728 +3 746 635 739 +3 729 810 727 +3 734 634 732 +3 431 527 526 +3 441 400 395 +3 739 635 672 +3 664 666 636 +3 879 727 877 +3 731 727 879 +3 892 783 778 +3 791 883 787 +3 773 774 771 +3 787 883 783 +3 879 878 880 +3 817 819 821 +3 726 819 812 +3 428 400 441 +3 397 394 395 +3 739 672 634 +3 634 672 673 +3 545 773 769 +3 773 771 769 +3 732 634 633 +3 634 673 633 +3 395 394 439 +3 328 666 284 +3 636 666 635 +3 294 299 297 +3 436 391 394 +3 529 438 392 +3 297 299 302 +3 302 652 305 +3 652 317 305 +3 559 535 566 +3 558 557 559 +3 424 559 566 +3 424 566 530 +3 349 350 84 +3 428 441 432 +3 880 878 797 +3 640 294 297 +3 879 877 878 +3 810 874 727 +3 412 84 317 +3 534 530 527 +3 640 297 284 +3 392 438 387 +3 527 437 526 +3 530 525 527 +3 435 437 438 +3 774 778 771 +3 883 797 788 +3 535 559 560 +3 559 557 560 +3 778 770 771 +3 317 310 305 +3 84 157 317 +3 305 310 319 +3 545 769 768 +3 391 387 385 +3 392 387 391 +3 437 442 438 +3 816 678 819 +3 728 677 722 +3 812 819 817 +3 678 821 819 +3 810 812 817 +3 732 633 676 +3 672 633 673 +3 635 272 672 +3 728 732 677 +3 432 441 353 +3 394 444 439 +3 391 388 394 +3 566 532 530 +3 535 532 566 +3 530 532 570 +3 718 728 722 +3 545 768 541 +3 771 770 769 +3 732 676 677 +3 439 444 445 +3 527 525 522 +3 317 157 310 +3 351 352 91 +3 432 353 352 +3 535 560 532 +3 545 538 557 +3 564 560 563 +3 877 874 873 +3 727 874 877 +3 873 874 721 +3 557 538 536 +3 768 900 901 +3 769 900 768 +3 557 536 560 +3 768 901 541 +3 810 817 721 +3 394 388 444 +3 635 666 272 +3 639 284 666 +3 305 319 297 +3 157 158 310 +3 321 319 308 +3 351 432 352 +3 439 445 441 +3 382 385 384 +3 391 385 388 +3 438 381 387 +3 527 522 518 +3 310 158 81 +3 84 351 89 +3 446 445 393 +3 388 382 451 +3 157 84 87 +3 518 522 434 +3 530 572 525 +3 157 85 158 +3 297 319 321 +3 310 308 319 +3 85 155 156 +3 810 721 874 +3 805 877 873 +3 805 878 877 +3 388 385 382 +3 387 383 385 +3 538 541 553 +3 545 541 538 +3 900 770 549 +3 553 541 550 +3 385 383 384 +3 85 87 155 +3 157 87 85 +3 441 445 446 +3 444 390 445 +3 441 446 354 +3 384 383 447 +3 633 272 632 +3 672 272 633 +3 676 633 632 +3 883 880 797 +3 84 89 87 +3 901 900 550 +3 769 770 900 +3 783 883 788 +3 778 783 788 +3 437 527 516 +3 525 434 522 +3 536 538 563 +3 438 442 450 +3 383 381 447 +3 387 381 383 +3 382 384 447 +3 386 444 388 +3 442 443 512 +3 156 155 154 +3 89 155 87 +3 284 286 280 +3 297 289 284 +3 878 805 876 +3 878 876 797 +3 666 328 272 +3 393 445 390 +3 328 280 331 +3 284 280 328 +3 721 871 873 +3 817 871 721 +3 708 826 712 +3 873 871 719 +3 89 91 154 +3 351 91 89 +3 353 354 401 +3 446 390 452 +3 291 325 326 +3 284 289 286 +3 560 536 563 +3 901 550 541 +3 525 572 434 +3 442 516 443 +3 437 516 442 +3 572 573 514 +3 353 441 354 +3 393 390 446 +3 724 728 718 +3 676 723 677 +3 444 386 390 +3 708 821 826 +3 678 826 821 +3 724 682 678 +3 530 570 572 +3 873 719 869 +3 817 717 871 +3 447 381 450 +3 381 438 450 +3 352 353 401 +3 352 401 149 +3 323 291 293 +3 297 324 289 +3 770 893 895 +3 778 893 770 +3 89 154 155 +3 401 355 147 +3 158 85 83 +3 308 310 81 +3 527 518 516 +3 532 560 564 +3 677 679 722 +3 532 564 569 +3 677 723 679 +3 871 717 719 +3 770 895 899 +3 805 807 876 +3 873 807 805 +3 717 869 719 +3 876 807 799 +3 797 876 799 +3 678 682 687 +3 679 680 722 +3 676 632 723 +3 328 331 272 +3 538 553 563 +3 900 549 550 +3 563 553 528 +3 272 331 268 +3 291 324 293 +3 564 565 569 +3 563 565 564 +3 873 869 820 +3 817 821 708 +3 324 291 326 +3 297 293 324 +3 308 81 320 +3 388 451 386 +3 447 451 382 +3 386 451 379 +3 893 778 884 +3 778 788 884 +3 570 569 573 +3 532 569 570 +3 572 570 573 +3 717 817 708 +3 678 687 826 +3 723 680 679 +3 632 631 723 +3 722 680 720 +3 447 450 451 +3 516 448 443 +3 518 434 514 +3 797 799 788 +3 869 866 713 +3 724 718 714 +3 297 321 293 +3 434 572 514 +3 516 518 440 +3 722 720 718 +3 723 631 681 +3 565 528 523 +3 563 528 565 +3 569 565 523 +3 81 83 82 +3 158 83 81 +3 91 352 149 +3 442 512 450 +3 682 714 711 +3 724 714 682 +3 720 681 683 +3 680 723 681 +3 272 265 632 +3 553 550 542 +3 550 549 542 +3 893 884 776 +3 321 323 293 +3 81 82 318 +3 324 326 289 +3 820 869 713 +3 717 866 869 +3 390 386 452 +3 386 379 452 +3 450 456 451 +3 512 509 456 +3 718 720 683 +3 680 681 720 +3 354 446 453 +3 446 452 453 +3 321 308 320 +3 888 893 776 +3 799 875 795 +3 710 685 686 +3 718 685 714 +3 788 784 884 +3 283 280 286 +3 326 286 289 +3 82 159 160 +3 151 91 149 +3 354 355 401 +3 83 85 156 +3 573 521 575 +3 569 521 573 +3 770 899 549 +3 190 321 320 +3 83 159 82 +3 322 321 190 +3 824 713 862 +3 712 709 835 +3 718 684 686 +3 516 440 448 +3 866 717 708 +3 826 709 712 +3 826 687 709 +3 718 686 685 +3 623 542 903 +3 553 542 537 +3 899 767 549 +3 714 685 710 +3 682 711 687 +3 354 453 355 +3 379 457 377 +3 154 91 151 +3 518 514 440 +3 573 575 578 +3 81 318 320 +3 684 718 716 +3 718 683 716 +3 631 630 681 +3 866 708 704 +3 687 688 709 +3 276 280 283 +3 323 295 291 +3 318 312 320 +3 331 280 276 +3 684 716 715 +3 549 767 542 +3 895 893 888 +3 573 578 514 +3 631 265 336 +3 632 265 631 +3 82 160 318 +3 83 156 159 +3 323 321 322 +3 160 186 318 +3 706 688 689 +3 711 689 687 +3 714 690 711 +3 286 326 283 +3 291 295 325 +3 450 512 456 +3 443 509 512 +3 767 903 542 +3 899 898 767 +3 528 553 531 +3 325 295 198 +3 521 523 519 +3 569 523 521 +3 575 521 519 +3 443 448 509 +3 581 578 513 +3 578 577 513 +3 159 156 75 +3 708 835 701 +3 712 835 708 +3 899 895 905 +3 784 908 884 +3 511 514 581 +3 575 577 578 +3 295 322 303 +3 323 322 295 +3 320 312 190 +3 709 688 706 +3 687 689 688 +3 684 715 686 +3 683 715 716 +3 681 630 683 +3 686 715 710 +3 448 449 509 +3 440 584 448 +3 156 90 68 +3 154 90 156 +3 575 519 577 +3 683 630 629 +3 517 524 520 +3 528 524 523 +3 709 706 841 +3 623 898 904 +3 767 898 903 +3 449 508 509 +3 448 508 449 +3 553 537 531 +3 452 379 377 +3 451 457 379 +3 895 888 905 +3 884 908 776 +3 149 147 101 +3 401 147 149 +3 453 389 355 +3 189 312 313 +3 159 76 160 +3 331 276 268 +3 326 327 283 +3 325 198 205 +3 448 584 587 +3 265 268 336 +3 272 268 265 +3 369 456 502 +3 508 454 509 +3 326 325 205 +3 190 193 322 +3 514 578 581 +3 519 574 510 +3 903 898 623 +3 899 905 898 +3 440 514 511 +3 452 377 458 +3 451 374 457 +3 453 452 380 +3 295 303 198 +3 283 327 329 +3 303 193 197 +3 283 329 276 +3 898 905 904 +3 776 908 885 +3 788 795 792 +3 807 808 799 +3 888 776 885 +3 440 511 584 +3 513 577 510 +3 90 151 152 +3 154 151 90 +3 689 690 693 +3 711 690 689 +3 714 710 690 +3 355 356 107 +3 276 330 332 +3 329 330 276 +3 327 205 206 +3 276 332 333 +3 312 186 313 +3 318 186 312 +3 905 896 904 +3 909 910 911 +3 904 896 624 +3 160 76 186 +3 788 799 795 +3 807 873 820 +3 866 862 713 +3 709 841 835 +3 843 841 700 +3 689 842 706 +3 799 808 872 +3 356 389 107 +3 355 389 356 +3 453 380 357 +3 630 631 337 +3 631 336 337 +3 276 333 268 +3 706 842 703 +3 509 454 456 +3 584 507 587 +3 511 507 584 +3 784 788 792 +3 799 872 875 +3 784 792 908 +3 76 75 74 +3 159 75 76 +3 706 703 841 +3 689 693 842 +3 710 707 690 +3 807 868 808 +3 807 820 868 +3 537 622 554 +3 542 623 537 +3 209 213 206 +3 326 205 327 +3 322 193 303 +3 76 313 186 +3 206 213 327 +3 380 458 461 +3 452 458 380 +3 457 375 377 +3 156 68 75 +3 905 888 889 +3 792 910 908 +3 795 910 792 +3 875 872 912 +3 868 865 813 +3 213 329 327 +3 198 303 197 +3 377 375 458 +3 454 498 456 +3 205 198 201 +3 457 374 375 +3 690 707 705 +3 715 627 626 +3 630 337 629 +3 508 448 587 +3 503 510 506 +3 519 523 515 +3 96 66 153 +3 90 65 68 +3 149 101 151 +3 389 357 135 +3 862 704 824 +3 866 704 862 +3 703 693 844 +3 524 531 562 +3 528 531 524 +3 520 524 562 +3 205 201 208 +3 820 824 823 +3 713 824 820 +3 268 333 335 +3 330 277 332 +3 537 554 531 +3 890 889 887 +3 715 683 629 +3 268 335 336 +3 338 339 262 +3 336 261 337 +3 622 537 623 +3 905 889 896 +3 90 152 65 +3 708 701 704 +3 704 830 824 +3 822 823 827 +3 691 629 628 +3 336 335 263 +3 147 355 107 +3 453 357 389 +3 375 462 372 +3 795 875 912 +3 820 865 868 +3 888 885 889 +3 795 912 911 +3 808 868 813 +3 152 59 153 +3 151 59 152 +3 193 190 189 +3 190 312 189 +3 68 73 75 +3 152 153 65 +3 194 189 311 +3 690 705 693 +3 715 629 691 +3 703 842 693 +3 201 197 301 +3 198 197 201 +3 208 201 301 +3 151 101 150 +3 66 65 153 +3 151 57 59 +3 808 813 867 +3 820 861 865 +3 451 456 369 +3 592 587 591 +3 313 311 189 +3 75 73 74 +3 193 189 194 +3 454 508 459 +3 581 513 510 +3 59 57 96 +3 857 830 858 +3 701 858 704 +3 554 622 552 +3 622 623 552 +3 885 887 889 +3 510 577 519 +3 554 552 620 +3 333 273 335 +3 330 213 277 +3 841 703 700 +3 374 369 464 +3 451 369 374 +3 701 835 843 +3 835 841 843 +3 458 375 463 +3 374 462 375 +3 147 107 144 +3 102 150 148 +3 151 150 57 +3 147 144 101 +3 510 503 581 +3 523 524 517 +3 531 554 620 +3 562 531 561 +3 519 515 574 +3 623 904 624 +3 896 889 894 +3 908 907 885 +3 206 205 208 +3 193 301 197 +3 78 76 74 +3 52 150 102 +3 808 867 872 +3 865 864 813 +3 824 830 857 +3 357 461 376 +3 380 461 357 +3 503 511 581 +3 515 517 617 +3 813 864 815 +3 617 517 520 +3 523 517 515 +3 562 618 520 +3 330 329 213 +3 336 262 261 +3 273 334 271 +3 340 261 262 +3 273 333 277 +3 333 332 277 +3 336 263 262 +3 885 907 887 +3 867 806 872 +3 832 824 857 +3 704 858 830 +3 701 699 697 +3 313 76 78 +3 68 65 66 +3 311 313 315 +3 910 795 911 +3 872 913 912 +3 864 818 815 +3 627 715 691 +3 337 261 340 +3 263 338 262 +3 502 498 465 +3 456 498 502 +3 701 843 699 +3 703 844 700 +3 700 844 843 +3 335 273 271 +3 335 271 264 +3 702 710 715 +3 702 707 710 +3 908 910 909 +3 913 806 870 +3 462 464 370 +3 374 464 462 +3 502 367 369 +3 626 627 692 +3 628 692 691 +3 209 208 285 +3 206 208 209 +3 311 315 188 +3 213 209 282 +3 505 515 617 +3 520 618 617 +3 357 376 358 +3 458 463 461 +3 461 463 376 +3 843 698 699 +3 844 698 843 +3 699 698 697 +3 369 367 366 +3 150 101 148 +3 101 144 145 +3 357 358 378 +3 552 623 551 +3 623 624 551 +3 907 906 887 +3 870 806 915 +3 872 806 913 +3 508 587 592 +3 501 511 503 +3 508 592 455 +3 508 455 459 +3 591 593 592 +3 594 455 592 +3 827 824 832 +3 701 697 696 +3 833 855 832 +3 133 357 378 +3 463 372 466 +3 107 389 135 +3 376 359 358 +3 221 277 216 +3 273 277 334 +3 562 561 618 +3 52 54 150 +3 335 264 263 +3 334 277 221 +3 343 337 340 +3 343 629 337 +3 858 701 696 +3 844 697 698 +3 301 193 194 +3 153 59 96 +3 864 865 818 +3 858 850 857 +3 343 340 259 +3 705 707 702 +3 691 692 627 +3 693 705 702 +3 574 515 505 +3 561 567 618 +3 510 574 582 +3 867 813 815 +3 213 282 277 +3 301 194 199 +3 592 593 594 +3 499 507 511 +3 498 454 459 +3 693 702 844 +3 499 590 507 +3 340 339 259 +3 262 339 340 +3 269 334 221 +3 912 913 870 +3 867 915 806 +3 74 73 72 +3 101 51 148 +3 375 372 463 +3 369 366 464 +3 373 463 466 +3 818 861 815 +3 865 861 818 +3 498 459 495 +3 148 51 102 +3 107 138 144 +3 823 824 827 +3 857 833 832 +3 315 78 79 +3 313 78 315 +3 498 495 465 +3 858 696 850 +3 844 696 697 +3 702 695 844 +3 715 626 702 +3 344 629 343 +3 820 823 822 +3 459 455 460 +3 455 594 597 +3 590 587 507 +3 203 301 199 +3 311 188 194 +3 376 463 359 +3 473 366 364 +3 867 815 917 +3 820 822 861 +3 372 462 370 +3 502 493 367 +3 208 301 203 +3 624 894 897 +3 896 894 624 +3 908 909 907 +3 282 285 214 +3 209 285 282 +3 216 282 214 +3 51 101 146 +3 101 145 146 +3 144 138 139 +3 358 359 378 +3 360 359 373 +3 51 103 102 +3 102 103 52 +3 78 72 86 +3 74 72 78 +3 466 372 471 +3 372 370 471 +3 344 628 629 +3 338 264 238 +3 73 68 66 +3 907 909 1012 +3 912 870 911 +3 73 66 72 +3 561 531 620 +3 552 551 621 +3 49 146 105 +3 51 146 103 +3 144 143 145 +3 590 591 587 +3 510 582 506 +3 861 822 825 +3 277 282 216 +3 208 203 204 +3 827 855 854 +3 832 855 827 +3 857 850 833 +3 593 591 590 +3 593 590 494 +3 894 890 1017 +3 889 890 894 +3 694 628 344 +3 887 906 886 +3 692 628 694 +3 285 208 204 +3 194 307 199 +3 188 314 194 +3 338 263 264 +3 285 204 212 +3 103 146 104 +3 145 105 146 +3 827 828 822 +3 499 501 497 +3 511 501 499 +3 506 582 503 +3 844 695 696 +3 626 695 702 +3 692 694 625 +3 194 314 195 +3 315 79 188 +3 138 135 136 +3 107 135 138 +3 378 359 360 +3 463 373 359 +3 827 854 828 +3 833 850 855 +3 366 365 364 +3 367 365 366 +3 364 365 492 +3 459 460 495 +3 593 494 594 +3 499 497 590 +3 495 460 470 +3 57 150 54 +3 100 57 54 +3 215 285 212 +3 199 204 203 +3 619 620 556 +3 561 620 567 +3 316 79 86 +3 188 79 314 +3 66 97 95 +3 890 886 1017 +3 887 886 890 +3 907 1012 906 +3 373 468 371 +3 466 468 373 +3 105 106 49 +3 145 106 105 +3 551 624 924 +3 624 897 924 +3 367 493 365 +3 103 104 52 +3 259 339 341 +3 339 338 341 +3 861 917 815 +3 831 853 852 +3 854 853 828 +3 867 917 915 +3 915 917 916 +3 863 870 916 +3 911 870 1008 +3 135 133 119 +3 357 133 135 +3 831 828 853 +3 855 853 854 +3 98 97 60 +3 96 97 66 +3 104 49 52 +3 343 259 256 +3 259 341 342 +3 503 582 583 +3 502 465 493 +3 141 143 140 +3 145 143 106 +3 894 1017 897 +3 460 455 597 +3 594 494 597 +3 503 583 588 +3 493 492 365 +3 465 489 493 +3 473 363 366 +3 93 66 95 +3 96 60 97 +3 96 57 100 +3 146 49 104 +3 52 49 53 +3 373 371 360 +3 466 371 468 +3 552 621 620 +3 1017 1018 897 +3 822 828 831 +3 855 852 853 +3 460 597 600 +3 626 692 625 +3 343 256 254 +3 96 100 99 +3 72 66 93 +3 626 625 695 +3 695 625 850 +3 490 497 588 +3 590 497 490 +3 60 96 99 +3 52 53 54 +3 98 99 56 +3 466 471 371 +3 551 924 926 +3 822 831 829 +3 363 464 366 +3 493 489 492 +3 316 86 88 +3 78 86 79 +3 621 556 620 +3 551 926 621 +3 617 618 567 +3 492 491 364 +3 344 343 254 +3 338 238 341 +3 852 850 840 +3 855 850 852 +3 695 850 696 +3 271 334 269 +3 214 285 215 +3 264 271 269 +3 138 136 139 +3 378 360 133 +3 471 475 371 +3 143 144 139 +3 143 139 140 +3 341 238 239 +3 72 93 92 +3 60 99 98 +3 259 342 258 +3 133 360 130 +3 582 505 504 +3 574 505 582 +3 465 467 469 +3 495 467 465 +3 571 567 568 +3 341 239 342 +3 264 269 266 +3 342 239 258 +3 582 504 583 +3 617 567 571 +3 491 489 487 +3 492 489 491 +3 216 214 215 +3 199 307 204 +3 556 555 619 +3 621 555 556 +3 1008 870 914 +3 915 916 870 +3 822 829 825 +3 465 488 489 +3 501 503 588 +3 216 215 218 +3 44 106 143 +3 44 143 41 +3 136 137 139 +3 135 119 136 +3 100 54 53 +3 488 469 472 +3 465 469 488 +3 460 600 482 +3 256 258 257 +3 259 258 256 +3 95 97 98 +3 100 56 99 +3 72 92 86 +3 95 98 93 +3 86 92 88 +3 204 307 304 +3 621 926 555 +3 1017 1015 1016 +3 100 53 56 +3 140 137 114 +3 139 137 140 +3 370 464 363 +3 491 474 362 +3 488 472 489 +3 471 370 475 +3 49 106 44 +3 49 44 108 +3 344 254 346 +3 694 344 346 +3 260 238 264 +3 260 264 266 +3 216 218 221 +3 314 79 316 +3 221 218 222 +3 212 292 210 +3 307 195 306 +3 491 487 474 +3 314 316 195 +3 41 141 142 +3 143 141 41 +3 505 617 571 +3 620 619 567 +3 926 929 555 +3 504 505 580 +3 53 58 56 +3 93 98 94 +3 92 93 94 +3 44 41 110 +3 41 142 110 +3 140 114 141 +3 494 590 490 +3 501 588 497 +3 504 500 583 +3 486 494 490 +3 917 861 825 +3 852 840 831 +3 583 500 496 +3 212 204 292 +3 194 195 307 +3 909 911 1008 +3 917 860 916 +3 886 906 1015 +3 831 840 834 +3 49 108 53 +3 53 108 111 +3 504 580 500 +3 239 238 260 +3 221 227 269 +3 258 239 257 +3 360 371 361 +3 371 475 361 +3 44 109 108 +3 44 110 109 +3 567 619 616 +3 505 571 580 +3 619 930 966 +3 370 363 475 +3 364 491 362 +3 210 288 212 +3 211 288 210 +3 141 114 112 +3 136 134 137 +3 117 114 115 +3 924 897 1018 +3 886 1015 1017 +3 926 924 972 +3 926 972 976 +3 694 346 347 +3 256 345 254 +3 204 304 292 +3 316 309 195 +3 269 227 266 +3 307 306 304 +3 142 141 112 +3 137 115 114 +3 906 1012 1015 +3 916 860 859 +3 288 215 212 +3 304 300 292 +3 306 202 304 +3 917 825 920 +3 831 834 829 +3 489 472 487 +3 467 470 469 +3 487 472 474 +3 221 222 227 +3 870 863 914 +3 914 863 1006 +3 195 309 306 +3 88 94 187 +3 473 364 362 +3 473 362 363 +3 597 494 600 +3 583 496 588 +3 580 571 576 +3 254 345 346 +3 136 119 118 +3 256 257 345 +3 227 229 266 +3 132 134 118 +3 137 134 115 +3 110 142 112 +3 829 834 836 +3 568 567 616 +3 555 929 619 +3 972 924 1019 +3 924 1018 1019 +3 1012 1011 1029 +3 467 495 470 +3 472 470 482 +3 469 470 472 +3 568 615 571 +3 571 614 576 +3 500 580 610 +3 116 112 117 +3 110 112 109 +3 116 109 112 +3 619 929 930 +3 360 361 368 +3 363 476 475 +3 362 476 363 +3 568 616 615 +3 929 966 930 +3 133 130 119 +3 119 130 129 +3 134 136 118 +3 472 482 602 +3 460 482 470 +3 909 1008 1011 +3 860 917 919 +3 1018 1016 1063 +3 1017 1016 1018 +3 909 1011 1012 +3 210 300 211 +3 292 300 210 +3 309 202 306 +3 475 476 361 +3 586 496 585 +3 588 496 596 +3 601 486 484 +3 494 486 600 +3 917 920 919 +3 829 836 825 +3 918 860 919 +3 115 134 117 +3 694 347 625 +3 345 347 346 +3 257 253 345 +3 625 347 845 +3 316 88 187 +3 92 94 88 +3 56 58 98 +3 309 316 187 +3 972 1019 976 +3 614 615 613 +3 571 615 614 +3 619 966 616 +3 309 187 200 +3 580 576 610 +3 220 215 288 +3 304 202 300 +3 863 916 859 +3 846 836 837 +3 1027 1012 1029 +3 920 825 921 +3 840 839 834 +3 834 839 836 +3 850 839 840 +3 625 845 850 +3 360 122 130 +3 476 368 361 +3 127 122 368 +3 920 921 851 +3 839 837 836 +3 963 616 933 +3 616 966 933 +3 926 976 927 +3 1015 1012 1014 +3 1008 1010 1011 +3 1024 1014 1025 +3 1015 1014 1016 +3 345 253 252 +3 239 260 257 +3 257 260 247 +3 222 229 227 +3 218 215 220 +3 222 218 220 +3 300 298 211 +3 211 298 296 +3 1008 914 1006 +3 1037 859 1002 +3 920 851 919 +3 266 229 240 +3 130 122 129 +3 360 368 122 +3 500 585 496 +3 490 588 484 +3 300 202 298 +3 825 836 846 +3 1024 1025 1061 +3 1012 1013 1014 +3 919 851 849 +3 837 838 846 +3 500 610 585 +3 614 613 576 +3 600 486 479 +3 490 484 486 +3 610 586 585 +3 48 5 50 +3 98 58 94 +3 1029 1010 1057 +3 1011 1010 1029 +3 222 220 275 +3 211 296 290 +3 202 296 298 +3 288 211 290 +3 576 613 612 +3 111 109 116 +3 114 117 112 +3 119 131 118 +3 921 825 846 +3 839 838 837 +3 1008 1006 1007 +3 922 848 923 +3 859 860 918 +3 921 848 851 +3 576 612 611 +3 345 252 347 +3 257 247 249 +3 222 275 229 +3 229 270 267 +3 260 266 240 +3 288 290 287 +3 220 288 281 +3 859 918 856 +3 229 275 270 +3 929 926 927 +3 1016 1014 1024 +3 978 929 927 +3 848 846 923 +3 921 846 848 +3 1063 1016 1024 +3 1014 1013 1025 +3 496 586 485 +3 576 611 610 +3 961 615 963 +3 615 616 963 +3 108 109 111 +3 134 132 117 +3 26 132 131 +3 220 281 279 +3 859 856 1002 +3 851 848 922 +3 260 240 247 +3 1019 1018 1063 +3 846 845 923 +3 838 845 846 +3 839 845 838 +3 850 845 839 +3 482 479 602 +3 600 479 482 +3 588 483 484 +3 474 472 602 +3 484 483 481 +3 1061 1013 1026 +3 1025 1013 1061 +3 976 925 977 +3 1019 974 976 +3 976 974 925 +3 918 919 849 +3 1019 1063 1064 +3 1013 1027 1026 +3 613 615 961 +3 979 929 978 +3 612 613 579 +3 974 1064 973 +3 1019 1064 974 +3 1024 1061 1026 +3 586 610 609 +3 610 611 609 +3 965 966 929 +3 974 975 925 +3 486 601 479 +3 484 481 601 +3 588 596 483 +3 1023 1024 1026 +3 1012 1027 1013 +3 1008 1009 1010 +3 483 596 480 +3 1063 1024 1022 +3 474 602 362 +3 601 602 479 +3 481 480 478 +3 275 279 274 +3 220 279 275 +3 288 287 281 +3 296 184 290 +3 270 275 233 +3 281 287 178 +3 202 200 207 +3 1 94 64 +3 117 132 120 +3 118 131 132 +3 933 966 965 +3 925 975 977 +3 613 961 579 +3 933 965 932 +3 119 129 131 +3 476 127 368 +3 1010 1009 1057 +3 863 859 1037 +3 481 483 480 +3 596 485 604 +3 496 485 596 +3 612 579 611 +3 963 933 932 +3 963 932 962 +3 978 928 979 +3 53 111 50 +3 117 120 116 +3 586 609 608 +3 601 481 478 +3 1006 863 1037 +3 918 849 999 +3 927 976 977 +3 1063 1022 1021 +3 974 973 975 +3 270 233 267 +3 281 178 279 +3 240 229 267 +3 611 579 609 +3 932 931 962 +3 1064 1063 1021 +3 1027 1029 1028 +3 1009 1031 1057 +3 856 918 999 +3 1006 1037 1004 +3 849 847 998 +3 851 922 847 +3 845 922 923 +3 116 120 35 +3 129 128 125 +3 1064 1021 973 +3 1020 1021 1062 +3 961 963 935 +3 965 931 932 +3 927 977 978 +3 275 274 233 +3 965 929 979 +3 973 1021 1020 +3 94 58 64 +3 53 50 58 +3 116 35 111 +3 202 309 200 +3 965 979 967 +3 978 977 928 +3 242 267 168 +3 274 174 172 +3 1022 1023 1062 +3 1024 1023 1022 +3 579 608 609 +3 586 607 485 +3 485 607 598 +3 1028 1029 1057 +3 1008 1007 1009 +3 1002 856 999 +3 851 847 849 +3 1059 1027 1028 +3 586 608 607 +3 1037 1001 1003 +3 1002 1001 1037 +3 928 977 969 +3 1022 1062 1021 +3 21 129 125 +3 122 128 129 +3 362 127 476 +3 1034 1007 1005 +3 1009 1007 1031 +3 120 26 123 +3 132 26 120 +3 111 45 50 +3 287 290 219 +3 296 202 207 +3 601 478 602 +3 596 477 480 +3 174 279 278 +3 279 178 278 +3 965 967 931 +3 928 969 979 +3 931 967 982 +3 959 961 936 +3 979 980 967 +3 1026 1027 1060 +3 1031 1007 1032 +3 1026 1060 1023 +3 1023 1060 1062 +3 1006 1004 1036 +3 1002 999 1001 +3 1051 1004 1003 +3 287 219 178 +3 274 279 174 +3 219 223 178 +3 235 274 172 +3 1001 999 1040 +3 922 997 847 +3 296 207 184 +3 253 257 249 +3 174 226 175 +3 971 975 973 +3 971 973 1020 +3 128 127 125 +3 122 127 128 +3 602 19 362 +3 579 961 959 +3 278 177 226 +3 178 177 278 +3 290 184 219 +3 980 969 968 +3 979 969 980 +3 967 980 968 +3 111 35 45 +3 131 129 21 +3 1007 1006 1005 +3 1037 1003 1004 +3 1027 1059 1060 +3 1057 1031 1032 +3 1060 1059 1058 +3 999 998 997 +3 849 998 999 +3 174 278 226 +3 177 223 224 +3 178 223 177 +3 579 959 937 +3 961 935 936 +3 958 938 937 +3 219 184 217 +3 200 192 196 +3 187 192 200 +3 253 249 252 +3 235 233 274 +3 936 935 987 +3 235 267 233 +3 219 179 223 +3 26 131 21 +3 26 21 22 +3 177 224 226 +3 963 962 935 +3 1030 1057 1032 +3 1001 1040 1003 +3 1006 1036 1005 +3 120 123 121 +3 1003 1040 1000 +3 1036 1052 1005 +3 1004 1052 1036 +3 977 975 971 +3 1060 1058 1062 +3 935 934 960 +3 962 934 935 +3 967 968 964 +3 1028 1057 1030 +3 1052 1051 1050 +3 478 477 602 +3 480 477 478 +3 608 589 607 +3 168 267 235 +3 224 179 176 +3 242 240 267 +3 123 22 124 +3 26 22 123 +3 125 19 21 +3 938 579 937 +3 936 937 959 +3 983 931 982 +3 977 971 970 +3 226 224 176 +3 223 179 224 +3 172 174 230 +3 174 175 230 +3 934 962 983 +3 962 931 983 +3 184 207 196 +3 207 200 196 +3 45 113 50 +3 35 113 45 +3 123 124 25 +3 21 19 22 +3 58 50 5 +3 120 121 35 +3 1005 1052 1050 +3 1004 1051 1052 +3 50 113 48 +3 187 94 1 +3 1028 1030 1058 +3 1007 1054 1032 +3 1059 1028 1058 +3 247 240 242 +3 172 230 232 +3 596 604 477 +3 934 983 984 +3 967 964 982 +3 1032 1054 1055 +3 235 172 232 +3 226 176 175 +3 1003 1000 1038 +3 999 997 1042 +3 1040 999 1042 +3 847 997 998 +3 845 995 922 +3 1040 1042 1041 +3 35 121 32 +3 175 176 230 +3 219 217 181 +3 968 969 970 +3 969 977 970 +3 1062 1058 1020 +3 982 964 983 +3 1003 1038 1051 +3 1040 1041 1000 +3 1051 1038 1050 +3 935 960 987 +3 964 984 983 +3 937 936 987 +3 1047 1041 996 +3 997 1044 1042 +3 181 217 183 +3 176 228 230 +3 179 219 181 +3 171 232 173 +3 485 598 604 +3 1054 1034 1053 +3 1007 1034 1054 +3 1020 1058 971 +3 1032 1055 1030 +3 608 579 589 +3 605 589 606 +3 247 242 164 +3 235 232 171 +3 64 63 2 +3 58 5 64 +3 113 43 48 +3 225 179 181 +3 184 183 217 +3 124 19 20 +3 22 19 124 +3 127 19 125 +3 362 19 127 +3 1030 1056 1058 +3 176 179 225 +3 228 176 225 +3 941 938 939 +3 937 987 958 +3 934 984 960 +3 607 589 605 +3 938 957 939 +3 958 987 957 +3 184 196 185 +3 187 1 192 +3 173 230 228 +3 183 180 181 +3 968 970 981 +3 1058 970 971 +3 964 968 981 +3 607 605 595 +3 941 579 938 +3 607 595 598 +3 598 595 603 +3 48 6 5 +3 35 32 36 +3 232 230 173 +3 181 180 225 +3 960 984 985 +3 113 35 36 +3 123 25 121 +3 247 250 249 +3 249 250 252 +3 251 250 255 +3 958 957 938 +3 960 985 987 +3 941 589 579 +3 170 235 171 +3 170 168 235 +3 987 985 989 +3 964 981 984 +3 943 589 941 +3 987 989 957 +3 6 43 7 +3 48 43 6 +3 984 981 986 +3 121 25 27 +3 32 121 31 +3 1056 1055 1058 +3 1030 1055 1056 +3 1005 1035 1034 +3 1041 1042 996 +3 1058 1055 970 +3 242 168 241 +3 228 225 231 +3 225 180 231 +3 32 31 36 +3 64 5 63 +3 63 5 62 +3 1054 1033 1055 +3 192 1 77 +3 242 241 165 +3 1054 1053 1033 +3 1042 1044 996 +3 922 1044 997 +3 1048 1000 1041 +3 168 170 241 +3 173 228 231 +3 604 603 477 +3 598 603 604 +3 605 951 950 +3 606 589 951 +3 64 2 1 +3 234 173 231 +3 184 185 183 +3 192 77 0 +3 605 606 951 +3 957 989 990 +3 984 986 985 +3 247 164 250 +3 170 169 241 +3 603 599 477 +3 595 599 603 +3 80 192 0 +3 2 70 1 +3 1053 1035 1033 +3 1034 1035 1053 +3 1033 1035 1055 +3 196 192 191 +3 1 70 71 +3 939 940 941 +3 595 605 950 +3 940 953 941 +3 589 943 951 +3 237 171 234 +3 171 173 234 +3 113 36 43 +3 121 27 31 +3 43 36 10 +3 1038 1000 1039 +3 1005 1050 1035 +3 164 165 163 +3 242 165 164 +3 180 183 182 +3 183 185 182 +3 595 950 599 +3 943 952 944 +3 941 952 943 +3 3 71 69 +3 71 70 69 +3 63 62 2 +3 6 7 5 +3 5 7 55 +3 1048 1049 1039 +3 1038 1049 1050 +3 170 171 237 +3 180 182 236 +3 36 31 33 +3 31 27 28 +3 124 20 25 +3 241 169 243 +3 0 77 71 +3 2 69 70 +3 1050 1049 1048 +3 1038 1039 1049 +3 951 943 944 +3 939 957 990 +3 164 255 250 +3 241 244 165 +3 252 250 251 +3 196 191 185 +3 25 20 27 +3 192 80 191 +3 165 244 166 +3 164 163 255 +3 950 946 947 +3 951 946 950 +3 952 941 942 +3 941 953 942 +3 951 944 946 +3 952 942 944 +3 944 945 946 +3 950 947 599 +3 234 231 236 +3 231 180 236 +3 191 236 185 +3 169 237 167 +3 170 237 169 +3 1044 995 996 +3 922 995 1044 +3 996 995 1043 +3 69 62 3 +3 2 62 69 +3 241 243 244 +3 244 243 166 +3 1050 1048 1035 +3 1000 1048 1039 +3 1046 1048 1047 +3 42 8 9 +3 43 8 7 +3 43 10 8 +3 20 23 27 +3 946 945 947 +3 942 992 949 +3 953 940 990 +3 77 1 71 +3 5 55 62 +3 80 0 71 +3 10 33 34 +3 36 33 10 +3 62 61 4 +3 163 161 255 +3 165 166 162 +3 252 251 347 +3 62 4 3 +3 8 10 38 +3 954 991 990 +3 940 939 990 +3 970 986 981 +3 991 953 990 +3 163 165 162 +3 237 236 245 +3 234 236 237 +3 80 71 191 +3 4 67 3 +3 3 67 71 +3 1045 1048 1046 +3 1041 1047 1048 +3 10 34 38 +3 31 12 33 +3 61 62 55 +3 955 956 988 +3 985 956 989 +3 942 953 992 +3 989 954 990 +3 255 161 251 +3 996 1043 1047 +3 956 986 988 +3 985 986 956 +3 944 942 949 +3 33 12 34 +3 4 55 67 +3 61 55 4 +3 12 29 30 +3 8 38 9 +3 954 989 955 +3 989 956 955 +3 15 28 126 +3 31 28 12 +3 954 955 991 +3 986 955 988 +3 47 8 42 +3 28 23 126 +3 1035 1048 1045 +3 1043 1046 1047 +3 995 1045 1043 +3 7 8 47 +3 38 40 9 +3 166 243 167 +3 243 169 167 +3 185 236 182 +3 71 236 191 +3 161 162 251 +3 163 162 161 +3 30 34 12 +3 27 23 28 +3 944 949 945 +3 953 991 992 +3 945 949 947 +3 994 949 948 +3 42 40 39 +3 9 40 42 +3 1035 1045 1055 +3 1043 1045 1046 +3 166 167 248 +3 166 248 162 +3 12 28 14 +3 992 991 993 +3 986 994 955 +3 13 34 30 +3 38 34 13 +3 12 14 29 +3 29 14 30 +3 28 15 14 +3 7 47 55 +3 38 39 40 +3 55 47 67 +3 67 47 71 +3 42 39 46 +3 14 13 30 +3 47 46 11 +3 42 46 47 +3 167 245 246 +3 237 245 167 +3 38 13 39 +3 15 24 14 +3 39 13 37 +3 14 24 17 +3 126 24 15 +3 23 24 126 +3 20 24 23 +3 167 246 248 +3 236 246 245 +3 71 246 236 +3 248 246 162 +3 992 993 949 +3 955 994 991 +3 39 37 11 +3 14 17 13 +3 47 11 71 +3 39 11 46 +3 947 949 994 +3 993 948 949 +3 991 994 993 +3 599 947 994 +3 599 994 477 +3 993 994 948 +3 970 994 986 +3 1055 994 970 +3 477 994 602 +3 37 13 16 +3 13 17 16 +3 37 16 11 +3 11 16 71 +3 17 18 16 +3 24 18 17 +3 20 18 24 +3 19 18 20 diff --git a/core/src/test/resources/las-delaunay.json b/core/src/test/resources/las-delaunay.json new file mode 100644 index 0000000..d6bf3f1 --- /dev/null +++ b/core/src/test/resources/las-delaunay.json @@ -0,0 +1,11 @@ +{ + "pipeline":[ + { + "filename":"core/src/test/resources/1.2-with-color.las", + "spatialreference":"EPSG:2993" + }, + { + "type": "filters.delaunay" + } + ] +} diff --git a/core/src/test/scala/io/pdal/PipelineSpec.scala b/core/src/test/scala/io/pdal/PipelineSpec.scala index f1be56d..984c60c 100644 --- a/core/src/test/scala/io/pdal/PipelineSpec.scala +++ b/core/src/test/scala/io/pdal/PipelineSpec.scala @@ -42,7 +42,7 @@ class PipelineSpec extends TestEnvironmentSpec { it("should validate as incorrect json (bad json passed)") { val badPipeline = Pipeline(badJson) badPipeline.validate() should be (false) - badPipeline.dispose() + badPipeline.close() badPipeline.ptr should be (0) } @@ -57,7 +57,7 @@ class PipelineSpec extends TestEnvironmentSpec { it("should create pointViews iterator") { val pvi = pipeline.getPointViews() pvi.asScala.length should be (1) - pvi.dispose() + pvi.close() } it("should have a valid point view size") { @@ -65,8 +65,8 @@ class PipelineSpec extends TestEnvironmentSpec { val pv = pvi.next() pv.length should be (1065) pvi.hasNext should be (false) - pv.dispose() - pvi.dispose() + pv.close() + pvi.close() } it("should read a valid (X, Y, Z) data") { @@ -75,23 +75,23 @@ class PipelineSpec extends TestEnvironmentSpec { pv.getX(0) should be (637012.24) pv.getY(0) should be (849028.31) pv.getZ(0) should be (431.66) - pv.dispose() - pvi.dispose() + pv.close() + pvi.close() } it("should read a valid packed data") { val pvi = pipeline.getPointViews() val pv = pvi.next() - val layout = pv.layout + val layout = pv.layout() val arr = pv.getPackedPoint(0, Array(DimType.X, DimType.Y)) val (xarr, yarr) = arr.take(layout.dimSize(DimType.X).toInt) -> arr.drop(layout.dimSize(DimType.Y).toInt) ByteBuffer.wrap(xarr).order(ByteOrder.nativeOrder()).getDouble should be (pv.getX(0)) ByteBuffer.wrap(yarr).order(ByteOrder.nativeOrder()).getDouble should be (pv.getY(0)) - layout.dispose() - pv.dispose() - pvi.dispose() + layout.close() + pv.close() + pvi.close() } it("should read the whole packed point and grab only one dim") { @@ -99,79 +99,79 @@ class PipelineSpec extends TestEnvironmentSpec { val pv = pvi.next() val arr = pv.getPackedPoint(0) pv.get(arr, DimType.Y).getDouble should be (pv.getY(0)) - pv.dispose() - pvi.dispose() + pv.close() + pvi.close() } it("should read all packed points and grab only one point out of it") { val pvi = pipeline.getPointViews() val pv = pvi.next() - pv.get(3, pv.getPackedPoints) should be (pv.getPackedPoint(3)) - pv.dispose() - pvi.dispose() + pv.get(3, pv.getPackedPoints()) should be (pv.getPackedPoint(3)) + pv.close() + pvi.close() } it("should read a valid value by name") { val pvi = pipeline.getPointViews() val pv = pvi.next() pv.getByte(0, "ReturnNumber") should be (1) - pv.dispose() - pvi.dispose() + pv.close() + pvi.close() } it("should read correctly data as a packed point") { val pvi = pipeline.getPointViews() val pv = pvi.next() - val layout = pv.layout + val layout = pv.layout() val arr = pv.getPackedPoint(0) layout.dimTypes().foreach { dt => pv.get(0, dt).array() should be(pv.get(arr, dt).array())} - layout.dispose() - pv.dispose() - pvi.dispose() + layout.close() + pv.close() + pvi.close() } it("layout should have a valid number of dims") { val pvi = pipeline.getPointViews() val pv = pvi.next() - pv.layout.dimTypes().length should be (16) - pv.dispose() - pvi.dispose() + pv.layout().dimTypes().length should be (16) + pv.close() + pvi.close() } it("should find a dim by name") { val pvi = pipeline.getPointViews() val pv = pvi.next() pv.findDimType("Red") should be (DimType("Red", "uint16_t")) - pv.dispose() - pvi.dispose() + pv.close() + pvi.close() } it("dim sizes should be of a valid size") { val pvi = pipeline.getPointViews() val pv = pvi.next() - val layout = pv.layout - layout.dimTypes().map(pv.layout.dimSize(_)).sum should be (layout.pointSize()) - layout.dispose() - pv.dispose() - pvi.dispose() + val layout = pv.layout() + layout.dimTypes().map(pv.layout().dimSize(_)).sum should be (layout.pointSize()) + layout.close() + pv.close() + pvi.close() } it("should read all packed points valid") { val pvi = pipeline.getPointViews() val pv = pvi.next() - val layout = pv.layout - pv.getPackedPoints.length should be (pv.length * layout.pointSize()) - layout.dispose() - pv.dispose() - pvi.dispose() + val layout = pv.layout() + pv.getPackedPoints().length should be (pv.length * layout.pointSize()) + layout.close() + pv.close() + pvi.close() } it("should read crs correct") { val pvi = pipeline.getPointViews() val pv = pvi.next() pv.getCrsProj4 should (be (proj4String) or be(proj4StringNew)) - pv.dispose() - pvi.dispose() + pv.close() + pvi.close() } it("should fail with InitializationException") { @@ -185,7 +185,62 @@ class PipelineSpec extends TestEnvironmentSpec { intercept[ExecutionException] { pipeline.getMetadata() } intercept[ExecutionException] { pipeline.getSchema() } - pipeline.dispose() + pipeline.close() + } + + it("should extract mesh in iterative fashion") { + pipelineDelaunay.validate() should be (true) + pipelineDelaunay.execute() + val pvi = pipelineDelaunay.getPointViews() + val pv = pvi.next() + val mesh = pv.getTriangularMesh() + val actual = mesh.asScala.toList + + actual should be (expectedDelaunayPlyTriangles) + + mesh.close() + pv.close() + pvi.close() + } + + it("should extract mesh as a bulk") { + val pvi = pipelineDelaunay.getPointViews() + val pv = pvi.next() + val mesh = pv.getTriangularMesh() + + val actual = mesh.asArray().toList + + actual should be (expectedDelaunayPlyTriangles) + + mesh.close() + pv.close() + pvi.close() + } + + it("should extract mesh directly by a triangle identifier") { + val pvi = pipelineDelaunay.getPointViews() + val pv = pvi.next() + val mesh = pv.getTriangularMesh() + + var i = 0 + while(i < mesh.size) { + mesh.get(i) shouldBe expectedDelaunayPlyTriangles(i) + i += 1 + } + + mesh.close() + pv.close() + pvi.close() + } + + it("should not extract mesh if it was not generated") { + val pvi = pipeline.getPointViews() + val pv = pvi.next() + + intercept[ExecutionException] { pv.getTriangularMesh() } + + pv.close() + pvi.close() } } } diff --git a/core/src/test/scala/io/pdal/PointCloudSpec.scala b/core/src/test/scala/io/pdal/PointCloudSpec.scala index 2bc00a8..1716f44 100644 --- a/core/src/test/scala/io/pdal/PointCloudSpec.scala +++ b/core/src/test/scala/io/pdal/PointCloudSpec.scala @@ -45,18 +45,18 @@ class PointCloudSpec extends TestEnvironmentSpec { val pvi = pipeline.getPointViews() val pv = pvi.next() - packedPoints = pv.getPointCloud + packedPoints = pv.getPointCloud() - pv.dispose() - pvi.dispose() + pv.close() + pvi.close() } it("should have a valid point view size") { val pvi = pipeline.getPointViews() val pv = pvi.next() pv.length should be (packedPoints.length) - pv.dispose() - pvi.dispose() + pv.close() + pvi.close() } it("should read a valid (X, Y, Z) data") { @@ -65,14 +65,14 @@ class PointCloudSpec extends TestEnvironmentSpec { pv.getX(0) should be (packedPoints.getX(0)) pv.getY(0) should be (packedPoints.getY(0)) pv.getZ(0) should be (packedPoints.getZ(0)) - pv.dispose() - pvi.dispose() + pv.close() + pvi.close() } it("should read a valid packed data") { val pvi = pipeline.getPointViews() val pv = pvi.next() - val layout = pv.layout + val layout = pv.layout() val arr = pv.getPackedPoint(0, Array(DimType.X, DimType.Y)) val (xarr, yarr) = arr.take(layout.dimSize(DimType.X).toInt) -> arr.drop(layout.dimSize(DimType.Y).toInt) @@ -84,33 +84,33 @@ class PointCloudSpec extends TestEnvironmentSpec { ByteBuffer.wrap(xmarr).order(ByteOrder.nativeOrder()).getDouble should be (pv.getX(0)) ByteBuffer.wrap(ymarr).order(ByteOrder.nativeOrder()).getDouble should be (pv.getY(0)) - layout.dispose() - pv.dispose() - pvi.dispose() + layout.close() + pv.close() + pvi.close() } it("should read the whole packed point and grab only one dim") { val pvi = pipeline.getPointViews() val pv = pvi.next() packedPoints.get(0, DimType.Y).getDouble should be (pv.getY(0)) - pv.dispose() - pvi.dispose() + pv.close() + pvi.close() } it("should read all packed points and grab only one point out of it") { val pvi = pipeline.getPointViews() val pv = pvi.next() - pv.get(3, pv.getPackedPoints) should be (packedPoints.get(3)) - pv.dispose() - pvi.dispose() + pv.get(3, pv.getPackedPoints()) should be (packedPoints.get(3)) + pv.close() + pvi.close() } it("should read a valid value by name") { val pvi = pipeline.getPointViews() val pv = pvi.next() pv.getByte(0, "ReturnNumber") should be (packedPoints.getByte(0, "ReturnNumber")) - pv.dispose() - pvi.dispose() + pv.close() + pvi.close() } it("should read correctly data as a packed point") { @@ -119,49 +119,49 @@ class PointCloudSpec extends TestEnvironmentSpec { packedPoints.dimTypes.asScala.foreach { case (_, sdt) => pv.get(0, sdt.dimType) should be (packedPoints.get(0, sdt)) } - pv.dispose() - pvi.dispose() + pv.close() + pvi.close() } it("layout should have a valid number of dims") { val pvi = pipeline.getPointViews() val pv = pvi.next() - pv.layout.dimTypes().length should be (packedPoints.dimTypes.size) - pv.dispose() - pvi.dispose() + pv.layout().dimTypes().length should be (packedPoints.dimTypes.size) + pv.close() + pvi.close() } it("should find a dim by name") { val pvi = pipeline.getPointViews() val pv = pvi.next() pv.findDimType("Red") should be (packedPoints.findDimType("Red")) - pv.dispose() - pvi.dispose() + pv.close() + pvi.close() } it("dim sizes should be of a valid size") { val pvi = pipeline.getPointViews() val pv = pvi.next() - val layout = pv.layout - layout.dimTypes().map(pv.layout.dimSize(_)).sum should be (packedPoints.pointSize) - layout.dispose() - pv.dispose() - pvi.dispose() + val layout = pv.layout() + layout.dimTypes().map(pv.layout().dimSize(_)).sum should be (packedPoints.pointSize) + layout.close() + pv.close() + pvi.close() } it("should read all packed points valid") { val pvi = pipeline.getPointViews() val pv = pvi.next() val length = packedPoints.bytes.length - pv.getPackedPoints.length should be (length) - pv.dispose() - pvi.dispose() + pv.getPackedPoints().length should be (length) + pv.close() + pvi.close() } it("should get correct points and all values") { val pvi = pipeline.getPointViews() val pv = pvi.next() - val length = pv.length + val length = pv.length() val dimTypes = packedPoints.dimTypes.values().asScala.map(_.dimType) for (i <- 0 until length) { packedPoints.get(i) should be (pv.getPackedPoint(i)) @@ -172,8 +172,8 @@ class PointCloudSpec extends TestEnvironmentSpec { packedPoints.get(i, dt).array() should be (pv.get(i, dt).array()) } } - pv.dispose() - pvi.dispose() + pv.close() + pvi.close() } it("should work as expected with csv files") { @@ -195,7 +195,7 @@ class PointCloudSpec extends TestEnvironmentSpec { pipeline.execute() val pvi = pipeline.getPointViews() val pv = pvi.next() - val length = pv.length + val length = pv.length() length should be (expected.size) @@ -217,9 +217,9 @@ class PointCloudSpec extends TestEnvironmentSpec { val pcs = pv.getPointCloud(idx, subsetDT) - val pcsX = pc.getDouble(idx, "X") - val pcsZ = pc.getDouble(idx, "Z") - val pcsTest = pc.getDouble(idx, "TEST") + val pcsX = pcs.getDouble(idx, "X") + val pcsZ = pcs.getDouble(idx, "Z") + val pcsTest = pcs.getDouble(idx, "TEST") x should be(pcX) x should be(pvX) @@ -234,11 +234,9 @@ class PointCloudSpec extends TestEnvironmentSpec { test should be(pcsTest) } - pipeline.dispose() + pipeline.close() } } - override def beforeAll() = { - pipeline.execute() - } + override def beforeAll(): Unit = pipeline.execute() } diff --git a/core/src/test/scala/io/pdal/TestEnvironmentSpec.scala b/core/src/test/scala/io/pdal/TestEnvironmentSpec.scala index 9ecb489..271c93d 100644 --- a/core/src/test/scala/io/pdal/TestEnvironmentSpec.scala +++ b/core/src/test/scala/io/pdal/TestEnvironmentSpec.scala @@ -46,8 +46,9 @@ trait TestEnvironmentSpec extends AnyFunSpec with Matchers with BeforeAndAfterAl json } - val json = getJson("/las.json") - val badJson = + val json: String = getJson("/las.json") + val jsonDelaunay: String = getJson("/las-delaunay.json") + val badJson: String = """ |{ | "pipeline": [ @@ -63,9 +64,20 @@ trait TestEnvironmentSpec extends AnyFunSpec with Matchers with BeforeAndAfterAl val proj4String = "+proj=lcc +lat_1=43 +lat_2=45.5 +lat_0=41.75 +lon_0=-120.5 +x_0=400000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs" val proj4StringNew = "+proj=lcc +lat_0=41.75 +lon_0=-120.5 +lat_1=43 +lat_2=45.5 +x_0=400000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs" - val pipeline: Pipeline = Pipeline(json) + val pipeline: Pipeline = Pipeline(json) + val pipelineDelaunay: Pipeline = Pipeline(jsonDelaunay) - override def afterAll() = { - pipeline.dispose() + val expectedDelaunayPlyTriangles: List[Triangle] = { + val stream = getClass.getResourceAsStream("/delaunay.ply") + val lines = scala.io.Source.fromInputStream(stream).getLines drop 1088 + val triangles = + lines.map { l => + val List(a, b, c) = l.split(" ").toList.tail.map(_.toInt) + Triangle(a, b, c) + }.toList + stream.close() + triangles } + + override def afterAll(): Unit = { pipeline.close(); pipelineDelaunay.close() } } diff --git a/examples/pdal-jni/build.sbt b/examples/pdal-jni/build.sbt index aec0152..01a5291 100644 --- a/examples/pdal-jni/build.sbt +++ b/examples/pdal-jni/build.sbt @@ -21,11 +21,11 @@ resolvers ++= Seq( fork := true -val pdalVersion = "2.0.0" +val pdalVersion = "2.1.2" libraryDependencies ++= Seq( "io.pdal" %% "pdal" % pdalVersion, "io.pdal" %% "pdal-scala" % pdalVersion, "io.pdal" % "pdal-native" % pdalVersion, - "org.scalatest" %% "scalatest" % "3.1.0" % Test + "org.scalatest" %% "scalatest" % "3.1.1" % Test ) diff --git a/examples/pdal-jni/src/main/scala/com/azavea/Main.scala b/examples/pdal-jni/src/main/scala/com/azavea/Main.scala index 03da0d0..aef009d 100644 --- a/examples/pdal-jni/src/main/scala/com/azavea/Main.scala +++ b/examples/pdal-jni/src/main/scala/com/azavea/Main.scala @@ -24,6 +24,6 @@ object Main { val pipeline = Pipeline(json) pipeline.execute() println(s"pipeline.getMetadata(): ${pipeline.getMetadata()}") - pipeline.dispose() + pipeline.close() } } diff --git a/examples/pdal-jni/src/main/scala/com/azavea/MainScala.scala b/examples/pdal-jni/src/main/scala/com/azavea/MainScala.scala index a639746..f39ab8a 100644 --- a/examples/pdal-jni/src/main/scala/com/azavea/MainScala.scala +++ b/examples/pdal-jni/src/main/scala/com/azavea/MainScala.scala @@ -25,10 +25,10 @@ object MainScala { |} """.stripMargin - val pipelineExpr = LasRead( + val pipelineExpr = ReadLas( filename = "data/1.2-with-color.las", spatialreference = Some("EPSG:2993") - ) ~ ReprojectionFilter(outSrs = "EPSG:3857") + ) ~ FilterReprojection(outSrs = "EPSG:3857") def main(args: Array[String]) = { // check that pipelineExpr corresponds to a raw json definition @@ -42,6 +42,6 @@ object MainScala { val pipeline: Pipeline = pipelineExpr.toPipeline pipeline.execute() println(s"pipeline.getMetadata(): ${pipeline.getMetadata()}") - pipeline.dispose() + pipeline.close() } } diff --git a/native/src/CMakeLists.txt b/native/src/CMakeLists.txt index c8fc26f..57492b6 100644 --- a/native/src/CMakeLists.txt +++ b/native/src/CMakeLists.txt @@ -9,7 +9,7 @@ set(MAKE_COLOR_MAKEFILE ON) project (pdaljni) set(PROJECT_VERSION_MAJOR 2) -set(PROJECT_VERSION_MINOR 0) +set(PROJECT_VERSION_MINOR 1) set(PROJECT_VERSION_PATCH 0) set(PDAL_LIB_NAME pdalcpp) diff --git a/native/src/JavaExceptions.cpp b/native/src/JavaExceptions.cpp new file mode 100644 index 0000000..4f9e651 --- /dev/null +++ b/native/src/JavaExceptions.cpp @@ -0,0 +1,50 @@ +/****************************************************************************** +* Copyright (c) 2020, hobu Inc. (info@hobu.co) +* +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following +* conditions are met: +* +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in +* the documentation and/or other materials provided +* with the distribution. +* * Neither the name of Hobu, Inc. nor the names of its +* contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +* OF SUCH DAMAGE. +****************************************************************************/ + +#pragma once + +#include "JavaExceptions.hpp" + +jstring throwInitializationException(JNIEnv *env, const char *message) +{ + jclass Exception = env->FindClass("io/pdal/InitializationException"); + env->ThrowNew(Exception, message); + return env->NewStringUTF(message); +} + +jstring throwExecutionException(JNIEnv *env, const char *message) +{ + jclass Exception = env->FindClass("io/pdal/ExecutionException"); + env->ThrowNew(Exception, message); + return env->NewStringUTF(message); +} diff --git a/native/src/include/JavaExceptions.hpp b/native/src/include/JavaExceptions.hpp new file mode 100644 index 0000000..33d4d02 --- /dev/null +++ b/native/src/include/JavaExceptions.hpp @@ -0,0 +1,45 @@ +/****************************************************************************** +* Copyright (c) 2020, hobu Inc. (info@hobu.co) +* +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following +* conditions are met: +* +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in +* the documentation and/or other materials provided +* with the distribution. +* * Neither the name of Hobu, Inc. nor the names of its +* contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +* OF SUCH DAMAGE. +****************************************************************************/ + +#pragma once + +#include + +#ifndef _JAVAEXCEPTIONS_H_INCLUDED_ +#define _JAVAEXCEPTIONS_H_INCLUDED_ + +jstring throwInitializationException(JNIEnv *env, const char *message); + +jstring throwExecutionException(JNIEnv *env, const char *message); + +#endif diff --git a/native/src/include/JavaIterator.hpp b/native/src/include/JavaSetIterator.hpp similarity index 89% rename from native/src/include/JavaIterator.hpp rename to native/src/include/JavaSetIterator.hpp index 0ba678e..1f76a45 100644 --- a/native/src/include/JavaIterator.hpp +++ b/native/src/include/JavaSetIterator.hpp @@ -36,8 +36,8 @@ #include #include "JavaPipeline.hpp" -#ifndef _JAVAITERATOR_H_INCLUDED_ -#define _JAVAITERATOR_H_INCLUDED_ +#ifndef _JAVASETITERATOR_H_INCLUDED_ +#define _JAVASETITERATOR_H_INCLUDED_ using pdal::PointViewLess; using pdal::PointViewPtr; @@ -45,13 +45,13 @@ using pdal::PointViewPtr; namespace libpdaljava { template -class JavaIterator { +class JavaSetIterator { public: - JavaIterator() {} - JavaIterator(const std::set set) + JavaSetIterator() {} + JavaSetIterator(const std::set set) : container{set}, curr_pos{0} { } - JavaIterator(const std::set *set) + JavaSetIterator(const std::set *set) : container{*set}, curr_pos{0} { } bool hasNext() const { @@ -72,6 +72,6 @@ class JavaIterator { unsigned int curr_pos; }; -typedef JavaIterator PointViewIterator; +typedef JavaSetIterator PointViewIterator; } #endif diff --git a/native/src/include/JavaTriangularMeshIterator.hpp b/native/src/include/JavaTriangularMeshIterator.hpp new file mode 100644 index 0000000..1296b98 --- /dev/null +++ b/native/src/include/JavaTriangularMeshIterator.hpp @@ -0,0 +1,77 @@ +/****************************************************************************** +* Copyright (c) 2020, hobu Inc. (info@hobu.co) +* +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following +* conditions are met: +* +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in +* the documentation and/or other materials provided +* with the distribution. +* * Neither the name of Hobu, Inc. nor the names of its +* contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +* OF SUCH DAMAGE. +****************************************************************************/ + +#include +#include "JavaPipeline.hpp" + +#ifndef _JAVATRIANGULARITERATOR_H_INCLUDED_ +#define _JAVATRIANGULARITERATOR_H_INCLUDED_ + +using pdal::Triangle; +using pdal::TriangularMesh; +using pdal::PointId; + +namespace libpdaljava +{ +class TriangularMeshIterator { +public: + TriangularMeshIterator() {} + TriangularMeshIterator(const TriangularMesh mesh) + : container{mesh}, curr_pos{0} + { } + TriangularMeshIterator(const TriangularMesh * mesh) + : container{*mesh}, curr_pos{0} + { } + bool hasNext() const { + return curr_pos < container.size(); + } + Triangle next() { + if(!hasNext()) + throw java_error("iterator is out of bounds"); + + return *std::next(container.begin(), curr_pos++); + } + int size() const { + return container.size(); + } + const Triangle& get(PointId id) const { + return container[id]; + } + +private: + TriangularMesh container; + unsigned int curr_pos; +}; + +} +#endif diff --git a/native/src/include/io_pdal_Pipeline.h b/native/src/include/io_pdal_Pipeline.h index e1ce78a..9a7a436 100644 --- a/native/src/include/io_pdal_Pipeline.h +++ b/native/src/include/io_pdal_Pipeline.h @@ -9,7 +9,7 @@ extern "C" { #endif /* * Class: io_pdal_Pipeline - * Method: initialise + * Method: initialize * Signature: ()V */ JNIEXPORT void JNICALL Java_io_pdal_Pipeline_initialize @@ -33,10 +33,10 @@ JNIEXPORT jobject JNICALL Java_io_pdal_Pipeline_getPointViews /* * Class: io_pdal_Pipeline - * Method: dispose + * Method: close * Signature: ()V */ -JNIEXPORT void JNICALL Java_io_pdal_Pipeline_dispose +JNIEXPORT void JNICALL Java_io_pdal_Pipeline_close (JNIEnv *, jobject); /* diff --git a/native/src/include/io_pdal_PointLayout.h b/native/src/include/io_pdal_PointLayout.h index bba5277..b46c14e 100644 --- a/native/src/include/io_pdal_PointLayout.h +++ b/native/src/include/io_pdal_PointLayout.h @@ -49,10 +49,10 @@ JNIEXPORT jlong JNICALL Java_io_pdal_PointLayout_pointSize /* * Class: io_pdal_PointLayout - * Method: dispose + * Method: close * Signature: ()V */ -JNIEXPORT void JNICALL Java_io_pdal_PointLayout_dispose +JNIEXPORT void JNICALL Java_io_pdal_PointLayout_close (JNIEnv *, jobject); #ifdef __cplusplus diff --git a/native/src/include/io_pdal_PointView.h b/native/src/include/io_pdal_PointView.h index 0d26817..e88de5d 100644 --- a/native/src/include/io_pdal_PointView.h +++ b/native/src/include/io_pdal_PointView.h @@ -42,7 +42,7 @@ JNIEXPORT jstring JNICALL Java_io_pdal_PointView_getCrsProj4 /* * Class: io_pdal_PointView * Method: getCrsWKT - * Signature: (IZ)Ljava/lang/String; + * Signature: (Z)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_io_pdal_PointView_getCrsWKT (JNIEnv *, jobject, jboolean); @@ -65,10 +65,18 @@ JNIEXPORT jbyteArray JNICALL Java_io_pdal_PointView_getPackedPoints /* * Class: io_pdal_PointView - * Method: dispose + * Method: getTriangularMesh + * Signature: (Ljava/lang/String;)Lio/pdal/TriangularMesh; + */ +JNIEXPORT jobject JNICALL Java_io_pdal_PointView_getTriangularMesh + (JNIEnv *, jobject, jstring); + +/* + * Class: io_pdal_PointView + * Method: close * Signature: ()V */ -JNIEXPORT void JNICALL Java_io_pdal_PointView_dispose +JNIEXPORT void JNICALL Java_io_pdal_PointView_close (JNIEnv *, jobject); #ifdef __cplusplus diff --git a/native/src/include/io_pdal_PointViewIterator.h b/native/src/include/io_pdal_PointViewIterator.h index 72518b2..659bcbc 100644 --- a/native/src/include/io_pdal_PointViewIterator.h +++ b/native/src/include/io_pdal_PointViewIterator.h @@ -25,10 +25,10 @@ JNIEXPORT jobject JNICALL Java_io_pdal_PointViewIterator_next /* * Class: io_pdal_PointViewIterator - * Method: dispose + * Method: close * Signature: ()V */ -JNIEXPORT void JNICALL Java_io_pdal_PointViewIterator_dispose +JNIEXPORT void JNICALL Java_io_pdal_PointViewIterator_close (JNIEnv *, jobject); #ifdef __cplusplus diff --git a/native/src/include/io_pdal_TriangularMesh.h b/native/src/include/io_pdal_TriangularMesh.h new file mode 100644 index 0000000..2bae0af --- /dev/null +++ b/native/src/include/io_pdal_TriangularMesh.h @@ -0,0 +1,61 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class io_pdal_TriangularMesh */ + +#ifndef _Included_io_pdal_TriangularMesh +#define _Included_io_pdal_TriangularMesh +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: io_pdal_TriangularMesh + * Method: size + * Signature: ()I + */ +JNIEXPORT jint JNICALL Java_io_pdal_TriangularMesh_size + (JNIEnv *, jobject); + +/* + * Class: io_pdal_TriangularMesh + * Method: get + * Signature: (J)Lio/pdal/Triangle; + */ +JNIEXPORT jobject JNICALL Java_io_pdal_TriangularMesh_get + (JNIEnv *, jobject, jlong); + +/* + * Class: io_pdal_TriangularMesh + * Method: hasNext + * Signature: ()Z + */ +JNIEXPORT jboolean JNICALL Java_io_pdal_TriangularMesh_hasNext + (JNIEnv *, jobject); + +/* + * Class: io_pdal_TriangularMesh + * Method: next + * Signature: ()Lio/pdal/Triangle; + */ +JNIEXPORT jobject JNICALL Java_io_pdal_TriangularMesh_next + (JNIEnv *, jobject); + +/* + * Class: io_pdal_TriangularMesh + * Method: asArray + * Signature: ()[Lio/pdal/Triangle; + */ +JNIEXPORT jobjectArray JNICALL Java_io_pdal_TriangularMesh_asArray + (JNIEnv *, jobject); + +/* + * Class: io_pdal_TriangularMesh + * Method: close + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_io_pdal_TriangularMesh_close + (JNIEnv *, jobject); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/native/src/io_pdal_Pipeline.cpp b/native/src/io_pdal_Pipeline.cpp index 547691c..6c730ad 100644 --- a/native/src/io_pdal_Pipeline.cpp +++ b/native/src/io_pdal_Pipeline.cpp @@ -38,7 +38,8 @@ #include "io_pdal_Pipeline.h" #include "JavaPipeline.hpp" -#include "JavaIterator.hpp" +#include "JavaSetIterator.hpp" +#include "JavaExceptions.hpp" #include "Accessors.hpp" using libpdaljava::Pipeline; @@ -52,20 +53,6 @@ using pdal::pdal_error; std::mutex execute_mutex; -jstring throwInitializationException(JNIEnv *env, const char *message) -{ - jclass Exception = env->FindClass("io/pdal/InitializationException"); - env->ThrowNew(Exception, message); - return env->NewStringUTF(message); -} - -jstring throwExecutionException(JNIEnv *env, const char *message) -{ - jclass Exception = env->FindClass("io/pdal/ExecutionException"); - env->ThrowNew(Exception, message); - return env->NewStringUTF(message); -} - JNIEXPORT void JNICALL Java_io_pdal_Pipeline_initialize (JNIEnv *env, jobject obj) { @@ -90,7 +77,7 @@ JNIEXPORT void JNICALL Java_io_pdal_Pipeline_initialize } } -JNIEXPORT void JNICALL Java_io_pdal_Pipeline_dispose +JNIEXPORT void JNICALL Java_io_pdal_Pipeline_close (JNIEnv *env, jobject obj) { Pipeline *p = getHandle(env, obj); diff --git a/native/src/io_pdal_PointLayout.cpp b/native/src/io_pdal_PointLayout.cpp index f0c27eb..8c47f11 100644 --- a/native/src/io_pdal_PointLayout.cpp +++ b/native/src/io_pdal_PointLayout.cpp @@ -123,7 +123,7 @@ JNIEXPORT jlong JNICALL Java_io_pdal_PointLayout_pointSize return pl->pointSize(); } -JNIEXPORT void JNICALL Java_io_pdal_PointLayout_dispose +JNIEXPORT void JNICALL Java_io_pdal_PointLayout_close (JNIEnv *env, jobject obj) { // A bit unclear why we can't remove this pointer, probably wrapping here makes sense as well diff --git a/native/src/io_pdal_PointView.cpp b/native/src/io_pdal_PointView.cpp index d55916f..d232090 100644 --- a/native/src/io_pdal_PointView.cpp +++ b/native/src/io_pdal_PointView.cpp @@ -35,11 +35,14 @@ #include #include "io_pdal_PointView.h" #include "JavaPipeline.hpp" +#include "JavaTriangularMeshIterator.hpp" +#include "JavaExceptions.hpp" #include "PointViewRawPtr.hpp" #include "Accessors.hpp" using libpdaljava::Pipeline; using libpdaljava::PointViewRawPtr; +using libpdaljava::TriangularMeshIterator; using pdal::PointView; using pdal::PointViewPtr; @@ -50,6 +53,7 @@ using pdal::PointId; using pdal::DimTypeList; using pdal::SpatialReference; using pdal::DimType; +using pdal::pdal_error; /// Converts JavaArray of DimTypes (In Java interpretation DimType is a pair of strings) /// into DimTypeList (vector of DimTypes), puts dim size into bufSize @@ -197,7 +201,31 @@ JNIEXPORT jbyteArray JNICALL Java_io_pdal_PointView_getPackedPoints return array; } -JNIEXPORT void JNICALL Java_io_pdal_PointView_dispose +JNIEXPORT jobject JNICALL Java_io_pdal_PointView_getTriangularMesh + (JNIEnv *env, jobject obj, jstring name) +{ + PointViewRawPtr *pvrp = getHandle(env, obj); + PointViewPtr pv = pvrp->shared_pointer; + std::string cname = std::string(env->GetStringUTFChars(name, 0)); + + TriangularMesh *m = pv->mesh(cname); + + if(m == NULL) + { + return throwExecutionException(env, "No mesh was generated. Check that the appropriate filter is a part of a PDAL Pipeline."); + } + + TriangularMeshIterator *it = new TriangularMeshIterator(m); + jclass meshClass = env->FindClass("io/pdal/TriangularMesh"); + jmethodID meshCtor = env->GetMethodID(meshClass, "", "()V"); + jobject mi = env->NewObject(meshClass, meshCtor); + + setHandle(env, mi, it); + + return mi; +} + +JNIEXPORT void JNICALL Java_io_pdal_PointView_close (JNIEnv *env, jobject obj) { PointViewRawPtr *pvrp = getHandle(env, obj); diff --git a/native/src/io_pdal_PointViewIterator.cpp b/native/src/io_pdal_PointViewIterator.cpp index 1a007dd..08f8834 100644 --- a/native/src/io_pdal_PointViewIterator.cpp +++ b/native/src/io_pdal_PointViewIterator.cpp @@ -34,7 +34,7 @@ #include #include "io_pdal_PointViewIterator.h" #include "JavaPipeline.hpp" -#include "JavaIterator.hpp" +#include "JavaSetIterator.hpp" #include "PointViewRawPtr.hpp" #include "Accessors.hpp" @@ -66,7 +66,7 @@ JNIEXPORT jobject JNICALL Java_io_pdal_PointViewIterator_next return jpv; } -JNIEXPORT void JNICALL Java_io_pdal_PointViewIterator_dispose +JNIEXPORT void JNICALL Java_io_pdal_PointViewIterator_close (JNIEnv *env, jobject obj) { PointViewIterator *it = getHandle(env, obj); diff --git a/native/src/io_pdal_TriangularMesh.cpp b/native/src/io_pdal_TriangularMesh.cpp new file mode 100644 index 0000000..be907c4 --- /dev/null +++ b/native/src/io_pdal_TriangularMesh.cpp @@ -0,0 +1,124 @@ +/****************************************************************************** +* Copyright (c) 2020, hobu Inc. (info@hobu.co) +* +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following +* conditions are met: +* +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in +* the documentation and/or other materials provided +* with the distribution. +* * Neither the name of Hobu, Inc. nor the names of its +* contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +* OF SUCH DAMAGE. +****************************************************************************/ + +#include +#include "io_pdal_TriangularMesh.h" +#include "JavaPipeline.hpp" +#include "JavaTriangularMeshIterator.hpp" +#include "PointViewRawPtr.hpp" +#include "Accessors.hpp" + +using libpdaljava::TriangularMeshIterator; +using pdal::Triangle; +using pdal::PointId; + +JNIEXPORT jint JNICALL Java_io_pdal_TriangularMesh_size + (JNIEnv *env, jobject obj) +{ + TriangularMeshIterator *it = getHandle(env, obj); + + return it->size(); +} + +JNIEXPORT jobject JNICALL Java_io_pdal_TriangularMesh_get + (JNIEnv *env, jobject obj, jlong jidx) +{ + TriangularMeshIterator *it = getHandle(env, obj); + Triangle triangle = it->get(static_cast(jidx)); + + jclass jtClass = env->FindClass("io/pdal/Triangle"); + jmethodID jtCtor = env->GetMethodID(jtClass, "", "(III)V"); + jobject jt = env->NewObject(jtClass, jtCtor, triangle.m_a, triangle.m_b, triangle.m_c); + + return jt; +} + +JNIEXPORT jboolean JNICALL Java_io_pdal_TriangularMesh_hasNext + (JNIEnv *env, jobject obj) +{ + TriangularMeshIterator *it = getHandle(env, obj); + + return it->hasNext(); +} + +JNIEXPORT jobject JNICALL Java_io_pdal_TriangularMesh_next + (JNIEnv *env, jobject obj) +{ + TriangularMeshIterator *it = getHandle(env, obj); + + Triangle triangle = it->next(); + + jclass jtClass = env->FindClass("io/pdal/Triangle"); + jmethodID jtCtor = env->GetMethodID(jtClass, "", "(III)V"); + jobject jt = env->NewObject(jtClass, jtCtor, triangle.m_a, triangle.m_b, triangle.m_c); + + return jt; +} + +/* + * Class: io_pdal_TriangularMesh + * Method: asArray + * Signature: ()[Lio/pdal/Triangle; + */ +JNIEXPORT jobjectArray JNICALL Java_io_pdal_TriangularMesh_asArray + (JNIEnv *env, jobject obj) +{ + TriangularMeshIterator *it = getHandle(env, obj); + + jclass jtClass = env->FindClass("io/pdal/Triangle"); + jmethodID jtCtor = env->GetMethodID(jtClass, "", "(III)V"); + + int size = it->size(); + jobjectArray result = env->NewObjectArray(size, jtClass, NULL); + + for (int i = 0; i < size; i++) + { + Triangle triangle = it->get(static_cast(i)); + jobject element = env->NewObject(jtClass, jtCtor, triangle.m_a, triangle.m_b, triangle.m_c); + + env->SetObjectArrayElement(result, i, element); + + env->DeleteLocalRef(element); + } + + return result; +} + + +JNIEXPORT void JNICALL Java_io_pdal_TriangularMesh_close + (JNIEnv *env, jobject obj) +{ + TriangularMeshIterator *it = getHandle(env, obj); + setHandle(env, obj, 0); + delete it; +} diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 6397747..f6aead6 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -1,8 +1,11 @@ import sbt._ import sbt.Keys._ +import de.heikoseeberger.sbtheader.{CommentCreator, CommentStyle, FileType} +import de.heikoseeberger.sbtheader.HeaderPlugin.autoImport.{HeaderLicense, headerLicense, headerMappings} + object Dependencies { - private def ver(for211: String, for213: String) = Def.setting { + private def ver(for211: String, for213: String): Def.Initialize[String] = Def.setting { CrossVersion.partialVersion(scalaVersion.value) match { case Some((2, 11)) => for211 case Some((2, 12)) | Some((2, 13)) => for213 @@ -10,10 +13,42 @@ object Dependencies { } } + def priorTo213(scalaVersion: String): Boolean = + CrossVersion.partialVersion(scalaVersion) match { + case Some((2, minor)) if minor < 13 => true + case _ => false + } + def circe(module: String) = Def.setting { "io.circe" %% s"circe-$module" % ver("0.11.2", "0.12.2").value } + lazy val macroSettings: Seq[Setting[_]] = Seq( + libraryDependencies ++= ( + if (priorTo213(scalaVersion.value)) Seq(compilerPlugin("org.scalamacros" %% "paradise" % "2.1.1" cross CrossVersion.full)) + else Nil + ), + scalacOptions ++= (if (priorTo213(scalaVersion.value)) Nil else Seq("-Ymacro-annotations")) + ) + + lazy val licenseSettings: Seq[Setting[_]] = Seq( + headerLicense := Some(HeaderLicense.ALv2(java.time.Year.now.getValue.toString, "Azavea")), + headerMappings := Map( + FileType.scala -> CommentStyle.cStyleBlockComment.copy(commentCreator = new CommentCreator() { + val Pattern = "(?s).*?(\\d{4}(-\\d{4})?).*".r + def findYear(header: String): Option[String] = header match { + case Pattern(years, _) => Some(years) + case _ => None + } + def apply(text: String, existingText: Option[String]): String = { + // preserve year of old headers + val newText = CommentStyle.cStyleBlockComment.commentCreator.apply(text, existingText) + existingText.flatMap(_ => existingText.map(_.trim)).getOrElse(newText) + } + }) + ) + ) + val jtsCore = "org.locationtech.jts" % "jts-core" % "1.16.1" - val scalaTest = "org.scalatest" %% "scalatest" % "3.1.0" + val scalaTest = "org.scalatest" %% "scalatest" % "3.1.1" } diff --git a/scripts/merge-native.sh b/scripts/merge-native.sh index e02e4fa..40b425d 100755 --- a/scripts/merge-native.sh +++ b/scripts/merge-native.sh @@ -17,13 +17,13 @@ done export PDAL_VERSION_SUFFIX=${PDAL_VERSION_SUFFIX-"-SNAPSHOT"} cd ./native/target -rm -f ./pdal-native-2.0.0${PDAL_VERSION_SUFFIX}.jar +rm -f ./pdal-native-2.1.2${PDAL_VERSION_SUFFIX}.jar rm -rf ./tmp; mkdir -p ./tmp -cd tmp; jar -xf ../pdal-native-x86_64-darwin-2.0.0${PDAL_VERSION_SUFFIX}.jar; cd ~- -cd tmp; jar -xf ../pdal-native-x86_64-linux-2.0.0${PDAL_VERSION_SUFFIX}.jar; cd ~- +cd tmp; jar -xf ../pdal-native-x86_64-darwin-2.1.2${PDAL_VERSION_SUFFIX}.jar; cd ~- +cd tmp; jar -xf ../pdal-native-x86_64-linux-2.1.2${PDAL_VERSION_SUFFIX}.jar; cd ~- -jar -cvf pdal-native-2.0.0${PDAL_VERSION_SUFFIX}.jar -C tmp . +jar -cvf pdal-native-2.1.2${PDAL_VERSION_SUFFIX}.jar -C tmp . cd ./tmp