trans_digit.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. /* **************************************************************************
  2. *
  3. * MODULE: v.transform
  4. * AUTHOR(S): See other files as well...
  5. * Eric G. Miller <egm2@jps.net>
  6. * Radim Blazek
  7. * DB support added by Martin Landa (08/2007)
  8. *
  9. * PURPOSE: To transform a vector layer's coordinates via a set of tie
  10. * points.
  11. *
  12. * COPYRIGHT: (C) 2002-2007 by the GRASS Development Team
  13. *
  14. * This program is free software under the GNU General Public
  15. * License (>=v2). Read the file COPYING that comes with GRASS
  16. * for details.
  17. *
  18. *****************************************************************************/
  19. #include <math.h>
  20. #include <grass/libtrans.h>
  21. #include <grass/vector.h>
  22. #include <grass/gis.h>
  23. #include <grass/dbmi.h>
  24. #include <grass/glocale.h>
  25. #include "trans.h"
  26. #define PI M_PI
  27. int
  28. transform_digit_file(struct Map_info *Old, struct Map_info *New,
  29. int shift_file, double ztozero, int swap, double *trans_params_def,
  30. char *table, char **columns, int field)
  31. {
  32. int i, type, cat;
  33. unsigned int j;
  34. double *trans_params;
  35. double ang, x, y;
  36. static struct line_pnts *Points;
  37. static struct line_cats *Cats;
  38. /* db */
  39. struct field_info *fi;
  40. int ctype;
  41. dbDriver *driver;
  42. dbValue val;
  43. cat = -1; /* dummy value for debugging */
  44. Points = Vect_new_line_struct();
  45. Cats = Vect_new_cats_struct();
  46. if (table) {
  47. fi = Vect_default_field_info(Old, 1, NULL, GV_1TABLE);
  48. driver = db_start_driver_open_database(fi->driver, fi->database);
  49. if (!driver)
  50. G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
  51. fi->database, fi->driver);
  52. trans_params = (double *)G_calloc(IDX_ZROT, sizeof(double));
  53. }
  54. else {
  55. trans_params = trans_params_def;
  56. ang = PI * trans_params[IDX_ZROT] / 180;
  57. }
  58. while (1) {
  59. type = Vect_read_next_line(Old, Points, Cats);
  60. if (type == -1) /* error */
  61. return 0;
  62. if (type == -2) /* EOF */
  63. return 1;
  64. if (field != -1 && !Vect_cat_get(Cats, field, NULL))
  65. continue;
  66. if (swap) {
  67. for (i = 0; i < Points->n_points; i++) {
  68. x = Points->x[i];
  69. Points->x[i] = Points->y[i];
  70. Points->y[i] = x;
  71. }
  72. }
  73. /* get transformation parameters */
  74. if (table) {
  75. Vect_cat_get(Cats, field, &cat); /* get first category */
  76. if (cat > -1) {
  77. for (j = 0; j <= IDX_ZROT; j++) {
  78. if (columns[j] == NULL) {
  79. trans_params[j] = trans_params_def[j];
  80. continue;
  81. }
  82. ctype = db_column_Ctype(driver, table, columns[j]);
  83. switch (ctype) {
  84. case DB_C_TYPE_INT:
  85. case DB_C_TYPE_DOUBLE:
  86. case DB_C_TYPE_STRING:
  87. break;
  88. case -1:
  89. G_fatal_error(_("Missing column <%s> in table <%s>"),
  90. columns[j], table);
  91. default:
  92. G_fatal_error(_("Unsupported column type of <%s>"),
  93. columns[j]);
  94. }
  95. if (db_select_value
  96. (driver, table, fi->key, cat, columns[j], &val) != 1
  97. || db_test_value_isnull(&val)) {
  98. trans_params[j] = trans_params_def[j];
  99. G_warning(_("Unable to select value for category %d from table <%s>, column <%s>. "
  100. "For category %d using default transformation parameter %.3f."),
  101. cat, table, columns[j], cat,
  102. trans_params[j]);
  103. }
  104. else {
  105. trans_params[j] = db_get_value_as_double(&val, ctype);
  106. }
  107. }
  108. }
  109. else {
  110. G_warning(_("No category number defined. Using default transformation parameters."));
  111. for (j = 0; j <= IDX_ZROT; j++) {
  112. trans_params[j] = trans_params_def[j];
  113. }
  114. }
  115. ang = PI * trans_params[IDX_ZROT] / 180;
  116. }
  117. /* transform points */
  118. for (i = 0; i < Points->n_points; i++) {
  119. if (shift_file) {
  120. transform_a_into_b(Points->x[i], Points->y[i],
  121. &(Points->x[i]), &(Points->y[i]));
  122. }
  123. else {
  124. G_debug(3, "idx=%d, cat=%d, xshift=%g, yshift=%g, zshift=%g, "
  125. "xscale=%g, yscale=%g, zscale=%g, zrot=%g",
  126. i, cat, trans_params[IDX_XSHIFT],
  127. trans_params[IDX_YSHIFT], trans_params[IDX_ZSHIFT],
  128. trans_params[IDX_XSCALE], trans_params[IDX_YSCALE],
  129. trans_params[IDX_ZSCALE], trans_params[IDX_ZROT]);
  130. /* transform point */
  131. x = trans_params[IDX_XSHIFT] +
  132. trans_params[IDX_XSCALE] * Points->x[i] * cos(ang)
  133. - trans_params[IDX_YSCALE] * Points->y[i] * sin(ang);
  134. y = trans_params[IDX_YSHIFT] +
  135. trans_params[IDX_XSCALE] * Points->x[i] * sin(ang)
  136. + trans_params[IDX_YSCALE] * Points->y[i] * cos(ang);
  137. Points->x[i] = x;
  138. Points->y[i] = y;
  139. }
  140. /* ztozero shifts oldmap z to zero, zshift shifts rescaled object
  141. * to target elevation: */
  142. Points->z[i] =
  143. ((Points->z[i] + ztozero) * trans_params[IDX_ZSCALE]) +
  144. trans_params[IDX_ZSHIFT];
  145. }
  146. Vect_write_line(New, type, Points, Cats);
  147. }
  148. if (field > 0) {
  149. db_close_database_shutdown_driver(driver);
  150. G_free((void *)trans_params);
  151. }
  152. }