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, &region);
96     Rast3d_set_window_map(Rast3d_maskMap, &region);
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