Gs3.c 27 KB

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