Beispiel #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());
}
Beispiel #2
0
static int DefaultCloneAttr(
       ATTRIBUTES *a)
{
       MAP *in;
       if (appClone != NULL)
       {
           char *dummy;
           in = AppOpenClone(&dummy, NULL);
           if (in == NULL )
                  return 1;
           if (ReadAttr(a,in,FALSE))
           {
                  Mclose(in);
                  return RetError(1,"while reading clone map '%s': %s",appClone,MstrError());
           }
           Mclose(in);
       }
       else
           DefaultAttr(a);
       return 0;
}
Beispiel #3
0
/* close all open maps at exit  (LIBRARY_INTERNAL)
 * passed through atexit to c-library
 * exit code
 */
static void CsfCloseCsfKernel(void)
{
  size_t i;

  for(i = 0; i < mapListLen; i++)
   if(mapList[i] != NULL)
    if(Mclose(mapList[i]))
      (void)fprintf(stderr,"CSF_INTERNAL_ERROR: unable to close %s at exit\n",
        mapList[i]->fileName);
  CSF_FREE(mapList);
  mapList = NULL;
}
Beispiel #4
0
/* Deallocates the array of input maps.
 * Closes the input and output maps.
 */
static void EndResample(
	MAP **in,		/* input maps to free */
	size_t nrMaps,		/* number of input maps */
	MAP *out)		/* output map to free */
{
	/* Deallocate and close the input maps */
	FreeMaps(in, nrMaps);

	if(Mclose(out))			/* Close the output map */
		MperrorExit(MgetFileName(out), 1);

	AppEnd();
}
Beispiel #5
0
/* Deallocates all input maps
 * Return nothing.
 */
