Пример #1
0
/// Read a field from a PointView and write its value as formatted for output
/// to the DB schema to the location as requested.
/// \param[in] view     PointView to read from.
/// \param[in] pos      Location in which to store field value.
/// \param[in] id       ID of the dimension to read.
/// \param[in] idx      Index of point to read.
/// \return  Size of field as read.
size_t DbWriter::readField(const PointView& view, char *pos,
    Dimension::Id::Enum id, PointId idx)
{
    using namespace Dimension;

    DimType& dt = m_dimMap[(int)id];
    size_t size = Dimension::size(dt.m_type);

    // Using the ID instead of a dimType as the arugment hides the complication
    // of the "type" of the dimension to retrieve in the case of location
    // scaling.
    view.getField(pos, id, dt.m_type, idx);

    auto iconvert = [pos](const XForm& xform, Dimension::Id::Enum dim)
    {
        double d;
        int32_t i;

        memcpy(&d, pos, sizeof(double));
        d = (d - xform.m_offset) / xform.m_scale;
        if (!Utils::numericCast(d, i))
        {
            std::ostringstream oss;
            oss << "Unable to convert double to int32 for packed DB output: ";
            oss << Dimension::name(dim) << ": (" << d << ").";
            throw pdal_error(oss.str());
        }
        memcpy(pos, &i, sizeof(int32_t));
    };

    if (m_locationScaling)
    {
        // For X, Y or Z.
        if (id == Id::X)
        {
            iconvert(m_xXform, Id::X);
            size = sizeof(int32_t);
        }
        else if (id == Id::Y)
        {
            iconvert(m_yXform, Id::Y);
            size = sizeof(int32_t);
        }
        else if (id == Id::Z)
        {
            iconvert(m_zXform, Id::Z);
            size = sizeof(int32_t);
        }
    }
    return size;
}
Пример #2
0
size_t DbWriter::readField(const PointView& view, char *pos, DimType dimType,
    PointId idx)
{
    using namespace Dimension;

    size_t size = Dimension::size(dimType.m_type);

    view.getField(pos, dimType.m_id, dimType.m_type, idx);

    auto iconvert = [pos](const XForm& xform)
    {
        double d;
        int32_t i;

        memcpy(&d, pos, sizeof(double));
        d = (d - xform.m_offset) / xform.m_scale;
        i = boost::numeric_cast<int32_t>(lround(d));
        memcpy(pos, &i, sizeof(int32_t));
    };

    if (m_locationScaling)
    {
        // For X, Y or Z.
        if (dimType.m_id == Id::X)
        {
            iconvert(m_xXform);
            size = sizeof(int32_t);
        }
        else if (dimType.m_id == Id::Y)
        {
            iconvert(m_yXform);
            size = sizeof(int32_t);
        }
        else if (dimType.m_id == Id::Z)
        {
            iconvert(m_zXform);
            size = sizeof(int32_t);
        }
    }
    return size;
}
Пример #3
0
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);

    bool hasColor = m_lasHeader.hasColor();
    bool hasTime = m_lasHeader.hasTime();
    PointId lastId = startId + blocksize;
    static const size_t maxReturnCount = m_lasHeader.maxReturnCount();
    LeInserter ostream(buf.data(), buf.size());
    for (PointId idx = startId; idx < lastId; idx++)
    {
        // we always write the base fields
        using namespace Dimension;

        uint8_t returnNumber(1);
        uint8_t numberOfReturns(1);
        if (view.hasDim(Id::ReturnNumber))
        {
            returnNumber = view.getFieldAs<uint8_t>(Id::ReturnNumber,
                idx);
            if (returnNumber < 1 || returnNumber > maxReturnCount)
                m_error.returnNumWarning(returnNumber);
        }
        if (view.hasDim(Id::NumberOfReturns))
            numberOfReturns = view.getFieldAs<uint8_t>(
                Id::NumberOfReturns, idx);
        if (numberOfReturns == 0)
            m_error.numReturnsWarning(0);
        if (numberOfReturns > maxReturnCount)
        {
            if (m_discardHighReturnNumbers)
            {
                // If this return number is too high, pitch the point.
                if (returnNumber > maxReturnCount)
                    continue;
                numberOfReturns = maxReturnCount;
            }
            else
                m_error.numReturnsWarning(numberOfReturns);
        }

        double xOrig = view.getFieldAs<double>(Id::X, idx);
        double yOrig = view.getFieldAs<double>(Id::Y, idx);
        double zOrig = view.getFieldAs<double>(Id::Z, idx);

        double x = (xOrig - m_xXform.m_offset) / m_xXform.m_scale;
        double y = (yOrig - m_yXform.m_offset) / m_yXform.m_scale;
        double z = (zOrig - m_zXform.m_offset) / m_zXform.m_scale;

        ostream << boost::numeric_cast<int32_t>(lround(x));
        ostream << boost::numeric_cast<int32_t>(lround(y));
        ostream << boost::numeric_cast<int32_t>(lround(z));

        uint16_t intensity = 0;
        if (view.hasDim(Id::Intensity))
            intensity = view.getFieldAs<uint16_t>(Id::Intensity, idx);
        ostream << intensity;

        uint8_t scanDirectionFlag(0);
        if (view.hasDim(Id::ScanDirectionFlag))
            scanDirectionFlag = view.getFieldAs<uint8_t>(
                Id::ScanDirectionFlag, idx);

        uint8_t edgeOfFlightLine(0);
        if (view.hasDim(Id::EdgeOfFlightLine))
            edgeOfFlightLine = view.getFieldAs<uint8_t>(
                Id::EdgeOfFlightLine, idx);

        uint8_t bits = returnNumber | (numberOfReturns<<3) |
            (scanDirectionFlag << 6) | (edgeOfFlightLine << 7);
        ostream << bits;

        uint8_t classification = 0;
        if (view.hasDim(Id::Classification))
            classification = view.getFieldAs<uint8_t>(Id::Classification,
                idx);
        ostream << classification;

        int8_t scanAngleRank = 0;
        if (view.hasDim(Id::ScanAngleRank))
            scanAngleRank = view.getFieldAs<int8_t>(Id::ScanAngleRank,
                idx);
        ostream << scanAngleRank;

        uint8_t userData = 0;
        if (view.hasDim(Id::UserData))
            userData = view.getFieldAs<uint8_t>(Id::UserData, idx);
        ostream << userData;

        uint16_t pointSourceId = 0;
        if (view.hasDim(Id::PointSourceId))
            pointSourceId = view.getFieldAs<uint16_t>(Id::PointSourceId,
                idx);
        ostream << pointSourceId;

        if (hasTime)
        {
            double t = 0.0;
            if (view.hasDim(Id::GpsTime))
                t = view.getFieldAs<double>(Id::GpsTime, idx);
            ostream << t;
        }

        if (hasColor)
        {
            uint16_t red = 0;
            uint16_t green = 0;
            uint16_t blue = 0;
            if (view.hasDim(Id::Red))
                red = view.getFieldAs<uint16_t>(Id::Red, idx);
            if (view.hasDim(Id::Green))
                green = view.getFieldAs<uint16_t>(Id::Green, idx);
            if (view.hasDim(Id::Blue))
                blue = view.getFieldAs<uint16_t>(Id::Blue, idx);

            ostream << red << green << blue;
        }

        Everything e;
        for (auto& dim : m_extraDims)
        {
            view.getField((char *)&e, dim.m_dimType.m_id,
                dim.m_dimType.m_type, idx);
            ostream.put(dim.m_dimType.m_type, e);
        }

        using namespace Dimension;
        m_summaryData.addPoint(xOrig, yOrig, zOrig, returnNumber);
    }
    return blocksize;
}