main.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  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. #define GLOBAL
  25. #include "distance.h"
  26. #include "local_proto.h"
  27. #include <grass/glocale.h>
  28. int main (int argc, char *argv[])
  29. {
  30. struct Distance *pd;
  31. char *input, *output, *mapset;
  32. char **zone_list;
  33. double to_meters;
  34. char *units;
  35. int offset;
  36. int count;
  37. int step, nsteps;
  38. struct History hist;
  39. struct GModule *module;
  40. struct Option *opt1, *opt2, *opt3, *opt4;
  41. struct Flag *flag2;
  42. int ZEROFLAG;
  43. /* initialize GRASS */
  44. G_gisinit(argv[0]);
  45. pgm_name = argv[0];
  46. module = G_define_module();
  47. module->keywords = _("raster, buffer");
  48. module->description =
  49. _("Creates a raster map layer showing buffer zones "
  50. "surrounding cells that contain non-NULL category values.");
  51. opt1 = G_define_standard_option(G_OPT_R_INPUT);
  52. opt2 = G_define_standard_option(G_OPT_R_OUTPUT);
  53. opt3 = G_define_option() ;
  54. opt3->key = "distances" ;
  55. opt3->type = TYPE_DOUBLE;
  56. opt3->required = YES ;
  57. opt3->multiple = YES;
  58. opt3->description= _("Distance zone(s)") ;
  59. opt4 = G_define_option() ;
  60. opt4->key = "units" ;
  61. opt4->options = "meters,kilometers,feet,miles,nautmiles";
  62. opt4->type = TYPE_STRING ;
  63. opt4->required = NO ;
  64. opt4->description= _("Units of distance") ;
  65. opt4->answer = "meters";
  66. flag2 = G_define_flag() ;
  67. flag2->key = 'z' ;
  68. flag2->description = _("Ignore zero (0) data cells instead of NULL cells") ;
  69. if (G_parser(argc, argv))
  70. exit(EXIT_FAILURE);
  71. init_grass();
  72. /* get input, output map names */
  73. input = opt1->answer;
  74. output = opt2->answer;
  75. zone_list = opt3->answers;
  76. units = opt4->answer;
  77. ZEROFLAG = 0; /* default: use NULL for non-data cells */
  78. ZEROFLAG = (flag2->answer);
  79. mapset = G_find_cell2 (input, "");
  80. if (mapset == NULL)
  81. G_fatal_error(_("Raster map <%s> not found"), input);
  82. if (G_legal_filename(output) < 0)
  83. G_fatal_error(_("<%s> is an illegal file name"), output);
  84. /* parse units */
  85. if (opt4->answer == NULL)
  86. units = "meters";
  87. if (strcmp(units, "meters") == 0)
  88. to_meters = 1.0;
  89. else if (strcmp(units, "feet") == 0)
  90. to_meters = FEET_TO_METERS;
  91. else if (strcmp(units, "kilometers") == 0)
  92. to_meters = KILOMETERS_TO_METERS;
  93. else if (strcmp(units, "miles") == 0)
  94. to_meters = MILES_TO_METERS;
  95. else if (strcmp(units, "nautmiles") == 0)
  96. to_meters = NAUT_MILES_TO_METERS;
  97. /* parse distances */
  98. if(!(count = parse_distances (zone_list, to_meters)))
  99. G_fatal_error(_("Parse distances error"));
  100. /* need to keep track of distance zones - in memory.
  101. * process MAX_DIST at a time
  102. *
  103. * Coding: 0 == not-yet determined, 1 == input cells,
  104. * 2 == distance zone #1, 3 == distance zone #2, etc.
  105. */
  106. read_input_map (input, mapset, ZEROFLAG);
  107. offset = 0;
  108. nsteps = (count - 1) / MAX_DIST + 1;
  109. pd = distances;
  110. for (step = 1; count > 0; step++)
  111. {
  112. if (nsteps > 1)
  113. G_message(_("Pass %d (of %d)"), step, nsteps);
  114. ndist = count;
  115. if (ndist > MAX_DIST)
  116. ndist = MAX_DIST;
  117. if(count_rows_with_data > 0)
  118. execute_distance();
  119. write_output_map(output, offset);
  120. offset += ndist;
  121. distances += ndist;
  122. count -= ndist;
  123. }
  124. distances = pd;
  125. make_support_files (output, units);
  126. /* write map history (meta data) */
  127. G_short_history(output, "raster", &hist);
  128. sprintf(hist.datsrc_1, "%s", input);
  129. if( strlen(opt3->answer) < (RECORD_LEN - 14) ) {
  130. sprintf(hist.edhist[0], "Buffer distance%s:", ndist>1 ? "s" : "");
  131. sprintf(hist.edhist[1], " %s %s", opt3->answer, units);
  132. hist.edlinecnt = 2;
  133. }
  134. G_command_history(&hist);
  135. G_write_history (output, &hist);
  136. exit(EXIT_SUCCESS);
  137. }