Beispiel #1
0
int get_cell(int col, float* buf_row, void* buf, RASTER_MAP_TYPE raster_type) {

	switch (raster_type) {

			case CELL_TYPE:
					if (Rast_is_null_value(&((CELL *) buf)[col],CELL_TYPE)) 
				Rast_set_f_null_value(&buf_row[col],1);
					else
				buf_row[col] =  (FCELL) ((CELL *) buf)[col];		
				break;

			case FCELL_TYPE:
					if (Rast_is_null_value(&((FCELL *) buf)[col],FCELL_TYPE)) 
				Rast_set_f_null_value(&buf_row[col],1);
					else
				buf_row[col] =  (FCELL) ((FCELL *) buf)[col];		
				break;
		
			case DCELL_TYPE:
					if (Rast_is_null_value(&((DCELL *) buf)[col],DCELL_TYPE)) 
				Rast_set_f_null_value(&buf_row[col],1);
					else
				buf_row[col] =  (FCELL) ((DCELL *) buf)[col];		
				break;
			}

return 0;
}
Beispiel #2
0
/*!
 * \brief Writes the null value to the N_array_2d struct at position col, row
 *
 * The null value will be automatically set to the array data type (CELL, FCELL or DCELL).
 *
 * \param data N_array_2d *
 * \param col int
 * \param row int
 * \return void
 * */
