Пример #1
0
static int CreateMap(
       const char *name,
       const ATTRIBUTES *a)
{
       UINT1 *buf;
       size_t i;
       double angle;
       MAP *m;

  size_t CELLMAX = (long int)(pow(2,30) - 1);
  if(((size_t)a->nrRows * (size_t)a->nrCols) > CELLMAX){
    printf("WARNING:\n  The specified amount of cells exceeds 2^30 - 1.\n  Not all PCRaster applications accept maps of this size.\n");
  }

       if (a->angle < 0)
           angle = -Deg2Rad(-a->angle);
       else
           angle = Deg2Rad(a->angle);
       m = Rcreate(name,(size_t)a->nrRows,(size_t)a->nrCols, a->cellRepr, a->valueScale,
                     a->projection, a->xUL, a->yUL, angle, a->cellSize);
       if (m == NULL)
        goto error1;

       PRECOND(a->gisFileId != MV_UINT4);
       if (MputGisFileId(m,a->gisFileId) == MV_UINT4)
              goto error2;

       if (RuseAs(m, CR_UINT1))
              goto error2;
       buf = (UINT1 *)Rmalloc(m, (size_t)a->nrCols);
       if (buf == NULL)
       {
        Mclose(m);
        remove(name);
        return 1;
       }
       for(i=0; i < a->nrRows; i++)
       {
              memset(buf,1,(size_t)a->nrCols);
              RputRow(m,i,buf);
       }
       Free(buf);
       Mclose(m);
       return 0;
error2:
       Mclose(m);
       remove(name);
error1:
       return       RetError(1,"Can not create '%s': %s",name,MstrError());
}
Пример #2
0
/* make all cells missing value in map
 * RputAllMV writes a missing values to all the cells in a
 * map. For this is allocates a buffer to hold one row at a
 * time.
 * returns 1 if succesfull, 0 in case of an error
 */
