simple_features.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /*!
  2. \file vector/Vlib/simple_features.c
  3. \brief Vector library - OGC Simple Features Access
  4. Note: In progress. Currently on GV_POINT, GV_LINE are supported.
  5. Higher level functions for reading/writing/manipulating vectors.
  6. (C) 2009 by the GRASS Development Team
  7. This program is free software under the GNU General Public License
  8. (>=v2). Read the file COPYING that comes with GRASS for details.
  9. \author Martin Landa <landa.martin gmail.com>
  10. */
  11. #include <stdio.h>
  12. #include <grass/vector.h>
  13. #include <grass/glocale.h>
  14. static int check_sftype(const struct line_pnts *, int, int, int);
  15. static int get_sftype(const struct line_pnts *, int, int);
  16. static void print_point(const struct line_pnts *, int, int, int, FILE *);
  17. /*!
  18. \brief Get SF type of given vector feature
  19. List of supported feature types:
  20. - GV_POINT -> SF_POINT
  21. - GV_LINE -> SF_LINE / SF_LINESTRING / SF_LINEARRING
  22. \param Points pointer to line_pnts structure
  23. \param type feature type (GV_POINT, GV_LINE, ...)
  24. \param with_z non-zero value for 3D data
  25. \return SF type identificator (see list of supported types)
  26. \return -1 on error
  27. */
  28. int Vect_sfa_get_line_type(const struct line_pnts *Points, int type, int with_z)
  29. {
  30. return get_sftype(Points, type, with_z);
  31. }
  32. /*!
  33. \brief Check SF type
  34. E.g. if <em>type</em> is GV_LINE with two or more segments and the
  35. start node is identical with the end node, and <em>sftype</em> is
  36. SF_LINEARRING, functions returns 1, otherwise 0.
  37. \param Points pointer to line_pnts structure
  38. \param type feature type (GV_POINT, GV_LINE, ...)
  39. \param sftype SF type to be checked (SF_POINT, SF_LINE, ...)
  40. \param with_z non-zero value for 3D data
  41. \return 1 if type is sftype
  42. \return 0 type differs from sftype
  43. */
  44. int Vect_sfa_check_line_type(const struct line_pnts *Points, int type, int sftype, int with_z)
  45. {
  46. return check_sftype(Points, type, sftype, with_z);
  47. }
  48. /*!
  49. \brief Print feature in Well-Known Text format
  50. \param Points pointer to line_pnts structure
  51. \param type feature type
  52. \param with_z non-zero value for 3D data
  53. \param precision floating number precision
  54. \param[out] file file where to write the output
  55. */
  56. void Vect_sfa_write_line_wkt(const struct line_pnts *Points, int type, int with_z, int precision, FILE *file)
  57. {
  58. int sftype;
  59. sftype = Vect_sfa_get_line_type(Points, type, with_z);
  60. switch(sftype) {
  61. case SF_POINT: {
  62. fprintf(file, "POINT(");
  63. print_point(Points, 0, with_z, precision, file);
  64. fprintf(file, ")\n");
  65. break;
  66. }
  67. case SF_LINESTRING: case SF_LINE: case SF_LINEARRING: {
  68. int i;
  69. if (sftype == SF_LINESTRING)
  70. fprintf(file, "LINESTRING(");
  71. else if (sftype == SF_LINE)
  72. fprintf(file, "LINE(");
  73. else
  74. fprintf(file, "LINEARRING(");
  75. for (i = 0; i < Points->n_points; i++) {
  76. print_point(Points, i, with_z, precision, file);
  77. if (i < Points->n_points - 1)
  78. fprintf(file, ", ");
  79. }
  80. fprintf(file, ")\n");
  81. break;
  82. }
  83. default: {
  84. G_warning(_("Unknown Simple Features type (%d)"), sftype);
  85. break;
  86. }
  87. }
  88. fflush(file);
  89. }
  90. int check_sftype(const struct line_pnts *points, int type, int sftype, int with_z)
  91. {
  92. if (type == GV_POINT && sftype == SF_POINT) {
  93. return 1;
  94. }
  95. if (type == GV_LINE) {
  96. if (sftype == SF_LINESTRING) {
  97. return 1;
  98. }
  99. if (sftype == SF_LINE && Vect_get_num_line_points(points) == 2) {
  100. return 1;
  101. }
  102. if (sftype == SF_LINEARRING) {
  103. int num = Vect_get_num_line_points(points);
  104. if (points->x[0] == points->x[num-1] &&
  105. points->y[0] == points->y[num-1]) {
  106. if (!with_z) {
  107. return 1;
  108. }
  109. else if (points->z[0] == points->z[num-1]) {
  110. return 1;
  111. }
  112. }
  113. }
  114. }
  115. return 0;
  116. }
  117. int get_sftype(const struct line_pnts *points, int type, int with_z)
  118. {
  119. if (check_sftype(points, type, SF_POINT, with_z))
  120. return SF_POINT;
  121. if (check_sftype(points, type, SF_LINE, with_z))
  122. return SF_LINE;
  123. if (check_sftype(points, type, SF_LINEARRING, with_z))
  124. return SF_LINEARRING;
  125. if (check_sftype(points, type, SF_LINESTRING, with_z))
  126. return SF_LINESTRING;
  127. return -1;
  128. }
  129. void print_point(const struct line_pnts *Points, int index, int with_z, int precision, FILE *file)
  130. {
  131. fprintf(file, "%.*f %.*f", precision, Points->x[index], precision, Points->y[index]);
  132. if (with_z)
  133. fprintf(file, " %.*f", precision, Points->z[index]);
  134. }