main.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. /****************************************************************************
  2. *
  3. * MODULE: r.stream.segment
  4. * AUTHOR(S): Jarek Jasiewicz jarekj amu.edu.pl
  5. *
  6. * PURPOSE: Calculate geometrical attributes for segments of current order,
  7. * divide segments on near straight line portions and
  8. * segment orientation and angles between streams and its
  9. * tributaries. For stream direction it use algorithm to divide
  10. * particular streams of the same order into near-straight line
  11. * portions.
  12. *
  13. *
  14. *
  15. * COPYRIGHT: (C) 2002,2010-2014 by the GRASS Development Team
  16. *
  17. * This program is free software under the GNU General Public
  18. * License (>=v2). Read the file COPYING that comes with GRASS
  19. * for details.
  20. *
  21. *****************************************************************************/
  22. #define MAIN
  23. #include <grass/glocale.h>
  24. #include "local_proto.h"
  25. int nextr[9] = { 0, -1, -1, -1, 0, 1, 1, 1, 0 };
  26. int nextc[9] = { 0, 1, 0, -1, -1, -1, 0, 1, 1 };
  27. int main(int argc, char *argv[])
  28. {
  29. struct GModule *module; /* GRASS module for parsing arguments */
  30. struct Option *in_dir_opt, /* options */
  31. *in_stm_opt,
  32. *in_elev_opt,
  33. *out_segment_opt,
  34. *out_sector_opt,
  35. *opt_length, *opt_skip, *opt_threshold, *opt_swapsize;
  36. struct Flag *flag_radians, *flag_segmentation; /* segmentation library */
  37. int i;
  38. int seg_length, seg_skip;
  39. int radians, segmentation; /* flags */
  40. double seg_treshold;
  41. int number_of_streams, ordered;
  42. /* initialize GIS environment */
  43. G_gisinit(argv[0]); /* reads grass env, stores program name to G_program_name() */
  44. /* initialize module */
  45. module = G_define_module();
  46. module->description =
  47. _("Divides network into near straight-line segments and calculate its order.");
  48. G_add_keyword(_("raster"));
  49. G_add_keyword(_("hydrology"));
  50. G_add_keyword(_("stream network"));
  51. G_add_keyword(_("stream divide"));
  52. in_stm_opt = G_define_standard_option(G_OPT_R_INPUT);
  53. in_stm_opt->key = "stream_rast";
  54. in_stm_opt->description = _("Name of input raster map with stream network");
  55. in_dir_opt = G_define_standard_option(G_OPT_R_INPUT);
  56. in_dir_opt->key = "direction";
  57. in_dir_opt->description = _("Name of input raster map with flow direction");
  58. in_elev_opt = G_define_standard_option(G_OPT_R_ELEV);
  59. out_segment_opt = G_define_standard_option(G_OPT_V_OUTPUT);
  60. out_segment_opt->key = "segments";
  61. out_segment_opt->description =
  62. _("Name for output vector map to write segment attributes");
  63. out_sector_opt = G_define_standard_option(G_OPT_V_OUTPUT);
  64. out_sector_opt->key = "sectors";
  65. out_sector_opt->description =
  66. _("Name for output vector map to write sector attributes");
  67. opt_length = G_define_option();
  68. opt_length->key = "length";
  69. opt_length->label = _("Search length to calculate direction");
  70. opt_length->description = _("Must be > 0");
  71. opt_length->answer = "15";
  72. opt_length->type = TYPE_INTEGER;
  73. opt_skip = G_define_option();
  74. opt_skip->key = "skip";
  75. opt_skip->label = _("Skip segments shorter than");
  76. opt_skip->description = _("Must be >= 0");
  77. opt_skip->answer = "5";
  78. opt_skip->type = TYPE_INTEGER;
  79. opt_threshold = G_define_option();
  80. opt_threshold->key = "threshold";
  81. opt_threshold->label = _("Max angle (degrees) between stream segments");
  82. opt_threshold->description = _("Must be > 0");
  83. opt_threshold->answer = "160";
  84. opt_threshold->type = TYPE_DOUBLE;
  85. opt_swapsize = G_define_option();
  86. opt_swapsize->key = "memory";
  87. opt_swapsize->type = TYPE_INTEGER;
  88. opt_swapsize->answer = "300";
  89. opt_swapsize->description = _("Max memory used in memory swap mode (MB)");
  90. opt_swapsize->guisection = _("Memory setings");
  91. flag_radians = G_define_flag();
  92. flag_radians->key = 'r';
  93. flag_radians->description =
  94. _("Output angles in radians (default: degrees)");
  95. flag_segmentation = G_define_flag();
  96. flag_segmentation->key = 'm';
  97. flag_segmentation->description = _("Use memory swap (operation is slow)");
  98. flag_segmentation->guisection = _("Memory setings");
  99. if (G_parser(argc, argv)) /* parser */
  100. exit(EXIT_FAILURE);
  101. seg_length = atoi(opt_length->answer);
  102. seg_treshold = atof(opt_threshold->answer);
  103. seg_skip = atoi(opt_skip->answer);
  104. radians = (flag_radians->answer != 0);
  105. segmentation = (flag_segmentation->answer != 0);
  106. if (seg_length <= 0)
  107. G_fatal_error(_("Search's length must be > 0"));
  108. if (seg_treshold < 0 || seg_treshold > 180)
  109. G_fatal_error(_("Threshold must be between 0 and 180"));
  110. if (seg_skip < 0)
  111. G_fatal_error(_("Segment's length must be >= 0"));
  112. seg_treshold = DEG2RAD(seg_treshold);
  113. nrows = Rast_window_rows();
  114. ncols = Rast_window_cols();
  115. Rast_get_window(&window);
  116. G_begin_distance_calculations();
  117. if (!segmentation) {
  118. MAP map_dirs, map_streams, map_elevation, map_unique_streams;
  119. CELL **streams, **dirs, **unique_streams = NULL;
  120. FCELL **elevation;
  121. G_message(_("All in RAM calculation..."));
  122. ram_create_map(&map_streams, CELL_TYPE);
  123. ram_read_map(&map_streams, in_stm_opt->answer, 1, CELL_TYPE);
  124. ram_create_map(&map_dirs, CELL_TYPE);
  125. ram_read_map(&map_dirs, in_dir_opt->answer, 1, CELL_TYPE);
  126. ram_create_map(&map_elevation, FCELL_TYPE);
  127. ram_read_map(&map_elevation, in_elev_opt->answer, 0, -1);
  128. streams = (CELL **) map_streams.map;
  129. dirs = (CELL **) map_dirs.map;
  130. elevation = (FCELL **) map_elevation.map;
  131. number_of_streams =
  132. ram_number_of_streams(streams, dirs, &ordered) + 1;
  133. ram_build_streamlines(streams, dirs, elevation, number_of_streams);
  134. if (ordered) {
  135. ram_create_map(&map_unique_streams, CELL_TYPE);
  136. unique_streams = (CELL **) map_unique_streams.map;
  137. ram_fill_streams(unique_streams, number_of_streams);
  138. ram_identify_next_stream(unique_streams, number_of_streams);
  139. ram_release_map(&map_unique_streams);
  140. }
  141. else
  142. ram_identify_next_stream(streams, number_of_streams);
  143. ram_release_map(&map_streams);
  144. ram_release_map(&map_dirs);
  145. ram_release_map(&map_elevation);
  146. }
  147. if (segmentation) {
  148. SEG map_dirs, map_streams, map_elevation, map_unique_streams;
  149. SEGMENT *streams, *dirs, *unique_streams = NULL;
  150. SEGMENT *elevation;
  151. int number_of_segs;
  152. G_message(_("Memory swap calculation (may take some time)..."));
  153. number_of_segs = (int)atof(opt_swapsize->answer);
  154. number_of_segs = number_of_segs < 32 ? (int)(32 / 0.18) : number_of_segs / 0.18;
  155. seg_create_map(&map_streams, SROWS, SCOLS, number_of_segs, CELL_TYPE);
  156. seg_read_map(&map_streams, in_stm_opt->answer, 1, CELL_TYPE);
  157. seg_create_map(&map_dirs, SROWS, SCOLS, number_of_segs, CELL_TYPE);
  158. seg_read_map(&map_dirs, in_dir_opt->answer, 1, CELL_TYPE);
  159. seg_create_map(&map_elevation, SROWS, SCOLS, number_of_segs,
  160. FCELL_TYPE);
  161. seg_read_map(&map_elevation, in_elev_opt->answer, 0, -1);
  162. streams = &map_streams.seg;
  163. dirs = &map_dirs.seg;
  164. elevation = &map_elevation.seg;
  165. number_of_streams =
  166. seg_number_of_streams(streams, dirs, &ordered) + 1;
  167. seg_build_streamlines(streams, dirs, elevation, number_of_streams);
  168. if (ordered) {
  169. seg_create_map(&map_unique_streams, SROWS, SCOLS, number_of_segs,
  170. CELL_TYPE);
  171. unique_streams = &map_unique_streams.seg;
  172. seg_fill_streams(unique_streams, number_of_streams);
  173. seg_identify_next_stream(unique_streams, number_of_streams);
  174. seg_release_map(&map_unique_streams);
  175. }
  176. else
  177. seg_identify_next_stream(streams, number_of_streams);
  178. seg_release_map(&map_streams);
  179. seg_release_map(&map_dirs);
  180. seg_release_map(&map_elevation);
  181. }
  182. for (i = 1; i < number_of_streams; ++i)
  183. G_message("%d %d %d", stream_attributes[i].stream,
  184. stream_attributes[i].next_stream,
  185. stream_attributes[i].last_cell_dir);
  186. /*
  187. for(i=1;i<number_of_streams;++i)
  188. printf("STREAM %d NEXT_STREAM %d POINT %d \n",
  189. stream_attributes[i].stream,
  190. stream_attributes[i].next_stream,
  191. stream_attributes[i].outlet);
  192. */
  193. G_message(_("Creating sectors and calculating attributes..."));
  194. for (i = 1; i < number_of_streams; ++i) {
  195. create_sectors(&stream_attributes[i], seg_length, seg_skip,
  196. seg_treshold);
  197. calc_tangents(&stream_attributes[i], seg_length, seg_skip,
  198. number_of_streams);
  199. }
  200. /*
  201. for(j=1;j<number_of_streams;++j)
  202. G_message("STREAM %d ncells %d len %f str %f sin %f",
  203. stream_attributes[j].stream,
  204. stream_attributes[j].number_of_cells,
  205. stream_attributes[j].length,
  206. stream_attributes[j].stright,
  207. stream_attributes[j].length/stream_attributes[j].stright);
  208. G_message("%d",j);
  209. for(j=1;j<number_of_streams;++j)
  210. printf("STREAM %d max %f min %f drop %f\n",
  211. stream_attributes[j].stream,
  212. stream_attributes[j].elevation[1],
  213. stream_attributes[j].elevation[stream_attributes[j].number_of_cells-1],
  214. stream_attributes[j].drop);
  215. for(j=1;j<number_of_streams;++j)
  216. for (i = 0; i < stream_attributes[j].number_of_sectors; ++i)
  217. printf("%d cat %d |BRAEK %d | dir %.2f | len %.2f | drop %.3f \n" ,j,
  218. stream_attributes[j].sector_cats[i],
  219. stream_attributes[j].sector_breakpoints[i],
  220. stream_attributes[j].sector_directions[i],
  221. stream_attributes[j].sector_lengths[i],
  222. stream_attributes[j].sector_drops[i]);
  223. for(j=1;j<number_of_streams;++j) {
  224. printf(" %d %d \n" ,j,stream_attributes[j].number_of_cells);
  225. for (i = 0; i <= stream_attributes[j].number_of_cells; ++i)
  226. printf("%d %f \n" ,i,stream_attributes[j].elevation[i]);
  227. }
  228. */
  229. create_segment_vector(out_segment_opt->answer, number_of_streams,
  230. radians);
  231. create_sector_vector(out_sector_opt->answer, number_of_streams, radians);
  232. free_attributes(number_of_streams);
  233. G_message("Done");
  234. exit(EXIT_SUCCESS);
  235. }