Esempio n. 1
0
vector<uint32_t> getListOfPoints(std::string p)
{
    vector<uint32_t> output;

    //Remove whitespace from string with awful remove/erase idiom.
    p.erase(remove_if(p.begin(), p.end(), ::isspace), p.end());

    vector<string> ranges = tokenize(p, ',');
    for (string s : ranges)
    {
        vector<string> limits = tokenize(s, '-');
        if (limits.size() == 1)
            addSingle(limits[0], output);
        else if (limits.size() == 2)
            addRange(limits[0], limits[1], output);
        else
            throw pdal_error(string("Invalid point range: ") + s);
    }
    return output;
}
Esempio n. 2
0
Stage& PipelineManager::makeWriter(StageCreationOptions& o)
{
    if (o.m_driver.empty())
    {
        o.m_driver = StageFactory::inferWriterDriver(o.m_filename);
        if (o.m_driver.empty())
            throw pdal_error("Cannot determine writer for output file: " +
                o.m_filename);
    }

    if (!o.m_filename.empty())
        o.m_options.replace("filename", o.m_filename);

    auto& writer = addWriter(o.m_driver);
    writer.setTag(o.m_tag);
    setOptions(writer, o.m_options);
    if (o.m_parent)
        writer.setInput(*o.m_parent);
    return writer;
}
Esempio n. 3
0
int PipelineKernel::execute()
{
    if (!Utils::fileExists(m_inputFile))
        throw pdal_error("file not found: " + m_inputFile);
    if (m_progressFile.size())
        m_progressFd = Utils::openProgress(m_progressFile);

    m_manager.readPipeline(m_inputFile);

    if (m_validate)
    {
        // Validate the options of the pipeline we were
        // given, and once we succeed, we're done
        m_manager.prepare();
        Utils::closeProgress(m_progressFd);
        return 0;
    }

    m_manager.execute();

    if (m_pipelineFile.size() > 0)
        PipelineWriter::writePipeline(m_manager.getStage(), m_pipelineFile);

    if (m_PointCloudSchemaOutput.size() > 0)
    {
#ifdef PDAL_HAVE_LIBXML2
        XMLSchema schema(m_manager.pointTable().layout());

        std::ostream *out = Utils::createFile(m_PointCloudSchemaOutput);
        std::string xml(schema.xml());
        out->write(xml.c_str(), xml.size());
        Utils::closeFile(out);
#else
        std::cerr << "libxml2 support not available, no schema is produced" <<
            std::endl;
#endif

    }
    Utils::closeProgress(m_progressFd);
    return 0;
}
Esempio n. 4
0
std::vector<Polygon::Ring> Polygon::interiorRings() const
{
    std::vector<Ring> rings;

    OGRwkbGeometryType t = m_geom->getGeometryType();
    if (t != wkbPolygon && t != wkbPolygon25D)
        throw pdal_error("Request for exterior ring on non-polygon.");

//    OGRPolygon *poly = m_geom->toPolygon();
     OGRPolygon *poly = static_cast<OGRPolygon *>(m_geom.get());
    for (int i = 0; i < poly->getNumInteriorRings(); ++i)
    {
        OGRLinearRing *er = poly->getInteriorRing(i);

        Ring r;
        for (int j = 0; j < er->getNumPoints(); ++j)
            r.push_back({er->getX(j), er->getY(j)});
        rings.push_back(r);
    }
    return rings;
}
Esempio n. 5
0
void PipelineManager::validateStageOptions() const
{
    // Make sure that the options specified are for relevant stages.
    for (auto& si : m_stageOptions)
    {
        const std::string& stageName = si.first;
        auto it = std::find_if(m_stages.begin(), m_stages.end(),
            [stageName](Stage *s)
            { return (s->getName() == stageName ||
                "stage." + s->tag() == stageName); });

        // If the option stage name matches no created stage, then error.
        if (it == m_stages.end())
        {
            std::ostringstream oss;
            oss << "Argument references invalid/unused stage: '" <<
                stageName << "'.";
            throw pdal_error(oss.str());
        }
    }
}
Esempio n. 6
0
void BpfWriter::loadBpfDimensions(PointLayoutPtr layout)
{
    // Verify that we have X, Y and Z and that they're the first three
    // dimensions.
    Dimension::IdList dims = layout->dims();
    std::sort(dims.begin(), dims.end());
    if (dims.size() < 3 || dims[0] != Dimension::Id::X ||
        dims[1] != Dimension::Id::Y || dims[2] != Dimension::Id::Z)
    {
        throw pdal_error("Missing one of dimensions X, Y or Z.  "
            "Can't write BPF.");
    }

    for (auto id : dims)
    {
        BpfDimension dim;
        dim.m_id = id;
        dim.m_label = layout->dimName(id);
        m_dims.push_back(dim);
    }
}
Esempio n. 7
0
void Reprojection::transform(double& x, double& y, double& z) const
{

#ifdef PDAL_HAVE_GDAL
    int ret = 0;

    ret = OCTTransform(m_transform_ptr.get(), 1, &x, &y, &z);    
    if (!ret)
    {
        std::ostringstream msg; 
        msg << "Could not project point for ReprojectionTransform::" << CPLGetLastErrorMsg() << ret;
        throw pdal_error(msg.str());
    }
#else
    boost::ignore_unused_variable_warning(x);
    boost::ignore_unused_variable_warning(y);
    boost::ignore_unused_variable_warning(z);
#endif
 
    return;
}
Esempio n. 8
0
bool PluginManager::loadPlugin(const std::string& driverFileName)
{
    std::vector<std::string> driverPathVec;
    driverPathVec = Utils::split2(driverFileName, '.');

    boost::filesystem::path full_path(driverFileName);

    if (boost::filesystem::is_directory(full_path))
        return false;

    std::string ext = full_path.extension().string();
    if (ext != dynamicLibraryExtension)
        return false;
    std::string stem = full_path.stem().string();
    std::vector<std::string> driverNameVec;
    driverNameVec = Utils::split2(driverPathVec[0], '_');

    std::string ptype;
    if (driverNameVec.size() >=3)
        ptype = driverNameVec[2];

    PF_PluginType type;
    if (Utils::iequals(ptype, "reader"))
        type = PF_PluginType_Reader;
    else if (Utils::iequals(ptype,"kernel"))
        type = PF_PluginType_Kernel;
    else if (Utils::iequals(ptype, "filter"))
        type = PF_PluginType_Filter;
    else if (Utils::iequals(ptype, "writer"))
        type = PF_PluginType_Writer;
    else
        throw pdal_error("Unknown plugin type '" + ptype +"'");

    if (loadByPath(full_path.string(), type))
    {
        return true;
    }

    return false;
}
Esempio n. 9
0
std::string Writer::LoadSQLData(std::string const& filename)
{
    if (!FileUtils::fileExists(filename))
    {
        std::ostringstream oss;
        oss << filename << " does not exist";
        throw pdal_error(oss.str());
    }

    std::istream::pos_type size;
    std::istream* input = FileUtils::openFile(filename, true);


    if (input->good())
    {
        std::string output;
        std::string line;
        while (input->good())
        {
            getline(*input, line);
            if (output.size())
            {
                output = output + "\n" + line;
            }
            else
            {
                output = line;
            }
        }

        return output;
    }
    else
    {
        FileUtils::closeFile(input);
        return std::string("");
    }

}
Esempio n. 10
0
    Geometry(const std::string& wkt, const SpatialRef& srs)
    {
        OGRGeometryH geom;

        char *p_wkt = const_cast<char *>(wkt.data());
        OGRSpatialReferenceH ref = srs.get();
        if (srs.empty())
        {
            ref = NULL;
        }
        bool isJson = wkt.find("{") != wkt.npos ||
                      wkt.find("}") != wkt.npos;

        if (!isJson)
        {
            OGRErr err = OGR_G_CreateFromWkt(&p_wkt, ref, &geom);
            if (err != OGRERR_NONE)
            {
                std::cout << "wkt: " << wkt << std::endl;
                std::ostringstream oss;
                oss << "unable to construct OGR Geometry";
                oss << " '" << CPLGetLastErrorMsg() << "'";
                throw pdal::pdal_error(oss.str());
            }
        }
        else
        {
            // Assume it is GeoJSON and try constructing from that
            geom = OGR_G_CreateGeometryFromJson(p_wkt);

            if (!geom)
                throw pdal_error("Unable to create geometry from "
                    "input GeoJSON");

            OGR_G_AssignSpatialReference(geom, ref);
        }

        newRef(geom);
    }
Esempio n. 11
0
void LasReader::initialize()
{
    if (m_initialized)
        return;
    m_istream = createStream();

    m_istream->seekg(0);
    ILeStream in(m_istream);
    in >> m_lasHeader;

    if (!m_lasHeader.pointFormatSupported())
    {
        std::ostringstream oss;
        oss << "Unsupported LAS input point format: " <<
            (int)m_lasHeader.pointFormat() << ".";
       throw pdal_error(oss.str());
    }

    // We need to read the VLRs in initialize() because they may contain an
    // extra-bytes VLR that is needed to determine dimensions.
    m_istream->seekg(m_lasHeader.vlrOffset());
    for (size_t i = 0; i < m_lasHeader.vlrCount(); ++i)
    {
        VariableLengthRecord r;
        in >> r;
        m_vlrs.push_back(std::move(r));
    }

    if (m_lasHeader.versionAtLeast(1, 4))
    {
        m_istream->seekg(m_lasHeader.eVlrOffset());
        for (size_t i = 0; i < m_lasHeader.eVlrCount(); ++i)
        {
            ExtVariableLengthRecord r;
            in >> r;
            m_vlrs.push_back(std::move(r));
        }
        readExtraBytesVlr();
    }
Esempio n. 12
0
void Reader::initialize()
{
    pdal::Reader::initialize();

    boost::scoped_ptr<PipelineManager> tmp(new PipelineManager());
    m_manager.swap(tmp);

    PipelineReader xmlreader(*m_manager);
    bool isWriter = xmlreader.readPipeline(m_filename);
    if (isWriter)
    {
        throw pdal_error("pipeline file is not a Reader");
    }
    m_stage = m_manager->getStage();
    m_stage->initialize();

    setNumPoints(m_stage->getNumPoints());
    setPointCountType(m_stage->getPointCountType());
    setBounds(m_stage->getBounds());

    return;
}
Esempio n. 13
0
void AttributeFilter::ready(PointTableRef table)
{
    for (auto& dim_par : m_dimensions)
    {
        Dimension::Id::Enum t = table.layout()->findDim(dim_par.first);
        dim_par.second.dim = t;

        if (dim_par.second.isogr)
        {

            OGRDSPtr ds = OGRDSPtr(OGROpen(dim_par.second.datasource.c_str(), 0, 0), OGRDataSourceDeleter());
            if (!ds)
            {
                std::ostringstream oss;
                oss << "Unable to open data source '" << dim_par.second.datasource <<"'";
                throw pdal_error(oss.str());
            }
            dim_par.second.ds = ds;
        }

    }
}
Esempio n. 14
0
// Determines the pixel/line position given an x/y.
// No reprojection is done at this time.
bool Colorization::getPixelAndLinePosition(double x,
        double y,
        boost::array<double, 6> const& inverse,
        boost::int32_t& pixel,
        boost::int32_t& line,
        void* ds)
{
#ifdef PDAL_HAVE_GDAL
    pixel = (boost::int32_t) std::floor(
                inverse[0]
                + inverse[1] * x
                + inverse[2] * y);
    line = (boost::int32_t) std::floor(
               inverse[3]
               + inverse[4] * x
               + inverse[5] * y);
    
    int xs = GDALGetRasterXSize(ds);
    int ys = GDALGetRasterYSize(ds);
    
    if (!xs || !ys)
    {
        throw pdal_error("Unable to get X or Y size from raster!");
    }

    if (pixel < 0 || 
        line < 0 || 
        pixel >= xs || 
        line  >= ys
       )
    {
        // The x, y is not coincident with this raster
        return false;
    }
#endif

    return true;
}
Esempio n. 15
0
void OptechReader::initialize()
{
    ILeStream stream(Utils::openFile(m_filename));
    if (!stream)
    {
        std::stringstream ss;
        ss << "Unable to open " << m_filename << " for reading.";
        throw pdal_error(ss.str());
    }

    stream.get(m_header.signature, 4);
    if (strcmp(m_header.signature, "CSD") != 0)
    {
        std::stringstream ss;
        ss << "Invalid header signature when reading CSD file: '"
           << m_header.signature << "'";
        throw optech_error(ss.str());
    }
    stream.get(m_header.vendorId, 64);
    stream.get(m_header.softwareVersion, 32);
    stream >> m_header.formatVersion >> m_header.headerSize >>
        m_header.gpsWeek >> m_header.minTime >> m_header.maxTime >>
        m_header.numRecords >> m_header.numStrips;
    for (size_t i = 0; i < 256; ++i)
    {
        stream >> m_header.stripPointers[i];
    }
    stream >> m_header.misalignmentAngles[0] >>
        m_header.misalignmentAngles[1] >> m_header.misalignmentAngles[2] >>
        m_header.imuOffsets[0] >> m_header.imuOffsets[1] >>
        m_header.imuOffsets[2] >> m_header.temperature >> m_header.pressure;
    stream.get(m_header.freeSpace, 830);

    m_boresightMatrix = createOptechRotationMatrix(
        m_header.misalignmentAngles[0] + m_header.imuOffsets[0],
        m_header.misalignmentAngles[1] + m_header.imuOffsets[1],
        m_header.misalignmentAngles[2] + m_header.imuOffsets[2]);
}
void GeoPackageWriter::createTableGpkgPctile(const std::string& table_name)
{
    if (m_sqlite->doesTableExist(table_name))
    {
        throw pdal_error("RialtoDB: invalid state (table '" + table_name + "' already exists)");
    }

    const std::string sql =
        "CREATE TABLE " + table_name + "("
        "id INTEGER PRIMARY KEY AUTOINCREMENT,"
        "zoom_level INTEGER NOT NULL,"
        "tile_column INTEGER NOT NULL,"
        "tile_row INTEGER NOT NULL,"
        "tile_data BLOB NOT NULL,"
        "num_points INTEGER NOT NULL,"
        "child_mask INTEGER NOT NULL,"
        "UNIQUE(zoom_level, tile_column, tile_row)"
        ")";

    m_sqlite->execute(sql);

    const std::string data =
        "INSERT INTO gpkg_extensions "
        "(table_name, column_name, extension_name, definition, scope) "
        "VALUES (?, ?, ?, ?, ?)";

    records rs;
    row r;

    r.push_back(column(table_name));
    r.push_back(column("NULL"));
    r.push_back(column("radiantblue_pctiles"));
    r.push_back(column("mailto:[email protected]"));
    r.push_back(column("read-write"));
    rs.push_back(r);

    m_sqlite->insert(data, rs);
}
void GeoPackageWriter::writeTile(const std::string& tileTableName, const GpkgTile& data)
{
    if (!m_sqlite)
    {
        throw pdal_error("RialtoDB: invalid state (session does exist)");
    }

    e_tilesWritten.start();

    const uint32_t buflen = data.getBlob().size();
    const char* buf = data.getBlob().data();
    assert(buf);
    assert(buflen);

    {
        const std::string sql =
            "INSERT INTO " + tileTableName +
            " (zoom_level, tile_column, tile_row, tile_data, num_points, child_mask)"
            " VALUES (?, ?, ?, ?, ?, ?)";

        records rs;
        row r;

        r.push_back(column(data.getLevel()));
        r.push_back(column(data.getColumn()));
        r.push_back(column(data.getRow()));
        r.push_back(blob(buf, (size_t)buflen));
        r.push_back(column(data.getNumPoints()));
        r.push_back(column(data.getMask()));
        rs.push_back(r);

        m_sqlite->insert(sql, rs);
    }

    e_tilesWritten.stop();

    m_numPointsWritten += data.getNumPoints();
}
Esempio n. 18
0
point_count_t PlyReader::read(PointViewPtr view, point_count_t num)
{
    CallbackContext context;
    context.view = view;
    context.dimensionMap = m_vertexDimensions;

    // It's possible that point_count_t holds a value that's larger than the
    // long that is the maximum rply (don't know about ply) point count.
    long cnt;
    cnt = Utils::inRange<long>(num) ? num : (std::numeric_limits<long>::max)();
    for (auto it : m_vertexDimensions)
    {
        ply_set_read_cb(m_ply, "vertex", it.first.c_str(), readPlyCallback,
            &context, cnt);
    }
    if (!ply_read(m_ply))
    {
        std::stringstream ss;
        ss << "Error reading " << m_filename << ".";
        throw pdal_error(ss.str());
    }
    return view->size();
}
Esempio n. 19
0
Polygon::Ring Polygon::exteriorRing() const
{
    Ring r;

    OGRwkbGeometryType t = m_geom->getGeometryType();
    if (t != wkbPolygon && t != wkbPolygon25D)
        throw pdal_error("Request for exterior ring on non-polygon.");

    // Not until GDAL 2.3
    /**
    OGRLinearRing *er = m_geom->toPolygon()->getExteriorRing();

    // For some reason there's no operator -> on an iterator.
    for (auto it = er->begin(); it != er->end(); ++it)
        r.push_back({(*it).getX(), (*it).getY()});
    **/
    OGRLinearRing *er =
        static_cast<OGRPolygon *>(m_geom.get())->getExteriorRing();
    for (int i = 0; i < er->getNumPoints(); ++i)
        r.push_back({er->getX(i), er->getY(i)});

    return r;
}
Esempio n. 20
0
int RandomKernel::execute()
{
    Options readerOptions;

    if (!m_bounds.empty())
        readerOptions.add("bounds", m_bounds);

    std::string distribution(Utils::tolower(m_distribution));
    if (distribution == "uniform")
        readerOptions.add("mode", "uniform");
    else if (distribution == "normal")
        readerOptions.add("mode", "normal");
    else if (distribution == "random")
        readerOptions.add("mode", "random");
    else
        throw pdal_error("invalid distribution: " + m_distribution);
    readerOptions.add("count", m_numPointsToWrite);

    Options writerOptions;
    if (m_bCompress)
        writerOptions.add("compression", true);

    Stage& reader = makeReader("", "readers.faux");
    reader.addOptions(readerOptions);

    Stage& writer = makeWriter(m_outputFile, reader, "");
    writer.addOptions(writerOptions);

    PointTable table;
    writer.prepare(table);
    PointViewSet viewSet = writer.execute(table);

    if (isVisualize())
        visualize(*viewSet.begin());

    return 0;
}
Esempio n. 21
0
void GreyhoundReader::initialize(PointTableRef table)
{
    // Parse the URL and query parameters (although we won't handle the schema
    // until addDimensions) and fetch the dataset `info`.

    Json::Value config;
    if (log()->getLevel() > LogLevel::Debug4)
        config["arbiter"]["verbose"] = true;
    m_arbiter.reset(new arbiter::Arbiter(config));

    // If this stage was parsed from a string parameter rather than JSON object
    // specification, normalize it to our URL.
    if (m_filename.size() && m_args.url.empty())
    {
        m_args.url = m_filename;
        const std::string pre("greyhound://");
        if (m_args.url.find(pre) == 0)
            m_args.url = m_args.url.substr(pre.size());
    }

    m_params = GreyhoundParams(m_args);

    log()->get(LogLevel::Debug) << "Fetching info from " << m_params.root() <<
        std::endl;

    try
    {
        m_info = parse(m_arbiter->get(m_params.root() + "info"));
    }
    catch (std::exception& e)
    {
        throw pdal_error(std::string("Failed to fetch info: ") + e.what());
    }

    if (m_info.isMember("srs") && getSpatialReference().empty())
        setSpatialReference(m_info["srs"].asString());
}
Esempio n. 22
0
void PipelineReaderJSON::readPipeline(const std::string& filename)
{
    m_inputJSONFile = filename;

    std::istream* input = Utils::openFile(filename);
    if (!input)
    {
        throw pdal_error("JSON pipeline: Unable to open stream for "
            "file \"" + filename + "\"");
    }

    try
    {
        readPipeline(*input);
    }
    catch (...)
    {
        Utils::closeFile(input);
        throw;
    }

    Utils::closeFile(input);
    m_inputJSONFile = "";
}
Esempio n. 23
0
void AttributeFilter::processOptions(const Options& options)
{
    std::vector<Option> dimensions = options.getOptions("dimension");
    for (auto i = dimensions.begin(); i != dimensions.end(); ++i)
    {
        std::string name = i->getValue<std::string>();
        boost::optional<Options const&> dimensionOptions = i->getOptions();
        if (!dimensionOptions)
        {
            std::ostringstream oss;
            oss << "No options dimension given for dimension '" <<
                name << "'";
            throw pdal_error(oss.str());
        }

        AttributeInfo info;
        info.datasource = dimensionOptions->getValueOrDefault<std::string>("datasource", "");


        // If we have no datasource, then we're simply setting a value.
        // If we have no value, throw an exception.
        if (!info.datasource.size())
        {
            info.value = dimensionOptions->getValueOrThrow<std::string>("value");
            info.isogr = false;
        } else
        {
            info.column = dimensionOptions->getValueOrDefault<std::string>("column",""); // take first column
            info.query = dimensionOptions->getValueOrDefault<std::string>("query","");
            info.layer = dimensionOptions->getValueOrDefault<std::string>("layer",""); // take first layer

        }

        m_dimensions.insert(std::make_pair(name, info));
    }
}
Esempio n. 24
0
void InPlaceReprojection::reprojectOffsets( double& offset_x,
                                            double& offset_y,
                                            double& offset_z)
{

#ifdef PDAL_HAVE_GDAL
    int ret = 0;
    
    double dummy_x(0.0);
    bool doOffsetZ = getOptions().getValueOrDefault<bool>("do_offset_z", false);
    
    double* x = doOffsetZ ? &offset_x : &dummy_x;
    ret = OCTTransform(m_transform_ptr.get(), 1, &offset_x, &offset_y, x);
    if (!ret)
    {
        std::ostringstream msg;
        msg << "Could not project offset for InPlaceReprojection::" << CPLGetLastErrorMsg() << ret;
        throw pdal_error(msg.str());
    }
#else

#endif

}
Esempio n. 25
0
void ColorizationFilter::processOptions(const Options& options)
{
    m_rasterFilename = options.getValueOrThrow<std::string>("raster");

    if (options.hasOption("dimension") && !options.hasOption("dimensions"))
        throw pdal_error("Option 'dimension' no longer supported.  Use "
            "'dimensions' instead.");

    StringList defaultDims;
    defaultDims.push_back("Red");
    defaultDims.push_back("Green");
    defaultDims.push_back("Blue");

    StringList dims =
        options.getValueOrDefault<StringList>("dimensions", defaultDims);

    uint32_t defaultBand = 1;
    for (std::string& dim : dims)
    {
        BandInfo bi = parseDim(dim, defaultBand);
        defaultBand = bi.m_band + 1;
        m_bands.push_back(bi);
    }
}
Esempio n. 26
0
    pdal::drivers::oci::Connection connect()
    {
        std::string connection  = m_options.getValueOrThrow<std::string>("connection");

        if (connection.empty())
            throw pdal_error("Oracle connection string empty! Unable to connect");

        std::string::size_type slash_pos = connection.find("/",0);
        std::string username = connection.substr(0,slash_pos);
        std::string::size_type at_pos = connection.find("@",slash_pos);

        std::string password = connection.substr(slash_pos+1, at_pos-slash_pos-1);
        std::string instance = connection.substr(at_pos+1);

        Connection con = boost::make_shared<OWConnection>(username.c_str(),password.c_str(),instance.c_str());

        if (!con->Succeeded())
        {
            throw connection_failed("Oracle connection failed");
        }

        return con;

    }
Esempio n. 27
0
void NitfWriter::doneFile()
{
    finishOutput();

    try
    {
        ::nitf::Record record(NITF_VER_21);
        ::nitf::FileHeader header = record.getHeader();
        header.getFileHeader().set("NITF");
        header.getComplianceLevel().set(m_cLevel);
        header.getSystemType().set(m_sType);
        header.getOriginStationID().set(m_oStationId);
        if (m_fileTitle.empty())
        	m_fileTitle = FileUtils::getFilename(m_nitfFilename);
        header.getFileTitle().set(m_fileTitle);
        header.getClassification().set(m_fileClass);
        header.getMessageCopyNum().set("00000");
        header.getMessageNumCopies().set("00000");
        header.getEncrypted().set("0");
        header.getBackgroundColor().setRawData(const_cast<char*>("000"), 3);
        header.getOriginatorName().set(m_origName);
        header.getOriginatorPhone().set(m_origPhone);
        header.getSecurityGroup().getClassificationSystem().set(
            m_securityClassificationSystem);
        header.getSecurityGroup().getControlAndHandling().set(
            m_securityControlAndHandling);
        header.getSecurityGroup().getClassificationText().set(m_sic);

        ::nitf::DESegment des = record.newDataExtensionSegment();

        des.getSubheader().getFilePartType().set("DE");
        des.getSubheader().getTypeID().set("LIDARA DES");
        des.getSubheader().getVersion().set("01");
        des.getSubheader().getSecurityClass().set(m_securityClass);
        ::nitf::FileSecurity security = record.getHeader().getSecurityGroup();
        des.getSubheader().setSecurityGroup(security.clone());

        ::nitf::TRE usrHdr("LIDARA DES", "raw_data");
        usrHdr.setField("raw_data", "not");
        ::nitf::Field fld = usrHdr.getField("raw_data");
        fld.setType(::nitf::Field::BINARY);

        std::streambuf *buf = m_oss.rdbuf();
        long size = buf->pubseekoff(0, m_oss.end);
        buf->pubseekoff(0, m_oss.beg);

        std::vector<char> bytes(size);
        buf->sgetn(bytes.data(), size);
        m_oss.clear();

        des.getSubheader().setSubheaderFields(usrHdr);

        ::nitf::ImageSegment image = record.newImageSegment();
        ::nitf::ImageSubheader subheader = image.getSubheader();

        BOX3D bounds =  reprojectBoxToDD(m_srs, m_bounds);

        //NITF decimal degree values for corner coordinates only has a
        // precision of 3 after the decimal. This may cause an invalid
        // polygon due to rounding errors with a small tile. Therefore
        // instead of rounding min values will use the floor value and
        // max values will use the ceiling values.
        bounds.minx = (floor(bounds.minx * 1000)) / 1000.0;
        bounds.miny = (floor(bounds.miny * 1000)) / 1000.0;
        bounds.maxx = (ceil(bounds.maxx * 1000)) / 1000.0;
        bounds.maxy = (ceil(bounds.maxy * 1000)) / 1000.0;

        double corners[4][2];
        corners[0][0] = bounds.maxy;
        corners[0][1] = bounds.minx;
        corners[1][0] = bounds.maxy;
        corners[1][1] = bounds.maxx;
        corners[2][0] = bounds.miny;
        corners[2][1] = bounds.maxx;
        corners[3][0] = bounds.miny;
        corners[3][1] = bounds.minx;
        subheader.setCornersFromLatLons(NRT_CORNERS_DECIMAL, corners);

        subheader.getImageSecurityClass().set(m_imgSecurityClass);
        subheader.setSecurityGroup(security.clone());
        if (m_imgDate.size())
            subheader.getImageDateAndTime().set(m_imgDate);

        ::nitf::BandInfo info;
        ::nitf::LookupTable lt(0,0);
        info.init(" ",    /* The band representation, Nth band */
                  " ",      /* The band subcategory */
                  "N",      /* The band filter condition */
                  "   ",    /* The band standard image filter code */
                  0,        /* The number of look-up tables */
                  0,        /* The number of entries/LUT */
                  lt);     /* The look-up tables */

        std::vector< ::nitf::BandInfo> bands;
        bands.push_back(info);
        subheader.setPixelInformation(
            "INT",      /* Pixel value type */
            8,         /* Number of bits/pixel */
            8,         /* Actual number of bits/pixel */
            "R",       /* Pixel justification */
            "NODISPLY",     /* Image representation */
            "VIS",     /* Image category */
            1,         /* Number of bands */
            bands);

        subheader.setBlocking(
            8,   /*!< The number of rows */
            8,  /*!< The number of columns */
            8, /*!< The number of rows/block */
            8,  /*!< The number of columns/block */
            "B");                /*!< Image mode */

        //Image Header fields to set
        subheader.getImageId().set("None");
        subheader.getImageTitle().set(m_imgIdentifier2);

        // 64 char string
        std::string zeros(64, '0');

        std::unique_ptr< ::nitf::BandSource> band(new ::nitf::MemorySource(
            const_cast<char*>(zeros.c_str()),
            zeros.size() /* memory size */,
            0 /* starting offset */,
            1 /* bytes per pixel */,
            0 /*skip*/));
        ::nitf::ImageSource iSource;
        iSource.addBand(*band);

        //AIMIDB
        ::nitf::TRE aimidbTre("AIMIDB");

        //LIDAR defaults
        if (m_imgDate.size())
        	aimidbTre.setField("ACQUISITION_DATE", m_imgDate);
        aimidbTre.setField("MISSION_NO", "UNKN");
        aimidbTre.setField("MISSION_IDENTIFICATION", "NOT AVAIL.");
        aimidbTre.setField("FLIGHT_NO", "00");
        aimidbTre.setField("CURRENT_SEGMENT", "AA");
        aimidbTre.setField("START_TILE_COLUMN", "001");
        aimidbTre.setField("START_TILE_ROW", "00001");
        aimidbTre.setField("END_SEGMENT", "00");
        aimidbTre.setField("END_TILE_COLUMN", "001");
        aimidbTre.setField("END_TILE_ROW", "00001");

        for (auto& s : m_aimidb)
        {
            StringList v = Utils::split2(s, ':');
            if (v.size() != 2)
            {
                std::ostringstream oss;
                oss << "Invalid name/value for AIMIDB '" << s <<
                    "'.  Format: <name>:<value>.";
                throw oss.str();
            }
            Utils::trim(v[0]);
            Utils::trim(v[1]);
            aimidbTre.setField(v[0], v[1]);
        }
        subheader.getExtendedSection().appendTRE(aimidbTre);

		//if IDATIM is empty set it equal to AIMIDB.ACQUISITION_DATE
        if(!m_imgDate.size())
        {
        	m_imgDate=aimidbTre.getField("ACQUISITION_DATE").toString();
			if (m_imgDate.size())
				subheader.getImageDateAndTime().set(m_imgDate);
        }

        //ACFTB
        ::nitf::TRE acftbTre("ACFTB");

        //LIDAR defaults
        acftbTre.setField("AC_MSN_ID", "NOT AVAILABLE");
        acftbTre.setField("SCENE_SOURCE", " ");
        if (m_imgDate.size()>7)
        	acftbTre.setField("PDATE", m_imgDate.substr(0,8));
        acftbTre.setField("MPLAN", "999");
        acftbTre.setField("LOC_ACCY", "000.00");
        acftbTre.setField("ROW_SPACING", "0000000");
        acftbTre.setField("ROW_SPACING_UNITS", "u");
        acftbTre.setField("COL_SPACING", "0000000");
        acftbTre.setField("COL_SPACING_UNITS", "u");
        acftbTre.setField("FOCAL_LENGTH", "999.99");

        for (auto& s : m_acftb)
        {
            StringList v = Utils::split2(s, ':');
            if (v.size() != 2)
            {
                std::ostringstream oss;
                oss << "Invalid name/value for ACFTB '" << s <<
                    "'.  Format: <name>:<value>.";
                throw oss.str();
            }
            Utils::trim(v[0]);
            Utils::trim(v[1]);
            acftbTre.setField(v[0], v[1]);
        }
        subheader.getExtendedSection().appendTRE(acftbTre);

        ::nitf::Writer writer;
        ::nitf::IOHandle output_io(m_nitfFilename.c_str(),
            NITF_ACCESS_WRITEONLY, NITF_CREATE);
        writer.prepare(output_io, record);

        ::nitf::SegmentWriter sWriter = writer.newDEWriter(0);

        ::nitf::SegmentMemorySource sSource(bytes.data(), size, 0, 0, false);
        sWriter.attachSource(sSource);

        ::nitf::ImageWriter iWriter = writer.newImageWriter(0);
        iWriter.attachSource(iSource);

        writer.write();
        output_io.close();
    }
    catch (except::Throwable & t)
    {
        std::ostringstream oss;
        // std::cout << t.getTrace();
        throw pdal_error(t.getMessage());
    }
}
Esempio n. 28
0
void AttributeFilter::UpdateGEOSBuffer(PointBuffer& buffer, AttributeInfo& info)
{
    QuadIndex idx(buffer);
    idx.build();

    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);

        int f_count = OGR_F_GetFieldCount (feature.get());

        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<std::size_t> ids = idx.getPoints(box);
        for (const auto& i : ids)
        {

            double x = buffer.getFieldAs<double>(Dimension::Id::X, i);
            double y = buffer.getFieldAs<double>(Dimension::Id::Y, i);
            double z = buffer.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);
                buffer.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());
    }
}
Esempio n. 29
0
boost::uint64_t Writer::write(  boost::uint64_t targetNumPointsToWrite,
                                boost::uint64_t startingPosition)
{
    if (!isInitialized())
    {
        throw pdal_error("stage not initialized");
    }

    boost::uint64_t actualNumPointsWritten = 0;

    UserCallback* callback = getUserCallback();
    do_callback(0.0, callback);

    const Schema& schema = getPrevStage().getSchema();
    
    if (m_writer_buffer == 0)
    {
        boost::uint64_t capacity(targetNumPointsToWrite);
        if (capacity == 0)
        {
            capacity = m_chunkSize;
        } else
        {
            capacity = (std::min)(static_cast<boost::uint64_t>(m_chunkSize), targetNumPointsToWrite) ;
        }
        m_writer_buffer = new PointBuffer (schema, capacity);
        
    }
    
    boost::scoped_ptr<StageSequentialIterator> iter(getPrevStage().createSequentialIterator(*m_writer_buffer));
    
    if (startingPosition)
        iter->skip(startingPosition);
        
    if (!iter) throw pdal_error("Unable to obtain iterator from previous stage!");

    // if we don't have an SRS, try to forward the one from the prev stage
    if (m_spatialReference.empty()) m_spatialReference = getPrevStage().getSpatialReference();

    writeBegin(targetNumPointsToWrite);

    iter->readBegin();



    //
    // The user has requested a specific number of points: proceed a
    // chunk at a time until we reach that number.  (If that number
    // is 0, we proceed until no more points can be read.)
    //
    // If the user requests an interrupt while we're running, we'll throw.
    //
    while (true)
    {
        // have we hit the end already?
        if (iter->atEnd()) break;

        // rebuild our PointBuffer, if it needs to hold less than the default max chunk size
        if (targetNumPointsToWrite != 0)
        {
            const boost::uint64_t numRemainingPointsToRead = targetNumPointsToWrite - actualNumPointsWritten;

            const boost::uint64_t numPointsToReadThisChunk64 = std::min<boost::uint64_t>(numRemainingPointsToRead, m_chunkSize);
            // this case is safe because m_chunkSize is a uint32
            const boost::uint32_t numPointsToReadThisChunk = static_cast<boost::uint32_t>(numPointsToReadThisChunk64);

            // we are reusing the buffer, so we may need to adjust the capacity for the last (and likely undersized) chunk
            if (m_writer_buffer->getCapacity() < numPointsToReadThisChunk)
            {
                m_writer_buffer->resize(numPointsToReadThisChunk);
            }
        }

        // read...
        iter->readBufferBegin(*m_writer_buffer);
        const boost::uint32_t numPointsReadThisChunk = iter->readBuffer(*m_writer_buffer);
        iter->readBufferEnd(*m_writer_buffer);

        assert(numPointsReadThisChunk == m_writer_buffer->getNumPoints());
        assert(numPointsReadThisChunk <= m_writer_buffer->getCapacity());

        // have we reached the end yet?
        if (numPointsReadThisChunk == 0) break;

        // write...
        writeBufferBegin(*m_writer_buffer);
        const boost::uint32_t numPointsWrittenThisChunk = writeBuffer(*m_writer_buffer);
        assert(numPointsWrittenThisChunk == numPointsReadThisChunk);
        writeBufferEnd(*m_writer_buffer);

        // update count
        actualNumPointsWritten += numPointsWrittenThisChunk;

        do_callback(actualNumPointsWritten, targetNumPointsToWrite, callback);

        if (targetNumPointsToWrite != 0)
        {
            // have we done enough yet?
            if (actualNumPointsWritten >= targetNumPointsToWrite) break;
        }

        // reset the buffer, so we can use it again
        m_writer_buffer->setNumPoints(0);
    }

    iter->readEnd();
    
    writeEnd(actualNumPointsWritten);

    assert((targetNumPointsToWrite == 0) || (actualNumPointsWritten <= targetNumPointsToWrite));

    do_callback(100.0, callback);

    
    return actualNumPointsWritten;
}
Esempio n. 30
0
void FauxReader::processOptions(const Options& options)
{
    BOX3D bounds;
    try
    {
        bounds = options.getValueOrDefault<BOX3D>("bounds",
            BOX3D(0, 0, 0, 1, 1, 1));
    }
    catch (Option::cant_convert)
    {
        std::string s = options.getValueOrDefault<std::string>("bounds");

        std::ostringstream oss;
        oss << getName() << ": Invalid 'bounds' specification: '" << s <<
            "'.  Format: '([xmin,xmax],[ymin,ymax],[zmin,zmax])'.";
        throw pdal_error(oss.str());
    }
    m_minX = bounds.minx;
    m_maxX = bounds.maxx;
    m_minY = bounds.miny;
    m_maxY = bounds.maxy;
    m_minZ = bounds.minz;
    m_maxZ = bounds.maxz;

    // For backward compatibility.
    if (m_count == 0)
        m_count = options.getValueOrThrow<point_count_t>("num_points");
    if (m_count == 0)
    {
        std::ostringstream oss;
        oss << getName() << ": Option 'count' must be non-zero.";
        throw pdal_error(oss.str());
    }

    m_mean_x = options.getValueOrDefault<double>("mean_x",0.0);
    m_mean_y = options.getValueOrDefault<double>("mean_y",0.0);
    m_mean_z = options.getValueOrDefault<double>("mean_z",0.0);
    m_stdev_x = options.getValueOrDefault<double>("stdev_x",1.0);
    m_stdev_y = options.getValueOrDefault<double>("stdev_y",1.0);
    m_stdev_z = options.getValueOrDefault<double>("stdev_z",1.0);
    m_mode = string2mode(options.getValueOrThrow<std::string>("mode"));
    m_numReturns = options.getValueOrDefault("number_of_returns", 0);
    if (m_numReturns > 10)
    {
        std::ostringstream oss;
        oss << getName() << ": Option 'number_of_returns' must be in the range "
            "[0,10].";
        throw pdal_error(oss.str());
    }
    if (m_count > 1)
    {
        m_delX = (m_maxX - m_minX) / (m_count - 1);
        m_delY = (m_maxY - m_minY) / (m_count - 1);
        m_delZ = (m_maxZ - m_minZ) / (m_count - 1);
    }
    else
    {
        m_delX = 0;
        m_delY = 0;
        m_delZ = 0;
    }
}