5 votos

¿Cuál es el formato de almacenamiento binario simple de ráster que puede leer ArcGIS?

Tengo un programa en C++ que manipula modelos digitales de elevación rasterizados.

He estado utilizando el formato ASCII de ArcGrid para los resultados. Es sencillo de codificar y hace el trabajo, pero requiere una salida decimal. Esto significa una pérdida de precisión en los números de punto flotante.

¿Existe un formato raster binario sencillo en el que pueda escribir y que ArcGIS pueda leer?

0 votos

Una forma de responder a esto es utilizar ArcGIS para exportar a un formato binario: en el proceso de hacerlo encontrarás todas las opciones (antes era sólo una, el formato ".flt") y tendrás un archivo de ejemplo con el que trabajar.

8voto

El formato más sencillo para la lectura/escritura externa sería un archivo binario puro (BSQ, BIL o BIP) . No contienen absolutamente ninguna información de cabecera, sólo un flujo de bits que comienza con el primer punto de datos y termina con el último. El orden de los bits en n dimensiones variará en función del método de intercalado: secuencial de banda (BSQ), intercalado de banda por línea (BIL), intercalado de banda por píxel (BIP), como se muestra a continuación.

Interleaves

Su software (por ejemplo, ArcGIS, ENVI) delimitará el archivo automáticamente basándose en las dimensiones de la imagen, el tipo de intercalación, el tamaño de los bits y otra información descrita en el archivo de texto adjunto con la extensión .hdr (para la cabecera) .

La ventaja de este formato es la simplicidad: puedes decirle a C++ (o a cualquier lenguaje de programación con soporte de E/S) que simplemente escriba los datos binarios de las matrices directamente en el disco y luego escriba el archivo de cabecera. La desventaja es que hay que ser extremadamente cuidado con su archivo de cabecera - cualquier error en las dimensiones o el tipo de bits causará graves problemas, y ya que sólo está leyendo los datos binarios en bruto ArcMap no será lo suficientemente "inteligente" para darse cuenta de que algo ha ido mal.

3voto

Jürgen Zornig Puntos 1477

El equivalente binario de la cuadrícula ASCII de ESRI es el (tataaa) Rejilla binaria de ArcINFO . Pero creo que no es muy sencillo leer o escribir (debido a que consiste en un montón de archivos) sin una biblioteca que haga este trabajo por ti, como GDAL.

Si utiliza una biblioteca como GDAL Creo que sería mejor escribir conjuntos de datos Raster basados en Filegeodatabase en primer lugar.

1 votos

No creo que la API de ESRI Filegeodatabase soporte actualmente los rásters. Por lo tanto, los rásteres contenidos en filegoedatabase no son accesibles a través de GDAL. Si esto ha cambiado, sería bueno saberlo.

3voto

music2myear Puntos 151

Acabé utilizando el formato raster de punto flotante de ArcGIS (extensión .flt ), como se describe aquí .

El C++ código que escribí para manejar las cosas sigue. No compilará sin una clase de rejilla, pero debería ser lo suficientemente fácil de leer y entender.

/**
  @brief  Writes a floating-point grid file

  @param[in]  &basename     Name, without extension, of output file
  @param[in]  &output_grid  DEM object to write

  @todo Does not check byte order (big-endian, little-endian)
  @todo Does not output only IEEE-754 32-bit floating-point,
        which is required by ArcGIS

  @returns 0 upon success
*/
template <class T>
int write_floating_data(const std::string basename,const array2d<T> &output_grid){
  std::string fn_header(basename), fn_data(basename);

  fn_header+=".hdr";
  fn_data+=".flt";

  {
    std::ofstream fout;
    fout.open(fn_header.c_str());
    if(!fout.is_open())
      exit(-1);

    diagnostic("Writing floating-point header file...");
    fout<<"ncols\t\t"<<output_grid.width()<<std::endl;
    fout<<"nrows\t\t"<<output_grid.height()<<std::endl;
    fout<<"xllcorner\t"<<std::fixed<<std::setprecision(10)<<output_grid.xllcorner<<std::endl;
    fout<<"yllcorner\t"<<std::fixed<<std::setprecision(10)<<output_grid.yllcorner<<std::endl;
    fout<<"cellsize\t"<<std::fixed<<std::setprecision(10)<<output_grid.cellsize<<std::endl;
    fout<<"NODATA_value\t"<<std::fixed<<std::setprecision(10)<<output_grid.no_data<<std::endl;
    fout<<"BYTEORDER\tLSBFIRST"<<std::endl; //TODO: Detect endian-ness
    fout.close();
  }

  {
    std::ofstream fout(fn_data.c_str(), std::ios::binary | std::ios::out);
    if(!fout.is_open())
      exit(-1);

    for(int y=0;y<output_grid.height();++y)
    for(int x=0;x<output_grid.width();++x)
      fout.write(reinterpret_cast<const char*>(&output_grid(x,y)), std::streamsize(sizeof(T)));
    fout.close();
  }

  return 0;
}

/**
  @brief  Reads in a floating-point grid file

  @param[in]  &basename     Name, without extension, of input file
  @param[in]  &grid         DEM object in which to store data

  @todo Does not check byte order (big-endian, little-endian)
  @todo Does not input only IEEE-754 32-bit floating-point,
        which is required by ArcGIS

  @returns 0 upon success
*/
template <class T>
int read_floating_data(const std::string basename,array2d<T> &grid){
  std::string fn_header(basename), fn_data(basename);

  fn_header+=".hdr";
  fn_data+=".flt";

  int columns, rows;
  char byteorder; //L=LSB first, M=MSB first

  {
    FILE *fin;
    fin=fopen(fn_header.c_str(),"r");
    if(fin==NULL)
      exit(-1);

    if(fscanf(fin,"ncols %d nrows %d xllcorner %lf yllcorner %lf cellsize %lf NODATA_value %f BYTEORDER %c",&columns, &rows, &grid.xllcorner, &grid.yllcorner, &grid.cellsize, &grid.no_data, &byteorder)!=7)
      exit(-1);
    fclose(fin);
  }

  grid.resize(columns,rows);

  {
    std::ifstream fin(fn_data.c_str(), std::ios::binary | std::ios::in);
    if(!fin.is_open())
      exit(-1);

    grid.data_cells=0;
    for(int y=0;y<rows;++y)
    for(int x=0;x<columns;++x){
      fin.read(reinterpret_cast<char*>(&grid(x,y)), std::streamsize(sizeof(T)));
      if(grid(x,y)!=grid.no_data)
        grid.data_cells++;
    }
  }

  return 0;
}

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X