1 #include <stdio.h>
2 #include <grass/gis.h>
3 #include "raster3d_intern.h"
4
5 /*--------------------------------------------------------------------------*/
6
7 /* the standard g3d file format is used to store the mask values. a NULL-value
8 is stored for values which are masked out and a "0." is stored for values
9 which are not masked out. to improve compression, the precision is set to
10 0 and RLE encoding is used.
11 */
12
13 /*--------------------------------------------------------------------------*/
14
15 static int Rast3d_maskMapExistsVar = 0;
16 static RASTER3D_Map *Rast3d_maskMap;
17
18 /*--------------------------------------------------------------------------*/
dummy(void)19 static void dummy(void)
20 {
21 return;
22 }
23
24
25 static float RASTER3D_MASKNUMmaskValue;
26
27 /* Call to dummy() to match void return type of Rast3d_set_null_value() */
28 #define RASTER3D_MASKNUM(map,Xmask,Ymask,Zmask,VALUEmask,TYPEmask) \
29 \
30 (RASTER3D_MASKNUMmaskValue = Rast3d_getMaskFloat (map, Xmask, Ymask, Zmask), \
31 ((Rast3d_is_null_value_num (&RASTER3D_MASKNUMmaskValue, FCELL_TYPE)) ? \
32 Rast3d_set_null_value (VALUEmask, 1, TYPEmask) : dummy()))
33
34 /*--------------------------------------------------------------------------*/
35
Rast3d_mask_close()36 int Rast3d_mask_close()
37 {
38 /* No Idea if this is correct return value */
39 if (!Rast3d_maskMapExistsVar)
40 return 1;
41
42 Rast3d_maskMapExistsVar = 0;
43
44 if (!Rast3d_close(Rast3d_maskMap)) {
45 Rast3d_error("Rast3d_mask_close: error closing mask");
46
47 return 0;
48 }
49
50 return 1;
51 }
52
53 /*--------------------------------------------------------------------------*/
54
55
56 /*!
57 * \brief
58 *
59 * Returns 1 if the 3d mask file exists.
60 *
61 * \return int
62 */
63
Rast3d_mask_file_exists(void)64 int Rast3d_mask_file_exists(void)
65 {
66 return G_find_file_misc(RASTER3D_DIRECTORY, RASTER3D_CELL_ELEMENT, RASTER3D_MASK_MAP, G_mapset()) != NULL;
67 }
68
69 /*--------------------------------------------------------------------------*/
70
71 static int maskOpenOldCacheDefault = RASTER3D_USE_CACHE_DEFAULT;
72
Rast3d_mask_open_old(void)73 int Rast3d_mask_open_old(void)
74 {
75 RASTER3D_Region region;
76
77 /* No Idea if this is correct return value */
78 if (Rast3d_maskMapExistsVar)
79 return 1;
80
81 Rast3d_maskMapExistsVar = Rast3d_mask_file_exists();
82
83 if (!Rast3d_maskMapExistsVar)
84 return 1;
85
86 if ((Rast3d_maskMap = Rast3d_open_cell_old(RASTER3D_MASK_MAP, G_mapset(),
87 RASTER3D_DEFAULT_WINDOW, FCELL_TYPE,
88 maskOpenOldCacheDefault))
89 == NULL) {
90 Rast3d_error("Rast3d_mask_open_old: cannot open mask");
91
92 return 0;
93 }
94
95 Rast3d_get_region_struct_map(Rast3d_maskMap, ®ion);
96 Rast3d_set_window_map(Rast3d_maskMap, ®ion);
97
98 return 1;
99 }
100
101 /*--------------------------------------------------------------------------*/
102
Rast3d_getMaskFloat(RASTER3D_Map * map,int x,int y,int z)103 static float Rast3d_getMaskFloat(RASTER3D_Map * map, int x, int y, int z)
104 {
105 double north, east, top;
106 float value;
107
108 north = ((double)map->window.rows - y - 0.5) / (double)map->window.rows *
109 (map->window.north - map->window.south) + map->window.south;
110 east = ((double)x + 0.5) / (double)map->window.cols *
111 (map->window.east - map->window.west) + map->window.west;
112 top = ((double)z + 0.5) / (double)map->window.depths *
113 (map->window.top - map->window.bottom) + map->window.bottom;
114
115 Rast3d_get_region_value(Rast3d_maskMap, north, east, top, &value, FCELL_TYPE);
116 return value;
117 }
118
119 /*--------------------------------------------------------------------------*/
120
121
122 /*!
123 * \brief
124 *
125 * This function should be used to adjust the cache size used for the
126 * 3d-mask. First the open 3d-mask is closed and then opened again with
127 * a cache size as specified with <em>cache</em>.
128 *
129 * \param cache
130 * \return 1 ... if successful
131 * 0 ... otherwise.
132 */
133
Rast3d_mask_reopen(int cache)134 int Rast3d_mask_reopen(int cache)
135 {
136 int tmp;
137
138 if (Rast3d_maskMapExistsVar)
139 if (!Rast3d_mask_close()) {
140 Rast3d_error("Rast3d_mask_reopen: error closing mask");
141
142 return 0;
143 }
144
145 tmp = maskOpenOldCacheDefault;
146 maskOpenOldCacheDefault = cache;
147
148 if (!Rast3d_mask_open_old()) {
149 Rast3d_error("Rast3d_mask_reopen: error opening mask");
150
151 return 0;
152 }
153
154 maskOpenOldCacheDefault = tmp;
155 return 1;
156 }
157
158 /*--------------------------------------------------------------------------*/
159
160
161 /*!
162 * \brief
163 *
164 * Returns 1 if the cell with cell-coordinates <em>(x, y, z)</em> is masked
165 * out. Returns 0 otherwise.
166 *
167 * \param x
168 * \param y
169 * \param z
170 * \return int
171 */
172
Rast3d_is_masked(RASTER3D_Map * map,int x,int y,int z)173 int Rast3d_is_masked(RASTER3D_Map * map, int x, int y, int z)
174 {
175 if (!Rast3d_maskMapExistsVar)
176 return 0;
177
178 RASTER3D_MASKNUMmaskValue = Rast3d_getMaskFloat(map, x, y, z);
179 return (Rast3d_is_null_value_num(&RASTER3D_MASKNUMmaskValue, FCELL_TYPE));
180 }
181
182 /*--------------------------------------------------------------------------*/
183
184
185 /*!
186 * \brief
187 *
188 * Replaces the value stored in <em>value</em> with the NULL-value if
189 * <em>Rast3d_is_masked (x, y, z)</em> returns 1. Does nothing otherwise.
190 * <em>value</em> is assumed to be of<em>type</em>.
191 *
192 * \param x
193 * \param y
194 * \param z
195 * \param value
196 * \param type
197 * \return void
198 */
199
Rast3d_mask_num(RASTER3D_Map * map,int x,int y,int z,void * value,int type)200 void Rast3d_mask_num(RASTER3D_Map * map, int x, int y, int z, void *value, int type)
201 {
202 if (!Rast3d_maskMapExistsVar)
203 return;
204 RASTER3D_MASKNUM(map, x, y, z, value, type);
205 }
206
207 /*--------------------------------------------------------------------------*/
208
209
210 /*!
211 * \brief
212 *
213 * Same as <em>Rast3d_mask_num (x, y, z, value, FCELL_TYPE)</em>.
214 *
215 * \param x
216 * \param y
217 * \param z
218 * \param value
219 * \return void
220 */
221
Rast3d_mask_float(RASTER3D_Map * map,int x,int y,int z,float * value)222 void Rast3d_mask_float(RASTER3D_Map * map, int x, int y, int z, float *value)
223 {
224 if (!Rast3d_maskMapExistsVar)
225 return;
226 RASTER3D_MASKNUM(map, x, y, z, value, FCELL_TYPE);
227 }
228
229 /*--------------------------------------------------------------------------*/
230
231
232 /*!
233 * \brief
234 *
235 * Same as <em>Rast3d_mask_num (x, y, z, value, DCELL_TYPE)</em>.
236 *
237 * \param x
238 * \param y
239 * \param z
240 * \param value
241 * \return void
242 */
243
Rast3d_mask_double(RASTER3D_Map * map,int x,int y,int z,double * value)244 void Rast3d_mask_double(RASTER3D_Map * map, int x, int y, int z, double *value)
245 {
246 if (!Rast3d_maskMapExistsVar)
247 return;
248 RASTER3D_MASKNUM(map, x, y, z, value, DCELL_TYPE);
249 }
250
251 /*--------------------------------------------------------------------------*/
252
253
254 /*!
255 * \brief
256 *
257 * Replaces the values stored in <em>tile</em> (with <em>tileIndex</em>) for
258 * which <em>Rast3d_is_masked</em> returns 1 with NULL-values. Does not change
259 * the remaining values. The values are assumed to be of <em>type</em>.
260 * Whether replacement is performed or not only depends on location of the
261 * cells of the tile and not on the status of the mask for <em>map</em>
262 * (i.e. turned on or off).
263 *
264 * \param map
265 * \param tileIndex
266 * \param tile
267 * \param type
268 * \return void
269 */
270
Rast3d_mask_tile(RASTER3D_Map * map,int tileIndex,void * tile,int type)271 void Rast3d_mask_tile(RASTER3D_Map * map, int tileIndex, void *tile, int type)
272 {
273 int nofNum, rows, cols, depths, xRedundant, yRedundant, zRedundant;
274 int x, y, z, xLength, yLength, dx, dy, dz, length;
275
276 if (!Rast3d_maskMapExistsVar)
277 return;
278
279 nofNum = Rast3d_compute_clipped_tile_dimensions(map, tileIndex,
280 &rows, &cols, &depths,
281 &xRedundant, &yRedundant,
282 &zRedundant);
283 Rast3d_tile_index_origin(map, tileIndex, &x, &y, &z);
284
285 if (nofNum == map->tileSize) {
286 /*AV*/
287 /* BEGIN OF ORIGINAL CODE */
288 /*
289 * Rast3d_get_tile_dimensions_map (map, &rows, &cols, &depths);
290 */
291 /*AV*/
292 /* BEGIN OF MY CODE */
293 Rast3d_get_tile_dimensions_map(map, &cols, &rows, &depths);
294 /* END OF MY CODE */
295 xRedundant = yRedundant = 0;
296 }
297
298 rows += y;
299 cols += x;
300 depths += z;
301 length = Rast3d_length(type);
302 xLength = xRedundant * length;
303 yLength = map->tileX * yRedundant * length;
304
305 for (dz = z; dz < depths; dz++) {
306 for (dy = y; dy < rows; dy++) {
307 for (dx = x; dx < cols; dx++) {
308 RASTER3D_MASKNUM(map, dx, dy, dz, tile, type);
309 tile += length;
310 }
311
312 tile += xLength;
313 }
314 tile += yLength;
315 }
316 }
317
318 /*--------------------------------------------------------------------------*/
319
320
321 /*!
322 * \brief
323 *
324 * Turns on the mask for <em>map</em>. Do
325 * not invoke this function after the first tile has been read since the result
326 * might be inconsistent cell-values.
327 *
328 * \param map
329 * \return void
330 */
331
Rast3d_mask_on(RASTER3D_Map * map)332 void Rast3d_mask_on(RASTER3D_Map * map)
333 {
334 map->useMask = 1;
335 }
336
337
338 /*!
339 * \brief
340 *
341 * Turns off the mask for <em>map</em>.
342 * This is the default. Do not invoke this function after the first tile has
343 * been read since the result might be inconsistent cell-values.
344 *
345 * \param map
346 * \return void
347 */
348
Rast3d_mask_off(RASTER3D_Map * map)349 void Rast3d_mask_off(RASTER3D_Map * map)
350 {
351 map->useMask = 0;
352 }
353
354
355 /*!
356 * \brief
357 *
358 * Returns 1 if the mask for <em>map</em>
359 * is turned on. Returns 0 otherwise.
360 *
361 * \param map
362 * \return int
363 */
364
Rast3d_mask_is_on(RASTER3D_Map * map)365 int Rast3d_mask_is_on(RASTER3D_Map * map)
366 {
367 return map->useMask;
368 }
369
370
371 /*!
372 * \brief
373 *
374 * Returns 1 if the mask for <em>map</em> is turned off. Returns 0 otherwise.
375 *
376 * \param map
377 * \return int
378 */
379
Rast3d_mask_is_off(RASTER3D_Map * map)380 int Rast3d_mask_is_off(RASTER3D_Map * map)
381 {
382 return !map->useMask;
383 }
384
385
386 /*!
387 * \brief
388 *
389 * Returns the name of the 3d mask file.
390 *
391 * \return char *
392 */
393
Rast3d_mask_file(void)394 const char *Rast3d_mask_file(void)
395 {
396 return RASTER3D_MASK_MAP;
397 }
398
399
400 /*!
401 * \brief
402 *
403 * Returns 1 if the 3d mask is loaded.
404 *
405 * \return int
406 */
407
Rast3d_mask_map_exists(void)408 int Rast3d_mask_map_exists(void)
409 {
410 return Rast3d_maskMapExistsVar;
411 }
412