gs3.c 26 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199
  1. /*!
  2. \file lib/ogsf/gs3.c
  3. \brief OGSF library - loading surfaces (lower level functions)
  4. GRASS OpenGL gsurf OGSF Library
  5. (C) 1999-2008 by the GRASS Development Team
  6. This program is free software under the
  7. GNU General Public License (>=v2).
  8. Read the file COPYING that comes with GRASS
  9. for details.
  10. \author Bill Brown USACERL, GMSL/University of Illinois (January 1993)
  11. \author Doxygenized by Martin Landa <landa.martin gmail.com> (May 2008)
  12. */
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <grass/gis.h>
  16. #include <grass/raster.h>
  17. #include <grass/glocale.h>
  18. #include <grass/bitmap.h>
  19. #include <grass/ogsf.h>
  20. /* for geoview & geodisplay in 3dview stuff */
  21. #include "gsget.h"
  22. /* for update_attrange - might be able to move this func now */
  23. /*!
  24. \brief Used in the function Gs_update_attrange()
  25. */
  26. #define INIT_MINMAX(p, nm, size, min, max, found) \
  27. found = 0; \
  28. p+=(size-1); \
  29. while (size--) \
  30. { \
  31. if (!BM_GET_BYOFFSET(nm, size)) \
  32. { \
  33. min = max = *p; \
  34. found = 1; \
  35. break; \
  36. } \
  37. p--; \
  38. }
  39. /*!
  40. \brief Used in the function Gs_update_attrange()
  41. */
  42. #define SET_MINMAX(p, nm, size, min, max) \
  43. p+=(size-1); \
  44. while(size--) \
  45. { \
  46. if (!BM_GET_BYOFFSET(nm, size)) \
  47. { \
  48. if (*p < min) \
  49. { \
  50. min = *p; \
  51. } \
  52. else if (*p > max) \
  53. { \
  54. max = *p; \
  55. } \
  56. } \
  57. p--; \
  58. }
  59. typedef int FILEDESC;
  60. #define NO_DATA_COL 0xffffff
  61. /*!
  62. \brief Calculates distance in METERS between two points in current projection (2D)
  63. Uses G_distance().
  64. \param from 'from' point (X, Y)
  65. \param to 'to' point (X, Y)
  66. \return distance
  67. */
  68. double Gs_distance(double *from, double *to)
  69. {
  70. static int first = 1;
  71. if (first) {
  72. first = 0;
  73. G_begin_distance_calculations();
  74. }
  75. return G_distance(from[0], from[1], to[0], to[1]);
  76. }
  77. /*!
  78. \brief Load raster map as floating point map
  79. Calling function must have already allocated space in buff for
  80. wind->rows * wind->cols floats.
  81. This routine simply loads the map into a 2d array by repetitve calls
  82. to get_f_raster_row.
  83. \param wind current window
  84. \param map_name raster map name
  85. \param[out] buff data buffer
  86. \param[out] nullmap null map buffer
  87. \param[out] has_null indicates if raster map contains null-data
  88. \return 1 on success
  89. \return 0 on failure
  90. */
  91. int Gs_loadmap_as_float(struct Cell_head *wind, const char *map_name,
  92. float *buff, struct BM *nullmap, int *has_null)
  93. {
  94. FILEDESC cellfile;
  95. const char *map_set;
  96. int offset, row, col;
  97. G_debug(3, "Gs_loadmap_as_float(): name=%s", map_name);
  98. map_set = G_find_raster2(map_name, "");
  99. if (!map_set) {
  100. G_warning(_("Raster map <%s> not found"), map_name);
  101. return 0;
  102. }
  103. *has_null = 0;
  104. cellfile = Rast_open_old(map_name, map_set);
  105. G_message(_("Loading raster map <%s>..."),
  106. G_fully_qualified_name(map_name, map_set));
  107. for (row = 0; row < wind->rows; row++) {
  108. offset = row * wind->cols;
  109. Rast_get_f_row(cellfile, &(buff[offset]), row);
  110. G_percent(row, wind->rows, 2);
  111. for (col = 0; col < wind->cols; col++) {
  112. if (Rast_is_f_null_value(buff + offset + col)) {
  113. *has_null = 1;
  114. BM_set(nullmap, col, row, 1);
  115. }
  116. /* set nm */
  117. }
  118. }
  119. G_percent(1, 1, 1);
  120. G_debug(4, " has_null=%d", *has_null);
  121. Rast_close(cellfile);
  122. return (1);
  123. }
  124. /*!
  125. \brief Load raster map as integer map
  126. Calling function must have already allocated space in buff for
  127. wind->rows * wind->cols floats.
  128. This routine simply loads the map into a 2d array by repetitve calls
  129. to get_f_raster_row.
  130. \todo fn body of Gs_loadmap_as_float()
  131. \param wind current window
  132. \param map_name raster map name
  133. \param[out] buff data buffer
  134. \param[out] nullmap null map buffer
  135. \param[out] has_null indicates if raster map contains null-data
  136. \return 1 on success
  137. \return 0 on failure
  138. */
  139. int Gs_loadmap_as_int(struct Cell_head *wind, const char *map_name, int *buff,
  140. struct BM *nullmap, int *has_null)
  141. {
  142. FILEDESC cellfile;
  143. const char *map_set;
  144. int offset, row, col;
  145. G_debug(3, "Gs_loadmap_as_int");
  146. map_set = G_find_raster2(map_name, "");
  147. if (!map_set) {
  148. G_warning(_("Raster map <%s> not found"), map_name);
  149. return 0;
  150. }
  151. *has_null = 0;
  152. cellfile = Rast_open_old(map_name, map_set);
  153. G_message(_("Loading raster map <%s>..."),
  154. G_fully_qualified_name(map_name, map_set));
  155. for (row = 0; row < wind->rows; row++) {
  156. offset = row * wind->cols;
  157. Rast_get_c_row(cellfile, &(buff[offset]), row);
  158. G_percent(row, wind->rows, 2);
  159. for (col = 0; col < wind->cols; col++) {
  160. if (Rast_is_f_null_value(buff + offset + col)) {
  161. *has_null = 1;
  162. BM_set(nullmap, col, row, 1);
  163. }
  164. /* set nm */
  165. }
  166. }
  167. G_percent(1, 1, 1);
  168. Rast_close(cellfile);
  169. return (1);
  170. }
  171. /*!
  172. \brief Get map data type
  173. \param filename raster map name
  174. \param negflag
  175. \return -1 if map is integer and Rast_read_range() fails
  176. \return data type (ARRY_*)
  177. */
  178. int Gs_numtype(const char *filename, int *negflag)
  179. {
  180. CELL max = 0, min = 0;
  181. struct Range range;
  182. const char *mapset;
  183. int shortbits, charbits, bitplace;
  184. static int max_short, max_char;
  185. static int first = 1;
  186. if (first) {
  187. max_short = max_char = 1;
  188. shortbits = 8 * sizeof(short);
  189. for (bitplace = 1; bitplace < shortbits; ++bitplace) {
  190. /*1 bit for sign */
  191. max_short *= 2;
  192. }
  193. max_short -= 1;
  194. /* NO bits for sign, using unsigned char */
  195. charbits = 8 * sizeof(unsigned char);
  196. for (bitplace = 0; bitplace < charbits; ++bitplace) {
  197. max_char *= 2;
  198. }
  199. max_char -= 1;
  200. first = 0;
  201. }
  202. mapset = G_find_raster2(filename, "");
  203. if (!mapset) {
  204. G_warning(_("Raster map <%s> not found"), filename);
  205. return -1;
  206. }
  207. if (Rast_map_is_fp(filename, mapset)) {
  208. G_debug(3, "Gs_numtype(): fp map detected");
  209. return (ATTY_FLOAT);
  210. }
  211. if (-1 == Rast_read_range(filename, mapset, &range)) {
  212. return (-1);
  213. }
  214. Rast_get_range_min_max(&range, &min, &max);
  215. *negflag = (min < 0);
  216. if (max < max_char && min > 0) {
  217. return (ATTY_CHAR);
  218. }
  219. if (max < max_short && min > -max_short) {
  220. return (ATTY_SHORT);
  221. }
  222. return (ATTY_INT);
  223. }
  224. /*!
  225. \brief Load raster map as integer map
  226. Calling function must have already allocated space in buff for
  227. wind->rows * wind->cols shorts.
  228. This routine simply loads the map into a 2d array by repetitve calls
  229. to get_map_row.
  230. \param wind current window
  231. \param map_name raster map name
  232. \param[out] buff data buffer
  233. \param[out] nullmap null map buffer
  234. \param[out] has_null indicates if raster map contains null-data
  235. \return 1 on success
  236. \return -1 on failure,
  237. \return -2 if read ok, but 1 or more values were too large (small)
  238. to fit into a short (in which case the max (min) short is used)
  239. */
  240. int Gs_loadmap_as_short(struct Cell_head *wind, const char *map_name,
  241. short *buff, struct BM *nullmap, int *has_null)
  242. {
  243. FILEDESC cellfile;
  244. const char *map_set;
  245. int *ti, *tmp_buf;
  246. int offset, row, col, val, max_short, overflow, shortsize, bitplace;
  247. short *ts;
  248. G_debug(3, "Gs_loadmap_as_short");
  249. overflow = 0;
  250. shortsize = 8 * sizeof(short);
  251. /* 1 bit for sign */
  252. /* same as 2 << (shortsize-1) */
  253. for (max_short = bitplace = 1; bitplace < shortsize; ++bitplace) {
  254. max_short *= 2;
  255. }
  256. max_short -= 1;
  257. map_set = G_find_raster2(map_name, "");
  258. if (!map_set) {
  259. G_warning(_("Raster map <%s> not found"), map_name);
  260. return -1;
  261. }
  262. *has_null = 0;
  263. cellfile = Rast_open_old(map_name, map_set);
  264. tmp_buf = (int *)G_malloc(wind->cols * sizeof(int)); /* G_fatal_error */
  265. if (!tmp_buf) {
  266. return -1;
  267. }
  268. G_message(_("Loading raster map <%s>..."),
  269. G_fully_qualified_name(map_name, map_set));
  270. for (row = 0; row < wind->rows; row++) {
  271. offset = row * wind->cols;
  272. Rast_get_c_row(cellfile, tmp_buf, row);
  273. G_percent(row, wind->rows, 2);
  274. ts = &(buff[offset]);
  275. ti = tmp_buf;
  276. for (col = 0; col < wind->cols; col++) {
  277. if (Rast_is_c_null_value(&tmp_buf[col])) {
  278. *has_null = 1;
  279. BM_set(nullmap, col, row, 1);
  280. }
  281. else {
  282. val = *ti;
  283. if (abs(val) > max_short) {
  284. overflow = 1;
  285. /* assign floor/ceiling value?
  286. */
  287. *ts = (short)(max_short * val / abs(val));
  288. }
  289. else {
  290. *ts = (short)val;
  291. }
  292. }
  293. ti++;
  294. ts++;
  295. }
  296. }
  297. G_percent(1, 1, 1);
  298. Rast_close(cellfile);
  299. G_free(tmp_buf);
  300. return (overflow ? -2 : 1);
  301. }
  302. /*!
  303. \brief Load raster map as integer map
  304. Calling function must have already allocated space in buff for
  305. wind->rows * wind->cols unsigned chars.
  306. This routine simply loads the map into a 2d array by repetitve calls
  307. to get_map_row.
  308. Since signs of chars can be tricky, we only load positive chars
  309. between 0-255.
  310. \todo fn body Gs_loadmap_as_float()
  311. \param wind current window
  312. \param map_name raster map name
  313. \param[out] buff data buffer
  314. \param[out] nullmap null map buffer
  315. \param[out] has_null indicates if raster map contains null-data
  316. \return 1 on success
  317. \return -1 on failure
  318. \return -2 if read ok, but 1 or more values
  319. were too large (small) to fit into an unsigned char.
  320. (in which case the max (min) char is used)
  321. */
  322. int Gs_loadmap_as_char(struct Cell_head *wind, const char *map_name,
  323. unsigned char *buff, struct BM *nullmap, int *has_null)
  324. {
  325. FILEDESC cellfile;
  326. const char *map_set;
  327. int *ti, *tmp_buf;
  328. int offset, row, col, val, max_char, overflow, charsize, bitplace;
  329. unsigned char *tc;
  330. G_debug(3, "Gs_loadmap_as_char");
  331. overflow = 0;
  332. charsize = 8 * sizeof(unsigned char);
  333. /* 0 bits for sign! */
  334. max_char = 1;
  335. for (bitplace = 0; bitplace < charsize; ++bitplace) {
  336. max_char *= 2;
  337. }
  338. max_char -= 1;
  339. map_set = G_find_raster2(map_name, "");
  340. if (!map_set) {
  341. G_warning(_("Raster map <%s> not found"), map_name);
  342. return -1;
  343. }
  344. *has_null = 0;
  345. cellfile = Rast_open_old(map_name, map_set);
  346. tmp_buf = (int *)G_malloc(wind->cols * sizeof(int)); /* G_fatal_error */
  347. if (!tmp_buf) {
  348. return -1;
  349. }
  350. G_message(_("Loading raster map <%s>..."),
  351. G_fully_qualified_name(map_name, map_set));
  352. for (row = 0; row < wind->rows; row++) {
  353. offset = row * wind->cols;
  354. Rast_get_c_row(cellfile, tmp_buf, row);
  355. tc = (unsigned char *)&(buff[offset]);
  356. ti = tmp_buf;
  357. G_percent(row, wind->rows, 2);
  358. for (col = 0; col < wind->cols; col++) {
  359. if (Rast_is_c_null_value(&tmp_buf[col])) {
  360. *has_null = 1;
  361. BM_set(nullmap, col, row, 1);
  362. }
  363. else {
  364. val = *ti;
  365. if (val > max_char) {
  366. overflow = 1;
  367. *tc = (unsigned char)max_char;
  368. }
  369. else if (val < 0) {
  370. overflow = 1;
  371. *tc = 0;
  372. }
  373. else {
  374. *tc = (unsigned char)val;
  375. }
  376. }
  377. ti++;
  378. tc++;
  379. }
  380. }
  381. G_percent(1, 1, 1);
  382. Rast_close(cellfile);
  383. G_free(tmp_buf);
  384. return (overflow ? -2 : 1);
  385. }
  386. /*!
  387. \brief Load raster map as integer map
  388. Calling function must have already allocated space in buff for
  389. struct BM of wind->rows & wind->cols.
  390. This routine simply loads the map into the bitmap by repetitve calls
  391. to get_map_row. Any value other than 0 in the map will set the bitmap.
  392. (may want to change later to allow specific value to set)
  393. Changed to use null.
  394. \param wind current window
  395. \param map_name raster map name
  396. \param[out] buff data buffer
  397. \returns 1 on success
  398. \return -1 on failure
  399. */
  400. int Gs_loadmap_as_bitmap(struct Cell_head *wind, const char *map_name,
  401. struct BM *buff)
  402. {
  403. FILEDESC cellfile;
  404. const char *map_set;
  405. int *tmp_buf;
  406. int row, col;
  407. G_debug(3, "Gs_loadmap_as_bitmap");
  408. map_set = G_find_raster2(map_name, "");
  409. if (!map_set) {
  410. G_warning(_("Raster map <%s> not found"), map_name);
  411. return -1;
  412. }
  413. cellfile = Rast_open_old(map_name, map_set);
  414. tmp_buf = (int *)G_malloc(wind->cols * sizeof(int)); /* G_fatal_error */
  415. if (!tmp_buf) {
  416. return -1;
  417. }
  418. G_message(_("Loading raster map <%s>..."),
  419. G_fully_qualified_name(map_name, map_set));
  420. for (row = 0; row < wind->rows; row++) {
  421. Rast_get_c_row(cellfile, tmp_buf, row);
  422. for (col = 0; col < wind->cols; col++) {
  423. if (Rast_is_c_null_value(&tmp_buf[col])) {
  424. /* no data */
  425. BM_set(buff, col, row, 1);
  426. }
  427. else {
  428. BM_set(buff, col, row, 0);
  429. }
  430. }
  431. }
  432. Rast_close(cellfile);
  433. G_free(tmp_buf);
  434. return (1);
  435. }
  436. /*!
  437. \brief Build color table (256)
  438. Calling function must have already allocated space in buff for range of
  439. data (256 for now) - simply calls get_color for each cat in color range
  440. \param filename raster map name
  441. \param[out] buff data buffer
  442. \return 1 on success
  443. \return 0 on failure
  444. */
  445. int Gs_build_256lookup(const char *filename, int *buff)
  446. {
  447. const char *mapset;
  448. struct Colors colrules;
  449. CELL min, max, cats[256];
  450. int i;
  451. unsigned char r[256], g[256], b[256], set[256];
  452. G_debug(3, "building color table");
  453. mapset = G_find_raster2(filename, "");
  454. if (!mapset) {
  455. G_warning(_("Raster map <%s> not found"), filename);
  456. return 0;
  457. }
  458. Rast_read_colors(filename, mapset, &colrules);
  459. Rast_get_c_color_range(&min, &max, &colrules);
  460. if (min < 0 || max > 255) {
  461. G_warning(_("Color table range doesn't match data (mincol=%d, maxcol=%d"),
  462. min, max);
  463. min = min < 0 ? 0 : min;
  464. max = max > 255 ? 255 : max;
  465. }
  466. G_zero(cats, 256 * sizeof(CELL));
  467. for (i = min; i <= max; i++) {
  468. cats[i] = i;
  469. }
  470. Rast_lookup_c_colors(cats, r, g, b, set, 256, &colrules);
  471. for (i = 0; i < 256; i++) {
  472. if (set[i]) {
  473. buff[i] =
  474. (r[i] & 0xff) | ((g[i] & 0xff) << 8) | ((b[i] & 0xff) << 16);
  475. }
  476. else {
  477. buff[i] = NO_DATA_COL;
  478. }
  479. }
  480. return (1);
  481. }
  482. /*!
  483. \brief Pack color table
  484. Passed an array of 32 bit ints that is converted from cell values
  485. to packed colors (0xbbggrr)
  486. \param filename raster map name
  487. \param buff
  488. \param rows number of rows
  489. \param cols number of cols
  490. */
  491. void Gs_pack_colors(const char *filename, int *buff, int rows, int cols)
  492. {
  493. const char *mapset;
  494. struct Colors colrules;
  495. unsigned char *r, *g, *b, *set;
  496. int *cur, i, j;
  497. mapset = G_find_raster2(filename, "");
  498. if (!mapset) {
  499. G_warning(_("Raster map <%s> not found"), filename);
  500. return;
  501. }
  502. r = (unsigned char *)G_malloc(cols);
  503. g = (unsigned char *)G_malloc(cols);
  504. b = (unsigned char *)G_malloc(cols);
  505. set = (unsigned char *)G_malloc(cols);
  506. Rast_read_colors(filename, mapset, &colrules);
  507. cur = buff;
  508. G_message(_("Translating colors from raster map <%s>..."),
  509. G_fully_qualified_name(filename, mapset));
  510. for (i = 0; i < rows; i++) {
  511. Rast_lookup_c_colors(cur, r, g, b, set, cols, &colrules);
  512. G_percent(i, rows, 2);
  513. for (j = 0; j < cols; j++) {
  514. if (set[j]) {
  515. cur[j] =
  516. (r[j] & 0xff) | ((g[j] & 0xff) << 8) | ((b[j] & 0xff) <<
  517. 16);
  518. }
  519. else {
  520. cur[j] = NO_DATA_COL;
  521. }
  522. }
  523. cur = &(cur[cols]);
  524. }
  525. G_percent(1, 1, 1);
  526. Rast_free_colors(&colrules);
  527. G_free(r);
  528. G_free(g);
  529. G_free(b);
  530. G_free(set);
  531. return;
  532. }
  533. /*!
  534. \brief Pack color table (floating-point map)
  535. Passed a array of floats that will be converted from cell values
  536. to packed colors (0xbbggrr) and float to int
  537. Floating point data not freed here, use:
  538. gsds_free_data_buff(id, ATTY_FLOAT)
  539. \param filename raster map name
  540. \param fbuf
  541. \param ibuf
  542. \param rows number of rows
  543. \param cols number of cols
  544. */
  545. void Gs_pack_colors_float(const char *filename, float *fbuf, int *ibuf,
  546. int rows, int cols)
  547. {
  548. const char *mapset;
  549. struct Colors colrules;
  550. unsigned char *r, *g, *b, *set;
  551. int i, j, *icur;
  552. FCELL *fcur;
  553. mapset = G_find_raster2(filename, "");
  554. if (!mapset) {
  555. G_warning(_("Raster map <%s> not found"), filename);
  556. return;
  557. }
  558. r = (unsigned char *)G_malloc(cols);
  559. g = (unsigned char *)G_malloc(cols);
  560. b = (unsigned char *)G_malloc(cols);
  561. set = (unsigned char *)G_malloc(cols);
  562. Rast_read_colors(filename, mapset, &colrules);
  563. fcur = fbuf;
  564. icur = ibuf;
  565. G_message(_("Translating colors from raster map <%s>..."),
  566. G_fully_qualified_name(filename, mapset));
  567. for (i = 0; i < rows; i++) {
  568. Rast_lookup_f_colors(fcur, r, g, b, set, cols, &colrules);
  569. G_percent(i, rows, 2);
  570. for (j = 0; j < cols; j++) {
  571. if (set[j]) {
  572. icur[j] =
  573. (r[j] & 0xff) | ((g[j] & 0xff) << 8) | ((b[j] & 0xff) <<
  574. 16);
  575. }
  576. else {
  577. icur[j] = NO_DATA_COL;
  578. }
  579. }
  580. icur = &(icur[cols]);
  581. fcur = &(fcur[cols]);
  582. }
  583. G_percent(1, 1, 1);
  584. Rast_free_colors(&colrules);
  585. G_free(r);
  586. G_free(g);
  587. G_free(b);
  588. G_free(set);
  589. return;
  590. }
  591. /*!
  592. \brief Get categories/labels
  593. Formats label as in d.what.rast -> (catval) catlabel
  594. \param filename raster map name
  595. \param drow
  596. \param dcol
  597. \param catstr category string
  598. \return 1 on success
  599. \return 0 on failure
  600. */
  601. int Gs_get_cat_label(const char *filename, int drow, int dcol, char *catstr)
  602. {
  603. struct Categories cats;
  604. const char *mapset;
  605. CELL *buf;
  606. DCELL *dbuf;
  607. RASTER_MAP_TYPE map_type;
  608. int fd = -1;
  609. if ((mapset = G_find_raster2(filename, "")) == NULL) {
  610. G_warning(_("Raster map <%s> not found"), filename);
  611. return 0;
  612. }
  613. if (-1 != Rast_read_cats(filename, mapset, &cats)) {
  614. fd = Rast_open_old(filename, mapset);
  615. map_type = Rast_get_map_type(fd);
  616. if (map_type == CELL_TYPE) {
  617. buf = Rast_allocate_c_buf();
  618. Rast_get_c_row(fd, buf, drow);
  619. if (Rast_is_c_null_value(&buf[dcol])) {
  620. sprintf(catstr, "(NULL) %s",
  621. Rast_get_c_cat(&buf[dcol], &cats));
  622. }
  623. else {
  624. sprintf(catstr, "(%d) %s", buf[dcol],
  625. Rast_get_c_cat(&buf[dcol], &cats));
  626. }
  627. G_free(buf);
  628. }
  629. else {
  630. /* fp map */
  631. dbuf = Rast_allocate_d_buf();
  632. Rast_get_d_row(fd, dbuf, drow);
  633. if (Rast_is_d_null_value(&dbuf[dcol])) {
  634. sprintf(catstr, "(NULL) %s",
  635. Rast_get_d_cat(&dbuf[dcol], &cats));
  636. }
  637. else {
  638. sprintf(catstr, "(%g) %s", dbuf[dcol],
  639. Rast_get_d_cat(&dbuf[dcol], &cats));
  640. }
  641. G_free(dbuf);
  642. }
  643. }
  644. else {
  645. strcpy(catstr, "no category label");
  646. return 0;
  647. }
  648. /* TODO: may want to keep these around for multiple queries */
  649. Rast_free_cats(&cats);
  650. if (fd >= 0)
  651. Rast_close(fd);
  652. return (1);
  653. }
  654. /*!
  655. \brief Save 3dview
  656. \param vname view name
  657. \param gv pointer to geoview struct
  658. \param gd pointer to geodisplay struct
  659. \param w current window
  660. \param defsurf default geosurf struct
  661. \return -1 on error
  662. \return ?
  663. */
  664. int Gs_save_3dview(const char *vname, geoview * gv, geodisplay * gd,
  665. struct Cell_head *w, geosurf * defsurf)
  666. {
  667. const char *mapset;
  668. struct G_3dview v;
  669. float zmax, zmin;
  670. GS_get_zrange(&zmin, &zmax, 0);
  671. G_get_3dview_defaults(&v, w);
  672. mapset = G_mapset();
  673. if (mapset != NULL) {
  674. if (defsurf) {
  675. if (defsurf->draw_mode & DM_WIRE_POLY) {
  676. v.display_type = 3;
  677. }
  678. else if (defsurf->draw_mode & DM_WIRE ||
  679. defsurf->draw_mode & DM_COL_WIRE) {
  680. v.display_type = 1;
  681. }
  682. else if (defsurf->draw_mode & DM_POLY) {
  683. v.display_type = 2;
  684. }
  685. v.mesh_freq = defsurf->x_modw; /* mesh resolution */
  686. v.poly_freq = defsurf->x_mod; /* poly resolution */
  687. v.dozero = !(defsurf->nz_topo);
  688. v.colorgrid = (defsurf->draw_mode & DM_COL_WIRE) ? 1 : 0;
  689. v.shading = (defsurf->draw_mode & DM_GOURAUD) ? 1 : 0;
  690. }
  691. if (gv->infocus) {
  692. GS_v3eq(v.from_to[TO], gv->real_to);
  693. v.from_to[TO][Z] -= zmin;
  694. GS_v3mult(v.from_to[TO], gv->scale);
  695. v.from_to[TO][Z] *= gv->vert_exag;
  696. }
  697. else {
  698. GS_v3eq(v.from_to[TO], gv->from_to[TO]);
  699. }
  700. gsd_model2real(v.from_to[TO]);
  701. GS_v3eq(v.from_to[FROM], gv->from_to[FROM]);
  702. gsd_model2real(v.from_to[FROM]);
  703. v.exag = gv->vert_exag;
  704. v.fov = gv->fov / 10.;
  705. v.twist = gv->twist;
  706. v.fringe = 0; /* not implemented here */
  707. v.lightson = 1; /* always true, curently */
  708. if (gv->lights[0].position[W] == 1) {
  709. /* local */
  710. v.lightpos[X] = gv->lights[0].position[X];
  711. v.lightpos[Y] = gv->lights[0].position[Y];
  712. v.lightpos[Z] = gv->lights[0].position[Z];
  713. gsd_model2real(v.lightpos);
  714. v.lightpos[W] = 1.0; /* local */
  715. }
  716. else {
  717. v.lightpos[X] = gv->lights[0].position[X];
  718. v.lightpos[Y] = gv->lights[0].position[Y];
  719. v.lightpos[Z] = gv->lights[0].position[Z];
  720. v.lightpos[W] = 0.0; /* inf */
  721. }
  722. v.lightcol[0] = gv->lights[0].color[0];
  723. v.lightcol[1] = gv->lights[0].color[1];
  724. v.lightcol[2] = gv->lights[0].color[2];
  725. v.ambient = (gv->lights[0].ambient[0] + gv->lights[0].ambient[1] +
  726. gv->lights[0].ambient[2]) / 3.;
  727. v.shine = gv->lights[0].shine;
  728. v.surfonly = 0; /* N/A - now uses constant color */
  729. strcpy((v.pgm_id), "Nvision-ALPHA!");
  730. return (G_put_3dview(vname, mapset, &v, w));
  731. }
  732. else {
  733. return (-1);
  734. }
  735. }
  736. /*!
  737. \brief Load 3dview
  738. \param vname view name
  739. \param gv pointer to geoview struct
  740. \param gd pointer to geodisplay struct
  741. \param w current window
  742. \param defsurf default geosurf struct
  743. \return 1
  744. */
  745. int Gs_load_3dview(const char *vname, geoview * gv, geodisplay * gd,
  746. struct Cell_head *w, geosurf * defsurf)
  747. {
  748. const char *mapset;
  749. struct G_3dview v;
  750. int ret = -1;
  751. float pt[3];
  752. mapset = G_find_file2("3d.view", vname, "");
  753. if (mapset != NULL) {
  754. ret = G_get_3dview(vname, mapset, &v);
  755. }
  756. if (ret >= 0) {
  757. if (strcmp((v.pgm_id), "Nvision-ALPHA!")) {
  758. G_warning(_("View not saved by this program,"
  759. "there may be some inconsistancies"));
  760. }
  761. /* set poly and mesh resolutions */
  762. v.mesh_freq = (int)(v.mesh_freq * v.vwin.ns_res / w->ns_res);
  763. v.poly_freq = (int)(v.poly_freq * v.vwin.ns_res / w->ns_res);
  764. /* Set To and FROM positions */
  765. /* TO */
  766. pt[0] = (v.from_to[TO][X] - w->west) - w->ew_res / 2.;
  767. pt[1] = (v.from_to[TO][Y] - w->south) - w->ns_res / 2.;
  768. pt[2] = v.from_to[TO][Z];
  769. GS_set_focus(pt);
  770. /* FROM */
  771. pt[0] = (float)v.from_to[FROM][X];
  772. pt[1] = (float)v.from_to[FROM][Y];
  773. pt[2] = (float)v.from_to[FROM][Z];
  774. GS_moveto_real(pt);
  775. if (defsurf) {
  776. int dmode = 0;
  777. GS_setall_drawres(v.poly_freq, v.poly_freq,
  778. v.mesh_freq, v.mesh_freq);
  779. while (v.display_type >= 10) {
  780. /* globe stuff not used */
  781. v.display_type -= 10;
  782. }
  783. /* set drawing modes */
  784. if (v.colorgrid) {
  785. dmode |= DM_COL_WIRE;
  786. }
  787. if (v.shading) {
  788. dmode |= DM_GOURAUD;
  789. }
  790. switch (v.display_type) {
  791. case 1:
  792. dmode |= DM_WIRE;
  793. break;
  794. case 2:
  795. dmode |= DM_POLY;
  796. break;
  797. case 3:
  798. dmode |= DM_WIRE_POLY;
  799. break;
  800. }
  801. GS_setall_drawmode(dmode);
  802. /* should also set nozeros here */
  803. }
  804. /* set exaggeration */
  805. if (v.exag)
  806. GS_set_global_exag(v.exag);
  807. /* Set FOV */
  808. if (v.fov) {
  809. GS_set_fov((int)
  810. (v.fov > 0 ? v.fov * 10. + 0.5 : v.fov * 10. - 0.5));
  811. }
  812. else {
  813. /* TODO: do ortho */
  814. }
  815. /* Set twist */
  816. if (v.twist)
  817. GS_set_twist((int)(v.twist > 0 ? v.twist + 0.5 : v.twist - 0.5));
  818. /* TODO: OK to here - need to unravel/reverse lights stuff*** */
  819. if (v.lightson) {
  820. /* Lights are on */
  821. /* Light Position */
  822. gv->lights[0].position[X] = v.lightpos[X];
  823. gv->lights[0].position[Y] = v.lightpos[Y];
  824. gv->lights[0].position[Z] = v.lightpos[Z];
  825. /* Light Color */
  826. gv->lights[0].color[0] = v.lightcol[0];
  827. gv->lights[0].color[1] = v.lightcol[1];
  828. gv->lights[0].color[2] = v.lightcol[2];
  829. /* Light Shininess */
  830. gv->lights[0].shine = v.shine;
  831. /* Light Ambient */
  832. gv->lights[0].ambient[0] = gv->lights[0].ambient[1] =
  833. gv->lights[0].ambient[2] = v.ambient * 3.;
  834. } /* Done with lights */
  835. GS_alldraw_wire();
  836. } /* Done with file */
  837. return (1);
  838. }
  839. /*!
  840. \brief Update no_zero ranges for attribute (actually no_null now)
  841. \param gs pointer to geosurf struct
  842. \param desc attribute id (descriptor)
  843. \return -1 on error
  844. \return 1 on success
  845. */
  846. int Gs_update_attrange(geosurf * gs, int desc)
  847. {
  848. long size;
  849. float min, max;
  850. typbuff *tb;
  851. struct BM *nm;
  852. int found;
  853. gs->att[desc].max_nz = gs->att[desc].min_nz = gs->att[desc].range_nz =
  854. 0.0;
  855. if (CONST_ATT == gs_get_att_src(gs, desc)) {
  856. gs->att[desc].max_nz = gs->att[desc].min_nz = gs->att[desc].constant;
  857. min = max = gs->att[desc].constant;
  858. gs->att[desc].range_nz = 0.0;
  859. }
  860. else if (CF_COLOR_PACKED & gsds_get_changed(gs->att[desc].hdata)) {
  861. gs->att[desc].max_nz = 0xFFFFFF;
  862. gs->att[desc].min_nz = 0x010101;
  863. gs->att[desc].range_nz = 0xFFFFFF;
  864. }
  865. else {
  866. if (NULL == (tb = gsds_get_typbuff(gs->att[desc].hdata, 0))) {
  867. return (-1);
  868. }
  869. nm = tb->nm;
  870. if (tb->ib) {
  871. int *p;
  872. size = gs->rows * gs->cols;
  873. p = tb->ib;
  874. INIT_MINMAX(p, nm, size, min, max, found);
  875. if (!found) {
  876. /* all nulls! */
  877. return (-1);
  878. }
  879. size = gs->rows * gs->cols;
  880. p = tb->ib;
  881. SET_MINMAX(p, nm, size, min, max);
  882. }
  883. else if (tb->sb) {
  884. short *p;
  885. size = gs->rows * gs->cols;
  886. p = tb->sb;
  887. INIT_MINMAX(p, nm, size, min, max, found);
  888. if (!found) {
  889. /* all nulls! */
  890. return (-1);
  891. }
  892. size = gs->rows * gs->cols;
  893. p = tb->sb;
  894. SET_MINMAX(p, nm, size, min, max);
  895. }
  896. else if (tb->cb) {
  897. char *p;
  898. size = gs->rows * gs->cols;
  899. p = (char *)tb->cb;
  900. INIT_MINMAX(p, nm, size, min, max, found);
  901. if (!found) {
  902. /* all nulls! */
  903. return (-1);
  904. }
  905. size = gs->rows * gs->cols;
  906. p = (char *)tb->cb;
  907. SET_MINMAX(p, nm, size, min, max);
  908. }
  909. else if (tb->fb) {
  910. float *p;
  911. size = gs->rows * gs->cols;
  912. p = tb->fb;
  913. INIT_MINMAX(p, nm, size, min, max, found);
  914. if (!found) {
  915. /* all nulls! */
  916. return (-1);
  917. }
  918. size = gs->rows * gs->cols;
  919. p = tb->fb;
  920. SET_MINMAX(p, nm, size, min, max);
  921. }
  922. gs->att[desc].max_nz = max;
  923. gs->att[desc].min_nz = min;
  924. gs->att[desc].range_nz = gs->att[desc].max_nz - gs->att[desc].min_nz;
  925. }
  926. if (ATT_TOPO == desc) {
  927. gs->zmin = min;
  928. gs->zmax = max;
  929. gs->zrange = gs->zmax - gs->zmin;
  930. gs->zminmasked = gs->zmin;
  931. gs->zmax_nz = gs->zmax;
  932. gs->zmin_nz = gs->zmin;
  933. gs->zrange_nz = gs->zmax_nz - gs->zmin_nz;
  934. }
  935. G_debug(3, "Gs_update_attrange(): min=%f max=%f", gs->zmin, gs->zmax);
  936. return (1);
  937. }