Пример #1
0
/// Write a point's packed data into a buffer.
/// \param[in] view PointView to write to.
/// \param[in] idx  Index of point to write.
/// \param[in] buf  Pointer to packed DB point data.
void DbReader::writePoint(PointView& view, PointId idx, const char *buf)
{
    using namespace Dimension;

    for (auto di = m_dims.begin(); di != m_dims.end(); ++di)
    {
        DimType dimType = di->m_dimType;
        // If we read X, Y or Z as a signed 32, apply the transform and write
        // the transformed value (double).
        if (dimType.m_type == Type::Signed32 &&
            (dimType.m_id == Id::X || dimType.m_id == Id::Y ||
             dimType.m_id == Id::Z))
        {
            int32_t i;

            memcpy(&i, buf, sizeof(int32_t));
            double d = (i * dimType.m_xform.m_scale) + dimType.m_xform.m_offset;
            view.setField(dimType.m_id, idx, d);
        }
        else
        {
            view.setField(dimType.m_id, dimType.m_type, idx, buf);
        }
        buf += Dimension::size(dimType.m_type);
    }
}
Пример #2
0
void ReprojectionFilter::filter(PointView& view)
{
    for (PointId id = 0; id < view.size(); ++id)
    {
        double x = view.getFieldAs<double>(Dimension::Id::X, id);
        double y = view.getFieldAs<double>(Dimension::Id::Y, id);
        double z = view.getFieldAs<double>(Dimension::Id::Z, id);

        transform(x, y, z);

        view.setField(Dimension::Id::X, id, x);
        view.setField(Dimension::Id::Y, id, y);
        view.setField(Dimension::Id::Z, id, z);
    }
}
Пример #3
0
void ColorizationFilter::filter(PointView& view)
{
    int32_t pixel(0);
    int32_t line(0);

    std::array<double, 2> pix = { {0.0, 0.0} };
    for (PointId idx = 0; idx < view.size(); ++idx)
    {
        double x = view.getFieldAs<double>(Dimension::Id::X, idx);
        double y = view.getFieldAs<double>(Dimension::Id::Y, idx);

        if (!getPixelAndLinePosition(x, y, m_inverse_transform, pixel,
                line, m_ds))
            continue;

        for (auto bi = m_bands.begin(); bi != m_bands.end(); ++bi)
        {
            BandInfo& b = *bi;
            GDALRasterBandH hBand = GDALGetRasterBand(m_ds, b.m_band);
            if (hBand == NULL)
            {
                std::ostringstream oss;
                oss << "Unable to get band " << b.m_band <<
                    " from data source!";
                throw pdal_error(oss.str());
            }
            if (GDALRasterIO(hBand, GF_Read, pixel, line, 1, 1,
                &pix[0], 1, 1, GDT_CFloat64, 0, 0) == CE_None)
                view.setField(b.m_dim, idx, pix[0] * b.m_scale);
        }
    }
}
Пример #4
0
void HAGFilter::filter(PointView& view)
{
    PointViewPtr gView = view.makeNew();
    PointViewPtr ngView = view.makeNew();
    std::vector<PointId> gIdx, ngIdx;

    // First pass: Separate into ground and non-ground views.
    for (PointId i = 0; i < view.size(); ++i)
    {
        double c = view.getFieldAs<double>(Dimension::Id::Classification, i);
        if (c == 2)
        {
            gView->appendPoint(view, i);
            gIdx.push_back(i);
        }
        else
        {
            ngView->appendPoint(view, i);
            ngIdx.push_back(i);
        }
    }

    // Bail if there weren't any points classified as ground.
    if (gView->size() == 0)
        throwError("Input PointView does not have any points classified "
            "as ground");

    // Build the 2D KD-tree.
    KD2Index kdi(*gView);
    kdi.build();

    // Second pass: Find Z difference between non-ground points and the nearest
    // neighbor (2D) in the ground view.
    for (PointId i = 0; i < ngView->size(); ++i)
    {
        PointRef point = ngView->point(i);
        double z0 = point.getFieldAs<double>(Dimension::Id::Z);
        auto ids = kdi.neighbors(point, 1);
        double z1 = gView->getFieldAs<double>(Dimension::Id::Z, ids[0]);
        view.setField(Dimension::Id::HeightAboveGround, ngIdx[i], z0 - z1);
    }

    // Final pass: Ensure that all ground points have height value pegged at 0.
    for (auto const& i : gIdx)
        view.setField(Dimension::Id::HeightAboveGround, i, 0.0);
}
Пример #5
0
void AttributeFilter::filter(PointView& view)
{
    if (m_value == m_value)
        for (PointId i = 0; i < view.size(); ++i)
            view.setField(m_dim, i, m_value);
    else
        UpdateGEOSBuffer(view);
}
void DbReader::writeField(PointView& view, const char *pos, const DimType& dim,
    PointId idx)
{
    using namespace Dimension;

    if (dim.m_id == Id::X || dim.m_id == Id::Y || dim.m_id == Id::Z)
    {
        Everything e;

        memcpy(&e, pos, Dimension::size(dim.m_type));
        double d = Utils::toDouble(e, dim.m_type);
        d = (d * dim.m_xform.m_scale.m_val) + dim.m_xform.m_offset.m_val;
        view.setField(dim.m_id, idx, d);
    }
    else
        view.setField(dim.m_id, dim.m_type, idx, pos);
}
Пример #7
0
void NormalFilter::filter(PointView& view)
{
    KD3Index& kdi = view.build3dIndex();

    for (PointId i = 0; i < view.size(); ++i)
    {
        // find the k-nearest neighbors
        auto ids = kdi.neighbors(i, m_knn);

        // compute covariance of the neighborhood
        auto B = eigen::computeCovariance(view, ids);

        // perform the eigen decomposition
        Eigen::SelfAdjointEigenSolver<Eigen::Matrix3f> solver(B);
        if (solver.info() != Eigen::Success)
            throwError("Cannot perform eigen decomposition.");
        auto eval = solver.eigenvalues();
        Eigen::Vector3f normal = solver.eigenvectors().col(0);

        if (m_viewpointArg->set())
        {
            PointRef p = view.point(i);
            Eigen::Vector3f vp(
                m_viewpoint.x - p.getFieldAs<double>(Dimension::Id::X),
                m_viewpoint.y - p.getFieldAs<double>(Dimension::Id::Y),
                m_viewpoint.z - p.getFieldAs<double>(Dimension::Id::Z));
            if (vp.dot(normal) < 0)
                normal *= -1.0;
        }
        else if (m_up)
        {
            if (normal[2] < 0)
                normal *= -1.0;
        }

        view.setField(Dimension::Id::NormalX, i, normal[0]);
        view.setField(Dimension::Id::NormalY, i, normal[1]);
        view.setField(Dimension::Id::NormalZ, i, normal[2]);

        double sum = eval[0] + eval[1] + eval[2];
        view.setField(Dimension::Id::Curvature, i,
                      sum ? std::fabs(eval[0] / sum) : 0);
    }
}
Пример #8
0
void DbReader::writeField(PointView& view, const char *pos, const DimType& dim,
    PointId idx)
{
    using namespace Dimension;

    if (dim.m_type == Type::Signed32 &&
        (dim.m_id == Id::X || dim.m_id == Id::Y || dim.m_id == Id::Z))
    {
        int32_t i;

        memcpy(&i, pos, sizeof(int32_t));
        double d = (i * dim.m_xform.m_scale) + dim.m_xform.m_offset;
        view.setField(dim.m_id, idx, d);
    }
    else
    {
        view.setField(dim.m_id, dim.m_type, idx, pos);
    }
}
Пример #9
0
void EstimateRankFilter::filter(PointView& view)
{
    KD3Index& kdi = view.build3dIndex();

    for (PointId i = 0; i < view.size(); ++i)
    {
        // find the k-nearest neighbors
        auto ids = kdi.neighbors(i, m_knn);

        view.setField(m_rank, i, eigen::computeRank(view, ids, m_thresh));
    }
}
Пример #10
0
void AttributeFilter::filter(PointView& view)
{

    for (auto& dim_par : m_dimensions)
    {
        if (dim_par.second.isogr)
        {
            UpdateGEOSBuffer(view, dim_par.second);
        }  else
        {
            for (PointId i = 0; i < view.size(); ++i)
            {
                double v = boost::lexical_cast<double>(dim_par.second.value);
                view.setField(dim_par.second.dim, i, v);
            }

        }
    }
}
Пример #11
0
void ColorizationFilter::filter(PointView& view)
{
    std::vector<double> data;

    for (PointId idx = 0; idx < view.size(); ++idx)
    {
        double x = view.getFieldAs<double>(Dimension::Id::X, idx);
        double y = view.getFieldAs<double>(Dimension::Id::Y, idx);

        if (!m_raster->read(x, y, data))
            continue;

        int i(0);
        for (auto bi = m_bands.begin(); bi != m_bands.end(); ++bi)
        {
            BandInfo& b = *bi;
            view.setField(b.m_dim, idx, data[i] * b.m_scale);
            ++i;
        }
    }
}
Пример #12
0
void BufferedInvocation::end(PointView& view, MetadataNode m)
{
    // 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);

    PointLayoutPtr layout(view.m_pointTable.layout());
    Dimension::IdList const& dims = layout->dims();

    for (auto di = dims.begin(); di != dims.end(); ++di)
    {
        Dimension::Id::Enum d = *di;
        const Dimension::Detail *dd = layout->dimDetail(d);
        std::string name = layout->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 < view.size(); ++idx)
        {
            view.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();
    addMetadata(m_metaOut, m);
}
Пример #13
0
point_count_t OciReader::readDimMajor(PointView& view, BlockPtr block,
    point_count_t numPts)
{
    using namespace Dimension;

    point_count_t numRemaining = block->numRemaining();
    PointId startId = view.size();
    point_count_t blockRemaining = numRemaining;
    point_count_t numRead = 0;

    DimTypeList dims = dbDimTypes();
    for (auto di = dims.begin(); di != dims.end(); ++di)
    {
        PointId nextId = startId;
        char *pos = seekDimMajor(*di, block);
        blockRemaining = numRemaining;
        numRead = 0;
        while (numRead < numPts && blockRemaining > 0)
        {
            writeField(view, pos, *di, nextId);
            pos += Dimension::size(di->m_type);

            if (di->m_id == Id::PointSourceId && m_updatePointSourceId)
                view.setField(Id::PointSourceId, nextId, block->obj_id);

            if (m_cb && di == dims.rbegin().base() - 1)
                m_cb(view, nextId);

            nextId++;
            numRead++;
            blockRemaining--;
        }
    }
    block->setNumRemaining(blockRemaining);
    return numRead;
}
Пример #14
0
void KDistanceFilter::filter(PointView& view)
{
    using namespace Dimension;
    
    // Build the 3D KD-tree.
    log()->get(LogLevel::Debug) << "Building 3D KD-tree...\n";
    KD3Index index(view);
    index.build();
    
    // Increment the minimum number of points, as knnSearch will be returning
    // the neighbors along with the query point.
    m_k++;
  
    // Compute the k-distance for each point. The k-distance is the Euclidean
    // distance to k-th nearest neighbor.
    log()->get(LogLevel::Debug) << "Computing k-distances...\n";
    for (PointId i = 0; i < view.size(); ++i)
    {
        std::vector<PointId> indices(m_k);
        std::vector<double> sqr_dists(m_k);
        index.knnSearch(i, m_k, &indices, &sqr_dists);
        view.setField(m_kdist, i, std::sqrt(sqr_dists[m_k-1]));
    }
}
Пример #15
0
void LOFFilter::filter(PointView& view)
{
    using namespace Dimension;

    KD3Index& index = view.build3dIndex();

    // Increment the minimum number of points, as knnSearch will be returning
    // the neighbors along with the query point.
    m_minpts++;

    // First pass: Compute the k-distance for each point.
    // The k-distance is the Euclidean distance to k-th nearest neighbor.
    log()->get(LogLevel::Debug) << "Computing k-distances...\n";
    for (PointId i = 0; i < view.size(); ++i)
    {
        std::vector<PointId> indices(m_minpts);
        std::vector<double> sqr_dists(m_minpts);
        index.knnSearch(i, m_minpts, &indices, &sqr_dists);
        view.setField(m_kdist, i, std::sqrt(sqr_dists[m_minpts-1]));
    }

    // Second pass: Compute the local reachability distance for each point.
    // For each neighbor point, the reachability distance is the maximum value
    // of that neighbor's k-distance and the distance between the neighbor and
    // the current point. The lrd is the inverse of the mean of the reachability
    // distances.
    log()->get(LogLevel::Debug) << "Computing lrd...\n";
    for (PointId i = 0; i < view.size(); ++i)
    {
        std::vector<PointId> indices(m_minpts);
        std::vector<double> sqr_dists(m_minpts);
        index.knnSearch(i, m_minpts, &indices, &sqr_dists);
        double M1 = 0.0;
        point_count_t n = 0;
        for (PointId j = 0; j < indices.size(); ++j)
        {
            double k = view.getFieldAs<double>(m_kdist, indices[j]);
            double reachdist = (std::max)(k, std::sqrt(sqr_dists[j]));
            M1 += (reachdist - M1) / ++n;
        }
        view.setField(m_lrd, i, 1.0 / M1);
    }

    // Third pass: Compute the local outlier factor for each point.
    // The LOF is the average of the lrd's for a neighborhood of points.
    log()->get(LogLevel::Debug) << "Computing LOF...\n";
    for (PointId i = 0; i < view.size(); ++i)
    {
        double lrdp = view.getFieldAs<double>(m_lrd, i);
        std::vector<PointId> indices(m_minpts);
        std::vector<double> sqr_dists(m_minpts);
        index.knnSearch(i, m_minpts, &indices, &sqr_dists);
        double M1 = 0.0;
        point_count_t n = 0;
        for (auto const& j : indices)
        {
            M1 += (view.getFieldAs<double>(m_lrd, j) / lrdp - M1) / ++n;
        }
        view.setField(m_lof, i, M1);
    }
}
Пример #16
0
void AttributeFilter::UpdateGEOSBuffer(PointView& view, AttributeInfo& info)
{
    QuadIndex idx(view);

    if (!info.lyr) // wake up the layer
    {
        if (info.layer.size())
            info.lyr = OGR_DS_GetLayerByName(info.ds.get(), info.layer.c_str());
        else if (info.query.size())
        {
            info.lyr = OGR_DS_ExecuteSQL(info.ds.get(), info.query.c_str(), 0, 0);
        }
        else
            info.lyr = OGR_DS_GetLayer(info.ds.get(), 0);
        if (!info.lyr)
        {
            std::ostringstream oss;
            oss << "Unable to select layer '" << info.layer << "'";
            throw pdal_error(oss.str());
        }
    }

    OGRFeaturePtr feature = OGRFeaturePtr(OGR_L_GetNextFeature(info.lyr), OGRFeatureDeleter());

    int field_index(1); // default to first column if nothing was set
    if (info.column.size())
    {

        field_index = OGR_F_GetFieldIndex(feature.get(), info.column.c_str());
        if (field_index == -1)
        {
            std::ostringstream oss;
            oss << "No column name '" << info.column << "' was found.";
            throw pdal_error(oss.str());
        }
    }

    while(feature)
    {
        OGRGeometryH geom = OGR_F_GetGeometryRef(feature.get());
        OGRwkbGeometryType t = OGR_G_GetGeometryType(geom);

        if (!(t == wkbPolygon ||
            t == wkbMultiPolygon ||
            t == wkbPolygon25D ||
            t == wkbMultiPolygon25D))
        {
            std::ostringstream oss;
            oss << "Geometry is not Polygon or MultiPolygon!";
            throw pdal::pdal_error(oss.str());
        }

        OGRGeometry* ogr_g = (OGRGeometry*) geom;
        GEOSGeometry* geos_g (0);
        if (!m_geosEnvironment)
        {

#if (GDAL_VERSION_MINOR < 11) && (GDAL_VERSION_MAJOR == 1)
        geos_g = ogr_g->exportToGEOS();
#else
        m_geosEnvironment = ogr_g->createGEOSContext();
        geos_g = ogr_g->exportToGEOS(m_geosEnvironment);

#endif
        }

        GEOSPreparedGeometry const* geos_pg = GEOSPrepare_r(m_geosEnvironment, geos_g);
        if (!geos_pg)
            throw pdal_error("unable to prepare geometry for index-accelerated intersection");

        // Compute a total bounds for the geometry. Query the QuadTree to
        // find out the points that are inside the bbox. Then test each
        // point in the bbox against the prepared geometry.
        BOX3D box = computeBounds(m_geosEnvironment, geos_g);
        std::vector<PointId> ids = idx.getPoints(box);
        for (const auto& i : ids)
        {

            double x = view.getFieldAs<double>(Dimension::Id::X, i);
            double y = view.getFieldAs<double>(Dimension::Id::Y, i);
            double z = view.getFieldAs<double>(Dimension::Id::Z, i);

            GEOSGeometry* p = createGEOSPoint(m_geosEnvironment, x, y ,z);

            if (static_cast<bool>(GEOSPreparedContains_r(m_geosEnvironment, geos_pg, p)))
            {
                // We're in the poly, write the attribute value
                int32_t v = OGR_F_GetFieldAsInteger(feature.get(), field_index);
                view.setField(info.dim, i, v);
//                 log()->get(LogLevel::Debug) << "Setting value: " << v << std::endl;
            }

            GEOSGeom_destroy_r(m_geosEnvironment, p);

        }

        feature = OGRFeaturePtr(OGR_L_GetNextFeature(info.lyr), OGRFeatureDeleter());
    }
}
Пример #17
0
void AttributeFilter::UpdateGEOSBuffer(PointView& view)
{
    QuadIndex idx(view);

    if (m_layer.size())
        m_lyr = OGR_DS_GetLayerByName(m_ds.get(), m_layer.c_str());
    else if (m_query.size())
        m_lyr = OGR_DS_ExecuteSQL(m_ds.get(), m_query.c_str(), 0, 0);
    else
        m_lyr = OGR_DS_GetLayer(m_ds.get(), 0);

    if (!m_lyr)
    {
        std::ostringstream oss;
        oss << getName() << ": Unable to select layer '" << m_layer << "'";
        throw pdal_error(oss.str());
    }

    OGRFeaturePtr feature = OGRFeaturePtr(OGR_L_GetNextFeature(m_lyr),
        OGRFeatureDeleter());

    int field_index(1); // default to first column if nothing was set
    if (m_column.size())
    {
        field_index = OGR_F_GetFieldIndex(feature.get(), m_column.c_str());
        if (field_index == -1)
        {
            std::ostringstream oss;
            oss << getName() << ": No column name '" << m_column <<
                "' was found.";
            throw pdal_error(oss.str());
        }
    }

    while (feature)
    {
        OGRGeometryH geom = OGR_F_GetGeometryRef(feature.get());
        OGRwkbGeometryType t = OGR_G_GetGeometryType(geom);
        int32_t fieldVal = OGR_F_GetFieldAsInteger(feature.get(), field_index);

        if (!(t == wkbPolygon ||
            t == wkbMultiPolygon ||
            t == wkbPolygon25D ||
            t == wkbMultiPolygon25D))
        {
            std::ostringstream oss;
            oss << getName() << ": Geometry is not Polygon or MultiPolygon!";
            throw pdal::pdal_error(oss.str());
        }

        pdal::Polygon p(geom, view.spatialReference(), GlobalEnvironment::get().geos());

        // Compute a total bounds for the geometry. Query the QuadTree to
        // find out the points that are inside the bbox. Then test each
        // point in the bbox against the prepared geometry.
        BOX3D box = p.bounds();
        std::vector<PointId> ids = idx.getPoints(box);


        for (const auto& i : ids)
        {
            PointRef ref(view, i);
            if (p.covers(ref))
                view.setField(m_dim, i, fieldVal);
        }
        feature = OGRFeaturePtr(OGR_L_GetNextFeature(m_lyr),
            OGRFeatureDeleter());
    }
}