ps_vareas.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. /* Functions: PS_area_plot
  2. **
  3. ** Author: Radim Blazek Jan 2000
  4. ** modified copy of ps_vector.c by Paul W. Carlson March 1992
  5. */
  6. #include <grass/gis.h>
  7. #include <grass/colors.h>
  8. #include <grass/raster.h>
  9. #include <grass/glocale.h>
  10. #include <grass/vector.h>
  11. #include <grass/dbmi.h>
  12. #include "vector.h"
  13. #include "ps_info.h"
  14. #include "clr.h"
  15. #include "local_proto.h"
  16. /* constuct subpath with moveto and repeated lineto from Points */
  17. int construct_path(struct line_pnts *Points, double shift, int t)
  18. {
  19. int i, np, k = 1;
  20. double *xarray, *yarray, x, y;
  21. np = Points->n_points;
  22. xarray = Points->x;
  23. yarray = Points->y;
  24. for (i = 0; i < np; i++) {
  25. x = XCONV(xarray[0] + shift);
  26. y = YCONV(yarray[0]);
  27. fprintf(PS.fp, "%.1f %.1f ", x, y);
  28. if (i == 0 && (t == START_PATH || t == WHOLE_PATH)) {
  29. fprintf(PS.fp, "M ");
  30. }
  31. else {
  32. fprintf(PS.fp, "LN ");
  33. }
  34. if (k == 2) {
  35. fprintf(PS.fp, "\n");
  36. k = 0;
  37. }
  38. else {
  39. fprintf(PS.fp, " ");
  40. k++;
  41. }
  42. xarray++;
  43. yarray++;
  44. }
  45. if (t == CLOSE_PATH || t == WHOLE_PATH) {
  46. fprintf(PS.fp, "CP\n");
  47. }
  48. return 1;
  49. }
  50. /* create paths for area and islands */
  51. static int plot_area(struct Map_info *P_map, int area, double shift)
  52. {
  53. struct line_pnts *Points;
  54. int j, ret, ni, island;
  55. /* allocate memory for coordinates */
  56. Points = Vect_new_line_struct();
  57. /* plot areas */
  58. if (0 > (ret = Vect_get_area_points(P_map, area, Points))) {
  59. if (ret == -1)
  60. G_warning(_("Read error in vector map"));
  61. return 0;
  62. }
  63. construct_path(Points, shift, WHOLE_PATH);
  64. /* plot islands */
  65. ni = Vect_get_area_num_isles(P_map, area);
  66. for (j = 0; j < ni; j++) {
  67. island = Vect_get_area_isle(P_map, area, j);
  68. if (0 > (ret = Vect_get_isle_points(P_map, island, Points))) {
  69. if (ret == -1)
  70. G_warning(_("Read error in vector map"));
  71. return -1;
  72. }
  73. construct_path(Points, shift, WHOLE_PATH);
  74. }
  75. return 1;
  76. }
  77. /* get pscolor based on rgb color definition stored in rgbcolumn */
  78. /* sets *color and returns 1 on success, -1 if no color found */
  79. int get_ps_color_rgbcol_varea(struct Map_info *map, int vec, int area,
  80. dbCatValArray * cvarr_rgb, PSCOLOR *color)
  81. {
  82. int cat, ret;
  83. dbCatVal *cv_rgb;
  84. int red, grn, blu;
  85. char *rgbstring = NULL;
  86. cat = Vect_get_area_cat(map, area, vector.layer[vec].field);
  87. ret = db_CatValArray_get_value(cvarr_rgb, cat, &cv_rgb);
  88. if (ret != DB_OK) {
  89. G_warning(_("No record for category [%d]"), cat);
  90. }
  91. else {
  92. rgbstring = db_get_string(cv_rgb->val.s);
  93. if (rgbstring == NULL ||
  94. G_str_to_color(rgbstring, &red, &grn, &blu) != 1) {
  95. G_warning(_("Invalid RGB color definition in column <%s> for category [%d]"),
  96. vector.layer[vec].rgbcol, cat);
  97. rgbstring = NULL;
  98. }
  99. }
  100. if (rgbstring) {
  101. G_debug(3, " dynamic varea fill rgb color = %s", rgbstring);
  102. set_color(color, red, grn, blu);
  103. }
  104. else {
  105. set_color(color, 0, 0, 0);
  106. return -1;
  107. }
  108. return 1;
  109. }
  110. /* plot areas */
  111. int PS_vareas_plot(struct Map_info *P_map, int vec)
  112. {
  113. int na, area, ret;
  114. double e, w, n, s, aw, shift;
  115. double llx, lly, urx, ury, sc;
  116. char pat[50];
  117. struct line_cats *Cats;
  118. struct bound_box box;
  119. struct varray *Varray = NULL;
  120. PSCOLOR color;
  121. int centroid;
  122. /* rgbcol */
  123. dbCatValArray cvarr_rgb;
  124. fprintf(PS.fp, "1 setlinejoin\n"); /* set line join to round */
  125. Cats = Vect_new_cats_struct();
  126. /* Create vector array if required */
  127. if (vector.layer[vec].cats != NULL || vector.layer[vec].where != NULL) {
  128. Varray = Vect_new_varray(Vect_get_num_areas(P_map));
  129. if (vector.layer[vec].cats != NULL) {
  130. ret =
  131. Vect_set_varray_from_cat_string(P_map,
  132. vector.layer[vec].field,
  133. vector.layer[vec].cats,
  134. GV_AREA, 1, Varray);
  135. }
  136. else {
  137. ret = Vect_set_varray_from_db(P_map, vector.layer[vec].field,
  138. vector.layer[vec].where, GV_AREA, 1,
  139. Varray);
  140. }
  141. G_debug(3, "%d items selected for vector %d", ret, vec);
  142. if (ret == -1)
  143. G_fatal_error(_("Cannot load data from table"));
  144. }
  145. /* load attributes if rgbcol used */
  146. if (vector.layer[vec].rgbcol != NULL) {
  147. load_catval_array_rgb(P_map, vec, &cvarr_rgb);
  148. }
  149. shift = 0;
  150. /* read and plot areas */
  151. na = Vect_get_num_areas(P_map);
  152. for (area = 1; area <= na; area++) {
  153. G_debug(4, "area = %d", area);
  154. if (Varray != NULL && Varray->c[area] == 0)
  155. continue; /* is not in array */
  156. if (!Vect_area_alive(P_map, area))
  157. continue;
  158. centroid = Vect_get_area_centroid(P_map, area);
  159. G_debug(4, "centroid = %d", centroid);
  160. if (centroid < 1) /* area is an island */
  161. continue;
  162. Vect_get_area_box(P_map, area, &box);
  163. n = box.N;
  164. s = box.S;
  165. e = box.E;
  166. w = box.W;
  167. if (PS.w.proj == PROJECTION_LL) {
  168. aw = G_adjust_easting(w, &PS.w);
  169. if (aw > PS.w.east)
  170. aw -= 360.0;
  171. shift = aw - w;
  172. e += shift;
  173. w += shift;
  174. }
  175. /* check if in window */
  176. if (n < PS.w.south || s > PS.w.north || e < PS.w.west ||
  177. w > PS.w.east)
  178. continue;
  179. fprintf(PS.fp, "NP\n");
  180. if (PS.w.proj == PROJECTION_LL) {
  181. /* plot area while in window */
  182. while (e > PS.w.west) {
  183. ret = plot_area(P_map, area, shift);
  184. if (ret != 1)
  185. return 0;
  186. shift -= 360.0;
  187. e -= 360.0;
  188. }
  189. }
  190. else {
  191. ret = plot_area(P_map, area, shift);
  192. if (ret != 1)
  193. return 0;
  194. }
  195. if (vector.layer[vec].pat != NULL ||
  196. (!color_none(&vector.layer[vec].fcolor) ||
  197. vector.layer[vec].rgbcol != NULL)) {
  198. if (vector.layer[vec].rgbcol != NULL) {
  199. /* load fill color from rgbcol */
  200. /* if data column is empty or cat is missing don't fill */
  201. if (get_ps_color_rgbcol_varea(P_map, vec, area, &cvarr_rgb, &color) != 1)
  202. return 0;
  203. }
  204. else {
  205. color = vector.layer[vec].fcolor;
  206. }
  207. if (vector.layer[vec].pat != NULL) { /* use pattern */
  208. sc = vector.layer[vec].scale;
  209. /* DEBUG */
  210. /*
  211. printf("\n eps pattern = %s\n", vector.layer[vec].eps);
  212. printf(" scale = %f\n", vector.layer[vec].scale);
  213. */
  214. /* load pattern */
  215. eps_bbox(vector.layer[vec].pat, &llx, &lly, &urx, &ury);
  216. sprintf(pat, "APATTEPS%d", vec);
  217. pat_save(PS.fp, vector.layer[vec].pat, pat);
  218. fprintf(PS.fp,
  219. "<< /PatternType 1\n /PaintType 1\n /TilingType 1\n");
  220. fprintf(PS.fp, " /BBox [%f %f %f %f]\n", llx * sc,
  221. lly * sc, urx * sc, ury * sc);
  222. fprintf(PS.fp, " /XStep %f\n /YStep %f\n",
  223. (urx - llx) * sc, (ury - lly) * sc);
  224. fprintf(PS.fp, " /PaintProc\n { begin\n");
  225. fprintf(PS.fp, " %f %f scale\n", sc, sc);
  226. set_ps_color(&color);
  227. fprintf(PS.fp, " %.8f W\n", vector.layer[vec].pwidth);
  228. fprintf(PS.fp, " %s\n", pat);
  229. fprintf(PS.fp, " end\n");
  230. fprintf(PS.fp, " } bind\n>>\n");
  231. sprintf(pat, "APATT%d", vec);
  232. fprintf(PS.fp, " matrix\n makepattern /%s exch def\n", pat);
  233. fprintf(PS.fp, "/Pattern setcolorspace\n %s setcolor\n", pat);
  234. }
  235. else {
  236. set_ps_color(&color);
  237. }
  238. fprintf(PS.fp, "F\n");
  239. }
  240. if (vector.layer[vec].width > 0 &&
  241. !(color_none(&vector.layer[vec].color))) {
  242. fprintf(PS.fp, "%.8f W\n", vector.layer[vec].width);
  243. set_ps_color(&(vector.layer[vec].color));
  244. fprintf(PS.fp, "stroke\n");
  245. }
  246. }
  247. fprintf(PS.fp, "\n");
  248. fprintf(PS.fp, "0 setlinejoin\n"); /* reset line join to miter */
  249. return 1;
  250. }