1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <sys/types.h>
4 #include <unistd.h>
5 
6 #include <grass/gis.h>
7 #include <grass/raster.h>
8 #include <grass/glocale.h>
9 
10 #include "raster3d_intern.h"
11 
12 /*---------------------------------------------------------------------------*/
13 
14 void
Rast3d_range_update_from_tile(RASTER3D_Map * map,const void * tile,int rows,int cols,int depths,int xRedundant,int yRedundant,int zRedundant,int nofNum,int type)15 Rast3d_range_update_from_tile(RASTER3D_Map * map, const void *tile, int rows, int cols,
16 			 int depths, int xRedundant, int yRedundant,
17 			 int zRedundant, int nofNum, int type)
18 {
19     int y, z, cellType;
20     struct FPRange *range;
21 
22     range = &(map->range);
23     cellType = Rast3d_g3d_type2cell_type(type);
24 
25     if (nofNum == map->tileSize) {
26 	Rast_row_update_fp_range(tile, map->tileSize, range, cellType);
27 	return;
28     }
29 
30     if (xRedundant) {
31 	for (z = 0; z < depths; z++) {
32 	    for (y = 0; y < rows; y++) {
33 		Rast_row_update_fp_range(tile, cols, range, cellType);
34 		tile = G_incr_void_ptr(tile, map->tileX * Rast3d_length(type));
35 	    }
36 	    if (yRedundant)
37 		tile =
38 		    G_incr_void_ptr(tile,
39 				    map->tileX * yRedundant *
40 				    Rast3d_length(type));
41 	}
42 	return;
43     }
44 
45     if (yRedundant) {
46 	for (z = 0; z < depths; z++) {
47 	    Rast_row_update_fp_range(tile, map->tileX * rows, range, cellType);
48 	    tile = G_incr_void_ptr(tile, map->tileXY * Rast3d_length(type));
49 	}
50 	return;
51     }
52 
53     Rast_row_update_fp_range(tile, map->tileXY * depths, range, cellType);
54 }
55 
56 /*---------------------------------------------------------------------------*/
57 
58 int
Rast3d_read_range(const char * name,const char * mapset,struct FPRange * drange)59 Rast3d_read_range(const char *name, const char *mapset, struct FPRange *drange)
60  /* adapted from Rast_read_fp_range */
61 {
62     int fd;
63     int bytes_read;
64     char xdr_buf[2 * RASTER3D_XDR_DOUBLE_LENGTH];
65     DCELL dcell1, dcell2;
66 
67     Rast_init_fp_range(drange);
68 
69     fd = -1;
70 
71     fd = G_open_old_misc(RASTER3D_DIRECTORY, RASTER3D_RANGE_ELEMENT, name, mapset);
72     if (fd < 0) {
73 	G_warning(_("Unable to open range file for [%s in %s]"), name, mapset);
74 	return -1;
75     }
76 
77     bytes_read = read(fd, xdr_buf, 2 * RASTER3D_XDR_DOUBLE_LENGTH);
78 
79     /* if the f_range file exists, but empty the range is NULL -> a NULL map */
80     if (bytes_read == 0) {
81 	close(fd);
82         return 1;
83     }
84 
85 
86     if (bytes_read != 2 * RASTER3D_XDR_DOUBLE_LENGTH) {
87 	close(fd);
88 	G_warning(_("Error reading range file for [%s in %s]"), name, mapset);
89 	return 2;
90     }
91 
92     G_xdr_get_double(&dcell1, &xdr_buf[RASTER3D_XDR_DOUBLE_LENGTH * 0]);
93     G_xdr_get_double(&dcell2, &xdr_buf[RASTER3D_XDR_DOUBLE_LENGTH * 1]);
94 
95     Rast_update_fp_range(dcell1, drange);
96     Rast_update_fp_range(dcell2, drange);
97     close(fd);
98     return 1;
99 }
100 
101 /*---------------------------------------------------------------------------*/
102 
103 
104 /*!
105  * \brief Loads the range into the range structure of <em>map</em>.
106  *
107  *  \param map a pointer to a raster 3D map object
108  *  \return 1 ... if successful
109  *          0 ... otherwise.
110  */
111 
Rast3d_range_load(RASTER3D_Map * map)112 int Rast3d_range_load(RASTER3D_Map * map)
113 {
114     if (map->operation == RASTER3D_WRITE_DATA)
115 	return 1;
116     if (Rast3d_read_range(map->fileName, map->mapset, &(map->range)) == -1) {
117 	return 0;
118     }
119 
120     return 1;
121 }
122 
123 /*---------------------------------------------------------------------------*/
124 
125 
126 /*!
127  * \brief Returns in <em>min</em> and <em>max</em> the minimum and maximum values of
128  *        the range.
129  *
130  *  \param map a pointer to a raster 3D map object
131  *  \param min a pointer to a double to store minumim
132  *  \param max a pointer to a double to store maximum
133  */
134 
Rast3d_range_min_max(RASTER3D_Map * map,double * min,double * max)135 void Rast3d_range_min_max(RASTER3D_Map * map, double *min, double *max)
136 {
137     Rast_get_fp_range_min_max(&(map->range), min, max);
138 }
139 
140 /*-------------------------------------------------------------------------*/
141 
writeRange(const char * name,struct FPRange * range)142 static int writeRange(const char *name, struct FPRange *range)
143  /* adapted from Rast_write_fp_range */
144 {
145     char xdr_buf[2 * RASTER3D_XDR_DOUBLE_LENGTH];
146     int fd;
147 
148     fd = G_open_new_misc(RASTER3D_DIRECTORY, RASTER3D_RANGE_ELEMENT, name);
149     if (fd < 0) {
150 	G_warning(_("Unable to open range file for <%s>"), name);
151 	return -1;
152     }
153 
154     if (range->first_time) {
155 	/* if range hasn't been updated, write empty file meaning NULLs */
156 	close(fd);
157 	return 0;
158     }
159 
160     G_xdr_put_double(&xdr_buf[RASTER3D_XDR_DOUBLE_LENGTH * 0], &range->min);
161     G_xdr_put_double(&xdr_buf[RASTER3D_XDR_DOUBLE_LENGTH * 1], &range->max);
162 
163     if (write(fd, xdr_buf, RASTER3D_XDR_DOUBLE_LENGTH * 2) != RASTER3D_XDR_DOUBLE_LENGTH * 2)
164 	goto error;
165 
166     close(fd);
167     return 0;
168 
169   error:
170     close(fd);
171     G_remove_misc(RASTER3D_DIRECTORY, RASTER3D_RANGE_ELEMENT, name);	/* remove the old file with this name */
172     G_warning("can't write range file for [%s in %s]", name, G_mapset());
173     return -1;
174 }
175 
176 /*---------------------------------------------------------------------------*/
177 
178 
179 /*!
180  * \brief
181  *
182  * Writes the range which is stored in the range structure of <em>map</em>.
183  * (This function is invoked automatically when a new file is closed).
184  *
185  *  \param map
186  *  \return 1 ... if successful
187  *          0 ... otherwise.
188  */
Rast3d_range_write(RASTER3D_Map * map)189 int Rast3d_range_write(RASTER3D_Map * map)
190 {
191     char path[GPATH_MAX];
192 
193     Rast3d_filename(path, RASTER3D_RANGE_ELEMENT, map->fileName, map->mapset);
194     remove(path);
195 
196     if (writeRange(map->fileName, &(map->range)) == -1) {
197 	Rast3d_error("Rast3d_closeCellNew: error in writeRange");
198 	return 0;
199     }
200 
201     return 1;
202 }
203 
204 /*---------------------------------------------------------------------------*/
205 
Rast3d_range_init(RASTER3D_Map * map)206 int Rast3d_range_init(RASTER3D_Map * map)
207 {
208     Rast_init_fp_range(&(map->range));
209     return 0;
210 }
211