bool process( std::string const& input, std::string const& output, liblas::Header & header, std::vector<liblas::FilterPtr>& filters, std::vector<liblas::TransformPtr>& transforms, boost::uint32_t split_mb, boost::uint32_t split_pts, bool verbose, bool min_offset) { std::ifstream ifs; if (!liblas::Open(ifs, input.c_str())) { std::cerr << "Cannot open " << input << "for read. Exiting..."; return false; } // set_ifstream_buffer(ifs, default_buffer_size); liblas::Reader reader(ifs); liblas::Summary* summary = new liblas::Summary; reader.SetFilters(filters); reader.SetTransforms(transforms); if (min_offset) { liblas::property_tree::ptree tree = reader.Summarize(); try { header.SetOffset(tree.get<double>("summary.points.minimum.x"), tree.get<double>("summary.points.minimum.y"), tree.get<double>("summary.points.minimum.z")); } catch (liblas::property_tree::ptree_bad_path const& e) { std::cerr << "Unable to write minimum header info. Does the outputted file have any points?"; std::cerr << e.what() << std::endl; return false; } if (verbose) { std::cout << "Using minimum offsets "; SetStreamPrecision(std::cout, header.GetScaleX()); std::cout << header.GetOffsetX() << " "; SetStreamPrecision(std::cout, header.GetScaleY()); std::cout << header.GetOffsetY() << " "; SetStreamPrecision(std::cout, header.GetScaleZ()); std::cout << header.GetOffsetZ() << " "; std::cout << std::endl; } reader.Reset(); } std::ofstream* ofs = new std::ofstream; std::string out = output; liblas::Writer* writer = 0; if (!split_mb && !split_pts) { writer = start_writer(ofs, output, header); } else { string::size_type dot_pos = output.find_first_of("."); out = output.substr(0, dot_pos); writer = start_writer(ofs, out+"-1"+".las", header); } if (verbose) std::cout << "Writing output:" << "\n - : " << output << std::endl; // // Translation of points cloud to features set // boost::uint32_t i = 0; boost::uint32_t const size = header.GetPointRecordsCount(); boost::int32_t split_bytes_count = 1024*1024*split_mb; boost::uint32_t split_points_count = 0; int fileno = 2; while (reader.ReadNextPoint()) { liblas::Point const& p = reader.GetPoint(); summary->AddPoint(p); writer->WritePoint(p); if (verbose) term_progress(std::cout, (i + 1) / static_cast<double>(size)); i++; split_points_count++; split_bytes_count = split_bytes_count - header.GetSchema().GetByteSize(); if (split_bytes_count < 0 && split_mb > 0 && ! split_pts) { // The user specifies a split size in mb, and we keep counting // down until we've written that many points into the file. // After that point, we make a new file and start writing into // that. delete writer; delete ofs; ofs = new std::ofstream; ostringstream oss; oss << out << "-"<< fileno <<".las"; writer = start_writer(ofs, oss.str(), header); ostringstream old_filename; old_filename << out << "-" << fileno - 1 << ".las"; liblas::Header hnew = FetchHeader(old_filename.str()); RepairHeader(*summary, hnew); RewriteHeader(hnew, old_filename.str()); delete summary; summary = new liblas::Summary; fileno++; split_bytes_count = 1024*1024*split_mb; } if (split_pts > 0 && ! split_mb && split_points_count == split_pts) { // The user specifies a split size in pts, and we keep counting // down until we've written that many points into the file. // After that point, we make a new file and start writing into // that. delete writer; delete ofs; ofs = new std::ofstream; ostringstream oss; oss << out << "-"<< fileno <<".las"; writer = start_writer(ofs, oss.str(), header); ostringstream old_filename; old_filename << out << "-" << fileno - 1 << ".las"; liblas::Header hnew = FetchHeader(old_filename.str()); RepairHeader(*summary, hnew); RewriteHeader(hnew, old_filename.str()); delete summary; summary = new liblas::Summary; fileno++; split_points_count = 0; } } if (verbose) std::cout << std::endl; reader.Reset(); // liblas::property_tree::ptree pts = summary->GetPTree(); // liblas::property_tree::ptree top; // top.add_child("summary.header",reader.GetHeader().GetPTree()); // top.add_child("summary.points",pts); // liblas::property_tree::write_xml("junk.xml", top); // liblas::property_tree::write_xml("schema.xml", reader.GetHeader().GetSchema().GetPTree()); // // std::cout << reader.GetHeader().GetSchema() << std::endl; delete writer; delete ofs; liblas::Header hnew = FetchHeader(output); RepairHeader(*summary, hnew); RewriteHeader(hnew, output); delete summary; return true; }
bool process( std::istream& ifs, std::string const& output, liblas::Header & header, std::vector<liblas::FilterPtr>& filters, std::vector<liblas::TransformPtr>& transforms, boost::uint32_t split_mb, boost::uint32_t split_pts, bool verbose, bool min_offset) { liblas::ReaderFactory f; liblas::Reader reader = f.CreateWithStream(ifs); SummaryPtr summary(new::liblas::CoordinateSummary); reader.SetFilters(filters); reader.SetTransforms(transforms); if (min_offset) { liblas::property_tree::ptree tree = SummarizeReader(reader); try { header.SetOffset(tree.get<double>("summary.points.minimum.x"), tree.get<double>("summary.points.minimum.y"), tree.get<double>("summary.points.minimum.z")); } catch (liblas::property_tree::ptree_bad_path const& e) { std::cerr << "Unable to write minimum header info. Does the outputted file have any points?"; std::cerr << e.what() << std::endl; return false; } if (verbose) { std::cout << "Using minimum offsets "; SetStreamPrecision(std::cout, header.GetScaleX()); std::cout << header.GetOffsetX() << " "; SetStreamPrecision(std::cout, header.GetScaleY()); std::cout << header.GetOffsetY() << " "; SetStreamPrecision(std::cout, header.GetScaleZ()); std::cout << header.GetOffsetZ() << " "; std::cout << std::endl; } reader.Reset(); // If we have any reprojection going on, we have to reset the offsets // of the HeaderPtr that is applied to the points as they are reprojected // or things will get screwed up when we go to re-assign the header // as we write the points with the min-offset std::vector<liblas::TransformPtr> transforms = reader.GetTransforms(); std::vector<liblas::TransformPtr> new_transforms; for (std::size_t i = 0; i < transforms.size(); i++) { liblas::TransformPtr transform = transforms[i]; if (dynamic_cast<liblas::ReprojectionTransform*>(transform.get())) { dynamic_cast<liblas::ReprojectionTransform*>(transform.get())->SetHeader(&header); } new_transforms.push_back(transform); } reader.SetTransforms(new_transforms); } std::ostream* ofs = NULL; std::string out = output; WriterPtr writer; if (!split_mb && !split_pts) { writer = start_writer(ofs, output, header); } else { string::size_type dot_pos = output.find_first_of("."); out = output.substr(0, dot_pos); writer = start_writer(ofs, out+"-1"+".las", header); } if (verbose) std::cout << "Writing output:" << "\n - : " << output << std::endl; // // Translation of points cloud to features set // boost::uint32_t i = 0; boost::uint32_t const size = header.GetPointRecordsCount(); boost::int32_t split_bytes_count = 1024*1024*split_mb; boost::uint32_t split_points_count = 0; int fileno = 2; while (reader.ReadNextPoint()) { if (min_offset) { liblas::Point p = reader.GetPoint(); summary->AddPoint(p); p.SetHeader(&header); writer->WritePoint(p); } else { liblas::Point const& p = reader.GetPoint(); summary->AddPoint(p); writer->WritePoint(p); } if (verbose) term_progress(std::cout, (i + 1) / static_cast<double>(size)); i++; split_points_count++; split_bytes_count = split_bytes_count - header.GetSchema().GetByteSize(); if (split_bytes_count < 0 && split_mb > 0 && ! split_pts) { // The user specifies a split size in mb, and we keep counting // down until we've written that many points into the file. // After that point, we make a new file and start writing into // that. // dereference the writer so it is deleted before the ofs writer = WriterPtr(); delete ofs; ofs = NULL; ostringstream oss; oss << out << "-"<< fileno <<".las"; writer = start_writer(ofs, oss.str(), header); ostringstream old_filename; old_filename << out << "-" << fileno - 1 << ".las"; liblas::Header hnew = FetchHeader(old_filename.str()); RepairHeader(*summary, hnew); RewriteHeader(hnew, old_filename.str()); summary = SummaryPtr(new liblas::CoordinateSummary); fileno++; split_bytes_count = 1024*1024*split_mb; } if (split_pts > 0 && ! split_mb && split_points_count == split_pts) { // The user specifies a split size in pts, and we keep counting // down until we've written that many points into the file. // After that point, we make a new file and start writing into // that. // dereference the writer so it is deleted before the ofs writer = WriterPtr(); delete ofs; ofs = NULL; ostringstream oss; oss << out << "-"<< fileno <<".las"; writer = start_writer(ofs, oss.str(), header); ostringstream old_filename; old_filename << out << "-" << fileno - 1 << ".las"; liblas::Header hnew = FetchHeader(old_filename.str()); RepairHeader(*summary, hnew); RewriteHeader(hnew, old_filename.str()); summary = SummaryPtr(new liblas::CoordinateSummary); fileno++; split_points_count = 0; } } if (verbose) std::cout << std::endl; // cheap hackery. We need the Writer to disappear before the stream. // Fix this up to not suck so bad. writer = WriterPtr(); delete ofs; ofs = NULL; if (!split_mb && !split_pts) { reader.Reset(); liblas::Header hnew = FetchHeader(output); RepairHeader(*summary, hnew); RewriteHeader(hnew, output); } return true; }