예제 #1
0
파일: PointLayout.cpp 프로젝트: cugwhp/PDAL
bool PointLayout::update(Dimension::Detail dd, const std::string& name)
{
    if (m_finalized)
    {
        throw pdal_error("Can't update layout after points have been added.");
    }

    Dimension::DetailList detail;

    bool used = Utils::contains(m_used, dd.id());
    for (auto id : m_used)
    {
        if (id == dd.id())
            detail.push_back(dd);
        else
            detail.push_back(m_detail[id]);
    }
    if (!used)
        detail.push_back(dd);

    // Find the dimension in the list that we're referring to with
    // this update.
    auto di = std::find_if(detail.begin(), detail.end(),
    [dd](const Dimension::Detail& td) {
        return td.id() == dd.id();
    });
    Dimension::Detail *cur = &(*di);

    {
        auto sorter = [this](const Dimension::Detail& d1,
                             const Dimension::Detail& d2) -> bool
        {
            if (d1.size() > d2.size())
                return true;
            if (d1.size() < d2.size())
                return false;
            return d1.id() < d2.id();
        };

        int offset = 0;
        std::sort(detail.begin(), detail.end(), sorter);
        for (auto& d : detail)
        {
            d.setOffset(offset);
            offset += (int)d.size();
        }
        //NOTE - I tried forcing all points to be aligned on 8-byte boundaries
        // in case this would matter to the optimized memcpy, but it made
        // no difference.  No sense wasting space for no difference.
        m_pointSize = (size_t)offset;
    }

    if (!used)
        m_used.push_back(dd.id());

    for (auto& dtemp : detail)
        m_detail[dtemp.id()] = dtemp;

    return true;
}
예제 #2
0
    bool compare(Dimension::Id::Enum dim, PointId id1, PointId id2)
    {
        Dimension::Detail *dd = m_context.dimDetail(dim);

        switch (dd->type())
        {
            case Dimension::Type::Float:
                return compare<float>(dim, id1, id2);
                break;
            case Dimension::Type::Double:
                return compare<double>(dim, id1, id2);
                break;
            case Dimension::Type::Signed8:
                return compare<int8_t>(dim, id1, id2);
                break;
            case Dimension::Type::Signed16:
                return compare<int16_t>(dim, id1, id2);
                break;
            case Dimension::Type::Signed32:
                return compare<int32_t>(dim, id1, id2);
                break;
            case Dimension::Type::Signed64:
                return compare<int64_t>(dim, id1, id2);
                break;
            case Dimension::Type::Unsigned8:
                return compare<uint8_t>(dim, id1, id2);
                break;
            case Dimension::Type::Unsigned16:
                return compare<uint16_t>(dim, id1, id2);
                break;
            case Dimension::Type::Unsigned32:
                return compare<uint32_t>(dim, id1, id2);
                break;
            case Dimension::Type::Unsigned64:
                return compare<uint64_t>(dim, id1, id2);
                break;
            case Dimension::Type::None:
            default:
                return false;
                break;
        }
    }