void N_put_array_2d_value_null(N_array_2d * data, int col, int row)
{

    G_debug(6,
	    "N_put_array_2d_value_null: put null value to array pos [%i][%i]",
	    col, row);

    if (data->offset == 0) {
	if (data->type == CELL_TYPE && data->cell_array != NULL) {
	    Rast_set_c_null_value((void *)
			       &(data->
				 cell_array[row * data->cols_intern + col]),
			       1);
	}
	else if (data->type == FCELL_TYPE && data->fcell_array != NULL) {
	    Rast_set_f_null_value((void *)
			       &(data->
				 fcell_array[row * data->cols_intern + col]),
			       1);
	}
	else if (data->type == DCELL_TYPE && data->dcell_array != NULL) {
	    Rast_set_d_null_value((void *)
			       &(data->
				 dcell_array[row * data->cols_intern + col]),
			       1);
	}
    }
    else {
	if (data->type == CELL_TYPE && data->cell_array != NULL) {
	    Rast_set_c_null_value((void *)
			       &(data->
				 cell_array[(row +
					     data->offset) *
					    data->cols_intern + col +
					    data->offset]), 1);
	}
	else if (data->type == FCELL_TYPE && data->fcell_array != NULL) {
	    Rast_set_f_null_value((void *)
			       &(data->
				 fcell_array[(row +
					      data->offset) *
					     data->cols_intern + col +
					     data->offset]), 1);
	}
	else if (data->type == DCELL_TYPE && data->dcell_array != NULL) {
	    Rast_set_d_null_value((void *)
			       &(data->
				 dcell_array[(row +
					      data->offset) *
					     data->cols_intern + col +
					     data->offset]), 1);
	}
    }

    return;
}
Beispiel #3
0
static int input_data(struct interp_params *params,
		      int first_row, int last_row,
		      struct fcell_triple *points,
		      int fdsmooth, int fdinp,
		      int inp_rows, int inp_cols,
		      double zmin, double inp_ns_res, double inp_ew_res)
{
    double x, y, sm;		/* input data and smoothing */
    int m1, m2;			/* loop counters */
    static FCELL *cellinp = NULL;	/* cell buffer for input data */
    static FCELL *cellsmooth = NULL;	/* cell buffer for smoothing */


    if (!cellinp)
	cellinp = Rast_allocate_f_buf();
    if (!cellsmooth)
	cellsmooth = Rast_allocate_f_buf();

    for (m1 = 0; m1 <= last_row - first_row; m1++) {
	Rast_get_f_row(fdinp, cellinp, inp_rows - m1 - first_row);
	if (fdsmooth >= 0)
	    Rast_get_f_row(fdsmooth, cellsmooth, inp_rows - m1 - first_row);

	y = params->y_orig + (m1 + first_row - 1 + 0.5) * inp_ns_res;
	for (m2 = 0; m2 < inp_cols; m2++) {
	    x = params->x_orig + (m2 + 0.5) * inp_ew_res;
	    /*
	     * z = cellinp[m2]*params->zmult;
	     */
	    if (fdsmooth >= 0)
		sm = (double)cellsmooth[m2];
	    else
		sm = 0.01;

	    points[m1 * inp_cols + m2].x = x - params->x_orig;
	    points[m1 * inp_cols + m2].y = y - params->y_orig;
	    if (!Rast_is_f_null_value(cellinp + m2)) {
		points[m1 * inp_cols + m2].z =
		    cellinp[m2] * params->zmult - zmin;
	    }
	    else {
		Rast_set_f_null_value(&(points[m1 * inp_cols + m2].z), 1);
	    }

	    /*              fprintf (stdout,"sm: %f\n",sm); */

	    points[m1 * inp_cols + m2].smooth = sm;
	}
    }
    return 1;
}
Beispiel #4
0
static void set_to_null(struct RASTER_MAP_PTR *buf, int col)
{
    switch (buf->type) {
    case CELL_TYPE:
	Rast_set_c_null_value(&(buf->data.c[col]), 1);
	break;
    case FCELL_TYPE:
	Rast_set_f_null_value(&(buf->data.f[col]), 1);
	break;
    case DCELL_TYPE:
	Rast_set_d_null_value(&(buf->data.d[col]), 1);
	break;
    }
}
Beispiel #5
0
static void convert_and_write_df(int fd, const void *vbuf)
{
    const DCELL *buf = vbuf;
    struct fileinfo *fcb = &R__.fileinfo[fd];
    FCELL *p = (FCELL *) fcb->data;
    int i;

    for (i = 0; i < fcb->cellhd.cols; i++)
	if (Rast_is_d_null_value(&buf[i]))
	    Rast_set_f_null_value(&p[i], 1);
	else
	    p[i] = (FCELL) buf[i];

    Rast_put_f_row(fd, p);
}
Beispiel #6
0
/* Saves map file from 2d array. NULL must be 0. Also meanwhile calculates area and volume. */
void save_map(FCELL ** out, int out_fd, int rows, int cols, int flag,
	      FCELL * min_depth, FCELL * max_depth, double *area,
	      double *volume)
{
    int row, col;
    double cellsize = -1;

    G_debug(1, "Saving new map");

    if (G_begin_cell_area_calculations() == 0 || G_begin_cell_area_calculations() == 1) {	/* All cells have constant size... */
	cellsize = G_area_of_cell_at_row(0);
    }
    G_debug(1, "Cell area: %f", cellsize);

    for (row = 0; row < rows; row++) {
	if (cellsize == -1)	/* Get LatLon current rows cell size */
	    cellsize = G_area_of_cell_at_row(row);
	for (col = 0; col < cols; col++) {
	    if (flag == 1)	/* Create negative map */
		out[row][col] = 0 - out[row][col];
	    if (out[row][col] == 0) {
		Rast_set_f_null_value(&out[row][col], 1);
	    }
	    if (out[row][col] > 0 || out[row][col] < 0) {
		G_debug(5, "volume %f += cellsize %f  * value %f [%d,%d]",
			*volume, cellsize, out[row][col], row, col);
		*area += cellsize;
		*volume += cellsize * out[row][col];
	    }

	    /* Get min/max depth. Can be usefull ;) */
	    if (out[row][col] > *max_depth)
		*max_depth = out[row][col];
	    if (out[row][col] < *min_depth)
		*min_depth = out[row][col];
	}
	Rast_put_f_row(out_fd, out[row]);
	G_percent(row + 1, rows, 5);
    }
}
Beispiel #7
0
static void write_row_float(png_bytep p)
{
    unsigned int x, c;
    channel *ch;

    for (x = 0; x < width; x++)
	for (c = 0; c < 6; c++)
	{
	    ch = &channels[c];
	    if (ch->active)
		ch->fbuf[x] = (FCELL) get_png_val(&p, bit_depth)
		    / ch->maxval;
	}

    if (t_gamma != 1.0)
	for (c = 0; c < 6; c++)
	{
	    ch = &channels[c];
	    if (c != C_A && ch->active)
		for (x = 0; x < width; x++)
		    ch->fbuf[x] = gamma_correct(ch->fbuf[x]);
	}

    if (channels[C_A].active && ialpha > 0)
	for (c = 0; c < 6; c++)
	{
	    ch = &channels[c];
	    if (c != C_A && ch->active)
		for (x = 0; x < width; x++)
		    if (channels[C_A].fbuf[x] <= alpha)
			Rast_set_f_null_value(&ch->fbuf[x], 1);
	}

    for (c = 0; c < 6; c++)
    {
	ch = &channels[c];
	if (ch->active)
	    Rast_put_f_row(ch->fd, ch->fbuf);
    }
}
Beispiel #8
0
double calculateF(area_des ad, int fd, char **par, double *result)
{
    FCELL *buf;
    FCELL corrCell;
    FCELL precCell;

    int i, j;
    int mask_fd = -1, *mask_buf;
    int ris = 0;
    int masked = FALSE;
    int a = 0;			/* a=0 if all cells are null */

    long m = 0;
    long tot = 0;
    long zero = 0;
    long totCorr = 0;

    double indice = 0;
    double somma = 0;
    double p = 0;
    double area = 0;
    double t;

    avl_tree albero = NULL;

    AVL_table *array;
    generic_cell uc;

    uc.t = FCELL_TYPE;

    /* open mask if needed */
    if (ad->mask == 1) {
	if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0)
	    return RLI_ERRORE;
	mask_buf = G_malloc(ad->cl * sizeof(int));
	if (mask_buf == NULL) {
	    G_fatal_error("malloc mask_buf failed");
	    return RLI_ERRORE;
	}
	masked = TRUE;
    }

    Rast_set_f_null_value(&precCell, 1);


    for (j = 0; j < ad->rl; j++) {	/* for each row */
	if (masked) {
	    if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) {
		G_fatal_error("mask read failed");
		return RLI_ERRORE;
	    }
	}

	buf = RLI_get_fcell_raster_row(fd, j + ad->y, ad);


	for (i = 0; i < ad->cl; i++) {	/* for each fcell in the row */

	    area++;
	    corrCell = buf[i + ad->x];

	    if (masked && mask_buf[i + ad->x] == 0) {
		Rast_set_f_null_value(&corrCell, 1);
		area--;
	    }

	    if (!(Rast_is_null_value(&corrCell, uc.t))) {
		a = 1;
		if (Rast_is_null_value(&precCell, uc.t)) {
		    precCell = corrCell;
		}
		if (corrCell != precCell) {
		    if (albero == NULL) {
			uc.val.fc = precCell;
			albero = avl_make(uc, totCorr);
			if (albero == NULL) {
			    G_fatal_error("avl_make error");
			    return RLI_ERRORE;
			}
			m++;
		    }
		    else {
			uc.val.fc = precCell;
			ris = avl_add(&albero, uc, totCorr);
			switch (ris) {
			case AVL_ERR:
			    {
				G_fatal_error("avl_add error");
				return RLI_ERRORE;
			    }
			case AVL_ADD:
			    {
				m++;
				break;
			    }
			case AVL_PRES:
			    {
				break;
			    }
			default:
			    {
				G_fatal_error("avl_make unknown error");
				return RLI_ERRORE;
			    }
			}
		    }
		    totCorr = 1;
		}		/* endif not equal fcells */
		else {		/*equal fcells */

		    totCorr++;
		}
		precCell = corrCell;
	    }


	}
    }

    /*last closing */
    if (a != 0) {
	if (albero == NULL) {
	    uc.val.fc = precCell;
	    albero = avl_make(uc, totCorr);
	    if (albero == NULL) {
		G_fatal_error("avl_make error");
		return RLI_ERRORE;
	    }
	    m++;
	}
	else {
	    uc.val.fc = precCell;
	    ris = avl_add(&albero, uc, totCorr);
	    switch (ris) {
	    case AVL_ERR:
		{
		    G_fatal_error("avl_add error");
		    return RLI_ERRORE;
		}
	    case AVL_ADD:
		{
		    m++;
		    break;
		}
	    case AVL_PRES:
		{
		    break;
		}
	    default:
		{
		    G_fatal_error("avl_add unknown error");
		    return RLI_ERRORE;
		}
	    }
	}
    }

    array = G_malloc(m * sizeof(AVL_tableRow));
    if (array == NULL) {
	G_fatal_error("malloc array failed");
	return RLI_ERRORE;
    }
    tot = avl_to_array(albero, zero, array);

    if (tot != m) {
	G_warning("avl_to_array unaspected value. the result could be wrong");
	return RLI_ERRORE;
    }

    char *sval;

    sval = par[0];
    double alpha_double;

    alpha_double = (double)atof(sval);
    /* calculate index summary */
    for (i = 0; i < m; i++) {
	t = (double)(array[i]->tot);
	p = t / area;
	G_debug(1, "Valore p: %g, valore pow: %g", p, pow(p, alpha_double));
	somma = somma + pow(p, alpha_double);
    }

    indice = (1 / (1 - alpha_double)) * log(somma);

    if (isnan(indice) || isinf(indice)) {
	indice = -1;
    }

    G_debug(1, "Valore somma: %g Valore indice: %g", somma, indice);

    *result = indice;


    G_free(array);
    if (masked)
	G_free(mask_buf);

    return RLI_OK;

}
Beispiel #9
0
int calculateF(int fd, struct area_entry *ad, double *result)
{
    FCELL *buf, *buf_sup, *buf_null;
    FCELL corrCell, precCell, supCell;
    long npatch, area; 
    long pid, old_pid, new_pid, *pid_corr, *pid_sup, *ltmp;
    struct pst *pst;
    long nalloc, incr;
    int i, j, k;
    int connected;
    int mask_fd, *mask_buf, *mask_sup, *mask_tmp, masked;
    struct Cell_head hd;

    Rast_get_window(&hd);

    buf_null = Rast_allocate_f_buf();
    Rast_set_f_null_value(buf_null, Rast_window_cols());
    buf_sup = buf_null;

    /* initialize patch ids */
    pid_corr = G_malloc(Rast_window_cols() * sizeof(long));
    pid_sup = G_malloc(Rast_window_cols() * sizeof(long));

    for (j = 0; j < Rast_window_cols(); j++) {
	pid_corr[j] = 0;
	pid_sup[j] = 0;
    }

    /* open mask if needed */
    mask_fd = -1;
    mask_buf = mask_sup = NULL;
    masked = FALSE;
    if (ad->mask == 1) {
	if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0)
	    return RLI_ERRORE;
	mask_buf = G_malloc(ad->cl * sizeof(int));
	if (mask_buf == NULL) {
	    G_fatal_error("malloc mask_buf failed");
	    return RLI_ERRORE;
	}
	mask_sup = G_malloc(ad->cl * sizeof(int));
	if (mask_sup == NULL) {
	    G_fatal_error("malloc mask_buf failed");
	    return RLI_ERRORE;
	}
	for (j = 0; j < ad->cl; j++)
	    mask_buf[j] = 0;

	masked = TRUE;
    }

    /* calculate number of patches */
    npatch = 0;
    area = 0;
    pid = 0;

    /* patch size and type */
    incr = 1024;
    if (incr > ad->rl)
	incr = ad->rl;
    if (incr > ad->cl)
	incr = ad->cl;
    if (incr < 2)
	incr = 2;
    nalloc = incr;
    pst = G_malloc(nalloc * sizeof(struct pst));
    for (k = 0; k < nalloc; k++) {
	pst[k].count = 0;
    }

    for (i = 0; i < ad->rl; i++) {
	buf = RLI_get_fcell_raster_row(fd, i + ad->y, ad);
	if (i > 0) {
	    buf_sup = RLI_get_fcell_raster_row(fd, i - 1 + ad->y, ad);
	}

	if (masked) {
	    mask_tmp = mask_sup;
	    mask_sup = mask_buf;
	    mask_buf = mask_tmp;
	    if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0)
		return 0;
	}
	
	ltmp = pid_sup;
	pid_sup = pid_corr;
	pid_corr = ltmp;

	Rast_set_f_null_value(&precCell, 1);

	connected = 0;
	for (j = 0; j < ad->cl; j++) {
	    pid_corr[j + ad->x] = 0;
	    
	    corrCell = buf[j + ad->x];
	    if (masked && (mask_buf[j] == 0)) {
		Rast_set_f_null_value(&corrCell, 1);
	    }

	    if (Rast_is_f_null_value(&corrCell)) {
		connected = 0;
		precCell = corrCell;
		continue;
	    }
	    
	    area++;
	    
	    supCell = buf_sup[j + ad->x];
	    if (masked && (mask_sup[j] == 0)) {
		Rast_set_f_null_value(&supCell, 1);
	    }

	    if (!Rast_is_f_null_value(&precCell) && corrCell == precCell) {
		pid_corr[j + ad->x] = pid_corr[j - 1 + ad->x];
		connected = 1;
		pst[pid_corr[j + ad->x]].count++;
	    }
	    else {
		connected = 0;
	    }

	    if (!Rast_is_f_null_value(&supCell) && corrCell == supCell) {

		if (pid_corr[j + ad->x] != pid_sup[j + ad->x]) {
		    /* connect or merge */
		    /* after r.clump */
		    if (connected) {
			npatch--;

			if (npatch == 0) {
			    G_fatal_error("npatch == 0 at row %d, col %d", i, j);
			}
		    }

		    old_pid = pid_corr[j + ad->x];
		    new_pid = pid_sup[j + ad->x];
		    pid_corr[j + ad->x] = new_pid;
		    if (old_pid > 0) {
			/* merge */
			/* update left side of the current row */
			for (k = 0; k < j; k++) {
			    if (pid_corr[k + ad->x] == old_pid)
				pid_corr[k + ad->x] = new_pid;
			}
			/* update right side of the previous row */
			for (k = j + 1; k < ad->cl; k++) {
			    if (pid_sup[k + ad->x] == old_pid)
				pid_sup[k + ad->x] = new_pid;
			}
			pst[new_pid].count += pst[old_pid].count;
			pst[old_pid].count = 0;
			
			if (old_pid == pid)
			    pid--;
		    }
		    else {
			pst[new_pid].count++;
		    }
		}
		connected = 1;
	    }

	    if (!connected) {
		/* start new patch */
		npatch++;
		pid++;
		pid_corr[j + ad->x] = pid;

		if (pid >= nalloc) {
		    pst = (struct pst *)G_realloc(pst, (pid + incr) * sizeof(struct pst));

		    for (k = nalloc; k < pid + incr; k++)
			pst[k].count = 0;
			
		    nalloc = pid + incr;
		}

		pst[pid].count = 1;
		pst[pid].type.t = CELL_TYPE;
		pst[pid].type.val.c = corrCell;
	    }
	    precCell = corrCell;
	}
    }

    if (npatch > 0) {
	double EW_DIST1, EW_DIST2, NS_DIST1, NS_DIST2;
	double area_p;
	double cell_size_m;
	double min, max;

	/* calculate distance */
	G_begin_distance_calculations();
	/* EW Dist at North edge */
	EW_DIST1 = G_distance(hd.east, hd.north, hd.west, hd.north);
	/* EW Dist at South Edge */
	EW_DIST2 = G_distance(hd.east, hd.south, hd.west, hd.south);
	/* NS Dist at East edge */
	NS_DIST1 = G_distance(hd.east, hd.north, hd.east, hd.south);
	/* NS Dist at West edge */
	NS_DIST2 = G_distance(hd.west, hd.north, hd.west, hd.south);

	cell_size_m = (((EW_DIST1 + EW_DIST2) / 2) / hd.cols) *
	              (((NS_DIST1 + NS_DIST2) / 2) / hd.rows);

	/* get min and max patch size */
	min = 1.0 / 0.0;	/* inf */
	max = -1.0 / 0.0;	/* -inf */
	for (old_pid = 1; old_pid <= pid; old_pid++) {
	    if (pst[old_pid].count > 0) {
		area_p = cell_size_m * pst[old_pid].count / 10000;
		if (min > area_p)
		    min = area_p;
		if (max < area_p)
		    max = area_p;
	    }
	}
	*result = max - min;
    }
    else
	Rast_set_d_null_value(result, 1);

    if (masked) {
	close(mask_fd);
	G_free(mask_buf);
	G_free(mask_sup);
    }
    G_free(buf_null);
    G_free(pid_corr);
    G_free(pid_sup);
    G_free(pst);

    return RLI_OK;
}
Beispiel #10
0
int main( int argc, char **argv )
{
  char *name = nullptr;
  struct Option *map;
  struct Cell_head window;

  G_gisinit( argv[0] );

  G_define_module();

  map = G_define_standard_option( G_OPT_R_OUTPUT );

  if ( G_parser( argc, argv ) )
    exit( EXIT_FAILURE );

  name = map->answer;

#ifdef Q_OS_WIN
  _setmode( _fileno( stdin ), _O_BINARY );
  _setmode( _fileno( stdout ), _O_BINARY );
  //setvbuf( stdin, NULL, _IONBF, BUFSIZ );
  // setting _IONBF on stdout works on windows correctly, data written immediately even without fflush(stdout)
  //setvbuf( stdout, NULL, _IONBF, BUFSIZ );
#endif

  QgsGrassDataFile stdinFile;
  stdinFile.open( stdin );
  QDataStream stdinStream( &stdinFile );

  QFile stdoutFile;
  stdoutFile.open( stdout, QIODevice::WriteOnly | QIODevice::Unbuffered );
  QDataStream stdoutStream( &stdoutFile );

  qint32 proj, zone;
  stdinStream >> proj >> zone;

  QgsRectangle extent;
  qint32 rows, cols;
  stdinStream >> extent >> cols >> rows;
  checkStream( stdinStream );

  QString err = QgsGrass::setRegion( &window, extent, rows, cols );
  if ( !err.isEmpty() )
  {
    G_fatal_error( "Cannot set region: %s", err.toUtf8().constData() );
  }
  window.proj = ( int ) proj;
  window.zone = ( int ) zone;

  G_set_window( &window );

  Qgis::DataType qgis_type;
  qint32 type;
  stdinStream >> type;
  checkStream( stdinStream );
  qgis_type = ( Qgis::DataType )type;

  RASTER_MAP_TYPE grass_type;
  switch ( qgis_type )
  {
    case Qgis::Int32:
      grass_type = CELL_TYPE;
      break;
    case Qgis::Float32:
      grass_type = FCELL_TYPE;
      break;
    case Qgis::Float64:
      grass_type = DCELL_TYPE;
      break;
    default:
      G_fatal_error( "QGIS data type %d not supported", qgis_type );
      return 1;
  }

  cf = Rast_open_new( name, grass_type );
  if ( cf < 0 )
  {
    G_fatal_error( "Unable to create raster map <%s>", name );
    return 1;
  }

  void *buf = Rast_allocate_buf( grass_type );

  int expectedSize = cols * QgsRasterBlock::typeSize( qgis_type );
  bool isCanceled = false;
  QByteArray byteArray;
  for ( int row = 0; row < rows; row++ )
  {
    stdinStream >> isCanceled;
    checkStream( stdinStream );
    if ( isCanceled )
    {
      break;
    }
    double noDataValue;
    stdinStream >> noDataValue;
    stdinStream >> byteArray;
    checkStream( stdinStream );

    if ( byteArray.size() != expectedSize )
    {
      G_fatal_error( "Wrong byte array size, expected %d bytes, got %d, row %d / %d", expectedSize, byteArray.size(), row, rows );
      return 1;
    }

    qint32 *cell = nullptr;
    float *fcell = nullptr;
    double *dcell = nullptr;
    if ( grass_type == CELL_TYPE )
      cell = ( qint32 * ) byteArray.data();
    else if ( grass_type == FCELL_TYPE )
      fcell = ( float * ) byteArray.data();
    else if ( grass_type == DCELL_TYPE )
      dcell = ( double * ) byteArray.data();

    void *ptr = buf;
    for ( int col = 0; col < cols; col++ )
    {
      if ( grass_type == CELL_TYPE )
      {
        if ( ( CELL )cell[col] == ( CELL )noDataValue )
        {
          Rast_set_c_null_value( ( CELL * )ptr, 1 );
        }
        else
        {
          Rast_set_c_value( ptr, ( CELL )( cell[col] ), grass_type );
        }
      }
      else if ( grass_type == FCELL_TYPE )
      {
        if ( ( FCELL )fcell[col] == ( FCELL )noDataValue )
        {
          Rast_set_f_null_value( ( FCELL * )ptr, 1 );
        }
        else
        {
          Rast_set_f_value( ptr, ( FCELL )( fcell[col] ), grass_type );
        }
      }
      else if ( grass_type == DCELL_TYPE )
      {
        if ( ( DCELL )dcell[col] == ( DCELL )noDataValue )
        {
          Rast_set_d_null_value( ( DCELL * )ptr, 1 );
        }
        else
        {
          Rast_set_d_value( ptr, ( DCELL )dcell[col], grass_type );
        }
      }

      ptr = G_incr_void_ptr( ptr, Rast_cell_size( grass_type ) );
    }
    Rast_put_row( cf, buf, grass_type );

#ifndef Q_OS_WIN
    // Because stdin is somewhere buffered on Windows (not clear if in QProcess or by Windows)
    // we cannot in QgsGrassImport wait for this because it hangs. Setting _IONBF on stdin does not help
    // and there is no flush() on QProcess.
    // OTOH, smaller stdin buffer is probably blocking QgsGrassImport so that the import can be canceled immediately.
    stdoutStream << ( bool )true; // row written
    stdoutFile.flush();
#endif
  }

  if ( isCanceled )
  {
    Rast_unopen( cf );
  }
  else
  {
    Rast_close( cf );
    struct History history;
    Rast_short_history( name, "raster", &history );
    Rast_command_history( &history );
    Rast_write_history( name, &history );
  }

  exit( EXIT_SUCCESS );
}
Beispiel #11
0
/* Process the raster and do atmospheric corrections.
   Params:
   * INPUT FILE
   ifd: input file descriptor
   iref: input file has radiance values (default is reflectance) ?
   iscale: input file's range (default is min = 0, max = 255)
   ialt_fd: height map file descriptor, negative if global value is used
   ivis_fd: visibility map file descriptor, negative if global value is used

   * OUTPUT FILE
   ofd: output file descriptor
   oflt: if true use FCELL_TYPE for output
   oscale: output file's range (default is min = 0, max = 255)
 */
