gp2.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711
  1. /*!
  2. \file lib/ogsf/gp2.c
  3. \brief OGSF library - loading and manipulating point sets (higher level functions)
  4. (C) 1999-2008, 2011 by the GRASS Development Team
  5. This program is free software under the GNU General Public License
  6. (>=v2). Read the file COPYING that comes with GRASS for details.
  7. \author Bill Brown USACERL (January 1994)
  8. \author Updated by Martin landa <landa.martin gmail.com>
  9. (doxygenized in May 2008, thematic mapping in June 2011)
  10. */
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <grass/gis.h>
  14. #include <grass/ogsf.h>
  15. #include <grass/glocale.h>
  16. #include "gsget.h"
  17. static int Site_ID[MAX_SITES];
  18. static int Next_site = 0;
  19. /*!
  20. \brief Check if point set exists
  21. \param id point set id
  22. \return 1 found
  23. \return 0 not found
  24. */
  25. int GP_site_exists(int id)
  26. {
  27. int i, found = 0;
  28. G_debug(4, "GP_site_exists(%d)", id);
  29. if (NULL == gp_get_site(id)) {
  30. return 0;
  31. }
  32. for (i = 0; i < Next_site && !found; i++) {
  33. if (Site_ID[i] == id) {
  34. found = 1;
  35. }
  36. }
  37. G_debug(3, "GP_site_exists(): found=%d", found);
  38. return found;
  39. }
  40. /*!
  41. \brief Create new point set
  42. \return point set id
  43. \return -1 on error (number of point sets exceeded)
  44. */
  45. int GP_new_site(void)
  46. {
  47. geosite *np;
  48. if (Next_site < MAX_SITES) {
  49. np = gp_get_new_site();
  50. gp_set_defaults(np);
  51. Site_ID[Next_site] = np->gsite_id;
  52. ++Next_site;
  53. G_debug(3, "GP_new_site() id=%d", np->gsite_id);
  54. return np->gsite_id;
  55. }
  56. return -1;
  57. }
  58. /*!
  59. \brief Get number of loaded point sets
  60. \return number of point sets
  61. */
  62. int GP_num_sites(void)
  63. {
  64. return gp_num_sites();
  65. }
  66. /*!
  67. \brief Get list of point sets
  68. Must freed when no longer needed!
  69. \param numsites number of point sets
  70. \return pointer to list of points sets
  71. \return NULL on error
  72. */
  73. int *GP_get_site_list(int *numsites)
  74. {
  75. int i, *ret;
  76. *numsites = Next_site;
  77. if (Next_site) {
  78. ret = (int *)G_malloc(Next_site * sizeof(int)); /* G_fatal_error */
  79. if (!ret) {
  80. return NULL;
  81. }
  82. for (i = 0; i < Next_site; i++) {
  83. ret[i] = Site_ID[i];
  84. }
  85. return ret;
  86. }
  87. return NULL;
  88. }
  89. /*!
  90. \brief Delete registrated point set
  91. \param id point set id
  92. \return 1 on success
  93. \return -1 on error (point sets not available)
  94. */
  95. int GP_delete_site(int id)
  96. {
  97. int i, j, found = 0;
  98. G_debug(4, "GP_delete_site(%d)", id);
  99. if (GP_site_exists(id)) {
  100. gp_delete_site(id);
  101. for (i = 0; i < Next_site && !found; i++) {
  102. if (Site_ID[i] == id) {
  103. found = 1;
  104. for (j = i; j < Next_site; j++) {
  105. Site_ID[j] = Site_ID[j + 1];
  106. }
  107. }
  108. }
  109. if (found) {
  110. --Next_site;
  111. return 1;
  112. }
  113. }
  114. return -1;
  115. }
  116. /*!
  117. \brief Load point set from file
  118. Check to see if handle already loaded, if so - free before loading
  119. new for now, always load to memory.
  120. \todo load file handle & ready for reading instead of using memory
  121. \param id point set id
  122. \param filename point set filename
  123. \return -1 on error
  124. \return 1 on success
  125. */
  126. int GP_load_site(int id, const char *filename)
  127. {
  128. geosite *gp;
  129. G_debug(3, "GP_load_site(id=%d, name=%s)", id, filename);
  130. if (NULL == (gp = gp_get_site(id))) {
  131. return -1;
  132. }
  133. if (gp->points) {
  134. gp_free_sitemem(gp);
  135. }
  136. gp->filename = G_store(filename);
  137. gp->points = Gp_load_sites(filename, &(gp->n_sites), &(gp->has_z));
  138. if (gp->points) {
  139. return 1;
  140. }
  141. return -1;
  142. }
  143. /*!
  144. \brief Get point set filename
  145. Note: char array is allocated by G_store()
  146. \param id point set id
  147. \param[out] filename point set filename
  148. \return -1 on error (point set not found)
  149. \return 1 on success
  150. */
  151. int GP_get_sitename(int id, char **filename)
  152. {
  153. geosite *gp;
  154. G_debug(4, "GP_get_sitename(%d)", id);
  155. if (NULL == (gp = gp_get_site(id))) {
  156. return -1;
  157. }
  158. *filename = G_store(gp->filename);
  159. return 1;
  160. }
  161. /*!
  162. \brief Get point set style
  163. \param id point set id
  164. \return 1 on success
  165. \return -1 on error (point set not found)
  166. */
  167. int GP_get_style(int id, int *color, int *width, float *size, int *symbol)
  168. {
  169. geosite *gp;
  170. G_debug(4, "GP_get_style(%d)", id);
  171. if (NULL == (gp = gp_get_site(id))) {
  172. return -1;
  173. }
  174. *color = gp->style->color;
  175. *width = gp->style->width;
  176. *symbol = gp->style->symbol;
  177. *size = gp->style->size;
  178. return 1;
  179. }
  180. /*!
  181. \brief Set point style
  182. Supported icon symbols (markers):
  183. - ST_X
  184. - ST_BOX
  185. - ST_SPHERE
  186. - ST_CUBE
  187. - ST_DIAMOND
  188. - ST_DEC_TREE
  189. - ST_CON_TREE
  190. - ST_ASTER
  191. - ST_GYRO
  192. - ST_HISTOGRAM
  193. \param id point set id
  194. \param color icon color
  195. \param width icon line width
  196. \param size icon size
  197. \param symbol icon symbol
  198. \return 1 on success
  199. \return -1 on error (point set not found)
  200. */
  201. int GP_set_style(int id, int color, int width, float size, int symbol)
  202. {
  203. geosite *gp;
  204. G_debug(4, "GP_set_style(id=%d, color=%d, width=%d, size=%f, symbol=%d)", id, color, width, size,
  205. symbol);
  206. if (NULL == (gp = gp_get_site(id))) {
  207. return -1;
  208. }
  209. gp->style->color = color;
  210. gp->style->symbol = symbol;
  211. gp->style->size = size;
  212. gp->style->width = width;
  213. return 1;
  214. }
  215. /*!
  216. \brief Set point set style for thematic mapping
  217. Updates also style for each geopoint.
  218. \param id point set id
  219. \param layer layer number for thematic mapping (-1 for undefined)
  220. \param color icon color column name
  221. \param width icon line width column name
  222. \param size icon size column name
  223. \param symbol icon symbol column name
  224. \param colors pointer to Colors structure or NULL
  225. \return 1 on success
  226. \return -1 on error (point set not found)
  227. */
  228. int GP_set_style_thematic(int id, int layer, const char* color, const char* width,
  229. const char* size, const char* symbol, struct Colors *color_rules)
  230. {
  231. geosite *gp;
  232. G_debug(4, "GP_set_style_thematic(id=%d, layer=%d, color=%s, width=%s, size=%s, symbol=%s)", id, layer,
  233. color, width, size, symbol);
  234. if (NULL == (gp = gp_get_site(id))) {
  235. return -1;
  236. }
  237. if(!gp->tstyle)
  238. gp->tstyle = (gvstyle_thematic *)G_malloc(sizeof(gvstyle_thematic));
  239. G_zero(gp->tstyle, sizeof(gvstyle_thematic));
  240. gp->tstyle->active = 1;
  241. gp->tstyle->layer = layer;
  242. if (color)
  243. gp->tstyle->color_column = G_store(color);
  244. if (symbol)
  245. gp->tstyle->symbol_column = G_store(symbol);
  246. if (size)
  247. gp->tstyle->size_column = G_store(size);
  248. if (width)
  249. gp->tstyle->width_column = G_store(width);
  250. Gp_load_sites_thematic(gp, color_rules);
  251. return 1;
  252. }
  253. /*!
  254. \brief Make style for thematic mapping inactive
  255. \param id point set id
  256. \return 1 on success
  257. \return -1 on error (point set not found)
  258. */
  259. int GP_unset_style_thematic(int id)
  260. {
  261. geosite *gp;
  262. G_debug(4, "GP_unset_style_thematic(): id=%d", id);
  263. if (NULL == (gp = gp_get_site(id))) {
  264. return -1;
  265. }
  266. if (gp->tstyle) {
  267. gp->tstyle->active = 0;
  268. }
  269. return 1;
  270. }
  271. /*!
  272. \brief Set z mode for point set
  273. \param id point set id
  274. \param use_z TRUE to use z-coordinaces when vector map is 3D
  275. \return 1 on success
  276. \return 0 vector map is not 3D
  277. \return -1 on error (invalid point set id)
  278. */
  279. /* I don't see who is using it? Why it's required? */
  280. int GP_set_zmode(int id, int use_z)
  281. {
  282. geosite *gp;
  283. G_debug(3, "GP_set_zmode(%d,%d)", id, use_z);
  284. if (NULL == (gp = gp_get_site(id))) {
  285. return -1;
  286. }
  287. if (use_z) {
  288. if (gp->has_z) {
  289. gp->use_z = 1;
  290. return 1;
  291. }
  292. return 0;
  293. }
  294. gp->use_z = 0;
  295. return 1;
  296. }
  297. /*!
  298. \brief Get z-mode
  299. \todo Who's using this?
  300. \param id point set id
  301. \param[out] use_z non-zero code to use z
  302. \return -1 on error (invalid point set id)
  303. \return 1 on success
  304. */
  305. int GP_get_zmode(int id, int *use_z)
  306. {
  307. geosite *gp;
  308. G_debug(4, "GP_get_zmode(%d)", id);
  309. if (NULL == (gp = gp_get_site(id))) {
  310. return -1;
  311. }
  312. *use_z = gp->use_z;
  313. return 1;
  314. }
  315. /*!
  316. \brief Set transformation params
  317. \param id point set id
  318. \param xtrans,ytrans,ztrans x/y/z values
  319. */
  320. void GP_set_trans(int id, float xtrans, float ytrans, float ztrans)
  321. {
  322. geosite *gp;
  323. G_debug(3, "GP_set_trans(): id=%d trans=%f,%f,%f",
  324. id, xtrans, ytrans, ztrans);
  325. gp = gp_get_site(id);
  326. if (gp) {
  327. gp->x_trans = xtrans;
  328. gp->y_trans = ytrans;
  329. gp->z_trans = ztrans;
  330. }
  331. return;
  332. }
  333. /*!
  334. \brief Get transformation params
  335. \param id point set id
  336. \param[out] xtrans,ytrans,ztrans x/y/z values
  337. */
  338. void GP_get_trans(int id, float *xtrans, float *ytrans, float *ztrans)
  339. {
  340. geosite *gp;
  341. gp = gp_get_site(id);
  342. if (gp) {
  343. *xtrans = gp->x_trans;
  344. *ytrans = gp->y_trans;
  345. *ztrans = gp->z_trans;
  346. }
  347. G_debug(3, "GP_get_trans(): id=%d, trans=%f,%f,%f",
  348. id, *xtrans, *ytrans, *ztrans);
  349. return;
  350. }
  351. /*!
  352. \brief Select surface for given point set
  353. \param hp point set id
  354. \param hs surface id
  355. \return 1 surface selected
  356. \return -1 on error
  357. */
  358. int GP_select_surf(int hp, int hs)
  359. {
  360. geosite *gp;
  361. G_debug(3, "GP_select_surf(%d,%d)", hp, hs);
  362. if (GP_surf_is_selected(hp, hs)) {
  363. return 1;
  364. }
  365. gp = gp_get_site(hp);
  366. if (gp && GS_surf_exists(hs)) {
  367. gp->drape_surf_id[gp->n_surfs] = hs;
  368. gp->n_surfs += 1;
  369. return 1;
  370. }
  371. return -1;
  372. }
  373. /*!
  374. \brief Unselect surface
  375. \param hp point set id
  376. \param hs surface id
  377. \return 1 surface unselected
  378. \return -1 on error
  379. */
  380. int GP_unselect_surf(int hp, int hs)
  381. {
  382. geosite *gp;
  383. int i, j;
  384. G_debug(3, "GP_unselect_surf(%d,%d)", hp, hs);
  385. if (!GP_surf_is_selected(hp, hs)) {
  386. return 1;
  387. }
  388. gp = gp_get_site(hp);
  389. if (gp) {
  390. for (i = 0; i < gp->n_surfs; i++) {
  391. if (gp->drape_surf_id[i] == hs) {
  392. for (j = i; j < gp->n_surfs - 1; j++) {
  393. gp->drape_surf_id[j] = gp->drape_surf_id[j + 1];
  394. }
  395. gp->n_surfs -= 1;
  396. return 1;
  397. }
  398. }
  399. }
  400. return -1;
  401. }
  402. /*!
  403. \brief Check if surface is selected
  404. \param hp point set id
  405. \param hs surface id
  406. \return 1 selected
  407. \return 0 not selected
  408. */
  409. int GP_surf_is_selected(int hp, int hs)
  410. {
  411. int i;
  412. geosite *gp;
  413. G_debug(3, "GP_surf_is_selected(%d,%d)", hp, hs);
  414. gp = gp_get_site(hp);
  415. if (gp) {
  416. for (i = 0; i < gp->n_surfs; i++) {
  417. if (hs == gp->drape_surf_id[i]) {
  418. return 1;
  419. }
  420. }
  421. }
  422. return 0;
  423. }
  424. /*!
  425. \brief Draw point set
  426. \param id point set id
  427. */
  428. void GP_draw_site(int id)
  429. {
  430. geosurf *gs;
  431. geosite *gp;
  432. int i;
  433. float n, yo, xo, e;
  434. gp = gp_get_site(id);
  435. GS_get_region(&n, &yo, &xo, &e);
  436. /* kind of sloppy - maybe site files should have an origin, too */
  437. if (gp) {
  438. if (gp->use_z && gp->has_z) {
  439. gpd_3dsite(gp, xo, yo, 0);
  440. }
  441. else {
  442. for (i = 0; i < gp->n_surfs; i++) {
  443. gs = gs_get_surf(gp->drape_surf_id[i]);
  444. if (gs) {
  445. gpd_2dsite(gp, gs, 0);
  446. G_debug(5, "Drawing site %d on Surf %d", id,
  447. gp->drape_surf_id[i]);
  448. }
  449. }
  450. }
  451. }
  452. return;
  453. }
  454. /*!
  455. \brief Draw all available point sets
  456. */
  457. void GP_alldraw_site(void)
  458. {
  459. int id;
  460. for (id = 0; id < Next_site; id++) {
  461. GP_draw_site(Site_ID[id]);
  462. }
  463. return;
  464. }
  465. /*!
  466. \brief Set client data
  467. \param id point set id
  468. \param clientd client data
  469. \return 1 on success
  470. \return -1 on error (invalid point set id)
  471. */
  472. int GP_Set_ClientData(int id, void *clientd)
  473. {
  474. geosite *gp;
  475. gp = gp_get_site(id);
  476. if (gp) {
  477. gp->clientdata = clientd;
  478. return 1;
  479. }
  480. return -1;
  481. }
  482. /*!
  483. \brief Get client data
  484. \param id point set id
  485. \return pointer to client data
  486. \return NULL on error
  487. */
  488. void *GP_Get_ClientData(int id)
  489. {
  490. geosite *gp;
  491. gp = gp_get_site(id);
  492. if (gp) {
  493. return (gp->clientdata);
  494. }
  495. return NULL;
  496. }
  497. /*!
  498. \brief Determine point marker symbol for string
  499. Supported markers:
  500. - ST_X
  501. - ST_BOX
  502. - ST_SPHERE
  503. - ST_CUBE
  504. - ST_DIAMOND
  505. - ST_DEC_TREE
  506. - ST_CON_TREE
  507. - ST_ASTER
  508. - ST_GYRO
  509. - ST_HISTOGRAM
  510. \param str string buffer
  511. \return marker code (default: ST_SPHERE)
  512. */
  513. int GP_str_to_marker(const char *str)
  514. {
  515. int marker;
  516. if (strcmp(str, "x") == 0)
  517. marker = ST_X;
  518. else if (strcmp(str, "box") == 0)
  519. marker = ST_BOX;
  520. else if (strcmp(str, "sphere") == 0)
  521. marker = ST_SPHERE;
  522. else if (strcmp(str, "cube") == 0)
  523. marker = ST_CUBE;
  524. else if (strcmp(str, "diamond") == 0)
  525. marker = ST_DIAMOND;
  526. else if (strcmp(str, "dec_tree") == 0)
  527. marker = ST_DEC_TREE;
  528. else if (strcmp(str, "con_tree") == 0)
  529. marker = ST_CON_TREE;
  530. else if (strcmp(str, "aster") == 0)
  531. marker = ST_ASTER;
  532. else if (strcmp(str, "gyro") == 0)
  533. marker = ST_GYRO;
  534. else if (strcmp(str, "histogram") == 0)
  535. marker = ST_HISTOGRAM;
  536. else {
  537. G_warning(_("Unknown icon marker, using \"sphere\""));
  538. marker = ST_SPHERE;
  539. }
  540. return marker;
  541. }