예제 #3
0
Dimension::Id::Enum PointLayout::assignDim(const std::string& name,
    Dimension::Type::Enum type)
{
    Dimension::Id::Enum id = (Dimension::Id::Enum)m_nextFree;

    auto di = m_propIds.find(name);
    if (di != m_propIds.end())
        id = di->second;
    Dimension::Detail dd = m_detail[id];
    dd.setType(resolveType(type, dd.type()));
    if (update(dd, name))
    {
        if (di == m_propIds.end())
        {
            m_nextFree++;
            m_propIds[name] = id;
        }
        return id;
    }
    return Dimension::Id::Unknown;
}
예제 #4
0
void BufferedInvocation::begin(PointBuffer& buffer)
{
    PointContext ctx = buffer.m_context;
    Dimension::IdList const& dims = ctx.dims();

    for (auto di = dims.begin(); di != dims.end(); ++di)
    {
        Dimension::Id::Enum d = *di;
        Dimension::Detail *dd = ctx.dimDetail(d);
        void *data = malloc(dd->size() * buffer.size());
        m_buffers.push_back(data);  // Hold pointer for deallocation
        char *p = (char *)data;
        for (PointId idx = 0; idx < buffer.size(); ++idx)
        {
            buffer.getFieldInternal(d, idx, (void *)p);
            p += dd->size();
        }
        std::string name = ctx.dimName(*di);
        insertArgument(name, (uint8_t *)data, dd->type(), buffer.size());
    }
}
예제 #5
0
void BufferedInvocation::end(PointBuffer& buffer)
{
    // for each entry in the script's outs dictionary,
    // look up that entry's name in the schema and then
    // copy the data into the right dimension spot in the
    // buffer

    std::vector<std::string> names;
    getOutputNames(names);

    PointContext ctx = buffer.m_context;
    Dimension::IdList const& dims = ctx.dims();

    for (auto di = dims.begin(); di != dims.end(); ++di)
    {
        Dimension::Id::Enum d = *di;
        Dimension::Detail *dd = ctx.dimDetail(d);
        std::string name = ctx.dimName(*di);
        auto found = std::find(names.begin(), names.end(), name);
        if (found == names.end()) continue; // didn't have this dim in the names

        assert(name == *found);
        assert(hasOutputVariable(name));

        size_t size = dd->size();
        void *data = extractResult(name, dd->type());
        char *p = (char *)data;
        for (PointId idx = 0; idx < buffer.size(); ++idx)
        {
            buffer.setField(d, dd->type(), idx, (void *)p);
            p += size;
        }
    }
    for (auto bi = m_buffers.begin(); bi != m_buffers.end(); ++bi)
        free(*bi);
    m_buffers.clear();
}
예제 #6
0
void PointLayout::registerDim(Dimension::Id::Enum id, Dimension::Type::Enum type)
{
    Dimension::Detail dd = m_detail[id];
    dd.setType(resolveType(type, dd.type()));
    update(dd, Dimension::name(id));
}
예제 #7
0
void PointBuffer::dump(std::ostream& ostr) const
{
    using std::endl;
    const Dimension::IdList& dims = m_context.dims();

    point_count_t numPoints = size();
    ostr << "Contains " << numPoints << "  points" << endl;
    for (PointId idx = 0; idx < numPoints; idx++)
    {
        ostr << "Point: " << idx << endl;

        for (auto di = dims.begin(); di != dims.end(); ++di)
        {
            Dimension::Id::Enum d = *di;
            Dimension::Detail *dd = m_context.dimDetail(d);
            ostr << Dimension::name(d) << " (" <<
                Dimension::interpretationName(dd->type()) << ") : ";

            switch (dd->type())
            {
            case Dimension::Type::Signed8:
                {
                    ostr << (int)(getFieldInternal<int8_t>(d, idx));
                    break;
                }
            case Dimension::Type::Signed16:
                {
                    ostr << getFieldInternal<int16_t>(d, idx);
                    break;
                }
            case Dimension::Type::Signed32:
                {
                    ostr << getFieldInternal<int32_t>(d, idx);
                    break;
                }
            case Dimension::Type::Signed64:
                {
                    ostr << getFieldInternal<int64_t>(d, idx);
                    break;
                }
            case Dimension::Type::Unsigned8:
                {
                    ostr << (unsigned)(getFieldInternal<uint8_t>(d, idx));
                    break;
                }
            case Dimension::Type::Unsigned16:
                {
                    ostr << getFieldInternal<uint16_t>(d, idx);
                    break;
                }
            case Dimension::Type::Unsigned32:
                {
                    ostr << getFieldInternal<uint32_t>(d, idx);
                    break;
                }
            case Dimension::Type::Unsigned64:
                {
                    ostr << getFieldInternal<uint64_t>(d, idx);
                    break;
                }
            case Dimension::Type::Float:
                {
                    ostr << getFieldInternal<float>(d, idx);
                    break;
                }
            case Dimension::Type::Double:
                {
                    ostr << getFieldInternal<double>(d, idx);
                    break;
                }
            default:
                throw;
            }
            ostr << endl;
        }
    }
}