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