link.c 5.9 KB

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