trans_digit.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. #include <math.h>
  2. #include <grass/vector.h>
  3. #include <grass/gis.h>
  4. #include <grass/dbmi.h>
  5. #include <grass/glocale.h>
  6. #include "trans.h"
  7. #define PI M_PI
  8. int transform_digit_file(struct Map_info *Old, struct Map_info *New,
  9. double ztozero, int swap, double *trans_params_def,
  10. char **columns, int field)
  11. {
  12. int i, type, cat, line, ret;
  13. int verbose, format;
  14. unsigned int j;
  15. double *trans_params;
  16. double ang, x, y;
  17. static struct line_pnts *Points;
  18. static struct line_cats *Cats;
  19. /* db */
  20. struct field_info *fi;
  21. int ctype;
  22. dbDriver *driver;
  23. dbValue val;
  24. cat = -1; /* dummy value for debugging */
  25. Points = Vect_new_line_struct();
  26. Cats = Vect_new_cats_struct();
  27. driver = NULL;
  28. fi = NULL;
  29. if (field > 0) {
  30. fi = Vect_get_field(Old, field);
  31. driver = db_start_driver_open_database(fi->driver, fi->database);
  32. if (!driver)
  33. G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
  34. fi->database, fi->driver);
  35. trans_params = (double *)G_calloc(IDX_ZROT + 1, sizeof(double));
  36. }
  37. else {
  38. trans_params = trans_params_def;
  39. ang = PI * trans_params[IDX_ZROT] / 180;
  40. }
  41. line = 0;
  42. ret = 1;
  43. format = G_info_format();
  44. verbose = G_verbose() > G_verbose_min();
  45. while (TRUE) {
  46. type = Vect_read_next_line(Old, Points, Cats);
  47. if (type == -1) { /* error */
  48. ret = 0;
  49. break;
  50. }
  51. if (type == -2) { /* EOF */
  52. ret = 1;
  53. break;
  54. }
  55. if (field != -1 && !Vect_cat_get(Cats, field, NULL))
  56. continue;
  57. if (verbose && line % 1000 == 0) {
  58. if (format == G_INFO_FORMAT_PLAIN)
  59. fprintf(stderr, "%d..", line);
  60. else
  61. fprintf(stderr, "%11d\b\b\b\b\b\b\b\b\b\b\b", line);
  62. }
  63. if (swap) {
  64. for (i = 0; i < Points->n_points; i++) {
  65. x = Points->x[i];
  66. Points->x[i] = Points->y[i];
  67. Points->y[i] = x;
  68. }
  69. }
  70. /* get transformation parameters */
  71. if (field > 0) {
  72. Vect_cat_get(Cats, field, &cat); /* get first category */
  73. if (cat > -1) {
  74. for (j = 0; j <= IDX_ZROT; j++) {
  75. if (columns[j] == NULL) {
  76. trans_params[j] = trans_params_def[j];
  77. continue;
  78. }
  79. ctype = db_column_Ctype(driver, fi->table, columns[j]);
  80. switch (ctype) {
  81. case DB_C_TYPE_INT:
  82. case DB_C_TYPE_DOUBLE:
  83. case DB_C_TYPE_STRING:
  84. break;
  85. case -1:
  86. G_fatal_error(_("Column <%s> not found in table <%s>"),
  87. columns[j], fi->table);
  88. default:
  89. G_fatal_error(_("Unsupported column type of <%s>"),
  90. columns[j]);
  91. }
  92. if (db_select_value
  93. (driver, fi->table, fi->key, cat, columns[j], &val) != 1
  94. || db_test_value_isnull(&val)) {
  95. trans_params[j] = trans_params_def[j];
  96. G_warning(_("Unable to select value for category %d from table <%s>, column <%s>. "
  97. "For category %d using default transformation parameter %.3f."),
  98. cat, fi->table, columns[j], cat,
  99. trans_params[j]);
  100. }
  101. else {
  102. trans_params[j] = db_get_value_as_double(&val, ctype);
  103. }
  104. }
  105. }
  106. else {
  107. G_warning(_("No category number defined. Using default transformation parameters."));
  108. for (j = 0; j <= IDX_ZROT; j++) {
  109. trans_params[j] = trans_params_def[j];
  110. }
  111. }
  112. ang = PI * trans_params[IDX_ZROT] / 180;
  113. }
  114. /* transform points */
  115. for (i = 0; i < Points->n_points; i++) {
  116. G_debug(3, "idx=%d, cat=%d, xshift=%g, yshift=%g, zshift=%g, "
  117. "xscale=%g, yscale=%g, zscale=%g, zrot=%g",
  118. i, cat, trans_params[IDX_XSHIFT],
  119. trans_params[IDX_YSHIFT], trans_params[IDX_ZSHIFT],
  120. trans_params[IDX_XSCALE], trans_params[IDX_YSCALE],
  121. trans_params[IDX_ZSCALE], trans_params[IDX_ZROT]);
  122. /* transform point */
  123. x = trans_params[IDX_XSHIFT] +
  124. trans_params[IDX_XSCALE] * Points->x[i] * cos(ang)
  125. - trans_params[IDX_YSCALE] * Points->y[i] * sin(ang);
  126. y = trans_params[IDX_YSHIFT] +
  127. trans_params[IDX_XSCALE] * Points->x[i] * sin(ang)
  128. + trans_params[IDX_YSCALE] * Points->y[i] * cos(ang);
  129. Points->x[i] = x;
  130. Points->y[i] = y;
  131. /* ztozero shifts oldmap z to zero, zshift shifts rescaled object
  132. * to target elevation: */
  133. Points->z[i] =
  134. ((Points->z[i] + ztozero) * trans_params[IDX_ZSCALE]) +
  135. trans_params[IDX_ZSHIFT];
  136. }
  137. Vect_write_line(New, type, Points, Cats);
  138. line++;
  139. }
  140. if (verbose && format != G_INFO_FORMAT_PLAIN)
  141. fprintf(stderr, "\r");
  142. if (field > 0) {
  143. db_close_database_shutdown_driver(driver);
  144. G_free((void *)trans_params);
  145. }
  146. return ret;
  147. }