Beispiel #1
0
static void load_input_raster3d_maps(struct Option *scalar_opt,
				     struct Option *vector_opt,
				     struct Gradient_info *gradient_info,
				     RASTER3D_Region * region)
{
    int i;

    if (scalar_opt->answer) {
	gradient_info->scalar_map =
	    Rast3d_open_cell_old(scalar_opt->answer,
				 G_find_raster3d(scalar_opt->answer, ""),
				 region, RASTER3D_TILE_SAME_AS_FILE,
				 RASTER3D_USE_CACHE_DEFAULT);
	if (!gradient_info->scalar_map)
	    Rast3d_fatal_error(_("Unable to open 3D raster map <%s>"),
			       scalar_opt->answer);
	gradient_info->compute_gradient = TRUE;
    }
    else {
	for (i = 0; i < 3; i++) {
	    gradient_info->velocity_maps[i] =
		Rast3d_open_cell_old(vector_opt->answers[i],
				     G_find_raster3d(vector_opt->answers[i],
						     ""), region,
				     RASTER3D_TILE_SAME_AS_FILE,
				     RASTER3D_USE_CACHE_DEFAULT);

	    if (!gradient_info->velocity_maps[i])
		Rast3d_fatal_error(_("Unable to open 3D raster map <%s>"),
				   vector_opt->answers[i]);
	}
	gradient_info->compute_gradient = FALSE;
    }
}
Beispiel #2
0
static void check_vector_input_maps(struct Option *vector_opt,
				    struct Option *seed_opt)
{
    int i;

    /* Check for velocity components maps. */
    if (vector_opt->answers != NULL) {
	for (i = 0; i < 3; i++) {
	    if (vector_opt->answers[i] != NULL) {
		if (NULL == G_find_raster3d(vector_opt->answers[i], ""))
		    Rast3d_fatal_error(_("3D raster map <%s> not found"),
				       vector_opt->answers[i]);
	    }
	    else {
		Rast3d_fatal_error(_("Please provide three 3D raster maps"));
	    }
	}
    }

