main.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. /****************************************************************
  2. *
  3. * MODULE: v.net.path
  4. *
  5. * AUTHOR(S): Radim Blazek
  6. * Stepan Turek <stepan.turek seznam.cz> (turns support)
  7. *
  8. * PURPOSE: Shortest path on vector network
  9. *
  10. * COPYRIGHT: (C) 2002, 2014 by the GRASS Development Team
  11. *
  12. * This program is free software under the
  13. * GNU General Public License (>=v2).
  14. * Read the file COPYING that comes with GRASS
  15. * for details.
  16. *
  17. ****************************************************************/
  18. #include <stdlib.h>
  19. #include <grass/gis.h>
  20. #include <grass/vector.h>
  21. #include <grass/glocale.h>
  22. int path(struct Map_info *, struct Map_info *, char *, int, double, int,
  23. int, int);
  24. int main(int argc, char **argv)
  25. {
  26. struct Option *input_opt, *output_opt, *afield_opt, *nfield_opt,
  27. *tfield_opt, *tucfield_opt, *afcol, *abcol, *ncol, *type_opt;
  28. struct Option *max_dist, *file_opt;
  29. struct Flag *geo_f, *segments_f, *turntable_f;
  30. struct GModule *module;
  31. struct Map_info In, Out;
  32. int type, afield, nfield, tfield, tucfield, geo;
  33. double maxdist;
  34. /* Initialize the GIS calls */
  35. G_gisinit(argv[0]);
  36. module = G_define_module();
  37. G_add_keyword(_("vector"));
  38. G_add_keyword(_("network"));
  39. G_add_keyword(_("shortest path"));
  40. module->description = _("Finds shortest path on vector network.");
  41. input_opt = G_define_standard_option(G_OPT_V_INPUT);
  42. output_opt = G_define_standard_option(G_OPT_V_OUTPUT);
  43. afield_opt = G_define_standard_option(G_OPT_V_FIELD);
  44. afield_opt->key = "arc_layer";
  45. afield_opt->answer = "1";
  46. afield_opt->required = YES;
  47. afield_opt->label = _("Arc layer");
  48. type_opt = G_define_standard_option(G_OPT_V_TYPE);
  49. type_opt->key = "arc_type";
  50. type_opt->options = "line,boundary";
  51. type_opt->answer = "line,boundary";
  52. type_opt->required = YES;
  53. type_opt->label = _("Arc type");
  54. nfield_opt = G_define_standard_option(G_OPT_V_FIELD);
  55. nfield_opt->key = "node_layer";
  56. nfield_opt->answer = "2";
  57. nfield_opt->required = YES;
  58. nfield_opt->label = _("Node layer");
  59. file_opt = G_define_standard_option(G_OPT_F_INPUT);
  60. file_opt->key = "file";
  61. file_opt->required = NO;
  62. file_opt->description = _("Name of file containing start and end points. "
  63. "If not given, read from stdin");
  64. afcol = G_define_option();
  65. afcol->key = "arc_column";
  66. afcol->type = TYPE_STRING;
  67. afcol->required = NO;
  68. afcol->description = _("Arc forward/both direction(s) cost column (number)");
  69. afcol->guisection = _("Cost");
  70. abcol = G_define_option();
  71. abcol->key = "arc_backward_column";
  72. abcol->type = TYPE_STRING;
  73. abcol->required = NO;
  74. abcol->description = _("Arc backward direction cost column (number)");
  75. abcol->guisection = _("Cost");
  76. ncol = G_define_option();
  77. ncol->key = "node_column";
  78. ncol->type = TYPE_STRING;
  79. ncol->required = NO;
  80. ncol->description = _("Node cost column (number)");
  81. ncol->guisection = _("Cost");
  82. max_dist = G_define_option();
  83. max_dist->key = "dmax";
  84. max_dist->type = TYPE_DOUBLE;
  85. max_dist->required = NO;
  86. max_dist->answer = "1000";
  87. max_dist->label = _("Maximum distance to the network");
  88. max_dist->description = _("If start/end are given as coordinates. "
  89. "If start/end point is outside this threshold, "
  90. "the path is not found "
  91. "and error message is printed. To speed up the process, keep this "
  92. "value as low as possible.");
  93. turntable_f = G_define_flag();
  94. turntable_f->key = 't';
  95. turntable_f->description = _("Use turntable");
  96. turntable_f->guisection = _("Turntable");
  97. tfield_opt = G_define_standard_option(G_OPT_V_FIELD);
  98. tfield_opt->key = "turn_layer";
  99. tfield_opt->answer = "3";
  100. tfield_opt->label = _("Layer with turntable");
  101. tfield_opt->description =
  102. _("Relevant only with -t flag");
  103. tfield_opt->guisection = _("Turntable");
  104. tucfield_opt = G_define_standard_option(G_OPT_V_FIELD);
  105. tucfield_opt->key = "turn_cat_layer";
  106. tucfield_opt->answer = "4";
  107. tucfield_opt->label = _("Layer with unique categories used in turntable");
  108. tucfield_opt->description =
  109. _("Relevant only with -t flag");
  110. tucfield_opt->guisection = _("Turntable");
  111. geo_f = G_define_flag();
  112. geo_f->key = 'g';
  113. geo_f->description =
  114. _("Use geodesic calculation for longitude-latitude locations");
  115. segments_f = G_define_flag();
  116. segments_f->key = 's';
  117. segments_f->description = _("Write output as original input segments, "
  118. "not each path as one line.");
  119. if (G_parser(argc, argv))
  120. exit(EXIT_FAILURE);
  121. type = Vect_option_to_types(type_opt);
  122. maxdist = atof(max_dist->answer);
  123. if (geo_f->answer) {
  124. geo = 1;
  125. if (G_projection() != PROJECTION_LL)
  126. G_warning(_("The current projection is not longitude-latitude"));
  127. }
  128. else
  129. geo = 0;
  130. Vect_check_input_output_name(input_opt->answer, output_opt->answer,
  131. G_FATAL_EXIT);
  132. Vect_set_open_level(2);
  133. if (Vect_open_old(&In, input_opt->answer, "") < 0)
  134. G_fatal_error(_("Unable to open vector map <%s>"), input_opt->answer);
  135. afield = Vect_get_field_number(&In, afield_opt->answer);
  136. nfield = Vect_get_field_number(&In, nfield_opt->answer);
  137. tfield = Vect_get_field_number(&In, tfield_opt->answer);
  138. tucfield = Vect_get_field_number(&In, tucfield_opt->answer);
  139. if (1 > Vect_open_new(&Out, output_opt->answer, Vect_is_3d(&In))) {
  140. Vect_close(&In);
  141. G_fatal_error(_("Unable to create vector map <%s>"),
  142. output_opt->answer);
  143. }
  144. Vect_hist_command(&Out);
  145. if (turntable_f->answer)
  146. Vect_net_ttb_build_graph(&In, type, afield, nfield, tfield, tucfield,
  147. afcol->answer, abcol->answer, ncol->answer,
  148. geo, 0);
  149. else
  150. Vect_net_build_graph(&In, type, afield, nfield, afcol->answer,
  151. abcol->answer, ncol->answer, geo, 0);
  152. path(&In, &Out, file_opt->answer, nfield, maxdist, segments_f->answer,
  153. tucfield, turntable_f->answer);
  154. Vect_close(&In);
  155. Vect_build(&Out);
  156. Vect_close(&Out);
  157. exit(EXIT_SUCCESS);
  158. }