00001 #include <megatree/common.h>
00002 #include <megatree/megatree.h>
00003 #include <megatree/storage_factory.h>
00004 #include <megatree/tree_functions.h>
00005
00006 #include <unistd.h>
00007 #include <iostream>
00008 #include <argp.h>
00009
00010 #include <liblas/liblas.hpp>
00011 #include <fstream>
00012 #include <iostream>
00013
00014 using namespace megatree;
00015
00016 static unsigned long total_points = 0;
00017 static Tictoc overall_timer;
00018
00019 void importLas(MegaTree &tree, const boost::filesystem::path &path, unsigned long max_intensity, unsigned int *skip = NULL)
00020 {
00021 printf("Loading las file: %s\n", path.string().c_str());
00022 std::ifstream fin;
00023 fin.open(path.string().c_str(), std::ios::in | std::ios::binary);
00024
00025 liblas::ReaderFactory f;
00026 liblas::Reader reader = f.CreateWithStream(fin);
00027
00028 liblas::Header const& header = reader.GetHeader();
00029 std::cout << "Compressed: " << ((header.Compressed() == true) ? "true":"false") << "\n";
00030 std::cout << "Signature: " << header.GetFileSignature() << '\n';
00031 std::cout << "Points count: " << header.GetPointRecordsCount() << '\n';
00032
00033 if (skip && *skip >= header.GetPointRecordsCount())
00034 {
00035 *skip -= header.GetPointRecordsCount();
00036 return;
00037 }
00038
00039
00040
00041
00042 if (tree.getNumPoints() == 0)
00043 {
00044 printf("Recentering tree to (%lf, %lf, %lf)\n", header.GetMinX(), header.GetMinY(), header.GetMinZ());
00045 tree.recenter(header.GetMinX(), header.GetMinY(), header.GetMinZ());
00046 }
00047
00048
00049
00050 bool has_color = false;
00051
00052
00053 unsigned i = 0;
00054 std::vector<double> point(3, 0.0);
00055 std::vector<double> color(3, 0.0);
00056 while (reader.ReadNextPoint())
00057 {
00058 const liblas::Point& p = reader.GetPoint();
00059 point[0] = p.GetX();
00060 point[1] = p.GetY();
00061 point[2] = p.GetZ();
00062 if (has_color) {
00063 color[0] = p.GetColor().GetRed();
00064 color[1] = p.GetColor().GetGreen();
00065 color[2] = p.GetColor().GetBlue();
00066 }
00067 else {
00068
00069
00070 double scaled_color = std::min((double)max_intensity, 255.0 * double(p.GetIntensity()) / max_intensity);
00071 color[0] = color[1] = color[2] = scaled_color;
00072
00073
00074 }
00075
00076 if (i % 100000 == 0) {
00077
00078 printf("%8.1f %s\n", overall_timer.toc(), tree.toString().c_str());
00079 tree.resetCount();
00080 }
00081 addPoint(tree, point, color);
00082
00083 ++total_points;
00084
00085
00086
00087
00088
00089
00090
00091
00092 ++i;
00093 }
00094 printf("%s\n", tree.toString().c_str());
00095 tree.resetCount();
00096 }
00097
00098
00099 struct arguments_t {
00100 int cache_size;
00101 char* tree;
00102 unsigned int skip;
00103 unsigned long max_intensity;
00104 std::vector<std::string> las_filenames;
00105 };
00106
00107
00108 static int parse_opt(int key, char *arg, struct argp_state *state)
00109 {
00110 struct arguments_t *arguments = (arguments_t*)state->input;
00111
00112 switch (key)
00113 {
00114 case 'c':
00115
00116 arguments->cache_size = parseNumberSuffixed(arg);
00117 break;
00118 case 't':
00119 arguments->tree = arg;
00120 break;
00121 case 's':
00122 arguments->skip = (unsigned int)parseNumberSuffixed(arg);
00123 break;
00124 case 'i':
00125 arguments->max_intensity = atol(arg);
00126 break;
00127 case ARGP_KEY_ARG:
00128 arguments->las_filenames.push_back(arg);
00129 break;
00130 }
00131 return 0;
00132 }
00133
00134
00135 int main (int argc, char** argv)
00136 {
00137
00138 struct arguments_t arguments;
00139 arguments.cache_size = 3000000;
00140 arguments.max_intensity = 255;
00141 arguments.skip = 0;
00142 arguments.tree = 0;
00143
00144
00145 struct argp_option options[] = {
00146 {"cache-size", 'c', "SIZE", 0, "Cache size"},
00147 {"tree", 't', "TREE", 0, "Path to tree"},
00148 {"skip", 's', "SKIP", 0, "Number of points to skip"},
00149 {"max-intensity", 'i', "INTENSITY", 0, "Maximum intensity value"},
00150 { 0 }
00151 };
00152 struct argp argp = { options, parse_opt };
00153 int parse_ok = argp_parse(&argp, argc, argv, 0, 0, &arguments);
00154 printf("Arguments parsed: %d\n", parse_ok);
00155 printf("Cache size: %d\n", arguments.cache_size);
00156 printf("Tree: %s\n", arguments.tree);
00157 if (arguments.skip > 0)
00158 printf("Skipping %u points\n", arguments.skip);
00159 assert(parse_ok == 0);
00160
00161 if (!arguments.tree) {
00162 fprintf(stderr, "No tree path given.\n");
00163 return 1;
00164 }
00165
00166 boost::shared_ptr<Storage> storage(openStorage(arguments.tree));
00167 MegaTree tree(storage, arguments.cache_size, false);
00168
00169 overall_timer.tic();
00170
00171 Tictoc timer;
00172 for (size_t i = 0; i < arguments.las_filenames.size(); ++i)
00173 {
00174 boost::filesystem::path las_path(arguments.las_filenames[i]);
00175 printf("Importing %s into tree\n", las_path.string().c_str());
00176
00177 Tictoc one_file_timer;
00178 importLas(tree, las_path, arguments.max_intensity, &arguments.skip);
00179 float t = one_file_timer.toc();
00180 printf("Flushing %s...\n", las_path.string().c_str());
00181 tree.flushCache();
00182 printf("Finished %s in %.3lf seconds (%.1lf min or %.1lf hours)\n",
00183 las_path.string().c_str(), t, t/60.0f, t/3600.0f);
00184 }
00185
00186 printf("Flushing the cache\n");
00187 tree.flushCache();
00188
00189 float t = timer.toc();
00190 unsigned long num_points = tree.getNumPoints();
00191 printf("Importing all files took %.3f seconds for %lu points ==> %.3f sec/million\n", t, num_points, t / num_points * 1e6);
00192
00193 printf("Finished.\n");
00194 return 0;
00195 }