All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.pdal.PointCloud.scala Maven / Gradle / Ivy

The newest version!
/**
 * **************************************************************************** Copyright (c) 2016, hobu Inc.
 * ([email protected])
 *
 * 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.nio.{ByteBuffer, ByteOrder}
import java.util

import scala.collection.JavaConverters._

/**
 * PointCloud abstraction to work with packed point(s) in JVM memory. SizedDimType contains size and offset for a
 * particular packed point with the current set of dims.
 */
case class PointCloud(bytes: Array[Byte], dimTypes: util.Map[String, SizedDimType]) {
  val pointSize: Int = dimTypes.values.asScala.map(_.size).sum.toInt
  val length: Int = bytes.length / pointSize
  val isPoint: Boolean = length == 1

  def dimSize(dim: SizedDimType): Long = dimTypes.asScala(dim.dimType.id).size
  def dimSize(dim: DimType): Long = dimTypes.asScala(dim.id).size
  def dimSize(dim: String): Long = dimTypes.asScala(dim).size
  def findDimType(dim: String): DimType = dimTypes.asScala(dim).dimType
  def findSizedDimType(dim: String): SizedDimType = dimTypes.asScala(dim)

  /**
   * Reads a packed point by point id from a set of packed points.
   */
  def get(i: Int): Array[Byte] = {
    if (isPoint) bytes
    else {
      val from = i * pointSize
      val result = new Array[Byte](pointSize)
      var j = 0
      while (j < pointSize) {
        result(j) = bytes(from + j)
        j += 1
      }
      result
    }
  }

  def getDouble(idx: Int, dim: SizedDimType): Double = getDouble(idx, dim.dimType)
  def getDouble(idx: Int, dim: DimType): Double = getDouble(idx, dim.id)
  def getDouble(idx: Int, dim: String): Double = get(idx, dim).getDouble

  def getFloat(idx: Int, dim: SizedDimType): Float = getFloat(idx, dim.dimType.id)
  def getFloat(idx: Int, dim: DimType): Float = getFloat(idx, dim.id)
  def getFloat(idx: Int, dim: String): Float = get(idx, dim).getFloat

  def getLong(idx: Int, dim: SizedDimType): Long = getLong(idx, dim.dimType.id)
  def getLong(idx: Int, dim: DimType): Long = getLong(idx, dim.id)
  def getLong(idx: Int, dim: String): Long = get(idx, dim).getLong

  def getInt(idx: Int, dim: SizedDimType): Int = getInt(idx, dim.dimType.id)
  def getInt(idx: Int, dim: DimType): Int = getInt(idx, dim.id)
  def getInt(idx: Int, dim: String): Int = get(idx, dim).getInt

  def getShort(idx: Int, dim: SizedDimType): Short = getShort(idx, dim.dimType.id)
  def getShort(idx: Int, dim: DimType): Short = getShort(idx, dim.id)
  def getShort(idx: Int, dim: String): Short = get(idx, dim).getShort

  def getChar(idx: Int, dim: SizedDimType): Char = getChar(idx, dim.dimType.id)
  def getChar(idx: Int, dim: DimType): Char = getChar(idx, dim.id)
  def getChar(idx: Int, dim: String): Char = get(idx, dim).getChar

  def getByte(idx: Int, dim: SizedDimType): Byte = getByte(idx, dim.dimType.id)
  def getByte(idx: Int, dim: DimType): Byte = getByte(idx, dim.id)
  def getByte(idx: Int, dim: String): Byte = get(idx, dim).get()

  def get(idx: Int, dim: SizedDimType): ByteBuffer = get(idx, dim.dimType.id)
  def get(idx: Int, dim: DimType): ByteBuffer = get(idx, dim.id)
  def get(idx: Int, dim: String): ByteBuffer = ByteBuffer.wrap(get(get(idx), dim)).order(ByteOrder.nativeOrder())

  def get(idx: Int, dims: Array[SizedDimType]): ByteBuffer = get(idx, dims.map(_.dimType.id))
  def get(idx: Int, dims: Array[DimType]): ByteBuffer = get(idx, dims.map(_.id))
  def get(idx: Int, dims: Array[String]): ByteBuffer =
    ByteBuffer.wrap(get(get(idx), dims)).order(ByteOrder.nativeOrder())

  def getX(idx: Int): Double = getDouble(idx, DimType.Id.X)
  def getY(idx: Int): Double = getDouble(idx, DimType.Id.Y)
  def getZ(idx: Int): Double = getDouble(idx, DimType.Id.Z)

  /**
   * Reads dim from a packed point.
   */
  def get(packedPoint: Array[Byte], dim: String): Array[Byte] = {
    val sdt = dimTypes.asScala(dim)
    val from = sdt.offset.toInt
    val dimSize = sdt.size.toInt
    val result = new Array[Byte](dimSize)
    var j = 0
    while (j < dimSize) {
      result(j) = packedPoint(from + j)
      j += 1
    }
    result
  }

  /**
   * Reads dims from a packed point.
   */
  private def get(packedPoint: Array[Byte], dims: Array[String]): Array[Byte] =
    dims.map(get(bytes, _)).fold(Array[Byte]())(_ ++ _)
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy