void ReprojectionFilter::ready(PointTableRef table) { if (m_inferInputSRS) { m_inSRS = table.spatialRef(); if (m_inSRS.getWKT().empty()) throw pdal_error("Source data has no spatial reference and none " "is specified with the 'in_srs' option."); } m_in_ref_ptr = ReferencePtr(OSRNewSpatialReference(0), OGRSpatialReferenceDeleter()); m_out_ref_ptr = ReferencePtr(OSRNewSpatialReference(0), OGRSpatialReferenceDeleter()); int result = OSRSetFromUserInput(m_in_ref_ptr.get(), m_inSRS.getWKT(pdal::SpatialReference::eCompoundOK).c_str()); if (result != OGRERR_NONE) { std::ostringstream msg; msg << "Invalid input spatial reference '" << m_inSRS.getWKT() << "'. This is usually caused by a bad value for the 'in_srs'" "option or an invalid spatial reference in the source file."; throw pdal_error(msg.str()); } result = OSRSetFromUserInput(m_out_ref_ptr.get(), m_outSRS.getWKT(pdal::SpatialReference::eCompoundOK).c_str()); if (result != OGRERR_NONE) { std::ostringstream msg; msg << "Invalid output spatial reference '" << m_outSRS.getWKT() << "'. This is usually caused by a bad value for the 'out_srs'" "option."; throw pdal_error(msg.str()); } m_transform_ptr = TransformPtr( OCTNewCoordinateTransformation(m_in_ref_ptr.get(), m_out_ref_ptr.get()), OSRTransformDeleter()); if (!m_transform_ptr.get()) { std::string msg = "Could not construct CoordinateTransformation in " "ReprojectionFilter:: "; throw std::runtime_error(msg); } setSpatialReference(m_outSRS); }
void LasWriter::ready(PointTableRef table) { const SpatialReference& srs = getSpatialReference().empty() ? table.spatialRef() : getSpatialReference(); if (!m_ostream) m_ostream = FileUtils::createFile(m_filename, true); if (!m_ostream) { std::stringstream out; out << "writers.las couldn't open file '" << m_filename << "' for output."; throw pdal_error(out.str()); } setVlrsFromMetadata(); setVlrsFromSpatialRef(srs); setExtraBytesVlr(); fillHeader(); if (m_lasHeader.compressed()) readyCompression(); // Write the header. m_ostream->seekp(m_streamOffset); OLeStream out(m_ostream); out << m_lasHeader; m_lasHeader.setVlrOffset((uint32_t)m_ostream->tellp()); for (auto vi = m_vlrs.begin(); vi != m_vlrs.end(); ++vi) { VariableLengthRecord& vlr = *vi; vlr.write(out, m_lasHeader.versionEquals(1, 0) ? 0xAABB : 0); } // Write the point data start signature for version 1.0. if (m_lasHeader.versionEquals(1, 0)) out << (uint16_t)0xCCDD; m_lasHeader.setPointOffset((uint32_t)m_ostream->tellp()); if (m_lasHeader.compressed()) openCompression(); }
void P2gWriter::done(PointTableRef table) { // If we never got any points, we're done. if (! m_coordinates.size()) return; m_GRID_SIZE_X = (int)(ceil((m_bounds.maxx - m_bounds.minx)/m_GRID_DIST_X)) + 1; m_GRID_SIZE_Y = (int)(ceil((m_bounds.maxy - m_bounds.miny)/m_GRID_DIST_Y)) + 1; log()->get(LogLevel::Debug) << "X grid size: " << m_GRID_SIZE_X << std::endl; log()->get(LogLevel::Debug) << "Y grid size: " << m_GRID_SIZE_Y << std::endl; log()->floatPrecision(6); log()->get(LogLevel::Debug) << "X grid distance: " << m_GRID_DIST_X << std::endl; log()->get(LogLevel::Debug) << "Y grid distance: " << m_GRID_DIST_Y << std::endl; log()->clearFloat(); std::unique_ptr<OutCoreInterp> p(new OutCoreInterp(m_GRID_DIST_X, m_GRID_DIST_Y, m_GRID_SIZE_X, m_GRID_SIZE_Y, m_RADIUS * m_RADIUS, m_bounds.minx, m_bounds.maxx, m_bounds.miny, m_bounds.maxy, m_fill_window_size)); m_interpolator.swap(p); if (m_interpolator->init() < 0) { throw p2g_error("unable to initialize interpolator"); } int rc(0); std::vector<boost::tuple<double, double, double> >::const_iterator i; for (i = m_coordinates.begin(); i!= m_coordinates.end(); ++i) { double x = i->get<0>(); double y = i->get<1>(); x = x - m_bounds.minx; y = y - m_bounds.miny; rc = m_interpolator->update(x, y, i->get<2>()); if (rc < 0) { throw p2g_error("interp->update() error while processing "); } } double adfGeoTransform[6]; adfGeoTransform[0] = m_bounds.minx - 0.5*m_GRID_DIST_X; adfGeoTransform[1] = m_GRID_DIST_X; adfGeoTransform[2] = 0.0; adfGeoTransform[3] = m_bounds.maxy + 0.5*m_GRID_DIST_Y; adfGeoTransform[4] = 0.0; adfGeoTransform[5] = -1 * m_GRID_DIST_Y; SpatialReference const& srs = table.spatialRef(); log()->get(LogLevel::Debug) << "Output SRS :'" << srs.getWKT() << "'" << std::endl; if ((rc = m_interpolator->finish(const_cast<char*>(m_filename.c_str()), m_outputFormat, m_outputTypes, adfGeoTransform, srs.getWKT().c_str())) < 0) { throw p2g_error("interp->finish() error"); } return; }
void NitfWriter::done(PointTableRef table) { LasWriter::done(table); 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); 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); flush(); m_oss.flush(); 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); des.getSubheader().setSubheaderFields(usrHdr); ::nitf::ImageSegment image = record.newImageSegment(); ::nitf::ImageSubheader subheader = image.getSubheader(); BOX3D bounds = reprojectBoxToDD(table.spatialRef(), 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("G", /* 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 */ "P"); /*!< 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 if (!m_aimidb.empty()) { boost::optional<const Options&> options = m_aimidb.getOptions(); if (options) { ::nitf::TRE tre("AIMIDB"); std::vector<Option> opts = options->getOptions(); for (auto i = opts.begin(); i != opts.end(); ++i) { tre.setField(i->getName(), i->getValue<std::string>()); } subheader.getExtendedSection().appendTRE(tre); } } //ACFTB if (!m_acftb.empty()) { boost::optional<const Options&> options = m_acftb.getOptions(); if (options) { ::nitf::TRE tre("ACFTB"); std::vector<Option> opts = options->getOptions(); for (auto i = opts.begin(); i != opts.end(); ++i) { tre.setField(i->getName(), i->getValue<std::string>()); } subheader.getExtendedSection().appendTRE(tre); } } ::nitf::Writer writer; ::nitf::IOHandle output_io(m_filename.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()); } }