main.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. /****************************************************************
  2. *
  3. * MODULE: v.net.spanningtree
  4. *
  5. * AUTHOR(S): Daniel Bundala
  6. *
  7. * PURPOSE: Computes spanning tree in the network
  8. *
  9. * COPYRIGHT: (C) 2002-2005 by the GRASS Development Team
  10. *
  11. * This program is free software under the
  12. * GNU General Public License (>=v2).
  13. * Read the file COPYING that comes with GRASS
  14. * for details.
  15. *
  16. ****************************************************************/
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <grass/gis.h>
  20. #include <grass/vector.h>
  21. #include <grass/glocale.h>
  22. #include <grass/neta.h>
  23. int main(int argc, char *argv[])
  24. {
  25. struct Map_info In, Out;
  26. static struct line_pnts *Points;
  27. struct line_cats *Cats;
  28. struct GModule *module; /* GRASS module for parsing arguments */
  29. struct Option *map_in, *map_out;
  30. struct Option *afield_opt, *nfield_opt, *afcol, *ncol;
  31. struct Flag *geo_f;
  32. int with_z;
  33. int afield, nfield, mask_type;
  34. dglGraph_s *graph;
  35. int i, edges, geo;
  36. struct ilist *tree_list;
  37. /* initialize GIS environment */
  38. G_gisinit(argv[0]); /* reads grass env, stores program name to G_program_name() */
  39. /* initialize module */
  40. module = G_define_module();
  41. G_add_keyword(_("vector"));
  42. G_add_keyword(_("network"));
  43. G_add_keyword(_("spanning tree"));
  44. module->description =
  45. _("Computes minimum spanning tree for the network.");
  46. /* Define the different options as defined in gis.h */
  47. map_in = G_define_standard_option(G_OPT_V_INPUT);
  48. map_out = G_define_standard_option(G_OPT_V_OUTPUT);
  49. afield_opt = G_define_standard_option(G_OPT_V_FIELD);
  50. afield_opt->key = "alayer";
  51. afield_opt->answer = "1";
  52. afield_opt->label = _("Arc layer");
  53. afield_opt->guisection = _("Cost");
  54. nfield_opt = G_define_standard_option(G_OPT_V_FIELD);
  55. nfield_opt->key = "nlayer";
  56. nfield_opt->answer = "2";
  57. nfield_opt->label = _("Node layer");
  58. nfield_opt->guisection = _("Cost");
  59. afcol = G_define_standard_option(G_OPT_DB_COLUMN);
  60. afcol->key = "afcolumn";
  61. afcol->required = NO;
  62. afcol->description =
  63. _("Arc forward/both direction(s) cost column (number)");
  64. afcol->guisection = _("Cost");
  65. ncol = G_define_standard_option(G_OPT_DB_COLUMN);
  66. ncol->key = "ncolumn";
  67. ncol->required = NO;
  68. ncol->description = _("Node cost column (number)");
  69. ncol->guisection = _("Cost");
  70. geo_f = G_define_flag();
  71. geo_f->key = 'g';
  72. geo_f->description =
  73. _("Use geodesic calculation for longitude-latitude locations");
  74. /* options and flags parser */
  75. if (G_parser(argc, argv))
  76. exit(EXIT_FAILURE);
  77. /* TODO: make an option for this */
  78. mask_type = GV_LINE | GV_BOUNDARY;
  79. Points = Vect_new_line_struct();
  80. Cats = Vect_new_cats_struct();
  81. Vect_check_input_output_name(map_in->answer, map_out->answer,
  82. G_FATAL_EXIT);
  83. Vect_set_open_level(2);
  84. if (1 > Vect_open_old(&In, map_in->answer, ""))
  85. G_fatal_error(_("Unable to open vector map <%s>"), map_in->answer);
  86. with_z = Vect_is_3d(&In);
  87. if (0 > Vect_open_new(&Out, map_out->answer, with_z)) {
  88. Vect_close(&In);
  89. G_fatal_error(_("Unable to create vector map <%s>"), map_out->answer);
  90. }
  91. if (geo_f->answer) {
  92. geo = 1;
  93. if (G_projection() != PROJECTION_LL)
  94. G_warning(_("The current projection is not longitude-latitude"));
  95. }
  96. else
  97. geo = 0;
  98. /* parse filter option and select appropriate lines */
  99. afield = Vect_get_field_number(&In, afield_opt->answer);
  100. nfield = Vect_get_field_number(&In, nfield_opt->answer);
  101. if (0 != Vect_net_build_graph(&In, mask_type, afield, nfield, afcol->answer, NULL,
  102. ncol->answer, geo, 0))
  103. G_fatal_error(_("Unable to build graph for vector map <%s>"), Vect_get_full_name(&In));
  104. graph = Vect_net_get_graph(&In);
  105. Vect_copy_head_data(&In, &Out);
  106. Vect_hist_copy(&In, &Out);
  107. Vect_hist_command(&Out);
  108. tree_list = Vect_new_list();
  109. edges = NetA_spanning_tree(graph, tree_list);
  110. G_debug(3, "Edges: %d", edges);
  111. for (i = 0; i < edges; i++) {
  112. int type =
  113. Vect_read_line(&In, Points, Cats, abs(tree_list->value[i]));
  114. Vect_write_line(&Out, type, Points, Cats);
  115. }
  116. Vect_destroy_list(tree_list);
  117. Vect_build(&Out);
  118. Vect_close(&In);
  119. Vect_close(&Out);
  120. exit(EXIT_SUCCESS);
  121. }