main.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. /***************************************************************************
  2. *
  3. * MODULE: r.buffer
  4. *
  5. * AUTHOR(S): Michael Shapiro, US Army Construction Engineering Research Laboratory
  6. * James Westervelt, US Army CERL
  7. *
  8. * PURPOSE: This program creates distance zones from non-zero
  9. * cells in a grid layer. Distances are specified in
  10. * meters (on the command-line). Window does not have to
  11. * have square cells. Works both for planimetric (UTM,
  12. * State Plane) and lat-long.
  13. *
  14. * COPYRIGHT: (c) 2006 by the GRASS Development Team
  15. *
  16. * This program is free software under the GNU General Public
  17. * License (>=v2). Read the file COPYING that comes with GRASS
  18. * for details.
  19. *
  20. **************************************************************************/
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include "distance.h"
  25. #include "local_proto.h"
  26. #include <grass/raster.h>
  27. #include <grass/glocale.h>
  28. struct Distance *distances;
  29. int ndist;
  30. int wrap_ncols;
  31. MAPTYPE *map;
  32. struct Cell_head window;
  33. int minrow, maxrow, mincol, maxcol;
  34. char *pgm_name;
  35. double meters_to_grid = 1.0;
  36. double ns_to_ew_squared;
  37. int count_rows_with_data;
  38. int main(int argc, char *argv[])
  39. {
  40. struct Distance *pd;
  41. const char *input, *output, *mapset;
  42. char **zone_list;
  43. double to_meters;
  44. const char *units;
  45. int offset;
  46. int count;
  47. int step, nsteps;
  48. struct History hist;
  49. struct GModule *module;
  50. struct Option *opt1, *opt2, *opt3, *opt4;
  51. struct Flag *flag2;
  52. int ZEROFLAG;
  53. /* initialize GRASS */
  54. G_gisinit(argv[0]);
  55. pgm_name = argv[0];
  56. module = G_define_module();
  57. G_add_keyword(_("raster"));
  58. G_add_keyword(_("buffer"));
  59. module->description =
  60. _("Creates a raster map showing buffer zones "
  61. "surrounding cells that contain non-NULL category values.");
  62. opt1 = G_define_standard_option(G_OPT_R_INPUT);
  63. opt2 = G_define_standard_option(G_OPT_R_OUTPUT);
  64. opt3 = G_define_option();
  65. opt3->key = "distances";
  66. opt3->type = TYPE_DOUBLE;
  67. opt3->required = YES;
  68. opt3->multiple = YES;
  69. opt3->description = _("Distance zone(s)");
  70. opt4 = G_define_option();
  71. opt4->key = "units";
  72. opt4->options = "meters,kilometers,feet,miles,nautmiles";
  73. opt4->type = TYPE_STRING;
  74. opt4->required = NO;
  75. opt4->description = _("Units of distance");
  76. opt4->answer = "meters";
  77. flag2 = G_define_flag();
  78. flag2->key = 'z';
  79. flag2->description =
  80. _("Ignore zero (0) data cells instead of NULL cells");
  81. if (G_parser(argc, argv))
  82. exit(EXIT_FAILURE);
  83. init_grass();
  84. /* get input, output map names */
  85. input = opt1->answer;
  86. output = opt2->answer;
  87. zone_list = opt3->answers;
  88. units = opt4->answer;
  89. ZEROFLAG = 0; /* default: use NULL for non-data cells */
  90. ZEROFLAG = (flag2->answer);
  91. mapset = G_find_raster2(input, "");
  92. if (mapset == NULL)
  93. G_fatal_error(_("Raster map <%s> not found"), input);
  94. /* parse units */
  95. if (opt4->answer == NULL)
  96. units = "meters";
  97. if (strcmp(units, "meters") == 0)
  98. to_meters = 1.0;
  99. else if (strcmp(units, "feet") == 0)
  100. to_meters = FEET_TO_METERS;
  101. else if (strcmp(units, "kilometers") == 0)
  102. to_meters = KILOMETERS_TO_METERS;
  103. else if (strcmp(units, "miles") == 0)
  104. to_meters = MILES_TO_METERS;
  105. else if (strcmp(units, "nautmiles") == 0)
  106. to_meters = NAUT_MILES_TO_METERS;
  107. /* parse distances */
  108. if (!(count = parse_distances(zone_list, to_meters)))
  109. G_fatal_error(_("Parse distances error"));
  110. /* need to keep track of distance zones - in memory.
  111. * process MAX_DIST at a time
  112. *
  113. * Coding: 0 == not-yet determined, 1 == input cells,
  114. * 2 == distance zone #1, 3 == distance zone #2, etc.
  115. */
  116. read_input_map(input, mapset, ZEROFLAG);
  117. offset = 0;
  118. nsteps = (count - 1) / MAX_DIST + 1;
  119. pd = distances;
  120. for (step = 1; count > 0; step++) {
  121. if (nsteps > 1)
  122. G_message(_("Pass %d (of %d)"), step, nsteps);
  123. ndist = count;
  124. if (ndist > MAX_DIST)
  125. ndist = MAX_DIST;
  126. if (count_rows_with_data > 0)
  127. execute_distance();
  128. write_output_map(output, offset);
  129. offset += ndist;
  130. distances += ndist;
  131. count -= ndist;
  132. }
  133. distances = pd;
  134. make_support_files(output, units);
  135. /* write map history (meta data) */
  136. Rast_short_history(output, "raster", &hist);
  137. Rast_set_history(&hist, HIST_DATSRC_1, input);
  138. Rast_append_format_history(&hist, "Buffer distance%s:", ndist > 1 ? "s" : "");
  139. Rast_append_format_history(&hist, " %s %s", opt3->answer, units);
  140. Rast_command_history(&hist);
  141. Rast_write_history(output, &hist);
  142. exit(EXIT_SUCCESS);
  143. }