2
2
/****************************************************************************
6
* AUTHOR(S): Original author
7
* Soeren Gebbert soerengebbert@gmx.de
9
* PURPOSE: Converts 2D raster map slices to one 3D volume map
11
* COPYRIGHT: (C) 2005 by the GRASS Development Team
13
* This program is free software under the GNU General Public
14
* License (>=v2). Read the file COPYING that comes with GRASS
17
*****************************************************************************/
6
* AUTHOR(S): Original author
7
* Soeren Gebbert soerengebbert@gmx.de
9
* PURPOSE: Converts 2D raster map slices to one 3D volume map
11
* COPYRIGHT: (C) 2005 by the GRASS Development Team
13
* This program is free software under the GNU General Public
14
* License (>=v2). Read the file COPYING that comes with GRASS
17
*****************************************************************************/
19
19
#include <stdlib.h>
20
20
#include <string.h>
21
21
#include <grass/gis.h>
22
#include <grass/G3d.h>
22
#include <grass/raster.h>
23
#include <grass/raster3d.h>
23
24
#include <grass/glocale.h>
24
25
#include <grass/config.h>
26
27
/*- params and global variables -----------------------------------------*/
29
struct Option *input, *output;
29
struct Option *input, *output, *tilesize;
33
paramType param; /*params */
33
paramType param; /*params */
34
34
int globalRastMapType;
35
35
int globalG3dMapType;
38
38
/*- prototypes --------------------------------------------------------------*/
39
void fatal_error(void *map, int *fd, int depths, char *errorMsg); /*Simple Error message */
40
void set_params(); /*Fill the paramType structure */
41
void raster_to_g3d(void *map, G3D_Region region, int *fd); /*Write the raster */
42
int open_input_raster_map(char *name, char *mapset); /*opens the outputmap */
43
void close_input_raster_map(int fd); /*close the map */
39
void fatal_error(void *map, int *fd, int depths, char *errorMsg); /*Simple Error message */
40
void set_params(); /*Fill the paramType structure */
41
void raster_to_g3d(void *map, RASTER3D_Region region, int *fd); /*Write the raster */
42
int open_input_raster_map(const char *name); /*opens the outputmap */
43
void close_input_raster_map(int fd); /*close the map */
47
47
/* ************************************************************************* */
48
48
/* Error handling ********************************************************** */
49
50
/* ************************************************************************* */
50
51
void fatal_error(void *map, int *fd, int depths, char *errorMsg)
102
113
cols = region.cols;
103
114
depths = region.depths;
105
rast = G_allocate_raster_buf(globalRastMapType);
116
rast = Rast_allocate_buf(globalRastMapType);
107
118
G_debug(3, "raster_to_g3d: Writing %i raster maps with %i rows %i cols.",
110
121
/*Every Rastermap */
111
for (z = 0; z < depths; z++) { /*From the bottom to the top */
112
G_debug(4, "Writing g3d slice %i", z + 1);
113
for (y = 0; y < rows; y++) {
114
G_percent(y, rows - 1, 10);
116
if (!G_get_raster_row(fd[z], rast, y, globalRastMapType))
117
fatal_error(map, fd, depths, _("Could not get raster row"));
119
for (x = 0, ptr = rast; x < cols; x++,
121
G_incr_void_ptr(ptr, G_raster_size(globalRastMapType))) {
122
if (globalRastMapType == CELL_TYPE) {
123
if (G_is_null_value(ptr, globalRastMapType)) {
124
G3d_setNullValue(&dvalue, 1, DCELL_TYPE);
127
dvalue = *(CELL *) ptr;
130
(map, x, y, z, (char *)&dvalue, DCELL_TYPE) < 0)
131
fatal_error(map, fd, depths,
132
"Error writing double data");
134
else if (globalRastMapType == FCELL_TYPE) {
135
if (G_is_null_value(ptr, globalRastMapType)) {
136
G3d_setNullValue(&fvalue, 1, FCELL_TYPE);
139
fvalue = *(FCELL *) ptr;
142
(map, x, y, z, (char *)&fvalue, FCELL_TYPE) < 0)
143
fatal_error(map, fd, depths,
144
"Error writing float data");
147
else if (globalRastMapType == DCELL_TYPE) {
148
if (G_is_null_value(ptr, globalRastMapType)) {
149
G3d_setNullValue(&dvalue, 1, DCELL_TYPE);
152
dvalue = *(DCELL *) ptr;
155
(map, x, y, z, (char *)&dvalue, DCELL_TYPE) < 0)
156
fatal_error(map, fd, depths,
157
"Error writing double data");
163
G_debug(2, "\nDone\n");
122
for (z = 0; z < depths; z++) { /*From the bottom to the top */
123
G_percent(z, depths, 1);
124
G_debug(4, "Writing g3d slice %i", z + 1);
125
for (y = 0; y < rows; y++) { /* From north to south */
127
Rast_get_row(fd[z], rast, y, globalRastMapType);
129
for (x = 0, ptr = rast; x < cols; x++,
131
G_incr_void_ptr(ptr, Rast_cell_size(globalRastMapType))) {
132
if (globalRastMapType == CELL_TYPE) {
133
if (Rast_is_null_value(ptr, globalRastMapType)) {
134
Rast3d_set_null_value(&dvalue, 1, DCELL_TYPE);
136
dvalue = *(CELL *) ptr;
139
(map, x, y, z, (char *) &dvalue, DCELL_TYPE) < 0)
140
fatal_error(map, fd, depths,
141
"Error writing double data");
142
} else if (globalRastMapType == FCELL_TYPE) {
143
if (Rast_is_null_value(ptr, globalRastMapType)) {
144
Rast3d_set_null_value(&fvalue, 1, FCELL_TYPE);
146
fvalue = *(FCELL *) ptr;
149
(map, x, y, z, (char *) &fvalue, FCELL_TYPE) < 0)
150
fatal_error(map, fd, depths,
151
"Error writing float data");
152
} else if (globalRastMapType == DCELL_TYPE) {
153
if (Rast_is_null_value(ptr, globalRastMapType)) {
154
Rast3d_set_null_value(&dvalue, 1, DCELL_TYPE);
156
dvalue = *(DCELL *) ptr;
159
(map, x, y, z, (char *) &dvalue, DCELL_TYPE) < 0)
160
fatal_error(map, fd, depths,
161
"Error writing double data");
173
175
/* ************************************************************************* */
174
/* Main function, open the raster maps and create the G3D raster map ******* */
176
/* Main function, open the raster maps and create the RASTER3D raster map ******* */
175
178
/* ************************************************************************* */
176
179
int main(int argc, char *argv[])
181
RASTER3D_Region region;
179
182
struct Cell_head window2d;
180
183
struct GModule *module;
181
void *map = NULL; /*The 3D Rastermap */
184
void *map = NULL; /*The 3D Rastermap */
183
int *fd = NULL; /*The filehandler array for the 2D inputmaps */
186
int *fd = NULL; /*The filehandler array for the 2D inputmaps */
184
187
int cols, rows, opencells;
187
189
int changemask = 0;
188
190
int maptype_tmp, nofile = 0;
190
193
/* Initialize GRASS */
191
194
G_gisinit(argv[0]);
193
196
module = G_define_module();
194
module->keywords = _("raster, volume, conversion");
197
G_add_keyword(_("raster"));
198
G_add_keyword(_("conversion"));
199
G_add_keyword(_("voxel"));
195
200
module->description =
196
_("Converts 2D raster map slices to one 3D raster volume map.");
201
_("Converts 2D raster map slices to one 3D raster volume map.");
198
203
/* Get parameters from user */
201
206
/* Have GRASS get inputs */
202
207
if (G_parser(argc, argv))
206
211
/*Check for output */
207
212
if (param.output->answer == NULL)
208
G3d_fatalError(_("No output map"));
213
Rast3d_fatal_error(_("No output map"));
215
/* Get the tile size */
216
maxSize = atoi(param.tilesize->answer);
210
218
/* Figure out the region from the map */
212
G3d_getWindow(®ion);
219
Rast3d_init_defaults();
220
Rast3d_get_window(®ion);
214
222
/*Check if the g3d-region is equal to the 2d rows and cols */
215
rows = G_window_rows();
216
cols = G_window_cols();
223
rows = Rast_window_rows();
224
cols = Rast_window_cols();
218
G_debug(2, "Check the 2d and 3d region settings");
226
G_debug(2, "Check the 2D and 3D region settings");
220
228
/*If not equal, set the 2D windows correct */
221
229
if (rows != region.rows || cols != region.cols) {
222
G_message(_("The 2d and 3d region settings are different. I will use the g3d settings to adjust the 2d region."));
223
G_get_set_window(&window2d);
224
window2d.ns_res = region.ns_res;
225
window2d.ew_res = region.ew_res;
226
window2d.rows = region.rows;
227
window2d.cols = region.cols;
228
G_set_window(&window2d);
230
G_message(_("The 2D and 3D region settings are different. Using the 3D region settings to adjust the 2D region."));
231
G_get_set_window(&window2d);
232
window2d.ns_res = region.ns_res;
233
window2d.ew_res = region.ew_res;
234
window2d.rows = region.rows;
235
window2d.cols = region.cols;
236
Rast_set_window(&window2d);
232
240
/*prepare the filehandler */
233
fd = (int *)G_malloc(region.depths * sizeof(int));
241
fd = (int *) G_malloc(region.depths * sizeof (int));
236
fatal_error(map, NULL, 0, _("Out of memory"));
238
if (G_legal_filename(param.output->answer) < 0)
239
fatal_error(map, NULL, 0, _("Illegal output file name"));
244
fatal_error(map, NULL, 0, _("Out of memory"));
245
248
globalRastMapType = DCELL_TYPE;
246
249
globalG3dMapType = DCELL_TYPE;
247
250
maptype_tmp = DCELL_TYPE;
249
opencells = 0; /*Number of opened maps */
252
opencells = 0; /*Number of opened maps */
250
253
/*Loop over all output maps! open */
251
254
for (i = 0; i < region.depths; i++) {
252
/*Open only existing maps */
253
if (param.input->answers[i] != NULL && nofile == 0) {
256
name = param.input->answers[i];
257
mapset = G_find_cell2(name, "");
259
if (mapset == NULL) {
260
fatal_error(map, fd, opencells, _("Cell file not found"));
267
/*if only one map is given, open it depths - times */
268
G_message(_("Open raster map %s - one time for each depth (%d/%d)"),
269
name, i + 1, region.depths);
270
fd[i] = open_input_raster_map(name, mapset);
273
maptype_tmp = G_get_raster_map_type(fd[i]);
277
globalRastMapType = maptype_tmp;
279
if (maptype_tmp != globalRastMapType) {
280
fatal_error(map, fd, opencells,
281
_("Input maps have to be from the same type. CELL, FCELL or DCELL!"));
255
/*Open only existing maps */
256
if (nofile == 0 && param.input->answers[i])
257
name = param.input->answers[i];
261
/*if only one map is given, open it depths - times */
262
G_verbose_message(_("Open raster map %s - one time for each depth (%d/%d)"),
263
name, i + 1, region.depths);
264
fd[i] = open_input_raster_map(name);
267
maptype_tmp = Rast_get_map_type(fd[i]);
271
globalRastMapType = maptype_tmp;
273
if (maptype_tmp != globalRastMapType) {
274
fatal_error(map, fd, opencells,
275
_("Input maps have to be from the same type. CELL, FCELL or DCELL!"));
285
279
G_message(_("Creating 3D raster map"));
282
/* Set the map type depending from the arster maps type */
283
if (globalRastMapType == CELL_TYPE || globalRastMapType == DCELL_TYPE)
284
globalG3dMapType = DCELL_TYPE;
286
globalG3dMapType = FCELL_TYPE;
289
if (globalRastMapType == CELL_TYPE) {
291
G3d_openCellNew(param.output->answer, DCELL_TYPE,
292
G3D_USE_CACHE_DEFAULT, ®ion);
293
globalG3dMapType = DCELL_TYPE;
295
else if (globalRastMapType == FCELL_TYPE) {
297
G3d_openCellNew(param.output->answer, FCELL_TYPE,
298
G3D_USE_CACHE_DEFAULT, ®ion);
299
globalG3dMapType = FCELL_TYPE;
301
else if (globalRastMapType == DCELL_TYPE) {
303
G3d_openCellNew(param.output->answer, DCELL_TYPE,
304
G3D_USE_CACHE_DEFAULT, ®ion);
305
globalG3dMapType = DCELL_TYPE;
288
map = Rast3d_open_new_opt_tile_size(param.output->answer, RASTER3D_USE_CACHE_XY, ®ion, globalG3dMapType, maxSize);
309
fatal_error(map, fd, opencells, _("Error opening 3d raster map"));
291
fatal_error(map, fd, opencells, _("Error opening 3D raster map"));
311
293
/*if requested set the Mask on */
312
294
if (param.mask->answer) {
313
if (G3d_maskFileExists()) {
315
if (G3d_maskIsOff(map)) {
295
if (Rast3d_mask_file_exists()) {
297
if (Rast3d_mask_is_off(map)) {
322
/*Create the G3D Rastermap */
304
/*Create the RASTER3D Rastermap */
323
305
raster_to_g3d(map, region, fd);
325
307
/*We set the Mask off, if it was off before */
326
308
if (param.mask->answer) {
327
if (G3d_maskFileExists())
328
if (G3d_maskIsOn(map) && changemask)
309
if (Rast3d_mask_file_exists())
310
if (Rast3d_mask_is_on(map) && changemask)
311
Rast3d_mask_off(map);
332
314
/*Loop over all output maps! close */
333
315
for (i = 0; i < region.depths; i++)
334
close_input_raster_map(fd[i]);
316
close_input_raster_map(fd[i]);
322
if (!Rast3d_flush_all_tiles(map))
323
Rast3d_fatal_error("Error flushing tiles with Rast3d_flush_all_tiles");
339
324
/* Close files and exit */
340
if (!G3d_closeCell(map))
341
G3d_fatalError(_("Error closing 3d raster map"));
325
if (!Rast3d_close(map))
326
Rast3d_fatal_error(_("Error closing 3d raster map"));