Пример #1
0
BOOL LASreaderBuffered::open()
{
  if (!lasreadopener.active())
  {
    fprintf(stderr, "ERROR: no input name\n");
    return FALSE;
  }

  // open the main file

  lasreader = lasreadopener.open();
  if (lasreader == 0)
  {
    fprintf(stderr, "ERROR: opening '%s'\n", lasreadopener.get_file_name());
    return FALSE;
  }

  // populate the merged header
  header = lasreader->header;

  // zero the pointers of the other header so they don't get deallocated twice
  lasreader->header.user_data_in_header = 0;
  lasreader->header.vlrs = 0;
  lasreader->header.laszip = 0;
  lasreader->header.vlr_lastiling = 0;
  lasreader->header.vlr_lasoriginal = 0;
  lasreader->header.user_data_after_header = 0;

  // special check for extra attributes
  if (header.number_extra_attributes)
  {
    header.number_extra_attributes = 0;
    header.init_extra_attributes(lasreader->header.number_extra_attributes, lasreader->header.extra_attributes);
  }

  // initialize the point with the header info

  if (header.laszip)
  {
    if (!point.init(&header, header.laszip->num_items, header.laszip->items)) return FALSE;
  }
  else
  {
    if (!point.init(&header, header.point_data_format, header.point_data_record_length)) return FALSE;
  }

  // maybe we have to look for neighbors from which we load buffer points

  if (lasreadopener_neighbors.active())
  {
    F64 xyz;

    lasreadopener_neighbors.set_inside_rectangle(header.min_x - buffer_size, header.min_y - buffer_size, header.max_x + buffer_size, header.max_y + buffer_size);

    // store current counts and bounding box in LASbufferVLR

    header.set_lasoriginal();

    while (lasreadopener_neighbors.active())
    {
      LASreader* lasreader_neighbor = lasreadopener_neighbors.open();
      if (lasreader_neighbor == 0)
      {
        fprintf(stderr, "ERROR: opening neighbor '%s'\n", lasreadopener_neighbors.get_file_name());
        return FALSE;
      }

      // a point type change could be problematic
      if (header.point_data_format != lasreader_neighbor->header.point_data_format)
      {
        if (!point_type_change) fprintf(stderr, "WARNING: files have different point types: %d vs %d\n", header.point_data_format, lasreader_neighbor->header.point_data_format);
        point_type_change = TRUE;
      }
      // a point size change could be problematic
      if (header.point_data_record_length != lasreader_neighbor->header.point_data_record_length)
      {
        if (!point_size_change) fprintf(stderr, "WARNING: files have different point sizes: %d vs %d\n", header.point_data_record_length, lasreader_neighbor->header.point_data_record_length);
        point_size_change = TRUE;
      }

      while (lasreader_neighbor->read_point())
      {
        // copy
        point = lasreader_neighbor->point;
        // copy_point_to_buffer
        copy_point_to_buffer();
        // increment number of points by return
        if (point.number_of_returns_of_given_pulse == 1)
        {
          header.number_of_points_by_return[0]++;
        }
        else if (point.number_of_returns_of_given_pulse == 2)
        {
          header.number_of_points_by_return[1]++;
        }
        else if (point.number_of_returns_of_given_pulse == 3)
        {
          header.number_of_points_by_return[2]++;
        }
        else if (point.number_of_returns_of_given_pulse == 4)
        {
          header.number_of_points_by_return[3]++;
        }
        else if (point.number_of_returns_of_given_pulse == 5)
        {
          header.number_of_points_by_return[4]++;
        }
        // grow bounding box
        xyz = point.get_x();
        if (header.min_x > xyz) header.min_x = xyz;
        else if (header.max_x < xyz) header.max_x = xyz;
        xyz = point.get_y();
        if (header.min_y > xyz) header.min_y = xyz;
        else if (header.max_y < xyz) header.max_y = xyz;
        xyz = point.get_z();
        if (header.min_z > xyz) header.min_z = xyz;
        else if (header.max_z < xyz) header.max_z = xyz;
      }
      lasreader_neighbor->close();
      delete lasreader_neighbor;
    }

    header.number_of_point_records += buffered_points;

    fprintf(stderr, "LASreaderBuffered: adding %u buffer points.\n", buffered_points);
  }

  // check if the header can support the enlarged bounding box

  // check x

  if ((((header.max_x - header.x_offset) / header.x_scale_factor) > I32_MAX) || (((header.min_x - header.x_offset) / header.x_scale_factor) < I32_MIN))
  {
    // maybe we can fix it by adjusting the offset (and if needed by lowering the resolution via the scale factor)
    F64 x_offset = (F64)I64_QUANTIZE((header.min_x + header.max_x)/2);
    F64 x_scale_factor = header.x_scale_factor;
    while ((((header.max_x - x_offset) / x_scale_factor) > I32_MAX) || (((header.min_x - x_offset) / x_scale_factor) < I32_MIN))
    {
      x_scale_factor *= 10;
    }
    if (header.x_scale_factor != x_scale_factor)
    {
      fprintf(stderr, "WARNING: i changed x_scale_factor from %g to %g to accommodate enlarged bounding box\n", header.x_scale_factor, x_scale_factor);
      header.x_scale_factor = x_scale_factor;
      rescale = TRUE;
    }
    // maybe we changed the resolution ... so do we really need to adjuste the offset
    if ((((header.max_x - header.x_offset) / x_scale_factor) > I32_MAX) || (((header.min_x - header.x_offset) / x_scale_factor) < I32_MIN))
    {
      fprintf(stderr, "WARNING: i changed x_offset from %g to %g to accommodate enlarged bounding box\n", header.x_offset, x_offset);
      header.x_offset = x_offset;
      reoffset = TRUE;
    }
  }
    
  // check y

  if ((((header.max_y - header.y_offset) / header.y_scale_factor) > I32_MAX) || (((header.min_y - header.y_offset) / header.y_scale_factor) < I32_MIN))
  {
    // maybe we can fix it by adjusting the offset (and if needed by lowering the resolution via the scale factor)
    F64 y_offset = (F64)I64_QUANTIZE((header.min_y + header.max_y)/2);
    F64 y_scale_factor = header.y_scale_factor;
    while ((((header.max_y - y_offset) / y_scale_factor) > I32_MAX) || (((header.min_y - y_offset) / y_scale_factor) < I32_MIN))
    {
      y_scale_factor *= 10;
    }
    if (header.y_scale_factor != y_scale_factor)
    {
      fprintf(stderr, "WARNING: i changed y_scale_factor from %g to %g to accommodate enlarged bounding box\n", header.y_scale_factor, y_scale_factor);
      header.y_scale_factor = y_scale_factor;
      rescale = TRUE;
    }
    // maybe we changed the resolution ... so do we really need to adjuste the offset
    if ((((header.max_y - header.y_offset) / y_scale_factor) > I32_MAX) || (((header.min_y - header.y_offset) / y_scale_factor) < I32_MIN))
    {
      fprintf(stderr, "WARNING: i changed y_offset from %g to %g to accommodate enlarged bounding box\n", header.y_offset, y_offset);
      header.y_offset = y_offset;
      reoffset = TRUE;
    }
  }
    
  // check z

  if ((((header.max_z - header.z_offset) / header.z_scale_factor) > I32_MAX) || (((header.min_z - header.z_offset) / header.z_scale_factor) < I32_MIN))
  {
    // maybe we can fix it by adjusting the offset (and if needed by lowering the resolution via the scale factor)
    F64 z_offset = (F64)I64_QUANTIZE((header.min_z + header.max_z)/2);
    F64 z_scale_factor = header.z_scale_factor;
    while ((((header.max_z - z_offset) / z_scale_factor) > I32_MAX) || (((header.min_z - z_offset) / z_scale_factor) < I32_MIN))
    {
      z_scale_factor *= 10;
    }
    if (header.z_scale_factor != z_scale_factor)
    {
      fprintf(stderr, "WARNING: i changed  z_scale_factor from %g to %g to accommodate enlarged bounding box\n", header.z_scale_factor, z_scale_factor);
      header.z_scale_factor = z_scale_factor;
      rescale = TRUE;
    }
    // maybe we changed the resolution ... so do we really need to adjuste the offset
    if ((((header.max_z - header.z_offset) / z_scale_factor) > I32_MAX) || (((header.min_z - header.z_offset) / z_scale_factor) < I32_MIN))
    {
      fprintf(stderr, "WARNING: i changed z_offset from %g to %g to accommodate enlarged bounding box\n", header.z_offset, z_offset);
      header.z_offset = z_offset;
      reoffset = TRUE;
    }
  }

  npoints = header.number_of_point_records;
  p_count = 0;

  return TRUE;
}
Пример #2
0
BOOL LASreaderMerged::open()
{
  if (file_name_number == 0)
  {
    fprintf(stderr, "ERROR: no valid file names\n");
    return FALSE;
  }

  // allocate space for the individual bounding_boxes
  if (bounding_boxes) delete [] bounding_boxes;
  bounding_boxes = new F64[file_name_number*4];

  // clean  header
  header.clean();

  // combine all headers

  U32 i;
  for (i = 0; i < file_name_number; i++)
  {
    // open the lasreader with the next file name
    if (lasreaderlas)
    {
      if (!lasreaderlas->open(file_names[i]))
      {
        fprintf(stderr, "ERROR: could not open lasreaderlas for file '%s'\n", file_names[i]);
        return FALSE;
      }
    }
    else if (lasreaderbin)
    {
      if (!lasreaderbin->open(file_names[i]))
      {
        fprintf(stderr, "ERROR: could not open lasreaderbin for file '%s'\n", file_names[i]);
        return FALSE;
      }
    }
    else if (lasreadershp)
    {
      if (!lasreadershp->open(file_names[i]))
      {
        fprintf(stderr, "ERROR: could not open lasreadershp for file '%s'\n", file_names[i]);
        return FALSE;
      }
    }
    else if (lasreaderqfit)
    {
      if (!lasreaderqfit->open(file_names[i]))
      {
        fprintf(stderr, "ERROR: could not open lasreaderqfit for file '%s'\n", file_names[i]);
        return FALSE;
      }
    }
    else if (lasreaderasc)
    {
      if (!lasreaderasc->open(file_names[i]))
      {
        fprintf(stderr, "ERROR: could not open lasreaderasc for file '%s'\n", file_names[i]);
        return FALSE;
      }
    }
    else if (lasreaderbil)
    {
      if (!lasreaderbil->open(file_names[i]))
      {
        fprintf(stderr, "ERROR: could not open lasreaderbil for file '%s'\n", file_names[i]);
        return FALSE;
      }
    }
    else
    {
      lasreadertxt->set_translate_intensity(translate_intensity);
      lasreadertxt->set_scale_intensity(scale_intensity);
      lasreadertxt->set_translate_scan_angle(translate_scan_angle);
      lasreadertxt->set_scale_scan_angle(scale_scan_angle);
      lasreadertxt->set_scale_factor(scale_factor);
      lasreadertxt->set_offset(offset);
      if (!lasreadertxt->open(file_names[i], parse_string, skip_lines, populate_header))
      {
        fprintf(stderr, "ERROR: could not open lasreadertxt for file '%s'\n", file_names[i]);
        return FALSE;
      }
    }
    // record individual bounding box info
    bounding_boxes[4*i+0] = lasreader->header.min_x;
    bounding_boxes[4*i+1] = lasreader->header.min_y;
    bounding_boxes[4*i+2] = lasreader->header.max_x;
    bounding_boxes[4*i+3] = lasreader->header.max_y;
    // populate the merged header
    if (i == 0)
    {
      // delete lastiling (meaningless)
      lasreader->header.clean_lastiling();
      // use the header info from the first file
      header = lasreader->header;
      // zero the pointers of the other header so they don't get deallocated twice
      lasreader->header.user_data_in_header = 0;
      lasreader->header.vlrs = 0;
      lasreader->header.laszip = 0;
      lasreader->header.vlr_lastiling = 0;
      lasreader->header.vlr_lasoriginal = 0;
      lasreader->header.user_data_after_header = 0;
      // count the points up to 64 bits
      npoints = header.number_of_point_records;
      // special check for extra attributes
      if (header.number_extra_attributes)
      {
        header.number_extra_attributes = 0;
        header.init_extra_attributes(lasreader->header.number_extra_attributes, lasreader->header.extra_attributes);
      }
    }
    else
    {
      // count the points up to 64 bits
      npoints += lasreader->header.number_of_point_records;
      // but increment point counters and widen the bounding box
      header.number_of_point_records += lasreader->header.number_of_point_records;
      header.number_of_points_by_return[0] += lasreader->header.number_of_points_by_return[0];
      header.number_of_points_by_return[1] += lasreader->header.number_of_points_by_return[1];
      header.number_of_points_by_return[2] += lasreader->header.number_of_points_by_return[2];
      header.number_of_points_by_return[3] += lasreader->header.number_of_points_by_return[3];
      header.number_of_points_by_return[4] += lasreader->header.number_of_points_by_return[4];
      if (header.max_x < lasreader->header.max_x) header.max_x = lasreader->header.max_x;
      if (header.max_y < lasreader->header.max_y) header.max_y = lasreader->header.max_y;
      if (header.max_z < lasreader->header.max_z) header.max_z = lasreader->header.max_z;
      if (header.min_x > lasreader->header.min_x) header.min_x = lasreader->header.min_x;
      if (header.min_y > lasreader->header.min_y) header.min_y = lasreader->header.min_y;
      if (header.min_z > lasreader->header.min_z) header.min_z = lasreader->header.min_z;
      // a point type change could be problematic
      if (header.point_data_format != lasreader->header.point_data_format)
      {
        if (!point_type_change) fprintf(stderr, "WARNING: files have different point types: %d vs %d\n", header.point_data_format, lasreader->header.point_data_format);
        point_type_change = TRUE;
      }
      // a point size change could be problematic
      if (header.point_data_record_length != lasreader->header.point_data_record_length)
      {
        if (!point_size_change) fprintf(stderr, "WARNING: files have different point sizes: %d vs %d\n", header.point_data_record_length, lasreader->header.point_data_record_length);
        point_size_change = TRUE;
      }
      // and check if we need to resample points because scalefactor of offsets change
      if (header.x_scale_factor != lasreader->header.x_scale_factor ||
          header.y_scale_factor != lasreader->header.y_scale_factor ||
          header.z_scale_factor != lasreader->header.z_scale_factor)
      {
//        if (!rescale) fprintf(stderr, "WARNING: files have different scale factors: %g %g %g vs %g %g %g\n", header.x_scale_factor, header.y_scale_factor, header.z_scale_factor, lasreader->header.x_scale_factor, lasreader->header.y_scale_factor, lasreader->header.z_scale_factor);
        rescale = TRUE;
      }
      if (header.x_offset != lasreader->header.x_offset ||
          header.y_offset != lasreader->header.y_offset ||
          header.z_offset != lasreader->header.z_offset)
      {
//        if (!reoffset) fprintf(stderr, "WARNING: files have different offsets: %g %g %g vs %g %g %g\n", header.x_offset, header.y_offset, header.z_offset, lasreader->header.x_offset, lasreader->header.y_offset, lasreader->header.z_offset);
        reoffset = TRUE;
      }
    }
    lasreader->close();
  }

  // was it requested to rescale or reoffset

  if (scale_factor)
  {
    if (scale_factor[0] && (header.x_scale_factor != scale_factor[0]))
    {
      header.x_scale_factor = scale_factor[0];
      rescale = TRUE;
    }
    if (scale_factor[1] && (header.y_scale_factor != scale_factor[1]))
    {
      header.y_scale_factor = scale_factor[1];
      rescale = TRUE;
    }
    if (scale_factor[2] && (header.z_scale_factor != scale_factor[2]))
    {
      header.z_scale_factor = scale_factor[2];
      rescale = TRUE;
    }
  }
  if (offset)
  {
    if (header.x_offset != offset[0])
    {
      header.x_offset = offset[0];
      reoffset = TRUE;
    }
    if (header.y_offset != offset[1])
    {
      header.y_offset = offset[1];
      reoffset = TRUE;
    }
    if (header.z_offset != offset[2])
    {
      header.z_offset = offset[2];
      reoffset = TRUE;
    }
  }

  // initialize the point with the header info

  if (header.laszip)
  {
    if (!point.init(&header, header.laszip->num_items, header.laszip->items)) return FALSE;
  }
  else
  {
    if (!point.init(&header, header.point_data_format, header.point_data_record_length)) return FALSE;
  }

  // check if the header can support the enlarged bounding box

  // check x

  if ((((header.max_x - header.x_offset) / header.x_scale_factor) > I32_MAX) || (((header.min_x - header.x_offset) / header.x_scale_factor) < I32_MIN))
  {
    // maybe we can fix it by adjusting the offset (and if needed by lowering the resolution via the scale factor)
    F64 x_offset = (F64)I64_QUANTIZE((header.min_x + header.max_x)/2);
    F64 x_scale_factor = header.x_scale_factor;
    while ((((header.max_x - x_offset) / x_scale_factor) > I32_MAX) || (((header.min_x - x_offset) / x_scale_factor) < I32_MIN))
    {
      x_scale_factor *= 10;
    }
    if (header.x_scale_factor != x_scale_factor)
    {
      fprintf(stderr, "WARNING: i changed x_scale_factor from %g to %g to accommodate enlarged bounding box\n", header.x_scale_factor, x_scale_factor);
      header.x_scale_factor = x_scale_factor;
      rescale = TRUE;
    }
    // maybe we changed the resolution ... so do we really need to adjuste the offset
    if ((((header.max_x - header.x_offset) / x_scale_factor) > I32_MAX) || (((header.min_x - header.x_offset) / x_scale_factor) < I32_MIN))
    {
      fprintf(stderr, "WARNING: i changed x_offset from %g to %g to accommodate enlarged bounding box\n", header.x_offset, x_offset);
      header.x_offset = x_offset;
      reoffset = TRUE;
    }
  }
    
  // check y

  if ((((header.max_y - header.y_offset) / header.y_scale_factor) > I32_MAX) || (((header.min_y - header.y_offset) / header.y_scale_factor) < I32_MIN))
  {
    // maybe we can fix it by adjusting the offset (and if needed by lowering the resolution via the scale factor)
    F64 y_offset = (F64)I64_QUANTIZE((header.min_y + header.max_y)/2);
    F64 y_scale_factor = header.y_scale_factor;
    while ((((header.max_y - y_offset) / y_scale_factor) > I32_MAX) || (((header.min_y - y_offset) / y_scale_factor) < I32_MIN))
    {
      y_scale_factor *= 10;
    }
    if (header.y_scale_factor != y_scale_factor)
    {
      fprintf(stderr, "WARNING: i changed y_scale_factor from %g to %g to accommodate enlarged bounding box\n", header.y_scale_factor, y_scale_factor);
      header.y_scale_factor = y_scale_factor;
      rescale = TRUE;
    }
    // maybe we changed the resolution ... so do we really need to adjuste the offset
    if ((((header.max_y - header.y_offset) / y_scale_factor) > I32_MAX) || (((header.min_y - header.y_offset) / y_scale_factor) < I32_MIN))
    {
      fprintf(stderr, "WARNING: i changed y_offset from %g to %g to accommodate enlarged bounding box\n", header.y_offset, y_offset);
      header.y_offset = y_offset;
      reoffset = TRUE;
    }
  }
    
  // check z

  if ((((header.max_z - header.z_offset) / header.z_scale_factor) > I32_MAX) || (((header.min_z - header.z_offset) / header.z_scale_factor) < I32_MIN))
  {
    // maybe we can fix it by adjusting the offset (and if needed by lowering the resolution via the scale factor)
    F64 z_offset = (F64)I64_QUANTIZE((header.min_z + header.max_z)/2);
    F64 z_scale_factor = header.z_scale_factor;
    while ((((header.max_z - z_offset) / z_scale_factor) > I32_MAX) || (((header.min_z - z_offset) / z_scale_factor) < I32_MIN))
    {
      z_scale_factor *= 10;
    }
    if (header.z_scale_factor != z_scale_factor)
    {
      fprintf(stderr, "WARNING: i changed  z_scale_factor from %g to %g to accommodate enlarged bounding box\n", header.z_scale_factor, z_scale_factor);
      header.z_scale_factor = z_scale_factor;
      rescale = TRUE;
    }
    // maybe we changed the resolution ... so do we really need to adjuste the offset
    if ((((header.max_z - header.z_offset) / z_scale_factor) > I32_MAX) || (((header.min_z - header.z_offset) / z_scale_factor) < I32_MIN))
    {
      fprintf(stderr, "WARNING: i changed z_offset from %g to %g to accommodate enlarged bounding box\n", header.z_offset, z_offset);
      header.z_offset = z_offset;
      reoffset = TRUE;
    }
  }

  if (rescale || reoffset)
  {
    if (lasreaderlas)
    {
      delete lasreaderlas;
      if (rescale && reoffset)
        lasreaderlas = new LASreaderLASrescalereoffset(header.x_scale_factor, header.y_scale_factor, header.z_scale_factor, header.x_offset, header.y_offset, header.z_offset);
      else if (rescale)
        lasreaderlas = new LASreaderLASrescale(header.x_scale_factor, header.y_scale_factor, header.z_scale_factor);
      else
        lasreaderlas = new LASreaderLASreoffset(header.x_offset, header.y_offset, header.z_offset);
      lasreader = lasreaderlas;
    }
    else if (lasreaderbin)
    {
      delete lasreaderbin;
      if (rescale && reoffset)
        lasreaderbin = new LASreaderBINrescalereoffset(header.x_scale_factor, header.y_scale_factor, header.z_scale_factor, header.x_offset, header.y_offset, header.z_offset);
      else if (rescale)
        lasreaderbin = new LASreaderBINrescale(header.x_scale_factor, header.y_scale_factor, header.z_scale_factor);
      else
        lasreaderbin = new LASreaderBINreoffset(header.x_offset, header.y_offset, header.z_offset);
      lasreader = lasreaderbin;
    }
    else if (lasreadershp)
    {
      delete lasreadershp;
      if (rescale && reoffset)
        lasreadershp = new LASreaderSHPrescalereoffset(header.x_scale_factor, header.y_scale_factor, header.z_scale_factor, header.x_offset, header.y_offset, header.z_offset);
      else if (rescale)
        lasreadershp = new LASreaderSHPrescale(header.x_scale_factor, header.y_scale_factor, header.z_scale_factor);
      else
        lasreadershp = new LASreaderSHPreoffset(header.x_offset, header.y_offset, header.z_offset);
      lasreader = lasreadershp;
    }
    else if (lasreaderqfit)
    {
      delete lasreaderqfit;
      if (rescale && reoffset)
        lasreaderqfit = new LASreaderQFITrescalereoffset(header.x_scale_factor, header.y_scale_factor, header.z_scale_factor, header.x_offset, header.y_offset, header.z_offset);
      else if (rescale)
        lasreaderqfit = new LASreaderQFITrescale(header.x_scale_factor, header.y_scale_factor, header.z_scale_factor);
      else
        lasreaderqfit = new LASreaderQFITreoffset(header.x_offset, header.y_offset, header.z_offset);
      lasreader = lasreaderqfit;
    }
    else if (lasreaderasc)
    {
      delete lasreaderasc;
      if (rescale && reoffset)
        lasreaderasc = new LASreaderASCrescalereoffset(header.x_scale_factor, header.y_scale_factor, header.z_scale_factor, header.x_offset, header.y_offset, header.z_offset);
      else if (rescale)
        lasreaderasc = new LASreaderASCrescale(header.x_scale_factor, header.y_scale_factor, header.z_scale_factor);
      else
        lasreaderasc = new LASreaderASCreoffset(header.x_offset, header.y_offset, header.z_offset);
      lasreader = lasreaderasc;
    }
    else if (lasreaderbil)
    {
      delete lasreaderbil;
      if (rescale && reoffset)
        lasreaderbil = new LASreaderBILrescalereoffset(header.x_scale_factor, header.y_scale_factor, header.z_scale_factor, header.x_offset, header.y_offset, header.z_offset);
      else if (rescale)
        lasreaderbil = new LASreaderBILrescale(header.x_scale_factor, header.y_scale_factor, header.z_scale_factor);
      else
        lasreaderbil = new LASreaderBILreoffset(header.x_offset, header.y_offset, header.z_offset);
      lasreader = lasreaderbil;
    }
    else
    {
      delete lasreadertxt;
      if (rescale && reoffset)
        lasreadertxt = new LASreaderTXTrescalereoffset(header.x_scale_factor, header.y_scale_factor, header.z_scale_factor, header.x_offset, header.y_offset, header.z_offset);
      else if (rescale)
        lasreadertxt = new LASreaderTXTrescale(header.x_scale_factor, header.y_scale_factor, header.z_scale_factor);
      else
        lasreadertxt = new LASreaderTXTreoffset(header.x_offset, header.y_offset, header.z_offset);
      lasreadertxt->set_translate_intensity(translate_intensity);
      lasreadertxt->set_scale_intensity(scale_intensity);
      lasreadertxt->set_translate_scan_angle(translate_scan_angle);
      lasreadertxt->set_scale_scan_angle(scale_scan_angle);
      lasreadertxt->set_scale_factor(scale_factor);
      lasreadertxt->set_offset(offset);
      lasreader = lasreadertxt;
    }
  }

  p_count = 0;
  file_name_current = 0;

  return TRUE;
}
Пример #3
0
BOOL LASreaderMerged::open()
{
  // mpi
  MPI_Comm_size(MPI_COMM_WORLD, &process_count);
  MPI_Comm_rank(MPI_COMM_WORLD,&rank);

  if (file_name_number == 0)
  {
    fprintf(stderr, "ERROR: no valid file names\n");
    return FALSE;
  }

  // allocate space for the individual bounding_boxes
  if (bounding_boxes) delete [] bounding_boxes;
  bounding_boxes = new F64[file_name_number*4];

  // clean  header
  header.clean();

  // combine all headers

  U32 i,j;
  BOOL first = TRUE;
  // mpi, allocate storage
  file_point_counts = (I64*)malloc(sizeof(I64)*file_name_number);

  for (i = 0; i < file_name_number; i++)
  {
    // open the lasreader with the next file name
    if (lasreaderlas)
    {
      if (!lasreaderlas->open(file_names[i], 512, (first == FALSE))) // starting from second just "peek" into file to get bounding box and count
      {
        fprintf(stderr, "ERROR: could not open lasreaderlas for file '%s'\n", file_names[i]);
        return FALSE;
      }
    }
    else if (lasreaderbin)
    {
      if (!lasreaderbin->open(file_names[i]))
      {
        fprintf(stderr, "ERROR: could not open lasreaderbin for file '%s'\n", file_names[i]);
        return FALSE;
      }
    }
    else if (lasreadershp)
    {
      if (!lasreadershp->open(file_names[i]))
      {
        fprintf(stderr, "ERROR: could not open lasreadershp for file '%s'\n", file_names[i]);
        return FALSE;
      }
    }
    else if (lasreaderqfit)
    {
      if (!lasreaderqfit->open(file_names[i]))
      {
        fprintf(stderr, "ERROR: could not open lasreaderqfit for file '%s'\n", file_names[i]);
        return FALSE;
      }
    }
    else if (lasreaderasc)
    {
      if (!lasreaderasc->open(file_names[i]))
      {
        fprintf(stderr, "ERROR: could not open lasreaderasc for file '%s'\n", file_names[i]);
        return FALSE;
      }
    }
    else if (lasreaderbil)
    {
      if (!lasreaderbil->open(file_names[i]))
      {
        fprintf(stderr, "ERROR: could not open lasreaderbil for file '%s'\n", file_names[i]);
        return FALSE;
      }
    }
    else if (lasreaderdtm)
    {
      if (!lasreaderdtm->open(file_names[i]))
      {
        fprintf(stderr, "ERROR: could not open lasreaderdtm for file '%s'\n", file_names[i]);
        return FALSE;
      }
    }
    else
    {
      lasreadertxt->set_translate_intensity(translate_intensity);
      lasreadertxt->set_scale_intensity(scale_intensity);
      lasreadertxt->set_translate_scan_angle(translate_scan_angle);
      lasreadertxt->set_scale_scan_angle(scale_scan_angle);
      lasreadertxt->set_scale_factor(scale_factor);
      lasreadertxt->set_offset(offset);
      if (!lasreadertxt->open(file_names[i], parse_string, skip_lines, populate_header))
      {
        fprintf(stderr, "ERROR: could not open lasreadertxt for file '%s'\n", file_names[i]);
        return FALSE;
      }
    }
    // mpi, store the point count for this file
    file_point_counts[i] = lasreader->npoints;
    // ignore bounding box if the file has no points
    if (lasreader->npoints == 0)
    {
      // record ignoring bounding box info
      bounding_boxes[4*i+0] = F64_MAX;
      bounding_boxes[4*i+1] = F64_MAX;
      bounding_boxes[4*i+2] = F64_MIN;
      bounding_boxes[4*i+3] = F64_MIN;
    }
    else
    {
      // record individual bounding box info
      bounding_boxes[4*i+0] = lasreader->header.min_x;
      bounding_boxes[4*i+1] = lasreader->header.min_y;
      bounding_boxes[4*i+2] = lasreader->header.max_x;
      bounding_boxes[4*i+3] = lasreader->header.max_y;
    }
    // populate the merged header
    if (first)
    {
      first = FALSE;
      // check for lastiling buffer
      if (lasreader->header.vlr_lastiling)
      {
        if (lasreader->header.vlr_lastiling->buffer)
        {
          fprintf(stderr, "WARNING: first file is a buffered tile. maybe remove buffers first?\n");
        }
      }
      // maybe we should keep the tiling
      if (keep_lastiling)
      {
        if (lasreader->header.vlr_lastiling == 0)
        {
          fprintf(stderr, "WARNING: first file has no LAStiling VLR cannot '-keep_lastiling' ...\n");
        }
      }
      else
      {
        // usually we delete the lastiling information as it becomes meaningless
        lasreader->header.clean_lastiling();
      }
      // use the entire header info from the first file
      header = lasreader->header;
      // unlink the pointers for other header so they don't get deallocated twice
      lasreader->header.unlink();
      // count the points up to 64 bits
      npoints = lasreader->npoints;
      // special check for attributes in extra bytes
      if (header.number_attributes)
      {
        header.number_attributes = 0;
        header.init_attributes(lasreader->header.number_attributes, lasreader->header.attributes);
      }
      // when merging multiple flightlines the merged header must have a file source ID of 0
      if (files_are_flightlines || apply_file_source_ID)
      {
        header.file_source_ID = 0;
      }      
    }
    else if (lasreader->npoints)
    {
      // count the points up to 64 bits
      npoints += lasreader->npoints;
      // have there not been any points before
      if (npoints == lasreader->npoints)
      {
        // use the counters 
        header.number_of_point_records = lasreader->header.number_of_point_records;
        for (j = 0; j < 5; j++)
        {
          header.number_of_points_by_return[j] = lasreader->header.number_of_points_by_return[j];
        }
        // and use the bounding box
        header.max_x = lasreader->header.max_x;
        header.max_y = lasreader->header.max_y;
        header.max_z = lasreader->header.max_z;
        header.min_x = lasreader->header.min_x;
        header.min_y = lasreader->header.min_y;
        header.min_z = lasreader->header.min_z;
        // as well as scale factor and offset
        header.x_scale_factor = lasreader->header.x_scale_factor;
        header.y_scale_factor = lasreader->header.y_scale_factor;
        header.z_scale_factor = lasreader->header.z_scale_factor;
        header.x_offset = lasreader->header.x_offset;
        header.y_offset = lasreader->header.y_offset;
        header.z_offset = lasreader->header.z_offset;
        // for LAS 1.4
        if (header.version_minor >= 4)
        {
          header.extended_number_of_point_records = (lasreader->header.extended_number_of_point_records ? lasreader->header.extended_number_of_point_records : lasreader->header.number_of_point_records);
          for (j = 0; j < 15; j++)
          {
            header.extended_number_of_points_by_return[j] = lasreader->header.extended_number_of_points_by_return[j];
          }
        }
      }
      else
      {
        // increment point counters 
        header.number_of_point_records += lasreader->header.number_of_point_records;
        for (j = 0; j < 5; j++)
        {
          header.number_of_points_by_return[j] += lasreader->header.number_of_points_by_return[j];
        }
        // widen the bounding box
        if (header.max_x < lasreader->header.max_x) header.max_x = lasreader->header.max_x;
        if (header.max_y < lasreader->header.max_y) header.max_y = lasreader->header.max_y;
        if (header.max_z < lasreader->header.max_z) header.max_z = lasreader->header.max_z;
        if (header.min_x > lasreader->header.min_x) header.min_x = lasreader->header.min_x;
        if (header.min_y > lasreader->header.min_y) header.min_y = lasreader->header.min_y;
        if (header.min_z > lasreader->header.min_z) header.min_z = lasreader->header.min_z;
        // for LAS 1.4
        if (header.version_minor >= 4)
        {
          header.extended_number_of_point_records += (lasreader->header.extended_number_of_point_records ? lasreader->header.extended_number_of_point_records : lasreader->header.number_of_point_records);
          for (j = 0; j < 15; j++)
          {
            header.extended_number_of_points_by_return[j] += lasreader->header.extended_number_of_points_by_return[j];
          }
        }
      }
      // a point type change could be problematic
      if (header.point_data_format != lasreader->header.point_data_format)
      {
        if (!point_type_change) fprintf(stderr, "WARNING: files have different point types: %d vs %d\n", header.point_data_format, lasreader->header.point_data_format);
        point_type_change = TRUE;
      }
      // a point size change could be problematic
      if (header.point_data_record_length != lasreader->header.point_data_record_length)
      {
        if (!point_size_change) fprintf(stderr, "WARNING: files have different point sizes: %d vs %d\n", header.point_data_record_length, lasreader->header.point_data_record_length);
        point_size_change = TRUE;
      }
      // and check if we need to resample points because scalefactor of offsets change
      if (header.x_scale_factor != lasreader->header.x_scale_factor ||
          header.y_scale_factor != lasreader->header.y_scale_factor ||
          header.z_scale_factor != lasreader->header.z_scale_factor)
      {
//        if (!rescale) fprintf(stderr, "WARNING: files have different scale factors: %g %g %g vs %g %g %g\n", header.x_scale_factor, header.y_scale_factor, header.z_scale_factor, lasreader->header.x_scale_factor, lasreader->header.y_scale_factor, lasreader->header.z_scale_factor);
        rescale = TRUE;
      }
      if (header.x_offset != lasreader->header.x_offset ||
          header.y_offset != lasreader->header.y_offset ||
          header.z_offset != lasreader->header.z_offset)
      {
//        if (!reoffset) fprintf(stderr, "WARNING: files have different offsets: %g %g %g vs %g %g %g\n", header.x_offset, header.y_offset, header.z_offset, lasreader->header.x_offset, lasreader->header.y_offset, lasreader->header.z_offset);
        reoffset = TRUE;
      }
    }
    lasreader->close();
  }

  // was it requested to rescale or reoffset

  if (scale_factor)
  {
    if (scale_factor[0] && (header.x_scale_factor != scale_factor[0]))
    {
      header.x_scale_factor = scale_factor[0];
      rescale = TRUE;
    }
    if (scale_factor[1] && (header.y_scale_factor != scale_factor[1]))
    {
      header.y_scale_factor = scale_factor[1];
      rescale = TRUE;
    }
    if (scale_factor[2] && (header.z_scale_factor != scale_factor[2]))
    {
      header.z_scale_factor = scale_factor[2];
      rescale = TRUE;
    }
  }
  if (offset)
  {
    if (header.x_offset != offset[0])
    {
      header.x_offset = offset[0];
      reoffset = TRUE;
    }
    if (header.y_offset != offset[1])
    {
      header.y_offset = offset[1];
      reoffset = TRUE;
    }
    if (header.z_offset != offset[2])
    {
      header.z_offset = offset[2];
      reoffset = TRUE;
    }
  }

  // initialize the point with the header info

  if (header.laszip)
  {
    if (!point.init(&header, header.laszip->num_items, header.laszip->items)) return FALSE;
  }
  else
  {
    if (!point.init(&header, header.point_data_format, header.point_data_record_length)) return FALSE;
  }

  // check if the header can support the enlarged bounding box

  // check x

  if ((((header.max_x - header.x_offset) / header.x_scale_factor) > I32_MAX) || (((header.min_x - header.x_offset) / header.x_scale_factor) < I32_MIN))
  {
    // maybe we can fix it by adjusting the offset (and if needed by lowering the resolution via the scale factor)
    F64 x_offset = (F64)I64_QUANTIZE((header.min_x + header.max_x)/2);
    F64 x_scale_factor = header.x_scale_factor;
    while ((((header.max_x - x_offset) / x_scale_factor) > I32_MAX) || (((header.min_x - x_offset) / x_scale_factor) < I32_MIN))
    {
      x_scale_factor *= 10;
    }
    if (header.x_scale_factor != x_scale_factor)
    {
      fprintf(stderr, "WARNING: i changed x_scale_factor from %g to %g to accommodate enlarged bounding box\n", header.x_scale_factor, x_scale_factor);
      header.x_scale_factor = x_scale_factor;
      rescale = TRUE;
    }
    // maybe we changed the resolution ... so do we really need to adjuste the offset
    if ((((header.max_x - header.x_offset) / x_scale_factor) > I32_MAX) || (((header.min_x - header.x_offset) / x_scale_factor) < I32_MIN))
    {
      fprintf(stderr, "WARNING: i changed x_offset from %g to %g to accommodate enlarged bounding box\n", header.x_offset, x_offset);
      header.x_offset = x_offset;
      reoffset = TRUE;
    }
  }
    
  // check y

  if ((((header.max_y - header.y_offset) / header.y_scale_factor) > I32_MAX) || (((header.min_y - header.y_offset) / header.y_scale_factor) < I32_MIN))
  {
    // maybe we can fix it by adjusting the offset (and if needed by lowering the resolution via the scale factor)
    F64 y_offset = (F64)I64_QUANTIZE((header.min_y + header.max_y)/2);
    F64 y_scale_factor = header.y_scale_factor;
    while ((((header.max_y - y_offset) / y_scale_factor) > I32_MAX) || (((header.min_y - y_offset) / y_scale_factor) < I32_MIN))
    {
      y_scale_factor *= 10;
    }
    if (header.y_scale_factor != y_scale_factor)
    {
      fprintf(stderr, "WARNING: i changed y_scale_factor from %g to %g to accommodate enlarged bounding box\n", header.y_scale_factor, y_scale_factor);
      header.y_scale_factor = y_scale_factor;
      rescale = TRUE;
    }
    // maybe we changed the resolution ... so do we really need to adjuste the offset
    if ((((header.max_y - header.y_offset) / y_scale_factor) > I32_MAX) || (((header.min_y - header.y_offset) / y_scale_factor) < I32_MIN))
    {
      fprintf(stderr, "WARNING: i changed y_offset from %g to %g to accommodate enlarged bounding box\n", header.y_offset, y_offset);
      header.y_offset = y_offset;
      reoffset = TRUE;
    }
  }
    
  // check z

  if ((((header.max_z - header.z_offset) / header.z_scale_factor) > I32_MAX) || (((header.min_z - header.z_offset) / header.z_scale_factor) < I32_MIN))
  {
    // maybe we can fix it by adjusting the offset (and if needed by lowering the resolution via the scale factor)
    F64 z_offset = (F64)I64_QUANTIZE((header.min_z + header.max_z)/2);
    F64 z_scale_factor = header.z_scale_factor;
    while ((((header.max_z - z_offset) / z_scale_factor) > I32_MAX) || (((header.min_z - z_offset) / z_scale_factor) < I32_MIN))
    {
      z_scale_factor *= 10;
    }
    if (header.z_scale_factor != z_scale_factor)
    {
      fprintf(stderr, "WARNING: i changed  z_scale_factor from %g to %g to accommodate enlarged bounding box\n", header.z_scale_factor, z_scale_factor);
      header.z_scale_factor = z_scale_factor;
      rescale = TRUE;
    }
    // maybe we changed the resolution ... so do we really need to adjuste the offset
    if ((((header.max_z - header.z_offset) / z_scale_factor) > I32_MAX) || (((header.min_z - header.z_offset) / z_scale_factor) < I32_MIN))
    {
      fprintf(stderr, "WARNING: i changed z_offset from %g to %g to accommodate enlarged bounding box\n", header.z_offset, z_offset);
      header.z_offset = z_offset;
      reoffset = TRUE;
    }
  }

  if (rescale || reoffset)
  {
    if (lasreaderlas)
    {
      delete lasreaderlas;
      if (rescale && reoffset)
        lasreaderlas = new LASreaderLASrescalereoffset(header.x_scale_factor, header.y_scale_factor, header.z_scale_factor, header.x_offset, header.y_offset, header.z_offset);
      else if (rescale)
        lasreaderlas = new LASreaderLASrescale(header.x_scale_factor, header.y_scale_factor, header.z_scale_factor);
      else
        lasreaderlas = new LASreaderLASreoffset(header.x_offset, header.y_offset, header.z_offset);
      lasreader = lasreaderlas;
    }
    else if (lasreaderbin)
    {
      delete lasreaderbin;
      if (rescale && reoffset)
        lasreaderbin = new LASreaderBINrescalereoffset(header.x_scale_factor, header.y_scale_factor, header.z_scale_factor, header.x_offset, header.y_offset, header.z_offset);
      else if (rescale)
        lasreaderbin = new LASreaderBINrescale(header.x_scale_factor, header.y_scale_factor, header.z_scale_factor);
      else
        lasreaderbin = new LASreaderBINreoffset(header.x_offset, header.y_offset, header.z_offset);
      lasreader = lasreaderbin;
    }
    else if (lasreadershp)
    {
      delete lasreadershp;
      if (rescale && reoffset)
        lasreadershp = new LASreaderSHPrescalereoffset(header.x_scale_factor, header.y_scale_factor, header.z_scale_factor, header.x_offset, header.y_offset, header.z_offset);
      else if (rescale)
        lasreadershp = new LASreaderSHPrescale(header.x_scale_factor, header.y_scale_factor, header.z_scale_factor);
      else
        lasreadershp = new LASreaderSHPreoffset(header.x_offset, header.y_offset, header.z_offset);
      lasreader = lasreadershp;
    }
    else if (lasreaderqfit)
    {
      delete lasreaderqfit;
      if (rescale && reoffset)
        lasreaderqfit = new LASreaderQFITrescalereoffset(header.x_scale_factor, header.y_scale_factor, header.z_scale_factor, header.x_offset, header.y_offset, header.z_offset);
      else if (rescale)
        lasreaderqfit = new LASreaderQFITrescale(header.x_scale_factor, header.y_scale_factor, header.z_scale_factor);
      else
        lasreaderqfit = new LASreaderQFITreoffset(header.x_offset, header.y_offset, header.z_offset);
      lasreader = lasreaderqfit;
    }
    else if (lasreaderasc)
    {
      delete lasreaderasc;
      if (rescale && reoffset)
        lasreaderasc = new LASreaderASCrescalereoffset(header.x_scale_factor, header.y_scale_factor, header.z_scale_factor, header.x_offset, header.y_offset, header.z_offset);
      else if (rescale)
        lasreaderasc = new LASreaderASCrescale(header.x_scale_factor, header.y_scale_factor, header.z_scale_factor);
      else
        lasreaderasc = new LASreaderASCreoffset(header.x_offset, header.y_offset, header.z_offset);
      lasreader = lasreaderasc;
    }
    else if (lasreaderbil)
    {
      delete lasreaderbil;
      if (rescale && reoffset)
        lasreaderbil = new LASreaderBILrescalereoffset(header.x_scale_factor, header.y_scale_factor, header.z_scale_factor, header.x_offset, header.y_offset, header.z_offset);
      else if (rescale)
        lasreaderbil = new LASreaderBILrescale(header.x_scale_factor, header.y_scale_factor, header.z_scale_factor);
      else
        lasreaderbil = new LASreaderBILreoffset(header.x_offset, header.y_offset, header.z_offset);
      lasreader = lasreaderbil;
    }
    else if (lasreaderdtm)
    {
      delete lasreaderdtm;
      if (rescale && reoffset)
        lasreaderdtm = new LASreaderDTMrescalereoffset(header.x_scale_factor, header.y_scale_factor, header.z_scale_factor, header.x_offset, header.y_offset, header.z_offset);
      else if (rescale)
        lasreaderdtm = new LASreaderDTMrescale(header.x_scale_factor, header.y_scale_factor, header.z_scale_factor);
      else
        lasreaderdtm = new LASreaderDTMreoffset(header.x_offset, header.y_offset, header.z_offset);
      lasreader = lasreaderdtm;
    }
    else
    {
      delete lasreadertxt;
      if (rescale && reoffset)
        lasreadertxt = new LASreaderTXTrescalereoffset(header.x_scale_factor, header.y_scale_factor, header.z_scale_factor, header.x_offset, header.y_offset, header.z_offset);
      else if (rescale)
        lasreadertxt = new LASreaderTXTrescale(header.x_scale_factor, header.y_scale_factor, header.z_scale_factor);
      else
        lasreadertxt = new LASreaderTXTreoffset(header.x_offset, header.y_offset, header.z_offset);
      lasreadertxt->set_translate_intensity(translate_intensity);
      lasreadertxt->set_scale_intensity(scale_intensity);
      lasreadertxt->set_translate_scan_angle(translate_scan_angle);
      lasreadertxt->set_scale_scan_angle(scale_scan_angle);
      lasreadertxt->set_scale_factor(scale_factor);
      lasreadertxt->set_offset(offset);
      lasreader = lasreadertxt;
    }
  }

  p_count = 0;
  file_name_current = 0;

  return TRUE;
}