    if (seed_opt->answer != NULL) {
	if (NULL == G_find_vector2(seed_opt->answer, ""))
	    G_fatal_error(_("Vector seed map <%s> not found"),
			  seed_opt->answer);
    }

}
Beispiel #3
0
void Rast3d_change_precision(void *map, int precision, const char *nameOut)
{
    void *map2;
    int x, y, z, savePrecision, saveCompression;
    char *data;
    RASTER3D_Region region;
    int typeIntern;
    int nx, ny, nz;
    int tileXsave, tileYsave, tileZsave, tileX, tileY, tileZ, saveType;

    saveType = Rast3d_get_file_type();
    /*   Rast3d_set_file_type (Rast3d_file_type_map (map)); */
    Rast3d_get_compression_mode(&saveCompression, &savePrecision);
    Rast3d_set_compression_mode(RASTER3D_COMPRESSION, precision);
    Rast3d_get_tile_dimension(&tileXsave, &tileYsave, &tileZsave);
    Rast3d_get_tile_dimensions_map(map, &tileX, &tileY, &tileZ);
    Rast3d_set_tile_dimension(tileX, tileY, tileZ);

    typeIntern = Rast3d_tile_type_map(map);
    Rast3d_get_region_struct_map(map, &region);

    map2 =
	Rast3d_open_cell_new(nameOut, typeIntern, RASTER3D_USE_CACHE_DEFAULT, &region);
    if (map2 == NULL)
	Rast3d_fatal_error("Rast3d_change_precision: error in Rast3d_open_cell_new");

    Rast3d_set_file_type(saveType);
    Rast3d_set_compression_mode(saveCompression, savePrecision);
    Rast3d_set_tile_dimension(tileXsave, tileYsave, tileZsave);

    data = Rast3d_alloc_tiles(map, 1);
    if (data == NULL)
	Rast3d_fatal_error("Rast3d_change_precision: error in Rast3d_alloc_tiles");
    Rast3d_get_nof_tiles_map(map2, &nx, &ny, &nz);

    for (z = 0; z < nz; z++)
	for (y = 0; y < ny; y++)
	    for (x = 0; x < nx; x++) {
		if (!Rast3d_read_tile(map, Rast3d_tile2tile_index(map, x, y, z), data,
				  typeIntern))
		    Rast3d_fatal_error
			("Rast3d_change_precision: error in Rast3d_read_tile");
		if (!Rast3d_write_tile
		    (map2, Rast3d_tile2tile_index(map2, x, y, z), data,
		     typeIntern))
		    Rast3d_fatal_error
			("Rast3d_change_precision: error in Rast3d_write_tile");
	    }

    Rast3d_free_tiles(data);
    if (!Rast3d_close(map2))
	Rast3d_fatal_error("Rast3d_change_precision: error in Rast3d_close");
}
Beispiel #4
0
void Rast3d_set_tile_dimension(int tileX, int tileY, int tileZ)
{
    if ((g3d_tile_dimension[0] = tileX) <= 0)
	Rast3d_fatal_error
	    ("Rast3d_set_tile_dimension: value for tile x environment variable out of range");

    if ((g3d_tile_dimension[1] = tileY) <= 0)
	Rast3d_fatal_error
	    ("Rast3d_set_tile_dimension: value for tile y environment variable out of range");

    if ((g3d_tile_dimension[2] = tileZ) <= 0)
	Rast3d_fatal_error
	    ("Rast3d_set_tile_dimension: value for tile z environment variable out of range");
}
Beispiel #5
0
static void
retileNocache(void *map, const char *nameOut, int tileX, int tileY, int tileZ)
{
    void *map2;
    int x, y, z, saveType, nx, ny, nz;
    int typeIntern;
    void *data;
    int tileXsave, tileYsave, tileZsave;
    RASTER3D_Region region;

    saveType = Rast3d_get_file_type();
    Rast3d_set_file_type(Rast3d_file_type_map(map));
    Rast3d_get_tile_dimension(&tileXsave, &tileYsave, &tileZsave);
    Rast3d_set_tile_dimension(tileX, tileY, tileZ);
    typeIntern = Rast3d_tile_type_map(map);
    Rast3d_get_region_struct_map(map, &region);

    map2 = Rast3d_open_cell_new(nameOut, typeIntern, RASTER3D_NO_CACHE, &region);

    if (map2 == NULL)
	Rast3d_fatal_error("Rast3d_retile: error in Rast3d_open_cell_new");

    Rast3d_set_file_type(saveType);
    Rast3d_set_tile_dimension(tileXsave, tileYsave, tileZsave);

    data = Rast3d_alloc_tiles(map2, 1);
    if (data == NULL)
	Rast3d_fatal_error("Rast3d_retile: error in Rast3d_alloc_tiles");

    Rast3d_get_nof_tiles_map(map2, &nx, &ny, &nz);

    for (z = 0; z < nz; z++) {
        G_percent(z, nz, 1);
	for (y = 0; y < ny; y++)
	    for (x = 0; x < nx; x++) {
		Rast3d_get_block(map, x * tileX, y * tileY, z * tileZ,
			     tileX, tileY, tileZ, data, typeIntern);
		if (!Rast3d_write_tile
		    (map2, Rast3d_tile2tile_index(map2, x, y, z), data,
		     typeIntern))
		    Rast3d_fatal_error
			("Rast3d_retileNocache: error in Rast3d_write_tile");
	    }
    }
    
    G_percent(1, 1, 1);
        
    Rast3d_free_tiles(data);
    Rast3d_close(map2);
}
Beispiel #6
0
void Rast3d_set_cache_size(int nTiles)
{
    if (nTiles < 0)
	Rast3d_fatal_error("Rast3d_set_cache_size: size out of range.");

    g3d_cache_default = nTiles;
}
Beispiel #7
0
void Rast3d_set_cache_limit(int nBytes)
{
    if (nBytes <= 0)
	Rast3d_fatal_error("Rast3d_set_cache_limit: size out of range.");

    g3d_cache_max = nBytes;
}
Beispiel #8
0
void Rast3d_set_file_type(int type)
{
    if ((type != FCELL_TYPE) && (type != DCELL_TYPE))
	Rast3d_fatal_error("Rast3d_setFileTypeDefault: invalid type");

    g3d_file_type = type;
}
Beispiel #9
0
/*---------------------------------------------------------------------------*/
void fatalError(char *errorMsg)
{
    if (map != NULL) {
        /* should unopen map here! */
        Rast3d_close(map);
    }

    Rast3d_fatal_error("%s", errorMsg);
}
Beispiel #10
0
static void init_flowaccum(RASTER3D_Region * region, RASTER3D_Map * flowacc)
{
    int c, r, d;

    for (d = 0; d < region->depths; d++)
	for (r = 0; r < region->rows; r++)
	    for (c = 0; c < region->cols; c++)
		if (Rast3d_put_float(flowacc, c, r, d, 0) != 1)
		    Rast3d_fatal_error(_("init_flowaccum: error in Rast3d_put_float"));
}
Beispiel #11
0
/* ************************************************************************* */
void fatal_error(void *map, int *fd, int depths, char *errorMsg)
{
    int i;

    /* Close files and exit */
    if (map != NULL) {
        if (!Rast3d_close(map))
            Rast3d_fatal_error(_("Unable to close 3D raster map"));
    }

    if (fd != NULL) {
        for (i = 0; i < depths; i++)
            Rast_unopen(fd[i]);
    }

    Rast3d_fatal_error("%s", errorMsg);
    exit(EXIT_FAILURE);

}
Beispiel #12
0
int Rast3d_length(int t)
{
    if (!RASTER3D_IS_CORRECT_TYPE(t))
        Rast3d_fatal_error("Rast3d_length: invalid type");

    if (t == FCELL_TYPE)
        return sizeof(FCELL);
    if (t == DCELL_TYPE)
        return sizeof(DCELL);
    return 0;
}
Beispiel #13
0
int Rast3d_extern_length(int t)
{
    if (!RASTER3D_IS_CORRECT_TYPE(t))
        Rast3d_fatal_error("Rast3d_extern_length: invalid type");

    if (t == FCELL_TYPE)
        return RASTER3D_XDR_FLOAT_LENGTH;
    if (t == DCELL_TYPE)
        return RASTER3D_XDR_DOUBLE_LENGTH;
    return 0;
}
Beispiel #14
0
/* ************************************************************************* */
void fatal_error(void *map, int elevfd, int outfd, char *errorMsg)
{

    /* Close files and exit */

    if (map != NULL) {
        if (!Rast3d_close(map))
            Rast3d_fatal_error(_("Unable to close 3D raster map"));
    }

    /*unopen the output map */
    if (outfd != -1)
        Rast_unopen(outfd);

    if (elevfd != -1)
        close_output_map(elevfd);

    Rast3d_fatal_error("%s", errorMsg);
    exit(EXIT_FAILURE);

}
Beispiel #15
0
static void
getParams(char **name, d_Mask ** maskRules, int *changeNull,
	  double *newNullVal)
{
    *name = params.map->answer;
    Rast3d_parse_vallist(params.setNull->answers, maskRules);

    *changeNull = (params.null->answer != NULL);
    if (*changeNull)
	if (sscanf(params.null->answer, "%lf", newNullVal) != 1)
	    Rast3d_fatal_error(_("Illegal value for null"));
}
Beispiel #16
0
int Rast3d_write_tile(RASTER3D_Map * map, int tileIndex, const void *tile, int type)
{
    int rows, cols, depths, xRedundant, yRedundant, zRedundant, nofNum;

    /* valid tileIndex ? */
    if ((tileIndex >= map->nTiles) || (tileIndex < 0))
	Rast3d_fatal_error("Rast3d_write_tile: tileIndex out of range");

    /* already written ? */
    if (map->index[tileIndex] != -1)
	return 2;

    /* save the file position */
    map->index[tileIndex] = lseek(map->data_fd, (long)0, SEEK_END);
    if (map->index[tileIndex] == -1) {
	Rast3d_error("Rast3d_write_tile: can't position file");
	return 0;
    }

    nofNum = Rast3d_compute_clipped_tile_dimensions(map, tileIndex,
					      &rows, &cols, &depths,
					      &xRedundant, &yRedundant,
					      &zRedundant);

    Rast3d_range_update_from_tile(map, tile, rows, cols, depths,
			     xRedundant, yRedundant, zRedundant, nofNum,
			     type);

    if (!Rast3d_tile2xdrTile(map, tile, rows, cols, depths,
			  xRedundant, yRedundant, zRedundant, nofNum, type)) {
	Rast3d_error("Rast3d_writeTileCompressed: error in Rast3d_tile2xdrTile");
	return 0;
    }

    if (map->compression == RASTER3D_NO_COMPRESSION) {
	if (!Rast3d_writeTileUncompressed(map, nofNum)) {
	    Rast3d_error("Rast3d_write_tile: error in Rast3d_writeTileUncompressed");
	    return 0;
	}
    }
    else if (!Rast3d_writeTileCompressed(map, nofNum)) {
	Rast3d_error("Rast3d_write_tile: error in Rast3d_writeTileCompressed");
	return 0;
    }

    /* compute the length */
    map->tileLength[tileIndex] = lseek(map->data_fd, (long)0, SEEK_END) -
	map->index[tileIndex];

    return 1;
}
Beispiel #17
0
static void cache_queue_enqueue(RASTER3D_cache * c, int left, int index)
{
    if (IS_IN_QUEUE_ELT(index))
	Rast3d_fatal_error("cache_queue_enqueue: index already in queue");

    if (c->first == -1) {
	if (left != c->last)
	    Rast3d_fatal_error("cache_queue_enqueue: position out of range");

	c->first = c->last = index;
	return;
    }

    if (left >= 0 && IS_NOT_IN_QUEUE_ELT(left))
	Rast3d_fatal_error("cache_queue_enqueue: position not in queue");


    if (left == -1) {
	c->next[index] = c->first;
	c->prev[c->first] = index;
	c->first = index;

	return;
    }

    c->prev[index] = left;

    if (c->next[left] == -1) {
	c->next[left] = index;
	c->last = index;

	return;
    }

    c->prev[c->next[left]] = index;
    c->next[index] = c->next[left];
    c->next[left] = index;
}
Beispiel #18
0
void
Rast3d_set_compression_mode(int doCompress, int doLzw, int doRle, int precision)
{
    if ((doCompress != RASTER3D_NO_COMPRESSION) && (doCompress != RASTER3D_COMPRESSION))
	Rast3d_fatal_error("Rast3d_set_compression_mode: wrong value for doCompress.");

    g3d_do_compression = doCompress;

    if (doCompress == RASTER3D_NO_COMPRESSION)
	return;

    if ((doLzw != RASTER3D_NO_LZW) && (doLzw != RASTER3D_USE_LZW))
	Rast3d_fatal_error("Rast3d_set_compression_mode: wrong value for doLzw.");

    if ((doRle != RASTER3D_NO_RLE) && (doRle != RASTER3D_USE_RLE))
	Rast3d_fatal_error("Rast3d_set_compression_mode: wrong value for doRle.");

    if (precision < -1)
	Rast3d_fatal_error("Rast3d_set_compression_mode: wrong value for precision.");

    g3d_do_lzw_compression = doLzw;
    g3d_do_rle_compression = doRle;
    g3d_precision = precision;
}
Beispiel #19
0
static void cache_queue_dequeue(RASTER3D_cache * c, int index)
{
    if (IS_NOT_IN_QUEUE_ELT(index))
	Rast3d_fatal_error("cache_queue_dequeue: index not in queue");

    if (index == c->first)
	c->first = c->next[index];
    if (index == c->last)
	c->last = c->prev[index];

    if (c->next[index] != -1)
	c->prev[c->next[index]] = c->prev[index];
    if (c->prev[index] != -1)
	c->next[c->prev[index]] = c->next[index];

    c->next[index] = c->prev[index] = -1;
}
Beispiel #20
0
int
Rast3d_flush_tile_cube(RASTER3D_Map * map, int xMin, int yMin, int zMin, int xMax,
		  int yMax, int zMax)
{
    int x, y, z;

    if (!map->useCache)
	Rast3d_fatal_error
	    ("Rast3d_flush_tile_cube: function invalid in non-cache mode");

    for (x = xMin; x <= xMax; x++)
	for (y = yMin; y <= yMax; y++)
	    for (z = zMin; z <= zMax; z++)
		if (!Rast3d_flush_tile(map, Rast3d_tile2tile_index(map, x, y, z))) {
		    Rast3d_error("Rast3d_flush_tile_cube: error in Rast3d_flush_tile");
		    return 0;
		}

    return 1;
}
Beispiel #21
0
int Rast3d_read_ints(int fd, int useXdr, int *i, int nofNum)
{
    char xdrIntBuf[RASTER3D_XDR_INT_LENGTH * 1024];
    unsigned int n;

    if (nofNum <= 0)
	Rast3d_fatal_error("Rast3d_read_ints: nofNum out of range");

    if (useXdr == RASTER3D_NO_XDR) {
	if (read(fd, i, sizeof(int) * nofNum) != sizeof(int) * nofNum) {
	    Rast3d_error("Rast3d_read_ints: reading from file failed");
	    return 0;
	}
	else {
	    return 1;
	}
    }

    do {
	int j;
	n = nofNum % 1024;
	if (n == 0)
	    n = 1024;

	if (read(fd, xdrIntBuf, RASTER3D_XDR_INT_LENGTH * n) !=
	    RASTER3D_XDR_INT_LENGTH * n) {
	    Rast3d_error("Rast3d_read_ints: reading xdr from file failed");
	    return 0;
	}

	for (j = 0; j < n; j++)
	    G_xdr_get_int(i, &xdrIntBuf[RASTER3D_XDR_INT_LENGTH * j]);

	nofNum -= n;
	i += n;
    } while (nofNum);

    return 1;
}
Beispiel #22
0
int Rast3d_write_ints(int fd, int useXdr, const int *i, int nofNum)
{
    char xdrIntBuf[RASTER3D_XDR_INT_LENGTH * 1024];
    unsigned int n;

    if (nofNum <= 0)
	Rast3d_fatal_error("Rast3d_write_ints: nofNum out of range");

    if (useXdr == RASTER3D_NO_XDR) {
	if (write(fd, i, sizeof(int) * nofNum) != sizeof(int) * nofNum) {
	    Rast3d_error("Rast3d_write_ints: writing to file failed");
	    return 0;
	}
	else {
	    return 1;
	}
    }

    do {
	int j;
	n = nofNum % 1024;
	if (n == 0)
	    n = 1024;

	for (j = 0; j < n; j++)
	    G_xdr_put_int(&xdrIntBuf[RASTER3D_XDR_INT_LENGTH * j], i);

	if (write(fd, xdrIntBuf, RASTER3D_XDR_INT_LENGTH * n) !=
	    RASTER3D_XDR_INT_LENGTH * n) {
	    Rast3d_error("Rast3d_write_ints: writing xdr to file failed");
	    return 0;
	}

	nofNum -= n;
	i += n;
    } while (nofNum);

    return 1;
}
Beispiel #23
0
static void makeMask(char *name, d_Mask * maskRules)
{
    void *map, *mask;
    RASTER3D_Region region;
    int tileX, tileY, tileZ, x, y, z, cacheSize;
    double value;
    float floatNull;

    cacheSize = Rast3d_cache_size_encode(RASTER3D_USE_CACHE_XY, 1);

    if (NULL == G_find_raster3d(name, ""))
	Rast3d_fatal_error(_("3D raster map <%s> not found"), name);

    map = Rast3d_open_cell_old(name, G_mapset(), RASTER3D_DEFAULT_WINDOW,
			  DCELL_TYPE, cacheSize);

    if (map == NULL)
	Rast3d_fatal_error(_("Unable to open 3D raster map <%s>"), name);

    Rast3d_get_region_struct_map(map, &region);

    Rast3d_get_tile_dimensions_map(map, &tileX, &tileY, &tileZ);

    mask = Rast3d_open_new_param(Rast3d_mask_file(), FCELL_TYPE, cacheSize,
			    &region, FCELL_TYPE, RASTER3D_COMPRESSION, 0,
			    tileX, tileY, tileZ);

    if (mask == NULL)
	Rast3d_fatal_error(_("Unable to open 3D raster mask file"));

    Rast3d_min_unlocked(map, RASTER3D_USE_CACHE_X);
    Rast3d_autolock_on(map);
    Rast3d_unlock_all(map);
    Rast3d_min_unlocked(mask, RASTER3D_USE_CACHE_X);
    Rast3d_autolock_on(mask);
    Rast3d_unlock_all(mask);

    Rast3d_set_null_value(&floatNull, 1, FCELL_TYPE);

    for (z = 0; z < region.depths; z++) {
	if ((z % tileZ) == 0) {
	    Rast3d_unlock_all(map);
	    Rast3d_unlock_all(mask);
	}
    
	for (y = 0; y < region.rows; y++)	/* We count from north to south in the cube coordinate system */
	    for (x = 0; x < region.cols; x++) {
		value = Rast3d_get_double_region(map, x, y, z);
		if (Rast3d_mask_d_select((DCELL *) & value, maskRules))
		    Rast3d_put_float(mask, x, y, z, (float)floatNull);	/* mask-out value */
		else
		    Rast3d_put_float(mask, x, y, z, (float)0.0);	/* not mask-out value */
	    }
	if ((z % tileZ) == 0) {
	    if (!Rast3d_flush_tiles_in_cube
		(mask, 0, 0, MAX(0, z - tileZ), region.rows - 1,
		 region.cols - 1, z))
		Rast3d_fatal_error(_("makeMask: error flushing tiles in cube"));
	}
    }

    if (!Rast3d_flush_all_tiles(mask))
	Rast3d_fatal_error(_("makeMask: error flushing all tiles"));

    Rast3d_autolock_off(map);
    Rast3d_unlock_all(map);
    Rast3d_autolock_off(mask);
    Rast3d_unlock_all(mask);

    if (!Rast3d_close(mask))
	Rast3d_fatal_error(_("Unable to close 3D raster mask file"));
    if (!Rast3d_close(map))
	Rast3d_fatal_error(_("Unable to close raster map <%s>"), name);
}
Beispiel #24
0
/* ************************************************************************* */
int main(int argc, char *argv[])
{
    RASTER3D_Region region, inputmap_bounds;
    struct Cell_head region2d;
    struct GModule *module;
    struct History history;
    void *map = NULL; /*The 3D Rastermap */
    int i = 0, changemask = 0;
    int *fd = NULL, output_type, cols, rows;
    char *RasterFileName;
    int overwrite = 0;

    /* Initialize GRASS */
    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("raster3d"));
    G_add_keyword(_("conversion"));
    G_add_keyword(_("raster"));
    G_add_keyword(_("voxel"));
    module->description = _("Converts 3D raster maps to 2D raster maps");

    /* Get parameters from user */
    set_params();

    /* Have GRASS get inputs */
    if (G_parser(argc, argv))
        exit(EXIT_FAILURE);

    G_debug(3, "Open 3D raster map <%s>", param.input->answer);

    if (NULL == G_find_raster3d(param.input->answer, ""))
        Rast3d_fatal_error(_("3D raster map <%s> not found"),
                       param.input->answer);

    /*Set the defaults */
    Rast3d_init_defaults();

    /*Set the resolution of the output maps */
    if (param.res->answer) {

        /*Open the map with current region */
        map = Rast3d_open_cell_old(param.input->answer,
                              G_find_raster3d(param.input->answer, ""),
                              RASTER3D_DEFAULT_WINDOW, RASTER3D_TILE_SAME_AS_FILE,
                              RASTER3D_USE_CACHE_DEFAULT);
        if (map == NULL)
            Rast3d_fatal_error(_("Unable to open 3D raster map <%s>"),
                           param.input->answer);


        /*Get the region of the map */
        Rast3d_get_region_struct_map(map, &region);
        /*set this region as current 3D window for map */
        Rast3d_set_window_map(map, &region);
        /*Set the 2d region appropriate */
        Rast3d_extract2d_region(&region, &region2d);
        /*Make the new 2d region the default */
        Rast_set_window(&region2d);

    } else {
        /* Figure out the region from the map */
        Rast3d_get_window(&region);

        /*Open the 3d raster map */
        map = Rast3d_open_cell_old(param.input->answer,
                              G_find_raster3d(param.input->answer, ""),
                              &region, RASTER3D_TILE_SAME_AS_FILE,
                              RASTER3D_USE_CACHE_DEFAULT);

        if (map == NULL)
            Rast3d_fatal_error(_("Unable to open 3D raster map <%s>"),
                           param.input->answer);
    }

    /*Check if the g3d-region is equal to the 2D rows and cols */
    rows = Rast_window_rows();
    cols = Rast_window_cols();

    /*If not equal, set the 3D window correct */
    if (rows != region.rows || cols != region.cols) {
        G_message(_("The 2D and 3D region settings are different. "
                    "Using the 2D window settings to adjust the 2D part of the 3D region."));
        G_get_set_window(&region2d);
        region.ns_res = region2d.ns_res;
        region.ew_res = region2d.ew_res;
        region.rows = region2d.rows;
        region.cols = region2d.cols;
        
        Rast3d_adjust_region(&region);
        
        Rast3d_set_window_map(map, &region);
    }

    /* save the input map region for later use (history meta-data) */
    Rast3d_get_region_struct_map(map, &inputmap_bounds);

    /*Get the output type */
    output_type = Rast3d_file_type_map(map);


    /*prepare the filehandler */
    fd = (int *) G_malloc(region.depths * sizeof (int));

    if (fd == NULL)
        fatal_error(map, NULL, 0, _("Out of memory"));

    G_message(_("Creating %i raster maps"), region.depths);

    /*Loop over all output maps! open */
    for (i = 0; i < region.depths; i++) {
        /*Create the outputmaps */
        G_asprintf(&RasterFileName, "%s_%05d", param.output->answer, i + 1);
        G_message(_("Raster map %i Filename: %s"), i + 1, RasterFileName);

        overwrite = G_check_overwrite(argc, argv);
        
        if (G_find_raster2(RasterFileName, "") && !overwrite)
            G_fatal_error(_("Raster map %d Filename: %s already exists. Use the flag --o to overwrite."),
                      i + 1, RasterFileName);

        if (output_type == FCELL_TYPE)
            fd[i] = open_output_map(RasterFileName, FCELL_TYPE);
        else if (output_type == DCELL_TYPE)
            fd[i] = open_output_map(RasterFileName, DCELL_TYPE);

    }

    /*if requested set the Mask on */
    if (param.mask->answer) {
        if (Rast3d_mask_file_exists()) {
            changemask = 0;
            if (Rast3d_mask_is_off(map)) {
                Rast3d_mask_on(map);
                changemask = 1;
            }
        }
    }

    /*Create the Rastermaps */
    g3d_to_raster(map, region, fd);


    /*Loop over all output maps! close */
    for (i = 0; i < region.depths; i++) {
        close_output_map(fd[i]);

        /* write history */
        G_asprintf(&RasterFileName, "%s_%i", param.output->answer, i + 1);
        G_debug(4, "Raster map %d Filename: %s", i + 1, RasterFileName);
        Rast_short_history(RasterFileName, "raster", &history);

        Rast_set_history(&history, HIST_DATSRC_1, "3D Raster map:");
        Rast_set_history(&history, HIST_DATSRC_2, param.input->answer);

        Rast_append_format_history(&history, "Level %d of %d", i + 1, region.depths);
        Rast_append_format_history(&history, "Level z-range: %f to %f",
                                   region.bottom + (i * region.tb_res),
                                   region.bottom + (i + 1 * region.tb_res));

        Rast_append_format_history(&history, "Input map full z-range: %f to %f",
                                   inputmap_bounds.bottom, inputmap_bounds.top);
        Rast_append_format_history(&history, "Input map z-resolution: %f",
                                   inputmap_bounds.tb_res);

        if (!param.res->answer) {
            Rast_append_format_history(&history, "GIS region full z-range: %f to %f",
                                       region.bottom, region.top);
            Rast_append_format_history(&history, "GIS region z-resolution: %f",
                                       region.tb_res);
        }

        Rast_command_history(&history);
        Rast_write_history(RasterFileName, &history);
    }

    /*We set the Mask off, if it was off before */
    if (param.mask->answer) {
        if (Rast3d_mask_file_exists())
            if (Rast3d_mask_is_on(map) && changemask)
                Rast3d_mask_off(map);
    }


    /*Cleaning */
    if (RasterFileName)
        G_free(RasterFileName);

    if (fd)
        G_free(fd);

    /* Close files and exit */
    if (!Rast3d_close(map))
        fatal_error(map, NULL, 0, _("Unable to close 3D raster map"));

    map = NULL;

    return (EXIT_SUCCESS);
}
Beispiel #25
0
/* ************************************************************************* */
void check_input_maps(void)
{
    int i = 0;
    const char *mapset, *name;

    /*Check top and bottom if surface is requested */
    if (param.structgrid->answer) {

        if (!param.top->answer || !param.bottom->answer)
            Rast3d_fatal_error(_("Specify top and bottom map"));

        mapset = NULL;
        name = NULL;
        name = param.top->answer;
        mapset = G_find_raster2(name, "");
        if (mapset == NULL) {
            Rast3d_fatal_error(_("Top cell map <%s> not found"),
                           param.top->answer);
        }

        mapset = NULL;
        name = NULL;
        name = param.bottom->answer;
        mapset = G_find_raster2(name, "");
        if (mapset == NULL) {
            Rast3d_fatal_error(_("Bottom cell map <%s> not found"),
                           param.bottom->answer);
        }
    }

    /*If input maps are provided, check them */
    if (param.input->answers != NULL) {
        for (i = 0; param.input->answers[i] != NULL; i++) {
            if (NULL == G_find_raster3d(param.input->answers[i], ""))
                Rast3d_fatal_error(_("3D raster map <%s> not found"),
                               param.input->answers[i]);
        }
    }

    /*Check for rgb maps. */
    if (param.rgbmaps->answers != NULL) {
        for (i = 0; i < 3; i++) {
            if (param.rgbmaps->answers[i] != NULL) {
                if (NULL == G_find_raster3d(param.rgbmaps->answers[i], ""))
                    Rast3d_fatal_error(_("3D raster map RGB map <%s> not found"),
                                   param.rgbmaps->answers[i]);
            } else {
                Rast3d_fatal_error(_("Please provide three RGB 3D raster maps"));
            }
        }
    }

    /*Check for vector maps. */
    if (param.vectormaps->answers != NULL) {
        for (i = 0; i < 3; i++) {
            if (param.vectormaps->answers[i] != NULL) {
                if (NULL == G_find_raster3d(param.vectormaps->answers[i], ""))
                    Rast3d_fatal_error(_("3D vector map <%s> not found"),
                                   param.vectormaps->answers[i]);
            } else {
                Rast3d_fatal_error(_("Please provide three 3D raster maps for the xyz-vector maps [x,y,z]"));
            }
        }
    }

    if (param.input->answers == NULL && param.rgbmaps->answers == NULL &&
        param.vectormaps->answers == NULL) {
        G_warning(_("No 3D raster data, RGB or xyz-vector maps are provided! Will only write the geometry."));
    }

    return;
}
Beispiel #26
0
int main(int argc, char **argv)
{
    RASTER3D_Map *input;
    RASTER3D_Map *output;
    RASTER3D_Region region;
    struct GModule *module;
    stat_func *method_fn;
    double quantile;
    int x, y, z;

    /* Initialize GRASS */
    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("raster3d"));
    G_add_keyword(_("neighbor"));
    G_add_keyword(_("aggregation"));
    G_add_keyword(_("statistics"));
    G_add_keyword(_("filter"));
    module->description =
	_("Makes each voxel value a "
	  "function of the values assigned to the voxels "
	  "around it, and stores new voxel values in an output 3D raster map");

    /* Get parameters from user */
    set_params();

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

    if (NULL == G_find_raster3d(param.input->answer, ""))
	Rast3d_fatal_error(_("3D raster map <%s> not found"),
			   param.input->answer);

    Rast3d_init_defaults();
    Rast3d_get_window(&region);

    nx = region.cols;
    ny = region.rows;
    nz = region.depths;

    /* Size fo the moving window */
    x_size = atoi(param.window->answers[0]);
    y_size = atoi(param.window->answers[1]);
    z_size = atoi(param.window->answers[2]);

    /* Distances in all directions */
    x_dist = x_size / 2;
    y_dist = y_size / 2;
    z_dist = z_size / 2;

    /* Maximum size of the buffer */
    size = x_size * y_size * z_size;

    /* Set the computation method */
    method_fn = menu[find_method(param.method->answer)].method;

    if (param.quantile->answer)
	quantile = atof(param.quantile->answer);
    else
	quantile = 0.0;

    input = Rast3d_open_cell_old(param.input->answer,
				 G_find_raster3d(param.input->answer, ""),
				 &region, RASTER3D_TILE_SAME_AS_FILE,
				 RASTER3D_USE_CACHE_DEFAULT);

    if (input == NULL)
	Rast3d_fatal_error(_("Unable to open 3D raster map <%s>"),
			   param.input->answer);

    output =
	Rast3d_open_new_opt_tile_size(param.output->answer,
				      RASTER3D_USE_CACHE_X, &region,
				      DCELL_TYPE, 32);

    if (output == NULL)
	Rast3d_fatal_error(_("Unable to open 3D raster map <%s>"),
			   param.output->answer);

    Rast3d_min_unlocked(output, RASTER3D_USE_CACHE_X);
    Rast3d_autolock_on(output);
    Rast3d_unlock_all(output);

    DCELL *buff = NULL, value;

    buff = (DCELL *) calloc(size, sizeof(DCELL));

    if (buff == NULL)
	Rast3d_fatal_error(_("Unable to allocate buffer"));

    for (z = 0; z < nz; z++) {
	for (y = 0; y < ny; y++) {
	    for (x = 0; x < nx; x++) {
		/* Gather values in moving window */
		int num = gather_values(input, buff, x, y, z);

		/* Compute the resulting value */
		if (num > 0)
		    (*method_fn) (&value, buff, num, &quantile);
		else
		    Rast_set_d_null_value(&value, 1);
		/* Write the value */
		Rast3d_put_double(output, x, y, z, value);
	    }
	}
    }

    free(buff);

    if (!Rast3d_flush_all_tiles(output))
	G_fatal_error(_("Error flushing tiles"));

    Rast3d_autolock_off(output);
    Rast3d_unlock_all(output);

    Rast3d_close(input);
    Rast3d_close(output);

    return 0;
}
Beispiel #27
0
void
Rast3d_retile(void *map, const char *nameOut, int tileX, int tileY, int tileZ)
{
    void *map2;
    double value;
    int x, y, z, saveType;
    int rows, cols, depths, typeIntern;
    int xTile, yTile, zTile;
    int xOffs, yOffs, zOffs, prev;
    int tileXsave, tileYsave, tileZsave;
    RASTER3D_Region region;

    if (!Rast3d_tile_use_cache_map(map)) {
	retileNocache(map, nameOut, tileX, tileY, tileZ);
	return;
    }

    saveType = Rast3d_get_file_type();
    Rast3d_set_file_type(Rast3d_file_type_map(map));
    Rast3d_get_tile_dimension(&tileXsave, &tileYsave, &tileZsave);
    Rast3d_set_tile_dimension(tileX, tileY, tileZ);

    typeIntern = Rast3d_tile_type_map(map);
    Rast3d_get_region_struct_map(map, &region);

    map2 =
	Rast3d_open_cell_new(nameOut, typeIntern, RASTER3D_USE_CACHE_DEFAULT, &region);
    if (map2 == NULL)
	Rast3d_fatal_error("Rast3d_retile: error in Rast3d_open_cell_new");

    Rast3d_set_file_type(saveType);
    Rast3d_set_tile_dimension(tileXsave, tileYsave, tileZsave);

    Rast3d_coord2tile_coord(map2, 0, 0, 0,
			&xTile, &yTile, &zTile, &xOffs, &yOffs, &zOffs);

    prev = zTile;

    x = 0;
    y = 0;

    Rast3d_get_coords_map(map, &rows, &cols, &depths);

    for (z = 0; z < depths; z++) {
        G_percent(z, depths, 1);
	Rast3d_coord2tile_coord(map2, x, y, z, &xTile, &yTile, &zTile,
			    &xOffs, &yOffs, &zOffs);
	if (zTile > prev) {
	    if (!Rast3d_flush_all_tiles(map2))
		Rast3d_fatal_error("Rast3d_retile: error in Rast3d_flush_all_tiles");
	    prev++;
	}

	for (y = 0; y < rows; y++)
	    for (x = 0; x < cols; x++) {

		Rast3d_get_value_region(map, x, y, z, &value, typeIntern);
		if (!Rast3d_put_value(map2, x, y, z, &value, typeIntern))
		    Rast3d_fatal_error("Rast3d_retile: error in Rast3d_put_value");
	    }
    }

    G_percent(1, 1, 1);
    if (!Rast3d_flush_all_tiles(map2))
	Rast3d_fatal_error("Rast3d_retile: error in Rast3d_flush_all_tiles");
    if (!Rast3d_close(map2))
	Rast3d_fatal_error("Rast3d_retile: error in Rast3d_close");
}
Beispiel #28
0
/* ************************************************************************* */
int main(int argc, char *argv[])
{
    RASTER3D_Region region;
    struct Cell_head window2d;
    struct GModule *module;
    void *map = NULL; /*The 3D Rastermap */
    int changemask = 0;
    int elevfd = -1, outfd = -1; /*file descriptors */
    int output_type, cols, rows;

    /* Initialize GRASS */
    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("raster3d"));
    G_add_keyword(_("profile"));
    G_add_keyword(_("raster"));
    G_add_keyword(_("voxel"));
    module->description =
        _("Creates cross section 2D raster map from 3D raster map based on 2D elevation map");

    /* Get parameters from user */
    set_params();

    /* Have GRASS get inputs */
    if (G_parser(argc, argv))
        exit(EXIT_FAILURE);

    G_debug(3, "Open 3D raster map %s", param.input->answer);

    if (NULL == G_find_raster3d(param.input->answer, ""))
        Rast3d_fatal_error(_("3D raster map <%s> not found"),
                       param.input->answer);

    /* Figure out the region from the map */
    Rast3d_init_defaults();
    Rast3d_get_window(&region);

    /*Check if the g3d-region is equal to the 2d rows and cols */
    rows = Rast_window_rows();
    cols = Rast_window_cols();

    /*If not equal, set the 2D windows correct */
    if (rows != region.rows || cols != region.cols) {
        G_message
            (_("The 2D and 3D region settings are different. Using the 3D raster map settings to adjust the 2D region."));
        G_get_set_window(&window2d);
        window2d.ns_res = region.ns_res;
        window2d.ew_res = region.ew_res;
        window2d.rows = region.rows;
        window2d.cols = region.cols;
        Rast_set_window(&window2d);
    }


    /*******************/
    /*Open the 3d raster map */

    /*******************/
    map = Rast3d_open_cell_old(param.input->answer,
                          G_find_raster3d(param.input->answer, ""),
                          &region, RASTER3D_TILE_SAME_AS_FILE,
                          RASTER3D_USE_CACHE_DEFAULT);

    if (map == NULL)
        Rast3d_fatal_error(_("Unable to open 3D raster map <%s>"),
                       param.input->answer);

    /*Get the output type */
    output_type = Rast3d_file_type_map(map);

    if (output_type == FCELL_TYPE || output_type == DCELL_TYPE) {

        /********************************/
        /*Open the elevation raster map */

        /********************************/

        elevfd = Rast_open_old(param.elevation->answer, "");

        globalElevMapType = Rast_get_map_type(elevfd);

        /**********************/
        /*Open the Outputmap */

        /**********************/

        if (G_find_raster2(param.output->answer, ""))
            G_message(_("Output map already exists. Will be overwritten!"));

        if (output_type == FCELL_TYPE)
            outfd = Rast_open_new(param.output->answer, FCELL_TYPE);
        else if (output_type == DCELL_TYPE)
            outfd = Rast_open_new(param.output->answer, DCELL_TYPE);

        /*if requested set the Mask on */
        if (param.mask->answer) {
            if (Rast3d_mask_file_exists()) {
                changemask = 0;
                if (Rast3d_mask_is_off(map)) {
                    Rast3d_mask_on(map);
                    changemask = 1;
                }
            }
        }

        /************************/
        /*Create the Rastermaps */

        /************************/
        rast3d_cross_section(map, region, elevfd, outfd);

        /*We set the Mask off, if it was off before */
        if (param.mask->answer) {
            if (Rast3d_mask_file_exists())
                if (Rast3d_mask_is_on(map) && changemask)
                    Rast3d_mask_off(map);
        }

        Rast_close(outfd);
        Rast_close(elevfd);

    } else {
        fatal_error(map, -1, -1,
                    _("Wrong 3D raster datatype! Cannot create raster map"));
    }

    /* Close files and exit */
    if (!Rast3d_close(map))
        Rast3d_fatal_error(_("Unable to close 3D raster map <%s>"),
                       param.input->answer);

    return (EXIT_SUCCESS);
}
Beispiel #29
0
void *Rast3d_open_cell_old(const char *name, const char *mapset,
		      RASTER3D_Region * window, int typeIntern, int cache)
{
    RASTER3D_Map *map;
    int proj, zone;
    int compression, useRle, useLzw, type, tileX, tileY, tileZ;
    int rows, cols, depths, precision;
    double ew_res, ns_res, tb_res;
    int nofHeaderBytes, dataOffset, useXdr, hasIndex;
    char *ltmp, *unit;
    double north, south, east, west, top, bottom;

    map = Rast3d_open_cell_old_no_header(name, mapset);
    if (map == NULL) {
	Rast3d_error(_("Rast3d_open_cell_old: error in Rast3d_open_cell_old_no_header"));
	return (void *)NULL;
    }

    if (lseek(map->data_fd, (long)0, SEEK_SET) == -1) {
	Rast3d_error(_("Rast3d_open_cell_old: can't rewind file"));
	return (void *)NULL;
    }

    if (!Rast3d_read_header(map,
			&proj, &zone,
			&north, &south, &east, &west, &top, &bottom,
			&rows, &cols, &depths,
			&ew_res, &ns_res, &tb_res,
			&tileX, &tileY, &tileZ,
			&type, &compression, &useRle, &useLzw,
			&precision, &dataOffset, &useXdr, &hasIndex, &unit)) {
	Rast3d_error(_("Rast3d_open_cell_old: error in Rast3d_read_header"));
	return 0;
    }

    if (window == RASTER3D_DEFAULT_WINDOW)
	window = Rast3d_window_ptr();

    if (proj != window->proj) {
	Rast3d_error(_("Rast3d_open_cell_old: projection does not match window projection"));
	return (void *)NULL;
    }
    if (zone != window->zone) {
	Rast3d_error(_("Rast3d_open_cell_old: zone does not match window zone"));
	return (void *)NULL;
    }

    map->useXdr = useXdr;

    if (hasIndex) {
	/* see RASTER3D_openCell_new () for format of header */
	if ((!Rast3d_read_ints(map->data_fd, map->useXdr,
			   &(map->indexLongNbytes), 1)) ||
	    (!Rast3d_read_ints(map->data_fd, map->useXdr,
			   &(map->indexNbytesUsed), 1))) {
	    Rast3d_error(_("Rast3d_open_cell_old: can't read header"));
	    return (void *)NULL;
	}

	/* if our long is to short to store offsets we can't read the file */
	if (map->indexNbytesUsed > sizeof(long))
	    Rast3d_fatal_error(_("Rast3d_open_cell_old: index does not fit into long"));

	ltmp = Rast3d_malloc(map->indexLongNbytes);
	if (ltmp == NULL) {
	    Rast3d_error(_("Rast3d_open_cell_old: error in Rast3d_malloc"));
	    return (void *)NULL;
	}

	/* convert file long to long */
	if (read(map->data_fd, ltmp, map->indexLongNbytes) !=
	    map->indexLongNbytes) {
	    Rast3d_error(_("Rast3d_open_cell_old: can't read header"));
	    return (void *)NULL;
	}
	Rast3d_long_decode(ltmp, &(map->indexOffset), 1, map->indexLongNbytes);
	Rast3d_free(ltmp);
    }

    nofHeaderBytes = dataOffset;

    if (typeIntern == RASTER3D_TILE_SAME_AS_FILE)
	typeIntern = type;

    if (!Rast3d_fill_header(map, RASTER3D_READ_DATA, compression, useRle, useLzw,
			type, precision, cache,
			hasIndex, map->useXdr, typeIntern,
			nofHeaderBytes, tileX, tileY, tileZ,
			proj, zone,
			north, south, east, west, top, bottom,
			rows, cols, depths, ew_res, ns_res, tb_res, unit)) {
	Rast3d_error(_("Rast3d_open_cell_old: error in Rast3d_fill_header"));
	return (void *)NULL;
    }

    Rast3d_region_copy(&(map->window), window);
    Rast3d_adjust_region(&(map->window));
    Rast3d_get_nearest_neighbor_fun_ptr(&(map->resampleFun));

    return map;
}
Beispiel #30
0
int main(int argc, char *argv[])
{
    struct Option *vector_opt, *seed_opt, *flowlines_opt, *flowacc_opt, *sampled_opt,
	*scalar_opt, *unit_opt, *step_opt, *limit_opt, *skip_opt, *dir_opt,
	*error_opt;
    struct Flag *table_fl;
    struct GModule *module;
    RASTER3D_Region region;
    RASTER3D_Map *flowacc, *sampled;
    struct Integration integration;
    struct Seed seed;
    struct Gradient_info gradient_info;
    struct Map_info seed_Map;
    struct line_pnts *seed_points;
    struct line_cats *seed_cats;
    struct Map_info fl_map;
    struct line_cats *fl_cats;	/* for flowlines */
    struct line_pnts *fl_points;	/* for flowlines */
    struct field_info *finfo;
    dbDriver *driver;
    int cat;			/* cat of flowlines */
    int if_table;
    int i, r, c, d;
    char *desc;
    int n_seeds, seed_count, ltype;
    int skip[3];

    G_gisinit(argv[0]);
    module = G_define_module();
    G_add_keyword(_("raster3d"));
    G_add_keyword(_("hydrology"));
    G_add_keyword(_("voxel"));
    module->description =
	_("Computes 3D flow lines and 3D flow accumulation.");


    scalar_opt = G_define_standard_option(G_OPT_R3_INPUT);
    scalar_opt->required = NO;
    scalar_opt->guisection = _("Input");

    vector_opt = G_define_standard_option(G_OPT_R3_INPUTS);
    vector_opt->key = "vector_field";
    vector_opt->required = NO;
    vector_opt->description = _("Names of three 3D raster maps describing "
				"x, y, z components of vector field");
    vector_opt->guisection = _("Input");

    seed_opt = G_define_standard_option(G_OPT_V_INPUT);
    seed_opt->required = NO;
    seed_opt->key = "seed_points";
    seed_opt->description = _("If no map is provided, "
			      "flow lines are generated "
			      "from each cell of the input 3D raster");
    seed_opt->label = _("Name of vector map with points "
			"from which flow lines are generated");
    seed_opt->guisection = _("Input");

    flowlines_opt = G_define_standard_option(G_OPT_V_OUTPUT);
    flowlines_opt->key = "flowline";
    flowlines_opt->required = NO;
    flowlines_opt->description = _("Name for vector map of flow lines");
    flowlines_opt->guisection = _("Output");

    flowacc_opt = G_define_standard_option(G_OPT_R3_OUTPUT);
    flowacc_opt->key = "flowaccumulation";
    flowacc_opt->required = NO;
    flowacc_opt->description =
	_("Name for output flowaccumulation 3D raster");
    flowacc_opt->guisection = _("Output");

    sampled_opt = G_define_standard_option(G_OPT_R3_INPUT);
    sampled_opt->key = "sampled";
    sampled_opt->required = NO;
    sampled_opt->label =
            _("Name for 3D raster sampled by flowlines");
    sampled_opt->description =
            _("Values of this 3D raster will be stored "
              "as attributes of flowlines segments");

    unit_opt = G_define_option();
    unit_opt->key = "unit";
    unit_opt->type = TYPE_STRING;
    unit_opt->required = NO;
    unit_opt->answer = "cell";
    unit_opt->options = "time,length,cell";
    desc = NULL;
    G_asprintf(&desc,
	       "time;%s;"
	       "length;%s;"
	       "cell;%s",
	       _("elapsed time"),
	       _("length in map units"), _("length in cells (voxels)"));
    unit_opt->descriptions = desc;
    unit_opt->label = _("Unit of integration step");
    unit_opt->description = _("Default unit is cell");
    unit_opt->guisection = _("Integration");

    step_opt = G_define_option();
    step_opt->key = "step";
    step_opt->type = TYPE_DOUBLE;
    step_opt->required = NO;
    step_opt->answer = "0.25";
    step_opt->label = _("Integration step in selected unit");
    step_opt->description = _("Default step is 0.25 cell");
    step_opt->guisection = _("Integration");

    limit_opt = G_define_option();
    limit_opt->key = "limit";
    limit_opt->type = TYPE_INTEGER;
    limit_opt->required = NO;
    limit_opt->answer = "2000";
    limit_opt->description = _("Maximum number of steps");
    limit_opt->guisection = _("Integration");

    error_opt = G_define_option();
    error_opt->key = "max_error";
    error_opt->type = TYPE_DOUBLE;
    error_opt->required = NO;
    error_opt->answer = "1e-5";
    error_opt->label = _("Maximum error of integration");
    error_opt->description = _("Influences step, increase maximum error "
			       "to allow bigger steps");
    error_opt->guisection = _("Integration");

    skip_opt = G_define_option();
    skip_opt->key = "skip";
    skip_opt->type = TYPE_INTEGER;
    skip_opt->required = NO;
    skip_opt->multiple = YES;
    skip_opt->description =
	_("Number of cells between flow lines in x, y and z direction");

    dir_opt = G_define_option();
    dir_opt->key = "direction";
    dir_opt->type = TYPE_STRING;
    dir_opt->required = NO;
    dir_opt->multiple = NO;
    dir_opt->options = "up,down,both";
    dir_opt->answer = "down";
    dir_opt->description = _("Compute flowlines upstream, "
			     "downstream or in both direction.");

    table_fl = G_define_flag();
    table_fl->key = 'a';
    table_fl->description = _("Create and fill attribute table");

    G_option_required(scalar_opt, vector_opt, NULL);
    G_option_exclusive(scalar_opt, vector_opt, NULL);
    G_option_required(flowlines_opt, flowacc_opt, NULL);
    G_option_requires(seed_opt, flowlines_opt, NULL);
    G_option_requires(table_fl, flowlines_opt, NULL);
    G_option_requires(sampled_opt, table_fl, NULL);

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

    driver = NULL;
    finfo = NULL;

    if_table = table_fl->answer ? TRUE : FALSE;

    check_vector_input_maps(vector_opt, seed_opt);

    Rast3d_init_defaults();
    Rast3d_get_window(&region);

    /* set up integration variables */
    if (step_opt->answer) {
	integration.step = atof(step_opt->answer);
	integration.unit = unit_opt->answer;
    }
    else {
	integration.unit = "cell";
	integration.step = 0.25;
    }
    integration.max_error = atof(error_opt->answer);
    integration.max_step = 5 * integration.step;
    integration.min_step = integration.step / 5;
    integration.limit = atof(limit_opt->answer);
    if (strcmp(dir_opt->answer, "up") == 0)
	integration.direction_type = FLOWDIR_UP;
    else if (strcmp(dir_opt->answer, "down") == 0)
	integration.direction_type = FLOWDIR_DOWN;
    else
	integration.direction_type = FLOWDIR_BOTH;


    /* cell size is the diagonal */
    integration.cell_size = sqrt(region.ns_res * region.ns_res +
				 region.ew_res * region.ew_res +
				 region.tb_res * region.tb_res);

    /* set default skip if needed */
    if (skip_opt->answers) {
	for (i = 0; i < 3; i++) {
	    if (skip_opt->answers[i] != NULL) {
		skip[i] = atoi(skip_opt->answers[i]);
	    }
	    else {
		G_fatal_error(_("Please provide 3 integer values for skip option."));
	    }
	}
    }
    else {
	skip[0] = fmax(1, region.cols / 10);
	skip[1] = fmax(1, region.rows / 10);
	skip[2] = fmax(1, region.depths / 10);

    }

    /* open raster 3D maps of velocity components */
    gradient_info.initialized = FALSE;
    load_input_raster3d_maps(scalar_opt, vector_opt, &gradient_info, &region);


    /* open new 3D raster map of flowacumulation */
    if (flowacc_opt->answer) {
	flowacc = Rast3d_open_new_opt_tile_size(flowacc_opt->answer,
						RASTER3D_USE_CACHE_DEFAULT,
						&region, FCELL_TYPE, 32);


	if (!flowacc)
	    Rast3d_fatal_error(_("Unable to open 3D raster map <%s>"),
			       flowacc_opt->answer);
	init_flowaccum(&region, flowacc);
    }

    /* open 3D raster map used for sampling */
    if (sampled_opt->answer) {
	sampled = Rast3d_open_cell_old(sampled_opt->answer,
				       G_find_raster3d(sampled_opt->answer, ""),
				       &region, RASTER3D_TILE_SAME_AS_FILE,
				       RASTER3D_USE_CACHE_DEFAULT);
	if (!sampled)
	    Rast3d_fatal_error(_("Unable to open 3D raster map <%s>"),
			       sampled_opt->answer);
    }
    else
	sampled = NULL;

    /* open new vector map of flowlines */
    if (flowlines_opt->answer) {
	fl_cats = Vect_new_cats_struct();
	fl_points = Vect_new_line_struct();
	if (Vect_open_new(&fl_map, flowlines_opt->answer, TRUE) < 0)
	    G_fatal_error(_("Unable to create vector map <%s>"),
			  flowlines_opt->answer);

	Vect_hist_command(&fl_map);

	if (if_table) {
	    create_table(&fl_map, &finfo, &driver,
			 gradient_info.compute_gradient, sampled ? 1 : 0);
	}
    }

    n_seeds = 0;
    /* open vector map of seeds */
    if (seed_opt->answer) {
	if (Vect_open_old2(&seed_Map, seed_opt->answer, "", "1") < 0)
	    G_fatal_error(_("Unable to open vector map <%s>"),
			  seed_opt->answer);
	if (!Vect_is_3d(&seed_Map))
	    G_fatal_error(_("Vector map <%s> is not 3D"), seed_opt->answer);

	n_seeds = Vect_get_num_primitives(&seed_Map, GV_POINT);
    }
    if (flowacc_opt->answer || (!seed_opt->answer && flowlines_opt->answer)) {
	if (flowacc_opt->answer)
	    n_seeds += region.cols * region.rows * region.depths;
	else {
	    n_seeds += ceil(region.cols / (double)skip[0]) *
		ceil(region.rows / (double)skip[1]) *
		ceil(region.depths / (double)skip[2]);
	}
    }
    G_debug(1, "Number of seeds is %d", n_seeds);

    seed_count = 0;
    cat = 1;
    if (seed_opt->answer) {

	seed_points = Vect_new_line_struct();
	seed_cats = Vect_new_cats_struct();

	/* compute flowlines from vector seed map */
	while (TRUE) {
	    ltype = Vect_read_next_line(&seed_Map, seed_points, seed_cats);
	    if (ltype == -1) {
		Vect_close(&seed_Map);
		G_fatal_error(_("Error during reading seed vector map"));
	    }
	    else if (ltype == -2) {
		break;
	    }
	    else if (ltype == GV_POINT) {
		seed.x = seed_points->x[0];
		seed.y = seed_points->y[0];
		seed.z = seed_points->z[0];
		seed.flowline = TRUE;
		seed.flowaccum = FALSE;
	    }
	    G_percent(seed_count, n_seeds, 1);
	    if (integration.direction_type == FLOWDIR_UP ||
		integration.direction_type == FLOWDIR_BOTH) {
		integration.actual_direction = FLOWDIR_UP;
		compute_flowline(&region, &seed, &gradient_info, flowacc, sampled,
				 &integration, &fl_map, fl_cats, fl_points,
				 &cat, if_table, finfo, driver);
	    }
	    if (integration.direction_type == FLOWDIR_DOWN ||
		integration.direction_type == FLOWDIR_BOTH) {
		integration.actual_direction = FLOWDIR_DOWN;
		compute_flowline(&region, &seed, &gradient_info, flowacc, sampled,
				 &integration, &fl_map, fl_cats, fl_points,
				 &cat, if_table, finfo, driver);
	    }
	    seed_count++;
	}

	Vect_destroy_line_struct(seed_points);
	Vect_destroy_cats_struct(seed_cats);
	Vect_close(&seed_Map);
    }
    if (flowacc_opt->answer || (!seed_opt->answer && flowlines_opt->answer)) {
	/* compute flowlines from points on grid */
	for (r = region.rows; r > 0; r--) {
	    for (c = 0; c < region.cols; c++) {
		for (d = 0; d < region.depths; d++) {
		    seed.x =
			region.west + c * region.ew_res + region.ew_res / 2;
		    seed.y =
			region.south + r * region.ns_res - region.ns_res / 2;
		    seed.z =
			region.bottom + d * region.tb_res + region.tb_res / 2;
		    seed.flowline = FALSE;
		    seed.flowaccum = FALSE;
		    if (flowacc_opt->answer)
			seed.flowaccum = TRUE;

		    if (flowlines_opt->answer && !seed_opt->answer &&
		       (c % skip[0] == 0) && (r % skip[1] == 0) && (d % skip[2] == 0))
			seed.flowline = TRUE;

		    if (seed.flowaccum || seed.flowline) {
			G_percent(seed_count, n_seeds, 1);

			if (integration.direction_type == FLOWDIR_UP ||
			    integration.direction_type == FLOWDIR_BOTH) {
			    integration.actual_direction = FLOWDIR_UP;
			    compute_flowline(&region, &seed, &gradient_info,
					     flowacc, sampled, &integration, &fl_map,
					     fl_cats, fl_points, &cat,
					     if_table, finfo, driver);
			}
			if (integration.direction_type == FLOWDIR_DOWN ||
			    integration.direction_type == FLOWDIR_BOTH) {
			    integration.actual_direction = FLOWDIR_DOWN;
			    compute_flowline(&region, &seed, &gradient_info,
					     flowacc, sampled, &integration, &fl_map,
					     fl_cats, fl_points, &cat,
					     if_table, finfo, driver);
			}
			seed_count++;
		    }
		}
	    }
	}
    }
    G_percent(1, 1, 1);
    if (flowlines_opt->answer) {
	if (if_table) {
	    db_commit_transaction(driver);
	    db_close_database_shutdown_driver(driver);
	}
	Vect_destroy_line_struct(fl_points);
	Vect_destroy_cats_struct(fl_cats);
	Vect_build(&fl_map);
	Vect_close(&fl_map);
    }

    if (flowacc_opt->answer)
	Rast3d_close(flowacc);


    return EXIT_SUCCESS;
}