// This isn't lovely as we have to seek for each dimension access. void BpfReader::readDimMajor(PointRef& point) { double x(0), y(0), z(0); for (size_t dim = 0; dim < m_dims.size(); ++dim) { seekDimMajor(dim, m_index); float f; m_stream >> f; double d = f + m_dims[dim].m_offset; if (m_dims[dim].m_id == Dimension::Id::X) x = d; else if (m_dims[dim].m_id == Dimension::Id::Y) y = d; else if (m_dims[dim].m_id == Dimension::Id::Z) z = d; else point.setField(m_dims[dim].m_id, d); } // Transformation only applies to X, Y and Z m_header.m_xform.apply(x, y, z); point.setField(Dimension::Id::X, x); point.setField(Dimension::Id::Y, y); point.setField(Dimension::Id::Z, z); m_index++; }
void BpfReader::readPointMajor(PointRef& point) { double x(0), y(0), z(0); seekPointMajor(m_index); for (size_t dim = 0; dim < m_dims.size(); ++dim) { float f; m_stream >> f; double d = f + m_dims[dim].m_offset; if (m_dims[dim].m_id == Dimension::Id::X) x = d; else if (m_dims[dim].m_id == Dimension::Id::Y) y = d; else if (m_dims[dim].m_id == Dimension::Id::Z) z = d; else point.setField(m_dims[dim].m_id, d); } m_header.m_xform.apply(x, y, z); point.setField(Dimension::Id::X, x); point.setField(Dimension::Id::Y, y); point.setField(Dimension::Id::Z, z); m_index++; }
void ColorizationFilter::filter(PointView& view) { PointRef point = view.point(0); for (PointId idx = 0; idx < view.size(); ++idx) { point.setPointId(idx); processOne(point); } }
bool processOne(PointRef& point) { PointRef bulkPoint = m_view->point(m_cnt); bulkPoint.getPackedData(m_dims, m_bulkBuf.data()); point.getPackedData(m_dims, m_buf.data()); EXPECT_EQ(memcmp(m_buf.data(), m_bulkBuf.data(), m_view->pointSize()), 0); m_cnt++; return true; }
point_count_t TileDBReader::read(PointViewPtr view, point_count_t count) { PointRef point = view->point(0); PointId id; for (id = 0; id < count; ++id) { point.setPointId(id); if (!processOne(point)) break; } return id; }
bool FauxReader::processOne(PointRef& point) { double x(0); double y(0); double z(0); if (m_index >= m_count) return false; switch (m_mode) { case Random: x = Utils::random(m_minX, m_maxX); y = Utils::random(m_minY, m_maxY); z = Utils::random(m_minZ, m_maxZ); break; case Constant: x = m_minX; y = m_minY; z = m_minZ; break; case Ramp: x = m_minX + m_delX * m_index; y = m_minY + m_delY * m_index; z = m_minZ + m_delZ * m_index; break; case Uniform: x = Utils::uniform(m_minX, m_maxX, m_seed++); y = Utils::uniform(m_minY, m_maxY, m_seed++); z = Utils::uniform(m_minZ, m_maxZ, m_seed++); break; case Normal: x = Utils::normal(m_mean_x, m_stdev_x, m_seed++); y = Utils::normal(m_mean_y, m_stdev_y, m_seed++); z = Utils::normal(m_mean_z, m_stdev_z, m_seed++); break; } point.setField(Dimension::Id::X, x); point.setField(Dimension::Id::Y, y); point.setField(Dimension::Id::Z, z); point.setField(Dimension::Id::OffsetTime, m_time++); if (m_numReturns > 0) { point.setField(Dimension::Id::ReturnNumber, m_returnNum); point.setField(Dimension::Id::NumberOfReturns, m_numReturns); m_returnNum = (m_returnNum % m_numReturns) + 1; } m_index++; return true; }
point_count_t LasWriter::fillWriteBuf(const PointView& view, PointId startId, std::vector<char>& buf) { point_count_t blocksize = buf.size() / m_lasHeader.pointLen(); blocksize = (std::min)(blocksize, view.size() - startId); PointId lastId = startId + blocksize; LeInserter ostream(buf.data(), buf.size()); PointRef point = (const_cast<PointView&>(view)).point(0); for (PointId idx = startId; idx < lastId; idx++) { point.setPointId(idx); fillPointBuf(point, ostream); } return blocksize; }
bool TransformationFilter::processOne(PointRef& point) { double x = point.getFieldAs<double>(Dimension::Id::X); double y = point.getFieldAs<double>(Dimension::Id::Y); double z = point.getFieldAs<double>(Dimension::Id::Z); point.setField(Dimension::Id::X, x * m_matrix[0] + y * m_matrix[1] + z * m_matrix[2] + m_matrix[3]); point.setField(Dimension::Id::Y, x * m_matrix[4] + y * m_matrix[5] + z * m_matrix[6] + m_matrix[7]); point.setField(Dimension::Id::Z, x * m_matrix[8] + y * m_matrix[9] + z * m_matrix[10] + m_matrix[11]); return true; }
bool processOne(PointRef& point) { static int i = 0; if (i == 0) { point.setField(Id::X, 2); point.setField(Id::Y, 2); } else if (i == 1) { point.setField(Id::X, 6); point.setField(Id::Y, 2); } else if (i == 2) { point.setField(Id::X, 8); point.setField(Id::Y, 2); } else if (i == 3) { point.setField(Id::X, 10); point.setField(Id::Y, 2); } else if (i == 4) { point.setField(Id::X, 12); point.setField(Id::Y, 2); } else return false; i++; return true; }
point_count_t Ilvis2Reader::read(PointViewPtr view, point_count_t count) { PointId idx = view->size(); point_count_t numRead = 0; PointRef point = PointRef(*view, 0); while (numRead < count) { point.setPointId(idx++); if (!processOne(point)) break; if (m_cb) m_cb(*view, idx); numRead++; } return numRead; }
bool FerryFilter::processOne(PointRef& point) { for (const auto& dim_par : m_dimensions_map) { double v = point.getFieldAs<double>(dim_par.first); point.setField(dim_par.second, v); } return true; }
bool SbetReader::processOne(PointRef& point) { for (auto di = m_dims.begin(); di != m_dims.end(); ++di) { double d; *m_stream >> d; Dimension::Id dim = *di; point.setField(dim, d); } return (m_stream->good()); }
bool NumpyReader::loadPoint(PointRef& point, point_count_t position) { using namespace Dimension; for (const Field& f : m_fields) point.setField(f.m_id, f.m_type, (void*)(p_data + f.m_offset)); if (m_storeXYZ) { point.setField(Dimension::Id::X, (position % m_xIter) / m_xDiv); if (m_ndims > 1) { point.setField(Dimension::Id::Y, (position % m_yIter) / m_yDiv); if (m_ndims > 2) point.setField(Dimension::Id::Z, (position % m_zIter) / m_zDiv); } } return (nextPoint()); }
bool FerryFilter::processOne(PointRef& point) { for (const auto& info : m_dims) { if (info.m_fromId != Dimension::Id::Unknown) { double v = point.getFieldAs<double>(info.m_fromId); point.setField(info.m_toId, v); } } return true; }
void BpfReader::readByteMajor(PointRef& point) { // We need a temp buffer for the point data union uu { float f; uint32_t u32; } u; double x(0), y(0), z(0); uint8_t u8; for (size_t dim = 0; dim < m_dims.size(); ++dim) { u.u32 = 0; for (size_t b = 0; b < sizeof(float); ++b) { seekByteMajor(dim, b, m_index); m_stream >> u8; u.u32 |= ((uint32_t)u8 << (b * CHAR_BIT)); } double d = u.f + m_dims[dim].m_offset; if (m_dims[dim].m_id == Dimension::Id::X) x = d; else if (m_dims[dim].m_id == Dimension::Id::Y) y = d; else if (m_dims[dim].m_id == Dimension::Id::Z) z = d; else point.setField(m_dims[dim].m_id, d); } m_header.m_xform.apply(x, y, z); point.setField(Dimension::Id::X, x); point.setField(Dimension::Id::Y, y); point.setField(Dimension::Id::Z, z); m_index++; }
void PlyWriter::writeValue(PointRef& point, Dimension::Id dim, Dimension::Type type) { if (m_format == Format::Ascii) { double d = point.getFieldAs<double>(dim); *m_stream << d; } else if (m_format == Format::BinaryLe) { OLeStream out(m_stream); Everything e; point.getField((char *)&e, dim, type); Utils::insertDim(out, type, e); } else if (m_format == Format::BinaryBe) { OBeStream out(m_stream); Everything e; point.getField((char *)&e, dim, type); Utils::insertDim(out, type, e); } }
bool ColorizationFilter::processOne(PointRef& point) { static std::vector<double> data; double x = point.getFieldAs<double>(Dimension::Id::X); double y = point.getFieldAs<double>(Dimension::Id::Y); if (m_raster->read(x, y, data) == gdal::GDALError::None) { int i(0); for (auto bi = m_bands.begin(); bi != m_bands.end(); ++bi) { BandInfo& b = *bi; point.setField(b.m_dim, data[i] * b.m_scale); ++i; } return true; } return false; }
bool TextReader::processOne(PointRef& point) { if (!fillFields()) return false; double d; for (size_t i = 0; i < m_fields.size(); ++i) { if (!Utils::fromString(m_fields[i], d)) { log()->get(LogLevel::Error) << "Can't convert " "field '" << m_fields[i] << "' to numeric value on line " << m_line << " in '" << m_filename << "'. Setting to 0." << std::endl; d = 0; } point.setField(m_dims[i], d); } return true; }
void RxpPointcloud::copyPoint(const Point& from, PointRef& to) const { using namespace Dimension; to.setField(Id::X, from.target.vertex[0]); to.setField(Id::Y, from.target.vertex[1]); to.setField(Id::Z, from.target.vertex[2]); to.setField(getTimeDimensionId(m_syncToPps), from.target.time); to.setField(Id::Amplitude, from.target.amplitude); to.setField(Id::Reflectance, from.target.reflectance); to.setField(Id::ReturnNumber, from.returnNumber); to.setField(Id::NumberOfReturns, from.numberOfReturns); to.setField(Id::EchoRange, from.target.echo_range); to.setField(Id::Deviation, from.target.deviation); to.setField(Id::BackgroundRadiation, from.target.background_radiation); to.setField(Id::IsPpsLocked, from.target.is_pps_locked); if (m_reflectanceAsIntensity) { uint16_t intensity; if (from.target.reflectance > m_maxReflectance) { intensity = (std::numeric_limits<uint16_t>::max)(); } else if (from.target.reflectance < m_minReflectance) { intensity = 0; } else { intensity = uint16_t(std::roundf(double((std::numeric_limits<uint16_t>::max)()) * (from.target.reflectance - m_minReflectance) / (m_maxReflectance - m_minReflectance))); } to.setField(Id::Intensity, intensity); } }
bool LasWriter::fillPointBuf(PointRef& point, LeInserter& ostream) { bool has14Format = m_lasHeader.has14Format(); static const size_t maxReturnCount = m_lasHeader.maxReturnCount(); // we always write the base fields using namespace Dimension; uint8_t returnNumber(1); uint8_t numberOfReturns(1); if (point.hasDim(Id::ReturnNumber)) returnNumber = point.getFieldAs<uint8_t>(Id::ReturnNumber); if (point.hasDim(Id::NumberOfReturns)) numberOfReturns = point.getFieldAs<uint8_t>(Id::NumberOfReturns); if (numberOfReturns > maxReturnCount) { if (m_discardHighReturnNumbers) { // If this return number is too high, pitch the point. if (returnNumber > maxReturnCount) return false; numberOfReturns = maxReturnCount; } } auto converter = [this](double d, Dimension::Id dim) -> int32_t { int32_t i(0); if (!Utils::numericCast(d, i)) throwError("Unable to convert scaled value (" + Utils::toString(d) + ") to " "int32 for dimension '" + Dimension::name(dim) + "' when writing LAS/LAZ file " + m_curFilename + "."); return i; }; double xOrig = point.getFieldAs<double>(Id::X); double yOrig = point.getFieldAs<double>(Id::Y); double zOrig = point.getFieldAs<double>(Id::Z); double x = m_scaling.m_xXform.toScaled(xOrig); double y = m_scaling.m_yXform.toScaled(yOrig); double z = m_scaling.m_zXform.toScaled(zOrig); ostream << converter(x, Id::X); ostream << converter(y, Id::Y); ostream << converter(z, Id::Z); ostream << point.getFieldAs<uint16_t>(Id::Intensity); uint8_t scanChannel = point.getFieldAs<uint8_t>(Id::ScanChannel); uint8_t scanDirectionFlag = point.getFieldAs<uint8_t>(Id::ScanDirectionFlag); uint8_t edgeOfFlightLine = point.getFieldAs<uint8_t>(Id::EdgeOfFlightLine); if (has14Format) { uint8_t bits = returnNumber | (numberOfReturns << 4); ostream << bits; uint8_t classFlags = point.getFieldAs<uint8_t>(Id::ClassFlags); bits = (classFlags & 0x0F) | ((scanChannel & 0x03) << 4) | ((scanDirectionFlag & 0x01) << 6) | ((edgeOfFlightLine & 0x01) << 7); ostream << bits; } else { uint8_t bits = returnNumber | (numberOfReturns << 3) | (scanDirectionFlag << 6) | (edgeOfFlightLine << 7); ostream << bits; } ostream << point.getFieldAs<uint8_t>(Id::Classification); uint8_t userData = point.getFieldAs<uint8_t>(Id::UserData); if (has14Format) { int16_t scanAngleRank = point.getFieldAs<float>(Id::ScanAngleRank) / .006; ostream << userData << scanAngleRank; } else { int8_t scanAngleRank = point.getFieldAs<int8_t>(Id::ScanAngleRank); ostream << scanAngleRank << userData; } ostream << point.getFieldAs<uint16_t>(Id::PointSourceId); if (m_lasHeader.hasTime()) ostream << point.getFieldAs<double>(Id::GpsTime); if (m_lasHeader.hasColor()) { ostream << point.getFieldAs<uint16_t>(Id::Red); ostream << point.getFieldAs<uint16_t>(Id::Green); ostream << point.getFieldAs<uint16_t>(Id::Blue); } if (m_lasHeader.hasInfrared()) ostream << point.getFieldAs<uint16_t>(Id::Infrared); Everything e; for (auto& dim : m_extraDims) { point.getField((char *)&e, dim.m_dimType.m_id, dim.m_dimType.m_type); Utils::insertDim(ostream, dim.m_dimType.m_type, e); } m_summaryData->addPoint(xOrig, yOrig, zOrig, returnNumber); return true; }
void Ilvis2Reader::readPoint(PointRef& point, StringList s, std::string pointMap) { point.setField(pdal::Dimension::Id::LvisLfid, convert<unsigned>(s, "LVIS_LFID", 0)); point.setField(pdal::Dimension::Id::ShotNumber, convert<unsigned>(s, "SHOTNUMBER", 1)); point.setField(pdal::Dimension::Id::GpsTime, convert<double>(s, "GPSTIME", 2)); point.setField(pdal::Dimension::Id::LongitudeCentroid, Utils::normalizeLongitude(convert<double>(s, "LONGITUDE_CENTROID", 3))); point.setField(pdal::Dimension::Id::LatitudeCentroid, convert<double>(s, "LATITUDE_CENTROID", 4)); point.setField(pdal::Dimension::Id::ElevationCentroid, convert<double>(s, "ELEVATION_CENTROID", 5)); point.setField(pdal::Dimension::Id::LongitudeLow, Utils::normalizeLongitude(convert<double>(s, "LONGITUDE_LOW", 6))); point.setField(pdal::Dimension::Id::LatitudeLow, convert<double>(s, "LATITUDE_LOW", 7)); point.setField(pdal::Dimension::Id::ElevationLow, convert<double>(s, "ELEVATION_LOW", 8)); point.setField(pdal::Dimension::Id::LongitudeHigh, Utils::normalizeLongitude(convert<double>(s, "LONGITUDE_HIGH", 9))); point.setField(pdal::Dimension::Id::LatitudeHigh, convert<double>(s, "LATITUDE_HIGH", 10)); point.setField(pdal::Dimension::Id::ElevationHigh, convert<double>(s, "ELEVATION_HIGH", 11)); double x, y, z; pdal::Dimension::Id::Enum xd, yd, zd; xd = m_layout->findDim("LONGITUDE_" + pointMap); yd = m_layout->findDim("LATITUDE_" + pointMap); zd = m_layout->findDim("ELEVATION_" + pointMap); x = point.getFieldAs<double>(xd); y = point.getFieldAs<double>(yd); z = point.getFieldAs<double>(zd); point.setField(pdal::Dimension::Id::X, x); point.setField(pdal::Dimension::Id::Y, y); point.setField(pdal::Dimension::Id::Z, z); }
bool LasWriter::writeLasZipBuf(PointRef& point) { #ifdef PDAL_HAVE_LASZIP const bool has14Format = m_lasHeader.has14Format(); const size_t maxReturnCount = m_lasHeader.maxReturnCount(); // we always write the base fields using namespace Dimension; uint8_t returnNumber(1); uint8_t numberOfReturns(1); if (point.hasDim(Id::ReturnNumber)) returnNumber = point.getFieldAs<uint8_t>(Id::ReturnNumber); if (point.hasDim(Id::NumberOfReturns)) numberOfReturns = point.getFieldAs<uint8_t>(Id::NumberOfReturns); if (numberOfReturns > maxReturnCount) { if (m_discardHighReturnNumbers) { // If this return number is too high, pitch the point. if (returnNumber > maxReturnCount) return false; numberOfReturns = maxReturnCount; } } auto converter = [this](double d, Dimension::Id dim) -> int32_t { int32_t i(0); if (!Utils::numericCast(d, i)) throwError("Unable to convert scaled value (" + Utils::toString(d) + ") to " "int32 for dimension '" + Dimension::name(dim) + "' when writing LAS/LAZ file " + m_curFilename + "."); return i; }; double xOrig = point.getFieldAs<double>(Id::X); double yOrig = point.getFieldAs<double>(Id::Y); double zOrig = point.getFieldAs<double>(Id::Z); double x = m_scaling.m_xXform.toScaled(xOrig); double y = m_scaling.m_yXform.toScaled(yOrig); double z = m_scaling.m_zXform.toScaled(zOrig); uint8_t scanChannel = point.getFieldAs<uint8_t>(Id::ScanChannel); uint8_t scanDirectionFlag = point.getFieldAs<uint8_t>(Id::ScanDirectionFlag); uint8_t edgeOfFlightLine = point.getFieldAs<uint8_t>(Id::EdgeOfFlightLine); uint8_t classification = point.getFieldAs<uint8_t>(Id::Classification); uint8_t classFlags = 0; if (point.hasDim(Id::ClassFlags)) classFlags = point.getFieldAs<uint8_t>(Id::ClassFlags); else classFlags = classification >> 5; laszip_point_struct p; p.X = converter(x, Id::X); p.Y = converter(y, Id::Y); p.Z = converter(z, Id::Z); p.intensity = point.getFieldAs<uint16_t>(Id::Intensity); p.scan_direction_flag = scanDirectionFlag; p.edge_of_flight_line = edgeOfFlightLine; if (has14Format) { p.extended_point_type = 1; p.extended_return_number = returnNumber; p.extended_number_of_returns = numberOfReturns; p.extended_scanner_channel = scanChannel; p.extended_scan_angle = roundf(point.getFieldAs<float>(Id::ScanAngleRank) / .006); p.extended_classification_flags = classFlags; p.extended_classification = classification; p.classification = (classification & 0x1F) | (classFlags << 5); // p.scan_angle_rank = point.getFieldAs<int8_t>(Id::ScanAngleRank); } else { p.synthetic_flag = classFlags & 0x1; p.keypoint_flag = (classFlags >> 1) & 0x1; p.withheld_flag = (classFlags >> 2) & 0x1; p.return_number = returnNumber; p.number_of_returns = numberOfReturns; p.scan_angle_rank = point.getFieldAs<int8_t>(Id::ScanAngleRank); p.classification = classification; } p.user_data = point.getFieldAs<uint8_t>(Id::UserData); p.point_source_ID = point.getFieldAs<uint16_t>(Id::PointSourceId); if (m_lasHeader.hasTime()) p.gps_time = point.getFieldAs<double>(Id::GpsTime); if (m_lasHeader.hasColor()) { p.rgb[0] = point.getFieldAs<uint16_t>(Id::Red); p.rgb[1] = point.getFieldAs<uint16_t>(Id::Green); p.rgb[2] = point.getFieldAs<uint16_t>(Id::Blue); } if (m_lasHeader.hasInfrared()) p.rgb[3] = point.getFieldAs<uint16_t>(Id::Infrared); if (m_extraDims.size()) { LeInserter ostream(m_pointBuf.data(), m_pointBuf.size()); Everything e; for (auto& dim : m_extraDims) { point.getField((char *)&e, dim.m_dimType.m_id, dim.m_dimType.m_type); Utils::insertDim(ostream, dim.m_dimType.m_type, e); } assert(m_extraByteLen == ostream.position()); } p.extra_bytes = (laszip_U8 *)m_pointBuf.data(); p.num_extra_bytes = m_extraByteLen; m_summaryData->addPoint(xOrig, yOrig, zOrig, returnNumber); handleLaszip(laszip_set_point(m_laszip, &p)); handleLaszip(laszip_write_point(m_laszip)); #endif return true; }