Ejemplo n.º 1
0
int main(int argc, char *argv[])
{
    int i;
#ifdef COMPILE_WITH_GUI
    bool gui = false;
#endif
    bool verbose = false;
    bool keep_lastiling = false;
    U32 chopchop = 0;
    bool projection_was_set = false;
    double start_time = 0;

    LASreadOpener lasreadopener;
    GeoProjectionConverter geoprojectionconverter;
    LASwriteOpener laswriteopener;

    if (argc == 1)
    {
#ifdef COMPILE_WITH_GUI
        return lasmerge_gui(argc, argv, 0);
#else
        fprintf(stderr,"%s is better run in the command line\n", argv[0]);
        char file_name[256];
        fprintf(stderr,"enter input file 1: ");
        fgets(file_name, 256, stdin);
        file_name[strlen(file_name)-1] = '\0';
        lasreadopener.add_file_name(file_name);
        fprintf(stderr,"enter input file 2: ");
        fgets(file_name, 256, stdin);
        file_name[strlen(file_name)-1] = '\0';
        lasreadopener.add_file_name(file_name);
        fprintf(stderr,"enter output file: ");
        fgets(file_name, 256, stdin);
        file_name[strlen(file_name)-1] = '\0';
        laswriteopener.set_file_name(file_name);
#endif
    }
    else
    {
        for (i = 1; i < argc; i++)
        {
            if (argv[i][0] == '–') argv[i][0] = '-';
        }
        if (!geoprojectionconverter.parse(argc, argv)) byebye(true);
        if (!lasreadopener.parse(argc, argv)) byebye(true);
        if (!laswriteopener.parse(argc, argv)) byebye(true);
    }

    for (i = 1; i < argc; i++)
    {
        if (argv[i][0] == '\0')
        {
            continue;
        }
        else if (strcmp(argv[i],"-h") == 0 || strcmp(argv[i],"-help") == 0)
        {
            fprintf(stderr, "LAStools (by [email protected]) version %d\n", LAS_TOOLS_VERSION);
            usage();
        }
        else if (strcmp(argv[i],"-v") == 0 || strcmp(argv[i],"-verbose") == 0)
        {
            verbose = true;
        }
        else if (strcmp(argv[i],"-version") == 0)
        {
            fprintf(stderr, "LAStools (by [email protected]) version %d\n", LAS_TOOLS_VERSION);
            byebye();
        }
        else if (strcmp(argv[i],"-gui") == 0)
        {
#ifdef COMPILE_WITH_GUI
            gui = true;
#else
            fprintf(stderr, "WARNING: not compiled with GUI support. ignoring '-gui' ...\n");
#endif
        }
        else if (strcmp(argv[i],"-split") == 0)
        {
            if ((i+1) >= argc)
            {
                fprintf(stderr,"ERROR: '%s' needs 1 argument: size\n", argv[i]);
                byebye(true);
            }
            i++;
            chopchop = atoi(argv[i]);
        }
        else if (strcmp(argv[i],"-keep_lastiling") == 0)
        {
            keep_lastiling = true;
        }
        else if ((argv[i][0] != '-') && (lasreadopener.get_file_name_number() == 0))
        {
            lasreadopener.add_file_name(argv[i]);
            argv[i][0] = '\0';
        }
        else
        {
            fprintf(stderr, "ERROR: cannot understand argument '%s'\n", argv[i]);
            byebye(true);
        }
    }

#ifdef COMPILE_WITH_GUI
    if (gui)
    {
        return lasmerge_gui(argc, argv, &lasreadopener);
    }
#endif

    // read all the input files merged

    lasreadopener.set_merged(TRUE);

    // maybe we want to keep the lastiling

    if (keep_lastiling)
    {
        lasreadopener.set_keep_lastiling(TRUE);
    }

    // we need to precompute the bounding box

    lasreadopener.set_populate_header(TRUE);

    // check input and output

    if (!lasreadopener.active())
    {
        fprintf(stderr, "ERROR: no input specified\n");
        byebye(true, argc==1);
    }

    if (!laswriteopener.active())
    {
        fprintf(stderr, "ERROR: no output specified\n");
        byebye(true, argc==1);
    }

    // make sure we do not corrupt the input file

    if (lasreadopener.get_file_name() && laswriteopener.get_file_name() && (strcmp(lasreadopener.get_file_name(), laswriteopener.get_file_name()) == 0))
    {
        fprintf(stderr, "ERROR: input and output file name are identical\n");
        usage(true);
    }

    // check if projection info was set in the command line

    int number_of_keys;
    GeoProjectionGeoKeys* geo_keys = 0;
    int num_geo_double_params;
    double* geo_double_params = 0;

    if (geoprojectionconverter.has_projection())
    {
        projection_was_set = geoprojectionconverter.get_geo_keys_from_projection(number_of_keys, &geo_keys, num_geo_double_params, &geo_double_params);
    }

    if (verbose) start_time = taketime();

    LASreader* lasreader = lasreadopener.open();
    if (lasreader == 0)
    {
        fprintf(stderr, "ERROR: could not open lasreader\n");
        byebye(true, argc==1);
    }

#ifdef _WIN32
    if (verbose) {
        fprintf(stderr,"merging headers took %g sec. there are %I64d points in total.\n", taketime()-start_time, lasreader->npoints);
        start_time = taketime();
    }
#else
    if (verbose) {
        fprintf(stderr,"merging headers took %g sec. there are %lld points in total.\n", taketime()-start_time, lasreader->npoints);
        start_time = taketime();
    }
#endif

    // prepare the header for the surviving points

    strncpy(lasreader->header.system_identifier, "LAStools (c) by rapidlasso GmbH", 32);
    lasreader->header.system_identifier[31] = '\0';
    char temp[64];
    sprintf(temp, "lasmerge (version %d)", LAS_TOOLS_VERSION);
    strncpy(lasreader->header.generating_software, temp, 32);
    lasreader->header.generating_software[31] = '\0';

    if (projection_was_set)
    {
        lasreader->header.set_geo_keys(number_of_keys, (LASvlr_key_entry*)geo_keys);
        free(geo_keys);
        if (geo_double_params)
        {
            lasreader->header.set_geo_double_params(num_geo_double_params, geo_double_params);
            free(geo_double_params);
        }
        else
        {
            lasreader->header.del_geo_double_params();
        }
        lasreader->header.del_geo_ascii_params();
    }

    if (chopchop)
    {
        I32 file_number = 0;
        LASwriter* laswriter = 0;
        // loop over the points
        while (lasreader->read_point())
        {
            if (laswriter == 0)
            {
                // open the next writer
                laswriteopener.make_file_name(0, file_number);
                file_number++;
                laswriter = laswriteopener.open(&lasreader->header);
            }
            laswriter->write_point(&lasreader->point);
            laswriter->update_inventory(&lasreader->point);
            if (laswriter->p_count == chopchop)
            {
                // close the current writer
                laswriter->update_header(&lasreader->header, TRUE);
                laswriter->close();
                if (verbose) {
                    fprintf(stderr,"splitting file '%s' took %g sec.\n", laswriteopener.get_file_name(), taketime()-start_time);
                    start_time = taketime();
                }
                delete laswriter;
                laswriter = 0;
            }
        }
        if (laswriter && laswriter->p_count)
        {
            // close the current writer
            laswriter->update_header(&lasreader->header, TRUE);
            laswriter->close();
            if (verbose) {
                fprintf(stderr,"splitting file '%s' took %g sec.\n", laswriteopener.get_file_name(), taketime()-start_time);
                start_time = taketime();
            }
            delete laswriter;
            laswriter = 0;
        }
    }
    else
    {
        // open the writer
        LASwriter* laswriter = laswriteopener.open(&lasreader->header);
        if (laswriter == 0)
        {
            fprintf(stderr, "ERROR: could not open laswriter\n");
            byebye(true, argc==1);
        }
        // loop over the points
        while (lasreader->read_point())
        {
            laswriter->write_point(&lasreader->point);
            laswriter->update_inventory(&lasreader->point);
        }
        // close the writer
        laswriter->update_header(&lasreader->header, TRUE);
        laswriter->close();
        if (verbose) fprintf(stderr,"merging files took %g sec.\n", taketime()-start_time);
        delete laswriter;
    }

    lasreader->close();
    delete lasreader;

    byebye(false, argc==1);

    return 0;
}
Ejemplo n.º 2
0
int main(int argc, char *argv[])
{
  MPI_Init(&argc, &argv);
  int i;
#ifdef COMPILE_WITH_GUI
  bool gui = false;
#endif
  bool verbose = false;
  bool keep_lastiling = false;
  U32 chopchop = 0;
  bool projection_was_set = false;
  double start_time = 0;

  LASreadOpener lasreadopener;
  GeoProjectionConverter geoprojectionconverter;
  LASwriteOpener laswriteopener;

  if (argc == 1)
  {
#ifdef COMPILE_WITH_GUI
    return lasmerge_gui(argc, argv, 0);
#else
    fprintf(stderr,"%s is better run in the command line\n", argv[0]);
    char file_name[256];
    fprintf(stderr,"enter input file 1: "); fgets(file_name, 256, stdin);
    file_name[strlen(file_name)-1] = '\0';
    lasreadopener.add_file_name(file_name);
    fprintf(stderr,"enter input file 2: "); fgets(file_name, 256, stdin);
    file_name[strlen(file_name)-1] = '\0';
    lasreadopener.add_file_name(file_name);
    fprintf(stderr,"enter output file: "); fgets(file_name, 256, stdin);
    file_name[strlen(file_name)-1] = '\0';
    laswriteopener.set_file_name(file_name);
#endif
  }
  else
  {
    for (i = 1; i < argc; i++)
    {
      if (argv[i][0] == '�') argv[i][0] = '-';
    }


    if (!geoprojectionconverter.parse(argc, argv)) byebye(true);
    if (!lasreadopener.parse(argc, argv)) byebye(true);
    if (lasreadopener.get_file_name_number()<2)
    {
      fprintf(stderr,"Must specify more than one input file.\n");
      byebye(true); // only support merging more than one file
    }
    if (!laswriteopener.parse(argc, argv)) byebye(true);
  }

  for (i = 1; i < argc; i++)
  {
    if (argv[i][0] == '\0')
    {
      continue;
    }
    else if (strcmp(argv[i],"-h") == 0 || strcmp(argv[i],"-help") == 0)
    {
      fprintf(stderr, "LAStools (by [email protected]) version %d\n", LAS_TOOLS_VERSION);
      usage();
    }
    else if (strcmp(argv[i],"-v") == 0 || strcmp(argv[i],"-verbose") == 0)
    {
      verbose = true;
    }
    else if (strcmp(argv[i],"-version") == 0)
    {
      fprintf(stderr, "LAStools (by [email protected]) version %d\n", LAS_TOOLS_VERSION);
      byebye();
    }
    else if (strcmp(argv[i],"-gui") == 0)
    {
#ifdef COMPILE_WITH_GUI
      gui = true;
#else
      fprintf(stderr, "WARNING: not compiled with GUI support. ignoring '-gui' ...\n");
#endif
    }
    else if (strcmp(argv[i],"-split") == 0)
    {
      if ((i+1) >= argc)
      {
        fprintf(stderr,"ERROR: '%s' needs 1 argument: size\n", argv[i]);
        byebye(true);
      }
      i++;
      chopchop = atoi(argv[i]);
    }
    else if (strcmp(argv[i],"-keep_lastiling") == 0)
    {
      keep_lastiling = true;
    }
    else if ((argv[i][0] != '-') && (lasreadopener.get_file_name_number() == 0))
    {
      lasreadopener.add_file_name(argv[i]);
      argv[i][0] = '\0';
    }
    else
    {
      fprintf(stderr, "ERROR: cannot understand argument '%s'\n", argv[i]);
      byebye(true);
    }
  }

#ifdef COMPILE_WITH_GUI
  if (gui)
  {
    return lasmerge_gui(argc, argv, &lasreadopener);
  }
#endif

  // read all the input files merged

  lasreadopener.set_merged(TRUE);

  // maybe we want to keep the lastiling 

  if (keep_lastiling)
  {
    lasreadopener.set_keep_lastiling(TRUE);
  }

  // we need to precompute the bounding box

  lasreadopener.set_populate_header(TRUE);

  // check input and output

  if (!lasreadopener.active())
  {
    fprintf(stderr, "ERROR: no input specified\n");
    byebye(true, argc==1);
  }

  if (!laswriteopener.active())
  {
    fprintf(stderr, "ERROR: no output specified\n");
    byebye(true, argc==1);
  }

  // make sure we do not corrupt the input file

  if (lasreadopener.get_file_name() && laswriteopener.get_file_name() && (strcmp(lasreadopener.get_file_name(), laswriteopener.get_file_name()) == 0))
  {
    fprintf(stderr, "ERROR: input and output file name are identical\n");
    usage(true);
  }

  // check if projection info was set in the command line

  int number_of_keys;
  GeoProjectionGeoKeys* geo_keys = 0;
  int num_geo_double_params;
  double* geo_double_params = 0;

  if (geoprojectionconverter.has_projection())
  {
    projection_was_set = geoprojectionconverter.get_geo_keys_from_projection(number_of_keys, &geo_keys, num_geo_double_params, &geo_double_params);
  }

  if (verbose) start_time = taketime();

  LASreader* lasreader = lasreadopener.open();
  lasreader->populate_rank_points();
  LASreaderMerged *lasreadermerged = (LASreaderMerged *)lasreader;
  I32 process_count = lasreadermerged->get_process_count();

  dbg(3, "rank %i, lasreadermerged->npoints %lli", lasreadermerged->get_rank(), lasreadermerged->npoints);
  for (i=0; i<process_count; i++)
  {
    dbg(3, "rank %i, rank_begin_point %lli", lasreadermerged->get_rank(), lasreadermerged->get_rank_begin_index()[i]);
    for(int j=lasreadermerged->get_file_name_start(); j< lasreadermerged->get_file_name_number(); j++)
    {
      dbg(3, "rank %i, number %i name %s count %lli, begin", lasreadermerged->get_rank(), j, lasreadermerged->get_file_names()[j], lasreadermerged->get_file_point_counts()[j]);
    }


  }
  dbg(3,"type of reader returned: class %s and declared name %s", typeid(*lasreader).name(), quote(*lasreader));


  if (lasreader == 0)
  {
    fprintf(stderr, "ERROR: could not open lasreader\n");
    byebye(true, argc==1);
  }

#ifdef _WIN32
  if (verbose) { fprintf(stderr,"merging headers took %g sec. there are %I64d points in total.\n", taketime()-start_time, lasreader->npoints); start_time = taketime(); }
#else
  if (verbose) { fprintf(stderr,"merging headers took %g sec. there are %lld points in total.\n", taketime()-start_time, lasreader->npoints); start_time = taketime(); }
#endif

  // prepare the header for the surviving points

  strncpy(lasreader->header.system_identifier, "LAStools (c) by rapidlasso GmbH", 32);
  lasreader->header.system_identifier[31] = '\0';
  char temp[64];
  sprintf(temp, "lasmerge (version %d)", LAS_TOOLS_VERSION);
  strncpy(lasreader->header.generating_software, temp, 32);
  lasreader->header.generating_software[31] = '\0';

  if (projection_was_set)
  {
    lasreader->header.set_geo_keys(number_of_keys, (LASvlr_key_entry*)geo_keys);
    free(geo_keys);
    if (geo_double_params)
    {
      lasreader->header.set_geo_double_params(num_geo_double_params, geo_double_params);
      free(geo_double_params);
    }
    else
    {
      lasreader->header.del_geo_double_params();
    }
    lasreader->header.del_geo_ascii_params();
  }

  if (chopchop)
  {
    I32 file_number = 0;
    LASwriter* laswriter = 0;
    // loop over the points
    while (lasreader->read_point())
    {
      if (laswriter == 0)
      {
        // open the next writer
        laswriteopener.make_file_name(0, file_number);
        file_number++;
        laswriter = laswriteopener.open(&lasreader->header);
      }
      laswriter->write_point(&lasreader->point);
      laswriter->update_inventory(&lasreader->point);
      if (laswriter->p_count == chopchop)
      {
        // close the current writer
        laswriter->update_header(&lasreader->header, TRUE);
        laswriter->close();
        if (verbose) { fprintf(stderr,"splitting file '%s' took %g sec.\n", laswriteopener.get_file_name(), taketime()-start_time); start_time = taketime(); }
        delete laswriter;
        laswriter = 0;
      }
    }
    if (laswriter && laswriter->p_count)
    {
      // close the current writer
      laswriter->update_header(&lasreader->header, TRUE);
      laswriter->close();
      if (verbose) { fprintf(stderr,"splitting file '%s' took %g sec.\n", laswriteopener.get_file_name(), taketime()-start_time); start_time = taketime(); }
      delete laswriter;
      laswriter = 0;
    }
  }
  else
  {
    // wait for all processes to open their input files
    MPI_Barrier(MPI_COMM_WORLD);

    // all processes open a writer
    LASwriter* laswriter = laswriteopener.open (&lasreader->header);

    // set the write file pointer... no filter support, assumes all input file's points are written to output file
    //ByteStreamOutFileLE *bs = (ByteStreamOutFileLE*) laswriter->get_stream ();  <-- this is the ByteStreamOut type for las files
    ByteStreamOut *bs = laswriter->get_stream ();

    I64 begin_index = (lasreadermerged->get_rank_begin_index())[lasreadermerged->get_rank ()];

    bs->seek (lasreader->header.point_data_record_length * begin_index + lasreader->header.offset_to_point_data);

    if (laswriter == 0)
    {
      fprintf (stderr, "ERROR: could not open laswriter\n");
      byebye (true, argc == 1);
    }

    // wait for all processes to open the output file and set their write file pointers.
    MPI_Barrier(MPI_COMM_WORLD);
    // loop over the points
    while (lasreader->read_point())
    {
      laswriter->write_point(&lasreader->point);
      laswriter->update_inventory(&lasreader->point);
    }

    int rank = lasreadermerged->get_rank();
    if(rank!=0)
    {
      laswriter->close(FALSE);
    }

    MPI_Barrier(MPI_COMM_WORLD); // not needed since reduce causes barrier, used for testing
    // this whole MPI_Reduce section is not technically needed since we don't yet support point filtering,
    // It was implemented now to ensure that it will work when point filtering of input files is supported
    MPI_Reduce(&(laswriter->inventory.extended_number_of_point_records), &extended_number_of_point_records, 1,
               MPI_LONG_LONG_INT,  MPI_SUM, 0, MPI_COMM_WORLD);
    int i;
    for(i=0; i<16; i++)
    {
      MPI_Reduce(&(laswriter->inventory.extended_number_of_points_by_return[i]), &extended_number_of_points_by_return[i], 1,
                     MPI_LONG_LONG_INT,  MPI_SUM, 0, MPI_COMM_WORLD);
    }
    MPI_Reduce(&(laswriter->inventory.max_X), &max_X, 1, MPI_INT,  MPI_MAX, 0, MPI_COMM_WORLD);
    MPI_Reduce(&(laswriter->inventory.min_X), &min_X, 1, MPI_INT,  MPI_MIN, 0, MPI_COMM_WORLD);
    MPI_Reduce(&(laswriter->inventory.max_Y), &max_Y, 1, MPI_INT,  MPI_MAX, 0, MPI_COMM_WORLD);
    MPI_Reduce(&(laswriter->inventory.min_Y), &min_Y, 1, MPI_INT,  MPI_MIN, 0, MPI_COMM_WORLD);
    MPI_Reduce(&(laswriter->inventory.max_Z), &max_Z, 1, MPI_INT,  MPI_MAX, 0, MPI_COMM_WORLD);
    MPI_Reduce(&(laswriter->inventory.min_Z), &min_Z, 1, MPI_INT,  MPI_MIN, 0, MPI_COMM_WORLD);

    if(rank==0)
    {
      dbg(3, "extended_number_of_point_records %lli", extended_number_of_point_records);
      laswriter->inventory.extended_number_of_point_records = extended_number_of_point_records;
      for(i=0; i<16; i++)
      {
        laswriter->inventory.extended_number_of_points_by_return[i] = extended_number_of_points_by_return[i];
      }
      laswriter->inventory.max_X = max_X;
      laswriter->inventory.min_X = min_X;
      laswriter->inventory.max_Y = max_Y;
      laswriter->inventory.min_Y = min_Y;
      laswriter->inventory.max_Z = max_Z;
      laswriter->inventory.min_Z = min_Z;
    }

    dbg(3, "rank %i, point data record length %i", lasreadermerged->get_rank(), lasreader->header.point_data_record_length);

    // close the writer
    if(rank==0)
    {
      // update header should only be called with TRUE when using the MPI_Reduce calls above,
      // lasreadopener.open(), called above, generates a correct header for the output file, provided no points are filtered during the read
      laswriter->update_header(&lasreader->header, TRUE);
      laswriter->close(FALSE);
    }

    if (verbose) fprintf(stderr,"merging files took %g sec.\n", taketime()-start_time); 
    delete laswriter;
  }
  MPI_Finalize();
  lasreader->close();
  delete lasreader;

  byebye(false, argc==1);

  return 0;
}