int RputAllMV(
	MAP *m)
{
	size_t i,nc,nr;
	void *buffer;
	CSF_CR cr;

	CHECKHANDLE_GOTO(m, error);
	if(! WRITE_ENABLE(m))
	{
		M_ERROR(NOACCESS);
		goto error;
	}

	cr = RgetCellRepr(m);
	nc = RgetNrCols(m);

	buffer = Rmalloc(m,nc);
	if(buffer == NULL)
	{
		M_ERROR(NOCORE);
		goto error;
	}

	/*  Fill buffer with determined Missingvalue*/
	SetMemMV(buffer, nc, cr);

	nr = RgetNrRows(m);
	for(i = 0 ; i < nr; i++)
	 if (RputRow(m, i, buffer) != nc)
	 {
	    M_ERROR(WRITE_ERROR);
	    goto error_f;
	 }
	CSF_FREE(buffer);

	CsfSetVarTypeMV( &(m->raster.minVal), cr);
	CsfSetVarTypeMV( &(m->raster.maxVal), cr);

	return(1);
error_f:  
	CSF_FREE(buffer);
error:
	return(0);
}
Пример #3
0
/*!
  \warning   The source raster must have only 1 band. Currently, the values in
             the source raster must be stored in one of the supported cell
             representations (CR_UINT1, CR_INT4, CR_REAL4, CR_REAL8).

  The meta data item PCRASTER_VALUESCALE will be checked to see what value
  scale to use. Otherwise a value scale is determined using
  GDALType2ValueScale(GDALDataType).

  This function always writes rasters using CR_UINT1, CR_INT4 or CR_REAL4
  cell representations.
*/
GDALDataset* PCRasterDataset::createCopy(
    char const* filename,
    GDALDataset* source,
    CPL_UNUSED int strict,
    CPL_UNUSED char** options,
    GDALProgressFunc progress,
    void* progressData)
{
  // Checks.
  int nrBands = source->GetRasterCount();
  if(nrBands != 1) {
    CPLError(CE_Failure, CPLE_NotSupported,
         "PCRaster driver: Too many bands ('%d'): must be 1 band", nrBands);
    return 0;
  }

  GDALRasterBand* raster = source->GetRasterBand(1);

  // Create PCRaster raster. Determine properties of raster to create.
  size_t nrRows = raster->GetYSize();
  size_t nrCols = raster->GetXSize();
  std::string string;

  // The in-file type of the cells.
  CSF_CR fileCellRepresentation = GDALType2CellRepresentation(
         raster->GetRasterDataType(), false);

  if(fileCellRepresentation == CR_UNDEFINED) {
    CPLError(CE_Failure, CPLE_NotSupported,
         "PCRaster driver: Cannot determine a valid cell representation");
    return 0;
  }

  // The value scale of the values.
  CSF_VS valueScale = VS_UNDEFINED;
  if(source->GetMetadataItem("PCRASTER_VALUESCALE")) {
    string = source->GetMetadataItem("PCRASTER_VALUESCALE");
  }

  valueScale = !string.empty()
         ? string2ValueScale(string)
         : GDALType2ValueScale(raster->GetRasterDataType());

  if(valueScale == VS_UNDEFINED) {
    CPLError(CE_Failure, CPLE_NotSupported,
         "PCRaster driver: Cannot determine a valid value scale");
    return 0;
  }

  CSF_PT const projection = PT_YDECT2B;
  REAL8  const angle = 0.0;
  REAL8 west = 0.0;
  REAL8 north = 0.0;
  REAL8 cellSize = 1.0;

  double transform[6];
  if(source->GetGeoTransform(transform) == CE_None) {
    if(transform[2] == 0.0 && transform[4] == 0.0) {
      west = static_cast<REAL8>(transform[0]);
      north = static_cast<REAL8>(transform[3]);
      cellSize = static_cast<REAL8>(transform[1]);
    }
  }

  // The in-memory type of the cells.
  CSF_CR appCellRepresentation = CR_UNDEFINED;
  appCellRepresentation = GDALType2CellRepresentation(
         raster->GetRasterDataType(), true);

  if(appCellRepresentation == CR_UNDEFINED) {
    CPLError(CE_Failure, CPLE_NotSupported,
         "PCRaster driver: Cannot determine a valid cell representation");
    return 0;
  }

  // Check whether value scale fits the cell representation. Adjust when
  // needed.
  valueScale = fitValueScale(valueScale, appCellRepresentation);

  // Create a raster with the in file cell representation.
  MAP* map = Rcreate(filename, nrRows, nrCols, fileCellRepresentation,
         valueScale, projection, west, north, angle, cellSize);

  if(!map) {
    CPLError(CE_Failure, CPLE_OpenFailed,
         "PCRaster driver: Unable to create raster %s", filename);
    return 0;
  }

  // Try to convert in app cell representation to the cell representation
  // of the file.
  if(RuseAs(map, appCellRepresentation)) {
    CPLError(CE_Failure, CPLE_NotSupported,
         "PCRaster driver: Cannot convert cells: %s", MstrError());
    Mclose(map);
    return 0;
  }

  int hasMissingValue;
  double missingValue = raster->GetNoDataValue(&hasMissingValue);

  // This is needed to get my (KDJ) unit tests running.
  // I am still uncertain why this is needed. If the input raster has float32
  // values and the output int32, than the missing value in the dataset object
  // is not updated like the values are.
  if(missingValue == ::missingValue(CR_REAL4) &&
         fileCellRepresentation == CR_INT4) {
    missingValue = ::missingValue(fileCellRepresentation);
  }

  // TODO conversie van INT2 naar INT4 ondersteunen. zie ruseas.c regel 503.
  // conversie op r 159.

  // Create buffer for one row of values.
  void* buffer = Rmalloc(map, nrCols);

  // Copy values from source to target.
  CPLErr errorCode = CE_None;
  for(size_t row = 0; errorCode == CE_None && row < nrRows; ++row) {

    // Get row from source.
    if(raster->RasterIO(GF_Read, 0, row, nrCols, 1, buffer, nrCols, 1,
         raster->GetRasterDataType(), 0, 0, NULL) != CE_None) {
      CPLError(CE_Failure, CPLE_FileIO,
         "PCRaster driver: Error reading from source raster");
      errorCode = CE_Failure;
      break;
    }

    // Upon reading values are converted to the
    // right data type. This includes the missing value. If the source
    // value cannot be represented in the target data type it is set to a
    // missing value.

    if(hasMissingValue) {
      alterToStdMV(buffer, nrCols, appCellRepresentation, missingValue);
    }

    if(valueScale == VS_BOOLEAN) {
      castValuesToBooleanRange(buffer, nrCols, appCellRepresentation);
    }

    // Write row in target.
    RputRow(map, row, buffer);

    if(!progress((row + 1) / (static_cast<double>(nrRows)), 0, progressData)) {
      CPLError(CE_Failure, CPLE_UserInterrupt,
         "PCRaster driver: User terminated CreateCopy()");
      errorCode = CE_Failure;
      break;
    }
  }

  Mclose(map);
  map = 0;

  free(buffer);
  buffer = 0;

  if( errorCode != CE_None )
      return NULL;

/* -------------------------------------------------------------------- */
/*      Re-open dataset, and copy any auxiliary pam information.        */
/* -------------------------------------------------------------------- */
  GDALPamDataset *poDS = (GDALPamDataset *)
        GDALOpen( filename, GA_Update );

  if( poDS )
      poDS->CloneInfo( source, GCIF_PAM_DEFAULT );

  return poDS;
}