Gs3.c 27 KB

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