static void process_raster(int ifd, InputMask imask, ScaleRange iscale,
			   int ialt_fd, int ivis_fd, int ofd, bool oint,
			   ScaleRange oscale)
{
    FCELL *buf;			/* buffer for the input values */
    FCELL *alt = NULL;		/* buffer for the elevation values */
    FCELL *vis = NULL;		/* buffer for the visibility values */
    FCELL prev_alt = -1.f;
    FCELL prev_vis = -1.f;
    int row, col, nrows, ncols;
    /* switch on optimization automatically if elevation and/or visibility map is given */
    bool optimize = (ialt_fd >= 0 || ivis_fd >= 0);
    
#ifdef _NO_OPTIMIZE_
    optimize = false;
#endif

    /* do initial computation with global elevation and visibility values */
    TransformInput ti;

    ti = compute();

    /* use a cache to increase computation speed when an elevation map 
     * and/or a visibility map is given */
    TICache ticache;

    /* allocate memory for buffers */
    buf = (FCELL *) Rast_allocate_buf(FCELL_TYPE);
    if (ialt_fd >= 0)
	alt = (FCELL *) Rast_allocate_buf(FCELL_TYPE);
    if (ivis_fd >= 0)
	vis = (FCELL *) Rast_allocate_buf(FCELL_TYPE);

    nrows = Rast_window_rows();
    ncols = Rast_window_cols();

    for (row = 0; row < nrows; row++) {
	G_percent(row, nrows, 1);	/* keep the user informed of our progress */

	/* read the next row */
	Rast_get_row(ifd, buf, row, FCELL_TYPE);

	/* read the next row of elevation values */
	if (ialt_fd >= 0)
	    Rast_get_row(ialt_fd, alt, row, FCELL_TYPE);

	/* read the next row of elevation values */
	if (ivis_fd >= 0)
	    Rast_get_row(ivis_fd, vis, row, FCELL_TYPE);

	/* loop over all the values in the row */
	for (col = 0; col < ncols; col++) {
	    if ((vis && Rast_is_f_null_value(&vis[col])) ||
		(alt && Rast_is_f_null_value(&alt[col])) ||
		Rast_is_f_null_value(&buf[col])) {
		Rast_set_f_null_value(&buf[col], 1);
		continue;
	    }
	    if (ialt_fd >= 0) {
		if (alt[col] < 0)
		    alt[col] = 0; /* on or below sea level, all the same for 6S */
		else
		    alt[col] /= 1000.0f;	/* converting to km from input which should be in meter */

		/* round to nearest altitude bin */
		/* rounding result: watch out for fp representation error */
		alt[col] = ((int) (alt[col] * BIN_ALT + 0.5)) / BIN_ALT;
	    }
	    if (ivis_fd >= 0) {
		if (vis[col] < 0)
		    vis[col] = 0; /* negative visibility is invalid, print a WARNING ? */

		/* round to nearest visibility bin */
		/* rounding result: watch out for fp representation error */
		vis[col] = ((int) (vis[col] + 0.5));
	    }

	    /* check if both maps are active and if whether any value has changed */
	    if ((ialt_fd >= 0) && (ivis_fd >= 0) &&
		((prev_vis != vis[col]) || (prev_alt != alt[col]))) {
		prev_alt = alt[col];	/* update new values */
		prev_vis = vis[col];
		if (optimize) {
		    int in_cache = ticache.search(alt[col], vis[col], &ti);

		    if (!in_cache) {
			pre_compute_hv(alt[col], vis[col]);	/* re-compute transformation inputs */
			ti = compute();	/* ... */

			ticache.add(ti, alt[col], vis[col]);
		    }
		}
		else {
		    pre_compute_hv(alt[col], vis[col]);	/* re-compute transformation inputs */
		    ti = compute();	/* ... */
		}
	    }
	    else {		/* only one of the maps is being used */

		if ((ivis_fd >= 0) && (prev_vis != vis[col])) {
		    prev_vis = vis[col];	/* keep track of previous visibility */

		    if (optimize) {
			int in_cache = ticache.search(0, vis[col], &ti);

			if (!in_cache) {
			    pre_compute_v(vis[col]);	/* re-compute transformation inputs */
			    ti = compute();	/* ... */

			    ticache.add(ti, 0, vis[col]);
			}
		    }
		    else {
			pre_compute_v(vis[col]);	/* re-compute transformation inputs */
			ti = compute();	/* ... */
		    }
		}

		if ((ialt_fd >= 0) && (prev_alt != alt[col])) {
		    prev_alt = alt[col];	/* keep track of previous altitude */

		    if (optimize) {
			int in_cache = ticache.search(alt[col], 0, &ti);

			if (!in_cache) {
			    pre_compute_h(alt[col]);	/* re-compute transformation inputs */
			    ti = compute();	/* ... */

			    ticache.add(ti, alt[col], 0);
			}
		    }
		    else {
			pre_compute_h(alt[col]);	/* re-compute transformation inputs */
			ti = compute();	/* ... */
		    }
		}
	    }
	    G_debug(3, "Computed r%d (%d), c%d (%d)", row, nrows, col, ncols);
	    /* transform from iscale.[min,max] to [0,1] */
	    buf[col] =
		(buf[col] - iscale.min) / ((float)iscale.max -
					   (float)iscale.min);
	    buf[col] = transform(ti, imask, buf[col]);
	    /* transform from [0,1] to oscale.[min,max] */
	    buf[col] =
		buf[col] * ((float)oscale.max - (float)oscale.min) +
		oscale.min;

	    if (oint && (buf[col] > (float)oscale.max))
		G_warning(_("The output data will overflow. Reflectance > 100%%"));
	}

	/* write output */
	if (oint)
	    write_fp_to_cell(ofd, buf);
	else
	    Rast_put_row(ofd, buf, FCELL_TYPE);
    }
    G_percent(1, 1, 1);

    /* free allocated memory */
    G_free(buf);
    if (ialt_fd >= 0)
	G_free(alt);
    if (ivis_fd >= 0)
	G_free(vis);
}
Beispiel #12
0
int calculateF(int fd, area_des ad, struct Cell_head hd, double *result)
{
    FCELL *buf;
    FCELL *buf_sup;

    FCELL corrCell;
    FCELL precCell;
    FCELL supCell;

    int i, j;
    int mask_fd = -1, *mask_buf;
    int ris = 0;
    int masked = FALSE;


    long npatch = 0;
    long tot = 0;
    long zero = 0;
    long uno = 1;
    long idCorr = 0;
    long lastId = 0;
    long doppi = 0;
    long *mask_patch_sup;
    long *mask_patch_corr;

    double indice = 0;
    double area = 0;		/*if all cells are null area=0 */
    double areaCorrect = 0;
    double EW_DIST1, EW_DIST2, NS_DIST1, NS_DIST2;

    avlID_tree albero = NULL;

    avlID_table *array;



    /* open mask if needed */
    if (ad->mask == 1) {
        if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0)
            return RLI_ERRORE;
        mask_buf = G_malloc(ad->cl * sizeof(int));
        if (mask_buf == NULL) {
            G_fatal_error("malloc mask_buf failed");
            return RLI_ERRORE;
        }
        masked = TRUE;
    }

    mask_patch_sup = G_malloc(ad->cl * sizeof(long));
    if (mask_patch_sup == NULL) {
        G_fatal_error("malloc mask_patch_sup failed");
        return RLI_ERRORE;
    }

    mask_patch_corr = G_malloc(ad->cl * sizeof(long));
    if (mask_patch_corr == NULL) {
        G_fatal_error("malloc mask_patch_corr failed");
        return RLI_ERRORE;
    }

    buf_sup = Rast_allocate_f_buf();
    if (buf_sup == NULL) {
        G_fatal_error("malloc buf_sup failed");
        return RLI_ERRORE;
    }


    buf = Rast_allocate_f_buf();
    if (buf == NULL) {
        G_fatal_error("malloc buf failed");
        return RLI_ERRORE;
    }

    Rast_set_f_null_value(buf_sup + ad->x, ad->cl);	/*the first time buf_sup is all null */

    for (i = 0; i < ad->cl; i++) {
        mask_patch_sup[i] = 0;
        mask_patch_corr[i] = 0;
    }
    /*for each raster row */

    for (j = 0; j < ad->rl; j++) {
        if (j > 0) {
            buf_sup = RLI_get_fcell_raster_row(fd, j - 1 + ad->y, ad);
        }
        buf = RLI_get_fcell_raster_row(fd, j + ad->y, ad);
        if (masked) {
            if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) {
                G_fatal_error("mask read failed");
                return RLI_ERRORE;
            }
        }
        Rast_set_f_null_value(&precCell, 1);
        for (i = 0; i < ad->cl; i++) {	/*for each cell in the row */


            corrCell = buf[i + ad->x];
            if (((masked) && (mask_buf[i + ad->x] == 0))) {
                Rast_set_f_null_value(&corrCell, 1);
            }
            if (!(Rast_is_null_value(&corrCell, FCELL_TYPE))) {
                area++;
                if (i > 0)
                    precCell = buf[i - 1 + ad->x];
                if (j == 0)
                    Rast_set_f_null_value(&supCell, 1);
                else
                    supCell = buf_sup[i + ad->x];


                if (corrCell != precCell) {
                    if (corrCell != supCell) {
                        /*new patch */
                        if (idCorr == 0) {	/*first patch */
                            lastId = 1;
                            idCorr = 1;
                            mask_patch_corr[i] = idCorr;
                        }
                        else {	/*not first patch */
                            /* put in the tree previous value */
                            if (albero == NULL) {
                                albero = avlID_make(idCorr, uno);
                                if (albero == NULL) {
                                    G_fatal_error("avlID_make error");
                                    return RLI_ERRORE;
                                }
                                npatch++;

                            }
                            else {	/*tree not empty */

                                ris = avlID_add(&albero, idCorr, uno);
                                switch (ris) {
                                case AVL_ERR:
                                {
                                    G_fatal_error("avlID_add error");
                                    return RLI_ERRORE;
                                }
                                case AVL_ADD:
                                {
                                    npatch++;
                                    break;
                                }
                                case AVL_PRES:
                                {
                                    break;
                                }
                                default:
                                {
                                    G_fatal_error
                                    ("avlID_add unknown error");
                                    return RLI_ERRORE;
                                }
                                }
                            }

                            lastId++;
                            idCorr = lastId;
                            mask_patch_corr[i] = idCorr;
                        }
                    }
                    else {	/*current cell and upper cell are equal */

                        if ((corrCell == precCell) &&
                                (mask_patch_sup[i] != mask_patch_corr[i - 1])) {
                            long r = 0;
                            long del = mask_patch_sup[i];

                            r = avlID_sub(&albero, del);
                            if (r == 0) {
                                G_fatal_error("avlID_sub error");
                                return RLI_ERRORE;
                            }
                            /*Remove one patch because it makes part of a patch already found */
                            ris = avlID_add(&albero, idCorr, uno);
                            switch (ris) {
                            case AVL_ERR:
                            {
                                G_fatal_error("avlID_add error");
                                return RLI_ERRORE;
                            }
                            case AVL_ADD:
                            {
                                npatch++;
                                break;
                            }
                            case AVL_PRES:
                            {
                                break;
                            }
                            default:
                            {
                                G_fatal_error("avlID_add unknown error");
                                return RLI_ERRORE;
                            }
                            }
                            r = i;
                            while (i < ad->cl) {
                                if (mask_patch_sup[r] == del) {
                                    mask_patch_sup[r] = idCorr;
                                }
                                else {
                                    r = ad->cl + 1;
                                }
                            }
                        }

                        if (albero == NULL) {
                            albero = avlID_make(idCorr, uno);
                            if (albero == NULL) {
                                G_fatal_error("avlID_make error");
                                return RLI_ERRORE;
                            }
                            npatch++;
                        }
                        else {	/*the tree (albero) isn't null */

                            ris = avlID_add(&albero, idCorr, uno);
                            switch (ris) {
                            case AVL_ERR:
                            {
                                G_fatal_error("avlID_add error");
                                return RLI_ERRORE;
                            }
                            case AVL_ADD:
                            {
                                npatch++;
                                break;
                            }
                            case AVL_PRES:
                            {
                                break;
                            }
                            default:
                            {
                                G_fatal_error("avlID_add unknown error");
                                return RLI_ERRORE;
                            }
                            }
                        }

                        idCorr = mask_patch_sup[i];
                        mask_patch_corr[i] = idCorr;
                    }
                }
                else {		/*current cell and previous cell are equal */

                    if ((corrCell == supCell) &&
                            (mask_patch_sup[i] != mask_patch_corr[i - 1])) {
                        int l;

                        mask_patch_corr[i] = mask_patch_sup[i];
                        l = i - 1;
                        while (l >= 0) {
                            if (mask_patch_corr[l] == idCorr) {
                                mask_patch_corr[l] = mask_patch_sup[i];
                                l--;
                            }
                            else {
                                l = (-1);
                            }
                        }
                        lastId--;
                        idCorr = mask_patch_sup[i];
                    }
                    else {
                        mask_patch_corr[i] = idCorr;
                    }

                }
            }
            else {		/*null cell or cell not to consider */

                mask_patch_corr[i] = 0;
            }
        }
        mask_patch_sup = mask_patch_corr;
    }



    if (area != 0) {
        if (albero == NULL) {
            albero = avlID_make(idCorr, uno);
            if (albero == NULL) {
                G_fatal_error("avlID_make error");
                return RLI_ERRORE;
            }
            npatch++;
        }
        else {
            ris = avlID_add(&albero, idCorr, uno);
            switch (ris) {
            case AVL_ERR:
            {
                G_fatal_error("avlID_add error");
                return RLI_ERRORE;
            }
            case AVL_ADD:
            {
                npatch++;
                break;
            }
            case AVL_PRES:
            {
                break;
            }
            default:
            {
                G_fatal_error("avlID_add unknown error");
                return RLI_ERRORE;
            }
            }
        }


        array = G_malloc(npatch * sizeof(avlID_tableRow));
        if (array == NULL) {
            G_fatal_error("malloc array failed");
            return RLI_ERRORE;
        }
        tot = avlID_to_array(albero, zero, array);

        if (tot != npatch) {
            G_warning
            ("avlID_to_array unaspected value. the result could be wrong");
            return RLI_ERRORE;
        }

        for (i = 0; i < npatch; i++) {
            if (array[i]->tot == 0)
                doppi++;

        }
        npatch = npatch - doppi;

        /*calculate distance */
        G_begin_distance_calculations();
        /* EW Dist at North edge */
        EW_DIST1 = G_distance(hd.east, hd.north, hd.west, hd.north);
        /* EW Dist at South Edge */
        EW_DIST2 = G_distance(hd.east, hd.south, hd.west, hd.south);
        /* NS Dist at East edge */
        NS_DIST1 = G_distance(hd.east, hd.north, hd.east, hd.south);
        /* NS Dist at West edge */
        NS_DIST2 = G_distance(hd.west, hd.north, hd.west, hd.south);

        areaCorrect = (((EW_DIST1 + EW_DIST2) / 2) / hd.cols) *
                      (((NS_DIST1 + NS_DIST2) / 2) / hd.rows) * (area);
        indice = areaCorrect / npatch;
        G_free(array);
    }
    else
        indice = (double)(0);


    *result = indice;


    if (masked)
        G_free(mask_buf);

    G_free(mask_patch_corr);

    return RLI_OK;
}
Beispiel #13
0
int main(int argc, char **argv)
{
	IO rasters[] = { /* rasters stores output buffers */
		{"dem",YES,"Input dem","input",UNKNOWN,-1,NULL}, /* WARNING: this one map is input */
		{"forms",NO,"Most common geomorphic forms","patterns",CELL_TYPE,-1,NULL},
		{"ternary",NO,"code of ternary patterns","patterns",CELL_TYPE,-1,NULL},
		{"positive",NO,"code of binary positive patterns","patterns",CELL_TYPE,-1,NULL},
		{"negative",NO,"code of binary negative patterns","patterns",CELL_TYPE,-1,NULL},
		{"intensity",NO,"rasters containing mean relative elevation of the form","geometry",FCELL_TYPE,-1,NULL},
		{"exposition",NO,"rasters containing maximum difference between extend and central cell","geometry",FCELL_TYPE,-1,NULL},
		{"range",NO,"rasters containing difference between max and min elevation of the form extend","geometry",FCELL_TYPE,-1,NULL},
		{"variance",NO,"rasters containing variance of form boundary","geometry",FCELL_TYPE,-1,NULL},
		{"elongation",NO,"rasters containing local elongation","geometry",FCELL_TYPE,-1,NULL},
		{"azimuth",NO,"rasters containing local azimuth of the elongation","geometry",FCELL_TYPE,-1,NULL},
		{"extend",NO,"rasters containing local extend (area) of the form","geometry",FCELL_TYPE,-1,NULL},
		{"width",NO,"rasters containing local width of the form","geometry",FCELL_TYPE,-1,NULL}
	}; /* adding more maps change IOSIZE macro */
	
	CATCOLORS ccolors[CNT]={ /* colors and cats for forms */
		{ZERO, 0, 0, 0, "forms"},
		{FL, 220, 220, 220, "flat"},
		{PK, 56, 0, 0, "summit"},
		{RI, 200, 0, 0, "ridge"},
		{SH, 255, 80, 20, "shoulder"},
		{CV, 250, 210, 60, "spur"},
		{SL, 255, 255, 60, "slope"},
		{CN, 180, 230, 20, "hollow"},
		{FS, 60, 250, 150, "footslope"},
		{VL, 0, 0, 255, "valley"},
		{PT, 0, 0, 56, "depression"},
		{__, 255, 0, 255, "ERROR"}};

struct GModule *module;
	struct Option
					*opt_input,
					*opt_output[io_size],
					*par_search_radius,
					*par_skip_radius,
					*par_flat_treshold,
					*par_flat_distance;
	struct Flag *flag_units,
							*flag_extended;

	struct History history;

	int i,j, n;
	int meters=0, multires=0, extended=0; /* flags */
	int row,cur_row,col,radius;
	int pattern_size;
	double max_resolution;
	char prefix[20];

	G_gisinit(argv[0]);

{  /* interface  parameters */
	module = G_define_module();
	module->description =
	_("Calculate geomorphons (terrain forms)and associated geometry using machine vision approach");
	G_add_keyword("Geomorphons");
	G_add_keyword("Terrain patterns");
	G_add_keyword("Machine vision geomorphometry");

	opt_input = G_define_standard_option(G_OPT_R_INPUT);
	opt_input->key = rasters[0].name;
	opt_input->required = rasters[0].required;
	opt_input->description = _(rasters[0].description);

		for (i=1;i<io_size;++i) { /* WARNING: loop starts from one, zero is for input */
	opt_output[i] = G_define_standard_option(G_OPT_R_OUTPUT);
	opt_output[i]->key = rasters[i].name;
	opt_output[i]->required = NO;
	opt_output[i]->description = _(rasters[i].description);
	opt_output[i]->guisection = _(rasters[i].gui);
		}

	par_search_radius = G_define_option();
	par_search_radius->key = "search";
	par_search_radius->type = TYPE_INTEGER;
	par_search_radius->answer = "3";
	par_search_radius->required = YES;
	par_search_radius->description = _("Outer search radius");

	par_skip_radius = G_define_option();
	par_skip_radius->key = "skip";
	par_skip_radius->type = TYPE_INTEGER;
	par_skip_radius->answer = "0";
	par_skip_radius->required = YES;
	par_skip_radius->description = _("Inner search radius");

	par_flat_treshold = G_define_option();
	par_flat_treshold->key = "flat";
	par_flat_treshold->type = TYPE_DOUBLE;
	par_flat_treshold->answer = "1";
	par_flat_treshold->required = YES;
	par_flat_treshold->description = _("Flatenss treshold (degrees)");

	par_flat_distance = G_define_option();
	par_flat_distance->key = "dist";
	par_flat_distance->type = TYPE_DOUBLE;
	par_flat_distance->answer = "0";
	par_flat_distance->required = YES;
	par_flat_distance->description = _("Flatenss distance, zero for none");

	flag_units = G_define_flag();
	flag_units->key = 'm';
	flag_units->description = _("Use meters to define search units (default is cells)");

	flag_extended = G_define_flag();
	flag_extended->key = 'e';
	flag_extended->description = _("Use extended form correction");

		if (G_parser(argc, argv))
	exit(EXIT_FAILURE);
}

{	/* calculate parameters */
	int num_outputs=0;
	double search_radius, skip_radius, start_radius, step_radius;
	double ns_resolution;

			for (i=1;i<io_size;++i) /* check for outputs */
	if(opt_output[i]->answer) {
			if (G_legal_filename(opt_output[i]->answer) < 0)
		G_fatal_error(_("<%s> is an illegal file name"), opt_output[i]->answer);
		num_outputs++;
	}
		if(!num_outputs && !multires)
	G_fatal_error(_("At least one output is required"));

	meters=(flag_units->answer != 0);
	extended=(flag_extended->answer != 0);
	nrows = Rast_window_rows();
	ncols = Rast_window_cols();
	Rast_get_window(&window);
	G_begin_distance_calculations();

	if(G_projection()==PROJECTION_LL)	{ /* for LL max_res should be NS */
		ns_resolution=G_distance(0,Rast_row_to_northing(0, &window),0,Rast_row_to_northing(1, &window));
		max_resolution=ns_resolution;
	} else {
		max_resolution=MAX(window.ns_res,window.ew_res); /* max_resolution MORE meters per cell */
	}
	G_message("NSRES, %f", ns_resolution);
	cell_res=max_resolution; /* this parameter is global */
	/* search distance */
	search_radius=atof(par_search_radius->answer);
	search_cells=meters?(int)(search_radius/max_resolution):search_radius;
		if(search_cells<1)
	G_fatal_error(_("Search radius size must cover at least 1 cell"));
	row_radius_size=meters?ceil(search_radius/max_resolution):search_radius;
	row_buffer_size=row_radius_size*2+1;
	search_distance=(meters)?search_radius:max_resolution*search_cells;
	/* skip distance */
	skip_radius=atof(par_skip_radius->answer);
	skip_cells=meters?(int)(skip_radius/max_resolution):skip_radius;
		if(skip_cells>=search_cells)
	G_fatal_error(_("Skip radius size must be at least 1 cell lower than radius"));
	skip_distance=(meters)?skip_radius:ns_resolution*skip_cells;

	/* flatness parameters */
	flat_threshold=atof(par_flat_treshold->answer);
		if(flat_threshold<=0.)
	G_fatal_error(_("Flatenss treshold must be grater than 0"));
	flat_threshold=DEGREE2RAD(flat_threshold);
	
	flat_distance=atof(par_flat_distance->answer);
	flat_distance=(meters)?flat_distance:ns_resolution*flat_distance;
	flat_threshold_height=tan(flat_threshold)*flat_distance;
	if((flat_distance>0&&flat_distance<=skip_distance)||flat_distance>=search_distance) {
		G_warning(_("Flatenss distance should be between skip and search radius. Otherwise ignored"));
		flat_distance=0;
	}
		if (search_distance<10*cell_res)
	extended=0;
	
	/* print information about distances */
	G_message("Search distance m: %f, cells: %d", search_distance, search_cells);
	G_message("Skip distance m: %f, cells: %d", skip_distance, skip_cells);
	G_message("Flat threshold distance m: %f, height: %f",flat_distance, flat_threshold_height);
	G_message("%s version",(extended)?"extended":"basic");
}

	/* generate global ternary codes */
		for(i=0;i<6561;++i)
	global_ternary_codes[i]=ternary_rotate(i);

	/* open DEM */
	strcpy(elevation.elevname,opt_input->answer);
	open_map(&elevation);

	PATTERN* pattern;
	PATTERN patterns[4];
	void* pointer_buf;
	int formA, formB, formC;
	double search_dist=search_distance;
	double skip_dist=skip_distance;
	double flat_dist=flat_distance;
	double area_of_octagon=4*(search_distance*search_distance)*sin(DEGREE2RAD(45.));

	cell_step=1;
	/* prepare outputs */
		for (i=1;i<io_size;++i) 
	if(opt_output[i]->answer) {
		rasters[i].fd=Rast_open_new(opt_output[i]->answer,rasters[i].out_data_type);
		rasters[i].buffer=Rast_allocate_buf(rasters[i].out_data_type);
	}
	
	/* main loop */
	for(row=0;row<nrows;++row) {
		G_percent(row, nrows, 2);
		cur_row = (row < row_radius_size)?row:
			((row >= nrows-row_radius_size-1) ? row_buffer_size - (nrows-row-1) : row_radius_size);
			
			if(row>(row_radius_size) && row<nrows-(row_radius_size+1))
		shift_buffers(row);
		for (col=0;col<ncols;++col) {
		/* on borders forms ussualy are innatural. */
			if(row<(skip_cells+1) || row>nrows-(skip_cells+2) ||
				col<(skip_cells+1) || col>ncols-(skip_cells+2) ||
				Rast_is_f_null_value(&elevation.elev[cur_row][col])) {
/* set outputs to NULL and do nothing if source value is null	or border*/
				for (i=1;i<io_size;++i)
					if(opt_output[i]->answer) {
						pointer_buf=rasters[i].buffer;
						switch (rasters[i].out_data_type) {
						case CELL_TYPE:
							Rast_set_c_null_value(&((CELL*)pointer_buf)[col],1);
							break;
						case FCELL_TYPE:
							Rast_set_f_null_value(&((FCELL*)pointer_buf)[col],1);
							break;
						case DCELL_TYPE:
							Rast_set_d_null_value(&((DCELL*)pointer_buf)[col],1);
							break;
						default:
							G_fatal_error(_("Unknown output data type"));
						}
					}
					continue; 
			} /* end null value */
{
	int cur_form, small_form;
	search_distance=search_dist;
	skip_distance=skip_dist;
	flat_distance=flat_dist;

	pattern_size=calc_pattern(&patterns[0],row,cur_row,col);
	pattern=&patterns[0];
	cur_form=determine_form(pattern->num_negatives,pattern->num_positives);

	/* correction of forms */
	if(extended) {
		/* 1) remove extensive innatural forms: ridges, peaks, shoulders and footslopes */
		if((cur_form==4||cur_form==8||cur_form==2||cur_form==3)) {
			search_distance=(search_dist/4.<4*max_resolution)? 4*max_resolution : search_dist/4.;
			skip_distance=0;
			flat_distance=0;
			pattern_size=calc_pattern(&patterns[1],row,cur_row,col);
			pattern=&patterns[1];
			small_form=determine_form(pattern->num_negatives,pattern->num_positives);
				if(cur_form==4||cur_form==8)
			cur_form=(small_form==1)? 1 : cur_form;
				if(cur_form==2||cur_form==3)
			cur_form=small_form;
		}
		
 } /* end of correction */
	pattern=&patterns[0];
		if(opt_output[o_forms]->answer) 
	((CELL*)rasters[o_forms].buffer)[col]=cur_form;
}

				if(opt_output[o_ternary]->answer)
			((CELL*)rasters[o_ternary].buffer)[col]=determine_ternary(pattern->pattern);
				if(opt_output[o_positive]->answer)
			((CELL*)rasters[o_positive].buffer)[col]=pattern->num_positives;//rotate(pattern->positives);
				if(opt_output[o_negative]->answer)
			((CELL*)rasters[o_negative].buffer)[col]=pattern->num_negatives;//rotate(pattern->negatives);
				if(opt_output[o_intensity]->answer)
			((FCELL*)rasters[o_intensity].buffer)[col]=intensity(pattern->elevation,pattern_size);
				if(opt_output[o_exposition]->answer)
			((FCELL*)rasters[o_exposition].buffer)[col]=exposition(pattern->elevation);
				if(opt_output[o_range]->answer)
			((FCELL*)rasters[o_range].buffer)[col]=range(pattern->elevation);
				if(opt_output[o_variance]->answer)
			((FCELL*)rasters[o_variance].buffer)[col]=variance(pattern->elevation, pattern_size);

//			 used only for next four shape functions 
			if(opt_output[o_elongation]->answer ||opt_output[o_azimuth]->answer||
				opt_output[o_extend]->answer || opt_output[o_width]->answer) {
				float azimuth,elongation,width;
				radial2cartesian(pattern);
				shape(pattern, pattern_size,&azimuth,&elongation,&width);
					if(opt_output[o_azimuth]->answer)
				((FCELL*)rasters[o_azimuth].buffer)[col]=azimuth;
					if(opt_output[o_elongation]->answer)
				((FCELL*)rasters[o_elongation].buffer)[col]=elongation;
					if(opt_output[o_width]->answer)
				((FCELL*)rasters[o_width].buffer)[col]=width;
			}
				if(opt_output[o_extend]->answer)
			((FCELL*)rasters[o_extend].buffer)[col]=extends(pattern, pattern_size)/area_of_octagon;

		} /* end for col */

		/* write existing outputs */
				for (i=1;i<io_size;++i)
			if(opt_output[i]->answer)
		Rast_put_row(rasters[i].fd, rasters[i].buffer, rasters[i].out_data_type);
	}
	G_percent(row, nrows, 2); /* end main loop */

	/* finish and close */
	free_map(elevation.elev, row_buffer_size+1);
		for (i=1;i<io_size;++i)
	if(opt_output[i]->answer) {
		G_free(rasters[i].buffer);
		Rast_close(rasters[i].fd);
		Rast_short_history(opt_output[i]->answer, "raster", &history);
		Rast_command_history(&history);
		Rast_write_history(opt_output[i]->answer, &history);
	}

		if(opt_output[o_forms]->answer)
	write_form_cat_colors(opt_output[o_forms]->answer,ccolors);
		if(opt_output[o_intensity]->answer)
	write_contrast_colors(opt_output[o_intensity]->answer);
		if(opt_output[o_exposition]->answer)
	write_contrast_colors(opt_output[o_exposition]->answer);
		if(opt_output[o_range]->answer)
	write_contrast_colors(opt_output[o_range]->answer);

G_message("Done!");
exit(EXIT_SUCCESS);
}
Beispiel #14
0
int main(int argc, char *argv[])
{
    struct Cell_head cellhd;
    char *name, *result;
    char **mapname;
    FCELL **fbuf;
    int n_measures, n_outputs, *measure_idx;
    int nrows, ncols;
    int row, col, first_row, last_row, first_col, last_col;
    int i, j;
    CELL **data;		/* Data structure containing image */
    DCELL *dcell_row;
    struct FPRange range;
    DCELL min, max, inscale;
    FCELL measure;		/* Containing measure done */
    int dist, size;	/* dist = value of distance, size = s. of moving window */
    int offset;
    int have_px, have_py, have_sentr, have_pxpys, have_pxpyd;
    int infd, *outfd;
    RASTER_MAP_TYPE data_type, out_data_type;
    struct GModule *module;
    struct Option *opt_input, *opt_output, *opt_size, *opt_dist, *opt_measure;
    struct Flag *flag_ind, *flag_all;
    struct History history;
    char p[1024];

    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("raster"));
    G_add_keyword(_("algebra"));
    G_add_keyword(_("statistics"));
    G_add_keyword(_("texture"));
    module->description =
	_("Generate images with textural features from a raster map.");
    module->overwrite = 1;

    /* Define the different options */

    opt_input = G_define_standard_option(G_OPT_R_INPUT);

    opt_output = G_define_standard_option(G_OPT_R_BASENAME_OUTPUT);

    opt_size = G_define_option();
    opt_size->key = "size";
    opt_size->key_desc = "value";
    opt_size->type = TYPE_INTEGER;
    opt_size->required = NO;
    opt_size->description = _("The size of moving window (odd and >= 3)");
    opt_size->answer = "3";

    /* Textural character is in direct relation of the spatial size of the texture primitives. */

    opt_dist = G_define_option();
    opt_dist->key = "distance";
    opt_dist->key_desc = "value";
    opt_dist->type = TYPE_INTEGER;
    opt_dist->required = NO;
    opt_dist->description = _("The distance between two samples (>= 1)");
    opt_dist->answer = "1";

    for (i = 0; menu[i].name; i++) {
	if (i)
	    strcat(p, ",");
	else
	    *p = 0;
	strcat(p, menu[i].name);
    }
    opt_measure = G_define_option();
    opt_measure->key = "method";
    opt_measure->type = TYPE_STRING;
    opt_measure->required = NO;
    opt_measure->multiple = YES;
    opt_measure->options = p;
    opt_measure->description = _("Textural measurement method");

    flag_ind = G_define_flag();
    flag_ind->key = 's';
    flag_ind->description = _("Separate output for each angle (0, 45, 90, 135)");

    flag_all = G_define_flag();
    flag_all->key = 'a';
    flag_all->description = _("Calculate all textural measurements");

    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    name = opt_input->answer;
    result = opt_output->answer;
    size = atoi(opt_size->answer);
    if (size <= 0)
	G_fatal_error(_("Size of the moving window must be > 0"));
    if (size % 2 != 1)
	G_fatal_error(_("Size of the moving window must be odd"));
    dist = atoi(opt_dist->answer);
    if (dist <= 0)
	G_fatal_error(_("The distance between two samples must be > 0"));

    n_measures = 0;
    if (flag_all->answer) {
	for (i = 0; menu[i].name; i++) {
	    menu[i].useme = 1;
	}
	n_measures = i;
    }
    else {
	for (i = 0; opt_measure->answers[i]; i++) {
	    if (opt_measure->answers[i]) {
		const char *measure_name = opt_measure->answers[i];
		int n = find_measure(measure_name);

		menu[n].useme = 1;
		n_measures++;
	    }
	}
    }
    if (!n_measures)
	G_fatal_error(_("Nothing to compute. Use at least one textural measure."));
	
    measure_idx = G_malloc(n_measures * sizeof(int));
    j = 0;
    for (i = 0; menu[i].name; i++) {
	if (menu[i].useme == 1) {
	    measure_idx[j] = menu[i].idx;
	    j++;
	}
    }

    /* variables needed */
    if (menu[2].useme || menu[11].useme || menu[12].useme)
	have_px = 1;
    else
	have_px = 0;
    if (menu[11].useme || menu[12].useme)
	have_py = 1;
    else
	have_py = 0;
    if (menu[6].useme || menu[7].useme)
	have_sentr = 1;
    else
	have_sentr = 0;
    if (menu[5].useme || menu[6].useme || menu[7].useme)
	have_pxpys = 1;
    else
	have_pxpys = 0;
    if (menu[9].useme || menu[10].useme)
	have_pxpyd = 1;
    else
	have_pxpyd = 0;

    infd = Rast_open_old(name, "");

    /* determine the inputmap type (CELL/FCELL/DCELL) */
    data_type = Rast_get_map_type(infd);

    Rast_get_cellhd(name, "", &cellhd);

    out_data_type = FCELL_TYPE;
    /* Allocate output buffers, use FCELL data_type */
    n_outputs = n_measures;
    if (flag_ind->answer) {
	n_outputs = n_measures * 4;
    }

    fbuf = G_malloc(n_outputs * sizeof(FCELL *));
    mapname = G_malloc(n_outputs * sizeof(char *));
    for (i = 0; i < n_outputs; i++) {
	mapname[i] = G_malloc(GNAME_MAX * sizeof(char));
	fbuf[i] = Rast_allocate_buf(out_data_type);
    }

    /* open output maps */
    outfd = G_malloc(n_outputs * sizeof(int));
    for (i = 0; i < n_measures; i++) {
	if (flag_ind->answer) {
	    for (j = 0; j < 4; j++) {
		sprintf(mapname[i * 4 + j], "%s%s_%d", result,
		        menu[measure_idx[i]].suffix, j * 45);
		outfd[i * 4 + j] = Rast_open_new(mapname[i * 4 + j], out_data_type);
	    }
	}
	else {
	    sprintf(mapname[i], "%s%s", result,
	            menu[measure_idx[i]].suffix);
	    outfd[i] = Rast_open_new(mapname[i], out_data_type);
	}
    }
    nrows = Rast_window_rows();
    ncols = Rast_window_cols();

    /* Load raster map. */

    /* allocate the space for one row of cell map data *A* */
    dcell_row = Rast_allocate_d_buf();

    /* Allocate appropriate memory for the structure containing the image */
    data = (int **)G_malloc(nrows * sizeof(int *));
    for (i = 0; i < nrows; i++) {
	data[i] = (int *)G_malloc(ncols * sizeof(int));
    }

    /* read input range */
    Rast_init_fp_range(&range);
    Rast_read_fp_range(name, "", &range);
    Rast_get_fp_range_min_max(&range, &min, &max);
    inscale = 0;
    if (min < 0 || max > 255) {
	inscale = 255. / (max - min);
    }
    /* input has 0 - 1 range */
    else if (max <= 1.) {
	inscale = 255. / (max - min);
    }

    /* Read in cell map values */
    /* TODO: use r.proj cache */
    G_important_message(_("Reading raster map..."));
    for (j = 0; j < nrows; j++) {
	Rast_get_row(infd, dcell_row, j, DCELL_TYPE);
	for (i = 0; i < ncols; i++) {
	    if (Rast_is_d_null_value(&(dcell_row[i])))
		data[j][i] = -1;
	    else if (inscale) {
		data[j][i] = (CELL)((dcell_row[i] - min) * inscale);
	    }
	    else
		data[j][i] = (CELL)dcell_row[i];
	}
    }

    /* close input cell map and release the row buffer */
    Rast_close(infd);
    G_free(dcell_row);

    /* Now raster map is loaded to memory. */

    /* *************************************************************************************************
     *
     * Compute of the matrix S.G.L.D. (Spatial Gray-Level Dependence Matrices) or co-occurrence matrix.
     * The image is analized for piece, every piece is naming moving window (s.w.). The s.w. must be    
     * square with number of size's samples odd, that because we want the sample at the center of matrix. 
     *
     ***************************************************************************************************/

    offset = size / 2;
    first_row = first_col = offset;
    last_row = nrows - offset;
    last_col = ncols - offset;
    Rast_set_f_null_value(fbuf[0], ncols);
    for (row = 0; row < first_row; row++) {
	for (i = 0; i < n_outputs; i++) {
	    Rast_put_row(outfd[i], fbuf[0], out_data_type);
	}
    }
    if (n_measures > 1)
	G_message(n_("Calculating %d texture measure", 
        "Calculating %d texture measures", n_measures), n_measures);
    else
	G_message(_("Calculating %s"), menu[measure_idx[0]].desc);
    alloc_vars(size, dist);
    for (row = first_row; row < last_row; row++) {
	G_percent(row, nrows, 2);

	for (i = 0; i < n_outputs; i++)
	    Rast_set_f_null_value(fbuf[i], ncols);

	/*process the data */
	for (col = first_col; col < last_col; col++) {

	    if (!set_vars(data, row, col, size, offset, dist)) {
		for (i = 0; i < n_outputs; i++)
		    Rast_set_f_null_value(&(fbuf[i][col]), 1);
		continue;
	    }

	    /* for all angles (0, 45, 90, 135) */
	    for (i = 0; i < 4; i++) {
		set_angle_vars(i, have_px, have_py, have_sentr, have_pxpys, have_pxpyd);
		/* for all requested textural measures */
		for (j = 0; j < n_measures; j++) {

		    measure = (FCELL) h_measure(measure_idx[j]);

		    if (flag_ind->answer) {
			/* output for each angle separately */
			fbuf[j * 4 + i][col] = measure;
		    }
		    else {
			/* use average over all angles for each measure */
			if (i == 0)
			    fbuf[j][col] = measure;
			else if (i < 3)
			    fbuf[j][col] += measure;
			else 
			    fbuf[j][col] = (fbuf[j][col] + measure) / 4.0;
		    }
		}
	    }
	}
	for (i = 0; i < n_outputs; i++) {
	    Rast_put_row(outfd[i], fbuf[i], out_data_type);
	}
    }
    Rast_set_f_null_value(fbuf[0], ncols);
    for (row = last_row; row < nrows; row++) {
	for (i = 0; i < n_outputs; i++) {
	    Rast_put_row(outfd[i], fbuf[0], out_data_type);
	}
    }
    G_percent(nrows, nrows, 1);

    for (i = 0; i < n_outputs; i++) {
	Rast_close(outfd[i]);

	Rast_short_history(mapname[i], "raster", &history);
	Rast_command_history(&history);
	Rast_write_history(mapname[i], &history);
	G_free(fbuf[i]);
    }

    G_free(fbuf);
    G_free(data);

    exit(EXIT_SUCCESS);
}