1 #include <grass/gis.h>
2 #include <grass/glocale.h>
3
4 #include <gdal.h>
5
6 #include "proto.h"
7
query_band(GDALRasterBandH hBand,const char * output,struct Cell_head * cellhd,struct band_info * info)8 void query_band(GDALRasterBandH hBand, const char *output,
9 struct Cell_head *cellhd, struct band_info *info)
10 {
11 info->gdal_type = GDALGetRasterDataType(hBand);
12
13 info->null_val = GDALGetRasterNoDataValue(hBand, &info->has_null);
14
15 cellhd->compressed = 0;
16
17 switch (info->gdal_type) {
18 case GDT_Float32:
19 info->data_type = FCELL_TYPE;
20 cellhd->format = -1;
21 break;
22
23 case GDT_Float64:
24 info->data_type = DCELL_TYPE;
25 cellhd->format = -1;
26 break;
27
28 case GDT_Byte:
29 info->data_type = CELL_TYPE;
30 cellhd->format = 0;
31 break;
32
33 case GDT_Int16:
34 case GDT_UInt16:
35 info->data_type = CELL_TYPE;
36 cellhd->format = 1;
37 break;
38
39 case GDT_Int32:
40 case GDT_UInt32:
41 info->data_type = CELL_TYPE;
42 cellhd->format = 3;
43 break;
44
45 default:
46 G_fatal_error(_("Complex types not supported"));
47 break;
48 }
49
50 if (info->have_minmax)
51 GDALComputeRasterMinMax(hBand, 0, info->minmax);
52
53 Rast_init_colors(&info->colors);
54
55 if (GDALGetRasterColorTable(hBand) != NULL) {
56 GDALColorTableH hCT;
57 int count, i;
58
59 G_verbose_message(_("Copying color table for %s"), output);
60
61 hCT = GDALGetRasterColorTable(hBand);
62 count = GDALGetColorEntryCount(hCT);
63
64 for (i = 0; i < count; i++) {
65 GDALColorEntry sEntry;
66
67 GDALGetColorEntryAsRGB(hCT, i, &sEntry);
68 if (sEntry.c4 == 0)
69 continue;
70
71 Rast_set_c_color(i, sEntry.c1, sEntry.c2, sEntry.c3, &info->colors);
72 }
73 }
74 else {
75 if (info->gdal_type == GDT_Byte) {
76 /* set full 0..255 range to grey scale: */
77 G_verbose_message(_("Setting grey color table for <%s> (full 8bit range)"),
78 output);
79 Rast_make_grey_scale_colors(&info->colors, 0, 255);
80 }
81 }
82 }
83
make_cell(const char * output,const struct band_info * info)84 void make_cell(const char *output, const struct band_info *info)
85 {
86 FILE *fp;
87
88 fp = G_fopen_new("cell", output);
89 if (!fp)
90 G_fatal_error(_("Unable to create cell/%s file"), output);
91
92 fclose(fp);
93
94 if (info->data_type == CELL_TYPE)
95 return;
96
97 fp = G_fopen_new("fcell", output);
98 if (!fp)
99 G_fatal_error(_("Unable to create fcell/%s file"), output);
100
101 fclose(fp);
102 }
103
make_link(const char * input,const char * output,int band,const struct band_info * info,int flip)104 void make_link(const char *input, const char *output, int band,
105 const struct band_info *info, int flip)
106 {
107 struct Key_Value *key_val = G_create_key_value();
108 char null_str[256], type_str[8], band_str[8];
109 FILE *fp;
110
111 sprintf(band_str, "%d", band);
112
113 if (info->has_null) {
114 if (info->data_type == CELL_TYPE)
115 sprintf(null_str, "%d", (int) info->null_val);
116 else
117 sprintf(null_str, "%.22g", info->null_val);
118 }
119 else
120 strcpy(null_str, "none");
121
122 sprintf(type_str, "%d", info->gdal_type);
123
124 G_set_key_value("file", input, key_val);
125 G_set_key_value("band", band_str, key_val);
126 G_set_key_value("null", null_str, key_val);
127 G_set_key_value("type", type_str, key_val);
128 if (flip & FLIP_H)
129 G_set_key_value("hflip", "yes", key_val);
130 if (flip & FLIP_V)
131 G_set_key_value("vflip", "yes", key_val);
132
133 fp = G_fopen_new_misc("cell_misc", "gdal", output);
134 if (!fp)
135 G_fatal_error(_("Unable to create cell_misc/%s/gdal file"), output);
136
137 if (G_fwrite_key_value(fp, key_val) < 0)
138 G_fatal_error(_("Error writing cell_misc/%s/gdal file"), output);
139
140 fclose(fp);
141 }
142
write_fp_format(const char * output,const struct band_info * info)143 void write_fp_format(const char *output, const struct band_info *info)
144 {
145 struct Key_Value *key_val;
146 const char *type;
147 FILE *fp;
148
149 if (info->data_type == CELL_TYPE)
150 return;
151
152 key_val = G_create_key_value();
153
154 type = (info->data_type == FCELL_TYPE)
155 ? "float"
156 : "double";
157 G_set_key_value("type", type, key_val);
158
159 G_set_key_value("byte_order", "xdr", key_val);
160
161 fp = G_fopen_new_misc("cell_misc", "f_format", output);
162 if (!fp)
163 G_fatal_error(_("Unable to create cell_misc/%s/f_format file"), output);
164
165 if (G_fwrite_key_value(fp, key_val) < 0)
166 G_fatal_error(_("Error writing cell_misc/%s/f_format file"), output);
167
168 fclose(fp);
169
170 G_free_key_value(key_val);
171 }
172
write_fp_quant(const char * output)173 void write_fp_quant(const char *output)
174 {
175 struct Quant quant;
176
177 Rast_quant_init(&quant);
178 Rast_quant_round(&quant);
179
180 Rast_write_quant(output, G_mapset(), &quant);
181 }
182
create_map(const char * input,int band,const char * output,struct Cell_head * cellhd,struct band_info * info,const char * title,int flip)183 void create_map(const char *input, int band, const char *output,
184 struct Cell_head *cellhd, struct band_info *info,
185 const char *title, int flip)
186 {
187 struct History history;
188 struct Categories cats;
189 char buf[1024];
190
191 Rast_put_cellhd(output, cellhd);
192
193 make_cell(output, info);
194
195 make_link(input, output, band, info, flip);
196
197 if (info->data_type != CELL_TYPE) {
198 write_fp_format(output, info);
199 write_fp_quant(output);
200 }
201
202 G_verbose_message(_("Creating support files for %s"), output);
203 Rast_short_history(output, "GDAL-link", &history);
204 Rast_command_history(&history);
205 sprintf(buf, "%s band %d", input, band);
206 Rast_set_history(&history, HIST_DATSRC_1, buf);
207 Rast_write_history(output, &history);
208
209 Rast_write_colors(output, G_mapset(), &info->colors);
210 Rast_init_cats(NULL, &cats);
211 Rast_write_cats((char *)output, &cats);
212
213 if (title)
214 Rast_put_cell_title(output, title);
215
216 if (info->have_minmax) {
217 if (info->data_type == CELL_TYPE) {
218 struct Range range;
219
220 Rast_init_range(&range);
221 Rast_update_range((CELL)info->minmax[0], &range);
222 Rast_update_range((CELL)info->minmax[1], &range);
223 Rast_write_range(output, &range);
224 }
225 else {
226 struct FPRange fprange;
227
228 Rast_init_fp_range(&fprange);
229 Rast_update_fp_range(info->minmax[0], &fprange);
230 Rast_update_fp_range(info->minmax[1], &fprange);
231 Rast_write_fp_range(output, &fprange);
232 }
233 }
234
235 G_message(_("Link to raster map <%s> created."), output);
236 }
237