static void FreeMaps(
		MAP **in,	/* write-only pointer to input maps */
		size_t nrMaps)	/* number of input maps */
{
	size_t i;
	for(i = 0; i < nrMaps; i++)	/* Close all maps */
	{
		MAP *tmp = in[i];
		if(Mclose(tmp))
			MperrorExit(MgetFileName(tmp), 1);
	}	
	Free(in);			/* Deallocate memory */
}
Beispiel #6
0
static int EditOption(
       const char *name)
{
       ATTRIBUTES a;
       MAP *in = Mopen(name, M_READ_WRITE);
       if (in == NULL || ReadAttr(&a,in,FALSE))
       {
         if (in != NULL)
          Mclose(in);
         return RetError(1,"while reading '%s': %s",name,MstrError());
       }
       if (a.version != 2)
        return RetError(1,"'%s' is not a version 2 map, no edits possible");
       a.cloneCreation = FALSE;
        switch(MakeCloneMenu(&a, name))
        { 
            case 0: return 0;
            case 1: return SetAndCloseMap(in, &a);
            case 2: fprintf(stderr,"No map attributes written\n");
                    return 0;
        }
        POSTCOND(FALSE);
        return 1;
}
Beispiel #7
0
int main(int argc, char *argv[]) {
    MAP *out, *clone = NULL;
    int c;
    size_t colNr[3] = {0 /*X*/, 1 /*Y*/, 2 /*V*/}; /* internal indices */
    const char *mv = "1e31";
    char *cloneFileName;
    COMP_CELL compCell = NOTHING;
    CSF_CR cellRepr;
    CSF_VS valueScale = VS_UNDEFINED;
    int parseVal;
    int sepChar = ',';

    if (InstallArgs(argc, argv, "x#y#v#m*(BLNOSDV)(atHM)(hl)s*", "col2map", __DATE__))
        goto failure;
    while ((c = GetOpt()) != 0)
        switch (c) {
        case 'x':
            parseVal = (*((const int *)OptArg)) - 1;
            if (parseVal < 0) {
                Error("-x: x column should be greater than 0");
                goto failure;
            }
            colNr[POS_X] = (size_t)parseVal;
            break;
        case 'y':
            parseVal = (*((const int *)OptArg)) - 1;
            if (parseVal < 0) {
                Error("-y: y column should be greater than 0");
                goto failure;
            }
            colNr[POS_Y] = (size_t)parseVal;
            break;
        case 'v':
            parseVal = (*((const int *)OptArg)) - 1;
            if (parseVal < 0) {
                Error("-v: value column should be greater than 0");
                goto failure;
            }
            colNr[POS_V] = (size_t)parseVal;
            break;
        case 'm':
            mv = (const char *)OptArg;
            break;
        case 'a':
            compCell = AVERAGE;
            break;
        case 'H':
            compCell = HIGHEST;
            break;
        case 'h':
            compCell = MAJORITY;
            break;
        case 'M':
            compCell = LOWEST;
            break;
        case 'l':
            compCell = MINORITY;
            break;
        case 't':
            compCell = TOTAL;
            break;
        case 's':
            sepChar = ((const char *)OptArg)[0];
            if (isdigit(sepChar)) {
                Error("-s: separator must be a non-digit (not [0-9])");
                goto failure;
            }
            break;
#include "case_vs.h"
        }

    argv = ArgArguments(&argc);
    if (argv == NULL)
        goto failure;
    if (AppArgCountCheck(argc, 3, 3, USAGE))
        goto failure;
    if (AppInputTest(argv[1]))
        goto failure;

    /* open the clone map */
    clone = AppOpenClone(&cloneFileName, NULL);
    if (clone == NULL)
        goto failure;

    if (valueScale == VS_UNDEFINED) {
        valueScale = RgetValueScale(clone);
        cellRepr = RgetCellRepr(clone);
    } else
        cellRepr = AppDefaultCellRepr(valueScale);

    if (!RvalueScale2(valueScale)) {
        Error("clone map '%s' has an illegal value scale", cloneFileName);
        goto failure2;
    }

    if (compCell == NOTHING) { /* defaults */
        switch (valueScale) {
        case VS_SCALAR:
            compCell = AVERAGE;
            break;
        case VS_DIRECTION:
            compCell = DIR_AVERAGE;
            break;
        default:
            compCell = MAJORITY;
            break;
        }
    } else {
        BOOL conflict = FALSE;
        CSF_VS vs = valueScale;
        switch (compCell) {
        case AVERAGE:
            conflict = (vs != VS_SCALAR && vs != VS_DIRECTION);
            if (vs == VS_DIRECTION)
                compCell = DIR_AVERAGE;
            break;
        case LOWEST:
        case HIGHEST:
            conflict = (vs != VS_SCALAR && vs != VS_ORDINAL);
            break;
        case MAJORITY:
        case MINORITY:
            conflict = (vs == VS_SCALAR || vs == VS_DIRECTION);
            break;
        case TOTAL:
            conflict = vs != VS_SCALAR;
            break;
        default:
            POSTCOND(FALSE);
        }
        if (conflict) {
            CompCellError(compCell, vs);
            goto failure2;
        }
    }

    out = Rdup(argv[2], clone, cellRepr, valueScale);
    if (out == NULL) {
        Error("output map '%s' can not be created", argv[2]);
        goto failure2;
    }
    Mclose(clone);
    clone = NULL;
    RuseAs(out, CR_REAL8);

    if (Col2Map(out, argv[1], compCell, mv, colNr, sepChar)) {
        Mclose(out);
        (void)remove(argv[2]);
        goto failure;
    }

    Mclose(out);
    AppEnd();
    exit(0);
    return 0;

failure2:
    if (clone == NULL)
        Mclose(clone);
failure:
    AppEnd();
    exit(1);
    return 1;
} /* main */
Beispiel #8
0
static int PrintOption(
 const char **names,
 int nrNames)
{
       ATTRIBUTES *a = (ATTRIBUTES *)ChkMalloc(sizeof(ATTRIBUTES) * nrNames);
       int *colLen = (int *)ChkMalloc(sizeof(int) * nrNames);
       int i;
       if (a == NULL || colLen == NULL)
              return 1;
       for(i = 0 ; i < nrNames; i++)
       {
              MAP *m= Mopen(names[i],M_READ);
              if (m == NULL)
                  {
                   Free(a);
                   return RetError(1,"while reading map '%s': %s",names[i],MstrError());
                  }
                  ReadAttr(a+i,m,TRUE);
                  colLen[i] = MAX(11, strlen(names[i]));
                  Mclose(m);
       }

       if (printDataType)
       {
        for(i = 0 ; i < nrNames; i++)
        {
        int c;
         switch(a[i].valueScale) {
              case VS_LDD : c = 'L'; break;
              case VS_SCALAR : c = 'S'; break;
              case VS_BOOLEAN : c = 'B'; break;
              case VS_NOMINAL : c = 'N'; break;
              case VS_ORDINAL : c = 'O'; break;
              case VS_DIRECTION : c = 'D'; break;
              default : c = ' '; break;
         }
         printf("%c",c);
        }
        return 1;
       }

        printf("%s",HEAD);
       for(i = 0 ; i < nrNames; i++)
         printf(" %-*s", colLen[i], names[i]);
       printf("\n");

        printf("%s",printLabels[ATTR_nrRows]);
       for(i = 0 ; i < nrNames; i++)
         printf(" %-*u", colLen[i], a[i].nrRows);
       printf("\n");

        printf("%s",printLabels[ATTR_nrCols]);
       for(i = 0 ; i < nrNames; i++)
         printf(" %-*u", colLen[i], a[i].nrCols);
       printf("\n");

        printf("%s",printLabels[ATTR_cellSize]);
       for(i = 0 ; i < nrNames; i++)
         printf(" %-*g", colLen[i], a[i].cellSize);
       printf("\n");

       
        printf("%s",printLabels[ATTR_valueScale]);
       for(i = 0 ; i < nrNames; i++)
         printf(" %-*s", colLen[i], RstrValueScale(a[i].valueScale));
       printf("\n");

        printf("%s",printLabels[ATTR_cellRepr]);
       for(i = 0 ; i < nrNames; i++)
       { const char *cStr;
         switch(a[i].cellRepr)
         { case CR_UINT1 : cStr = "small"; break;
           case CR_INT4  : cStr = "large"; break;
           case CR_REAL4 : cStr = "single"; break;
           case CR_REAL8 : cStr = "double"; break;
           default : cStr = RstrCellRepr(a[i].cellRepr);
          }
         printf(" %-*s", colLen[i], cStr);
        }
       printf("\n");

       printf("%s",printLabels[ATTR_projection]);
       for(i = 0 ; i < nrNames; i++)
         printf(" %-*s", colLen[i], a[i].projection ? "yb2t" : "yt2b" );
       printf("\n");

        printf("%s",printLabels[ATTR_angle]);
       for(i = 0 ; i < nrNames; i++)
         printf(" %-*g", colLen[i], a[i].angle);
       printf("\n");

       printf("%s",printLabels[ATTR_xUL]);
       for(i = 0 ; i < nrNames; i++)
         printf(" %-*g", colLen[i], a[i].xUL);
       printf("\n");

       printf("%s",printLabels[ATTR_yUL]);
       for(i = 0 ; i < nrNames; i++)
         printf(" %-*g", colLen[i], a[i].yUL);
       printf("\n");

       printf("%s",printLabels[ATTR_minVal]);
       for(i = 0 ; i < nrNames; i++)
        if (IS_MV_REAL8(&(a[i].minVal)))
         printf(" %-*s", colLen[i], "mv");
        else
        { 
         if ((a[i].cellRepr) & CSF_FLOAT_MASK)
          printf(" %-*g", colLen[i], a[i].minVal);
         else
          printf(" %-*d", colLen[i], (int)a[i].minVal);
        }
       printf("\n");

       printf("%s",printLabels[ATTR_maxVal]);
       for(i = 0 ; i < nrNames; i++)
        if (IS_MV_REAL8(&(a[i].maxVal)))
         printf(" %-*s", colLen[i], "mv");
        else
        {
         if ((a[i].cellRepr) & CSF_FLOAT_MASK)
          printf(" %-*g", colLen[i], a[i].maxVal);
         else
          printf(" %-*d", colLen[i], (int)a[i].maxVal);
        }
       printf("\n");

       printf("%s",printLabels[ATTR_version]);
       for(i = 0 ; i < nrNames; i++)
         printf(" %-*u", colLen[i], a[i].version);
       printf("\n");

       printf("%s",printLabels[ATTR_gisFileId]);
       for(i = 0 ; i < nrNames; i++)
         printf(" %-*u", colLen[i], a[i].gisFileId);
       printf("\n");

       printf("%s",printLabels[ATTR_byteOrder]);
       for(i = 0 ; i < nrNames; i++)
         printf(" %-*s", colLen[i], a[i].byteOrder == 1 ? "y" : "n");
       printf("\n");

       printf("%s",printLabels[ATTR_attrTable]);
       for(i = 0 ; i < nrNames; i++)
         printf(" %-*s", colLen[i], a[i].attrTable == 0 ? "n" : "y");
       printf("\n");

       return 0;
}
GDALDataset* PCRasterDataset::create(
     const char* filename,
     int nr_cols,
     int nr_rows,
     int nrBands,
     GDALDataType gdalType,
     char** papszParmList)
{
  // Checks
  if(nrBands != 1){
    CPLError(CE_Failure, CPLE_NotSupported,
         "PCRaster driver : "
         "attempt to create dataset with too many bands (%d); "
         "must be 1 band.\n", nrBands);
    return NULL;
  }

  int row_col_max = INT4_MAX - 1;
  if(nr_cols > row_col_max){
    CPLError(CE_Failure, CPLE_NotSupported,
         "PCRaster driver : "
         "attempt to create dataset with too many columns (%d); "
         "must be smaller than %d.", nr_cols, row_col_max);
    return NULL;
  }

  if(nr_rows > row_col_max){
    CPLError(CE_Failure, CPLE_NotSupported,
         "PCRaster driver : "
         "attempt to create dataset with too many rows (%d); "
         "must be smaller than %d.", nr_rows, row_col_max);
    return NULL;
  }

  if(gdalType != GDT_Byte &&
     gdalType != GDT_Int32 &&
     gdalType != GDT_Float32){
     CPLError( CE_Failure, CPLE_AppDefined,
       "PCRaster driver: "
       "attempt to create dataset with an illegal data type (%s); "
       "use either Byte, Int32 or Float32.",
       GDALGetDataTypeName(gdalType));
    return NULL;
  }

  // value scale must be specified by the user,
  // determines cell representation
  const char *valueScale = CSLFetchNameValue(
    papszParmList,"PCRASTER_VALUESCALE");

  if(valueScale == NULL){
    CPLError(CE_Failure, CPLE_AppDefined,
         "PCRaster driver: value scale can not be determined; "
         "specify PCRASTER_VALUESCALE.");
    return NULL;
  }


  CSF_VS csf_value_scale = string2ValueScale(valueScale);

  if(csf_value_scale == VS_UNDEFINED){
    CPLError( CE_Failure, CPLE_AppDefined,
         "PCRaster driver: value scale can not be determined (%s); "
         "use either VS_BOOLEAN, VS_NOMINAL, VS_ORDINAL, VS_SCALAR, "
         "VS_DIRECTION, VS_LDD",
          valueScale);
    return NULL;
  }

  CSF_CR csf_cell_representation = GDALType2CellRepresentation(gdalType, false);

  // default values
  REAL8 west = 0.0;
  REAL8 north = 0.0;
  REAL8 length = 1.0;
  REAL8 angle = 0.0;
  CSF_PT projection = PT_YDECT2B;

  // Create a new raster
  MAP* map = Rcreate(filename, nr_rows, nr_cols, csf_cell_representation,
         csf_value_scale, projection, west, north, angle, length);

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

  Mclose(map);
  map = NULL;

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

  return poDS;
}
Beispiel #10
0
/*!
  \warning   The map given in the constructor is closed.
*/
PCRasterDataset::~PCRasterDataset()
{
    FlushCache();
    Mclose(d_map);
}
Beispiel #11
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;
}