示例#1
0
文件: Stage.cpp 项目: cugwhp/PDAL
PointViewSet Stage::execute(PointTableRef table)
{
    table.finalize();

    PointViewSet views;

    // If the inputs are empty, we're a reader.
    if (m_inputs.empty())
    {
        views.insert(PointViewPtr(new PointView(table)));
    }
    else
    {
        for (size_t i = 0; i < m_inputs.size(); ++i)
        {
            Stage *prev = m_inputs[i];
            PointViewSet temp = prev->execute(table);
            views.insert(temp.begin(), temp.end());
        }
    }

    PointViewSet outViews;
    std::vector<StageRunnerPtr> runners;

    // Put the spatial references from the views onto the table.
    // The table's spatial references are only valid as long as the stage
    // is running.
    // ABELL - Should we clear the references once the stage run has
    //   completed?  Wondering if that would break something where a
    //   writer wants to check a table's SRS.
    SpatialReference srs;
    table.clearSpatialReferences();
    for (auto const& it : views)
        table.addSpatialReference(it->spatialReference());

    // Do the ready operation and then start running all the views
    // through the stage.
    ready(table);
    for (auto const& it : views)
    {
        StageRunnerPtr runner(new StageRunner(this, it));
        runners.push_back(runner);
        runner->run();
    }

    // As the stages complete (synchronously at this time), propagate the
    // spatial reference and merge the output views.
    srs = getSpatialReference();
    for (auto const& it : runners)
    {
        StageRunnerPtr runner(it);
        PointViewSet temp = runner->wait();

        // If our stage has a spatial reference, the view takes it on once
        // the stage has been run.
        if (!srs.empty())
            for (PointViewPtr v : temp)
                v->setSpatialReference(srs);
        outViews.insert(temp.begin(), temp.end());
    }
    done(table);
    return outViews;
}
示例#2
0
void TIndexKernel::mergeFile()
{
    using namespace gdal;

    std::ostringstream out;

    if (!openDataset(m_idxFilename))
    {
        std::ostringstream out;
        out << "Couldn't open index dataset file '" << m_idxFilename << "'.";
        throw pdal_error(out.str());
    }
    if (!openLayer(m_layerName))
    {
        std::ostringstream out;
        out << "Couldn't open layer '" << m_layerName <<
            "' in output file '" << m_idxFilename << "'.";
        throw pdal_error(out.str());
    }

    FieldIndexes indexes = getFields();

    SpatialRef outSrs(m_tgtSrsString);
    if (!outSrs)
        throw pdal_error("Couldn't interpret target SRS string.");

    if (!m_wkt.empty())
    {
        Geometry g(m_wkt, outSrs);

        if (!g)
            throw pdal_error("Couldn't interpret geometry filter string.");
        OGR_L_SetSpatialFilter(m_layer, g.get());
    }

    std::vector<FileInfo> files;

    // Docs are bad here.  You need this call even if you haven't read anything
    // or nothing happens.
    OGR_L_ResetReading(m_layer);
    while (true)
    {
        OGRFeatureH feature = OGR_L_GetNextFeature(m_layer);
        if (!feature)
            break;

        FileInfo fileInfo;
        fileInfo.m_filename =
            OGR_F_GetFieldAsString(feature, indexes.m_filename);
        fileInfo.m_srs =
            OGR_F_GetFieldAsString(feature, indexes.m_srs);
        files.push_back(fileInfo);

        OGR_F_Destroy(feature);
    }

    StageFactory factory;

    MergeFilter merge;

    Options cropOptions;
    if (!m_bounds.empty())
        cropOptions.add("bounds", m_bounds);
    else
        cropOptions.add("polygon", m_wkt);

    for (auto f : files)
    {
        Stage *premerge = NULL;
        std::string driver = factory.inferReaderDriver(f.m_filename);
        Stage *reader = factory.createStage(driver);
        if (!reader)
        {
            out << "Unable to create reader for file '" << f.m_filename << "'.";
            throw pdal_error(out.str());
        }
        Options readerOptions;
        readerOptions.add("filename", f.m_filename);
        reader->setOptions(readerOptions);
        premerge = reader;

        if (m_tgtSrsString != f.m_srs)
        {
            Stage *repro = factory.createStage("filters.reprojection");
            repro->setInput(*reader);
            Options reproOptions;
            reproOptions.add("out_srs", m_tgtSrsString);
            reproOptions.add("in_srs", f.m_srs);
            repro->setOptions(reproOptions);
            premerge = repro;
        }

        // WKT is set, even if we're using a bounding box for fitering, so
        // can be used as a test here.
        if (!m_wkt.empty())
        {
            Stage *crop = factory.createStage("filters.crop");
            crop->setOptions(cropOptions);
            crop->setInput(*premerge);
            premerge = crop;
        }

        merge.setInput(*premerge);
    }

    std::string driver = factory.inferWriterDriver(m_filespec);
    Options factoryOptions = factory.inferWriterOptionsChanges(m_filespec);
    Stage *writer = factory.createStage(driver);
    if (!writer)
    {
        out << "Unable to create reader for file '" << m_filespec << "'.";
        throw pdal_error(out.str());
    }
    writer->setInput(merge);

    applyExtraStageOptionsRecursive(writer);

    Options writerOptions(factoryOptions);
    setCommonOptions(writerOptions);

    writerOptions.add("filename", m_filespec);
    writerOptions.add("offset_x", "auto");
    writerOptions.add("offset_y", "auto");
    writerOptions.add("offset_z", "auto");
    writer->addConditionalOptions(writerOptions);

    PointTable table;
    writer->prepare(table);
    writer->execute(table);
}
示例#3
0
TIndexKernel::FileInfo TIndexKernel::getFileInfo(KernelFactory& factory,
    const std::string& filename)
{
    FileInfo fileInfo;

    StageFactory f;

    std::string driverName = f.inferReaderDriver(filename);
    Stage *s = f.createStage(driverName);
    Options ops;
    ops.add("filename", filename);
    setCommonOptions(ops);
    s->setOptions(ops);
    applyExtraStageOptionsRecursive(s);
    if (m_fastBoundary)
    {
        QuickInfo qi = s->preview();

        std::stringstream polygon;
        polygon << "POLYGON ((";

        polygon <<         qi.m_bounds.minx << " " << qi.m_bounds.miny;
        polygon << ", " << qi.m_bounds.maxx << " " << qi.m_bounds.miny;
        polygon << ", " << qi.m_bounds.maxx << " " << qi.m_bounds.maxy;
        polygon << ", " << qi.m_bounds.minx << " " << qi.m_bounds.maxy;
        polygon << ", " << qi.m_bounds.minx << " " << qi.m_bounds.miny;
        polygon << "))";
        fileInfo.m_boundary = polygon.str();
        if (!qi.m_srs.empty())
            fileInfo.m_srs = qi.m_srs.getWKT();
    }
    else
    {
        PointTable table;

        Stage *hexer = f.createStage("filters.hexbin");
        if (! hexer)
        {

            std::ostringstream oss;

            oss << "Unable to create hexer stage to create boundaries. "
                << "Is PDAL_DRIVER_PATH environment variable set?";
            throw pdal_error(oss.str());
        }
        hexer->setInput(*s);

        hexer->prepare(table);
        PointViewSet set = hexer->execute(table);

        MetadataNode m = table.metadata();
        m = m.findChild("filters.hexbin:boundary");
        fileInfo.m_boundary = m.value();

        PointViewPtr v = *set.begin();
        if (!v->spatialReference().empty())
            fileInfo.m_srs = v->spatialReference().getWKT();
    }

    FileUtils::fileTimes(filename, &fileInfo.m_ctime, &fileInfo.m_mtime);
    fileInfo.m_filename = filename;

    return fileInfo;
}