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