Exemplo n.º 1
0
GDALDataset* SRTMHGTDataset::Open(GDALOpenInfo* poOpenInfo)
{
  if (!Identify(poOpenInfo))
      return nullptr;

  const char* fileName = CPLGetFilename(poOpenInfo->pszFilename);
  CPLString osLCFilename(CPLString(fileName).tolower());
  if( !STARTS_WITH(fileName, "/vsizip/") &&
      osLCFilename.endsWith(".hgt.zip") )
  {
      CPLString osFilename ("/vsizip/");
      osFilename += poOpenInfo->pszFilename;
      osFilename += "/";
      osFilename += CPLString(fileName).substr(0, 7);
      osFilename += ".hgt";
      GDALOpenInfo oOpenInfo(osFilename, poOpenInfo->eAccess);
      GDALDataset* poDS = Open(&oOpenInfo);
      if( poDS != nullptr )
      {
          // override description with the main one
          poDS->SetDescription(poOpenInfo->pszFilename);
      }
      return poDS;
  }

  if( !STARTS_WITH(fileName, "/vsizip/") &&
      osLCFilename.endsWith(".srtmswbd.raw.zip") )
  {
      CPLString osFilename("/vsizip/");
      osFilename += poOpenInfo->pszFilename;
      osFilename += "/";
      osFilename += CPLString(fileName).substr(0, 7);
      osFilename += ".raw";
      GDALOpenInfo oOpenInfo(osFilename, poOpenInfo->eAccess);
      GDALDataset* poDS = Open(&oOpenInfo);
      if( poDS != nullptr )
      {
          // override description with the main one
          poDS->SetDescription(poOpenInfo->pszFilename);
      }
      return poDS;
  }

  char latLonValueString[4];
  memset(latLonValueString, 0, 4);
  strncpy(latLonValueString, &fileName[1], 2);
  int southWestLat = atoi(latLonValueString);
  memset(latLonValueString, 0, 4);
  // cppcheck-suppress redundantCopy
  strncpy(latLonValueString, &fileName[4], 3);
  int southWestLon = atoi(latLonValueString);

  if(fileName[0] == 'N' || fileName[0] == 'n')
    /*southWestLat = southWestLat */;
  else if(fileName[0] == 'S' || fileName[0] == 's')
    southWestLat = southWestLat * -1;
  else
    return nullptr;

  if(fileName[3] == 'E' || fileName[3] == 'e')
    /*southWestLon = southWestLon */;
  else if(fileName[3] == 'W' || fileName[3] == 'w')
    southWestLon = southWestLon * -1;
  else
    return nullptr;

/* -------------------------------------------------------------------- */
/*      Create a corresponding GDALDataset.                             */
/* -------------------------------------------------------------------- */
  SRTMHGTDataset* poDS  = new SRTMHGTDataset();

  poDS->fpImage = poOpenInfo->fpL;
  poOpenInfo->fpL = nullptr;

  VSIStatBufL fileStat;
  if(VSIStatL(poOpenInfo->pszFilename, &fileStat) != 0)
  {
      delete poDS;
      return nullptr;
  }

  int numPixels_x, numPixels_y;

  GDALDataType eDT = GDT_Int16;
  switch (fileStat.st_size) {
  case 3601 * 3601:
    numPixels_x = numPixels_y = 3601;
    eDT = GDT_Byte;
    break;
  case 3601 * 3601 * 2:
    numPixels_x = numPixels_y = 3601;
    break;
  case 1801 * 3601 * 2:
    numPixels_x = 1801;
    numPixels_y = 3601;
    break;
  case 1201 * 1201 * 2:
    numPixels_x = numPixels_y = 1201;
    break;
  default:
    numPixels_x = numPixels_y = 0;
    break;
  }

  poDS->eAccess = poOpenInfo->eAccess;
#ifdef CPL_LSB
  if(poDS->eAccess == GA_Update && eDT == GDT_Int16)
  {
      poDS->panBuffer
          = reinterpret_cast<GInt16 *>( CPLMalloc(numPixels_x * sizeof(GInt16)) );
  }
#endif

/* -------------------------------------------------------------------- */
/*      Capture some information from the file that is of interest.     */
/* -------------------------------------------------------------------- */
  poDS->nRasterXSize = numPixels_x;
  poDS->nRasterYSize = numPixels_y;
  poDS->nBands = 1;

  poDS->adfGeoTransform[0] = southWestLon - 0.5 / (numPixels_x - 1);
  poDS->adfGeoTransform[1] = 1.0 / (numPixels_x-1);
  poDS->adfGeoTransform[2] = 0.0;
  poDS->adfGeoTransform[3] = southWestLat + 1 + 0.5 / (numPixels_y - 1);
  poDS->adfGeoTransform[4] = 0.0;
  poDS->adfGeoTransform[5] = -1.0 / (numPixels_y-1);

  poDS->SetMetadataItem( GDALMD_AREA_OR_POINT, GDALMD_AOP_POINT );

/* -------------------------------------------------------------------- */
/*      Create band information object.                                 */
/* -------------------------------------------------------------------- */
  SRTMHGTRasterBand* tmpBand = new SRTMHGTRasterBand(poDS, 1, eDT);
  poDS->SetBand(1, tmpBand);

/* -------------------------------------------------------------------- */
/*      Initialize any PAM information.                                 */
/* -------------------------------------------------------------------- */
  poDS->SetDescription(poOpenInfo->pszFilename);
  poDS->TryLoadXML();

/* -------------------------------------------------------------------- */
/*      Support overviews.                                              */
/* -------------------------------------------------------------------- */
  poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );

  return poDS;
}