GP2.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683
  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/gstypes.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 set 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
  220. \param color icon color
  221. \param width icon line width
  222. \param size icon size
  223. \param symbol icon symbol
  224. \return 1 on success
  225. \return -1 on error (point set not found)
  226. */
  227. int GP_set_style_thematic(int id, int layer, const char* color, const char* width, const char* size, const char* symbol)
  228. {
  229. geosite *gp;
  230. G_debug(4, "GP_set_style_thematic(id=%d, layer=%d, color=%s, width=%s, size=%s, symbol=%s)", id, layer,
  231. color, width, size, symbol);
  232. if (NULL == (gp = gp_get_site(id))) {
  233. return -1;
  234. }
  235. if(!gp->tstyle)
  236. gp->tstyle = (gvstyle_thematic *)G_malloc(sizeof(gvstyle_thematic));
  237. G_zero(gp->tstyle, sizeof(gvstyle_thematic));
  238. gp->tstyle->layer = layer;
  239. if (color)
  240. gp->tstyle->color_column = G_store(color);
  241. if (symbol)
  242. gp->tstyle->symbol_column = G_store(symbol);
  243. if (size)
  244. gp->tstyle->size_column = G_store(size);
  245. if (width)
  246. gp->tstyle->width_column = G_store(width);
  247. Gp_load_sites_thematic(gp);
  248. return 1;
  249. }
  250. /*!
  251. \brief Set z-mode
  252. \param id poin set id
  253. \param use_z use z ?
  254. \return 1 on success
  255. \return 0 no z
  256. \return -1 on error (invalid point set id)
  257. */
  258. /* I don't see who is using it? Why it's required? */
  259. int GP_set_zmode(int id, int use_z)
  260. {
  261. geosite *gp;
  262. G_debug(3, "GP_set_zmode(%d,%d)", id, use_z);
  263. if (NULL == (gp = gp_get_site(id))) {
  264. return -1;
  265. }
  266. if (use_z) {
  267. if (gp->has_z) {
  268. gp->use_z = 1;
  269. return 1;
  270. }
  271. return 0;
  272. }
  273. gp->use_z = 0;
  274. return 1;
  275. }
  276. /*!
  277. \brief Get z-mode
  278. \todo Who's using this?
  279. \param id point set id
  280. \param[out] use_z non-zero code to use z
  281. \return -1 on error (invalid point set id)
  282. \return 1 on success
  283. */
  284. int GP_get_zmode(int id, int *use_z)
  285. {
  286. geosite *gp;
  287. G_debug(4, "GP_get_zmode(%d)", id);
  288. if (NULL == (gp = gp_get_site(id))) {
  289. return -1;
  290. }
  291. *use_z = gp->use_z;
  292. return 1;
  293. }
  294. /*!
  295. \brief Set transformation params
  296. \param id point set id
  297. \param xtrans,ytrans,ztrans x/y/z values
  298. */
  299. void GP_set_trans(int id, float xtrans, float ytrans, float ztrans)
  300. {
  301. geosite *gp;
  302. G_debug(3, "GP_set_trans(): id=%d trans=%f,%f,%f",
  303. id, xtrans, ytrans, ztrans);
  304. gp = gp_get_site(id);
  305. if (gp) {
  306. gp->x_trans = xtrans;
  307. gp->y_trans = ytrans;
  308. gp->z_trans = ztrans;
  309. }
  310. return;
  311. }
  312. /*!
  313. \brief Get transformation params
  314. \param id point set id
  315. \param[out] xtrans,ytrans,ztrans x/y/z values
  316. */
  317. void GP_get_trans(int id, float *xtrans, float *ytrans, float *ztrans)
  318. {
  319. geosite *gp;
  320. gp = gp_get_site(id);
  321. if (gp) {
  322. *xtrans = gp->x_trans;
  323. *ytrans = gp->y_trans;
  324. *ztrans = gp->z_trans;
  325. }
  326. G_debug(3, "GP_get_trans(): id=%d, trans=%f,%f,%f",
  327. id, *xtrans, *ytrans, *ztrans);
  328. return;
  329. }
  330. /*!
  331. \brief Select surface for given point set
  332. \param hp point set id
  333. \param hs surface id
  334. \return 1 surface selected
  335. \return -1 on error
  336. */
  337. int GP_select_surf(int hp, int hs)
  338. {
  339. geosite *gp;
  340. G_debug(3, "GP_select_surf(%d,%d)", hp, hs);
  341. if (GP_surf_is_selected(hp, hs)) {
  342. return 1;
  343. }
  344. gp = gp_get_site(hp);
  345. if (gp && GS_surf_exists(hs)) {
  346. gp->drape_surf_id[gp->n_surfs] = hs;
  347. gp->n_surfs += 1;
  348. return 1;
  349. }
  350. return -1;
  351. }
  352. /*!
  353. \brief Unselect surface
  354. \param hp point set id
  355. \param hs surface id
  356. \return 1 surface unselected
  357. \return -1 on error
  358. */
  359. int GP_unselect_surf(int hp, int hs)
  360. {
  361. geosite *gp;
  362. int i, j;
  363. G_debug(3, "GP_unselect_surf(%d,%d)", hp, hs);
  364. if (!GP_surf_is_selected(hp, hs)) {
  365. return 1;
  366. }
  367. gp = gp_get_site(hp);
  368. if (gp) {
  369. for (i = 0; i < gp->n_surfs; i++) {
  370. if (gp->drape_surf_id[i] == hs) {
  371. for (j = i; j < gp->n_surfs - 1; j++) {
  372. gp->drape_surf_id[j] = gp->drape_surf_id[j + 1];
  373. }
  374. gp->n_surfs -= 1;
  375. return 1;
  376. }
  377. }
  378. }
  379. return -1;
  380. }
  381. /*!
  382. \brief Check if surface is selected
  383. \param hp point set id
  384. \param hs surface id
  385. \return 1 selected
  386. \return 0 not selected
  387. */
  388. int GP_surf_is_selected(int hp, int hs)
  389. {
  390. int i;
  391. geosite *gp;
  392. G_debug(3, "GP_surf_is_selected(%d,%d)", hp, hs);
  393. gp = gp_get_site(hp);
  394. if (gp) {
  395. for (i = 0; i < gp->n_surfs; i++) {
  396. if (hs == gp->drape_surf_id[i]) {
  397. return 1;
  398. }
  399. }
  400. }
  401. return 0;
  402. }
  403. /*!
  404. \brief Draw point set
  405. \param id point set id
  406. */
  407. void GP_draw_site(int id)
  408. {
  409. geosurf *gs;
  410. geosite *gp;
  411. int i;
  412. float n, yo, xo, e;
  413. gp = gp_get_site(id);
  414. GS_get_region(&n, &yo, &xo, &e);
  415. /* kind of sloppy - maybe site files should have an origin, too */
  416. if (gp) {
  417. if (gp->use_z && gp->has_z) {
  418. gpd_3dsite(gp, xo, yo, 0);
  419. }
  420. else {
  421. for (i = 0; i < gp->n_surfs; i++) {
  422. gs = gs_get_surf(gp->drape_surf_id[i]);
  423. if (gs) {
  424. gpd_2dsite(gp, gs, 0);
  425. G_debug(5, "Drawing site %d on Surf %d", id,
  426. gp->drape_surf_id[i]);
  427. }
  428. }
  429. }
  430. }
  431. return;
  432. }
  433. /*!
  434. \brief Draw all available point sets
  435. */
  436. void GP_alldraw_site(void)
  437. {
  438. int id;
  439. for (id = 0; id < Next_site; id++) {
  440. GP_draw_site(Site_ID[id]);
  441. }
  442. return;
  443. }
  444. /*!
  445. \brief Set client data
  446. \param id point set id
  447. \param clientd client data
  448. \return 1 on success
  449. \return -1 on error (invalid point set id)
  450. */
  451. int GP_Set_ClientData(int id, void *clientd)
  452. {
  453. geosite *gp;
  454. gp = gp_get_site(id);
  455. if (gp) {
  456. gp->clientdata = clientd;
  457. return 1;
  458. }
  459. return -1;
  460. }
  461. /*!
  462. \brief Get client data
  463. \param id point set id
  464. \return pointer to client data
  465. \return NULL on error
  466. */
  467. void *GP_Get_ClientData(int id)
  468. {
  469. geosite *gp;
  470. gp = gp_get_site(id);
  471. if (gp) {
  472. return (gp->clientdata);
  473. }
  474. return NULL;
  475. }
  476. /*!
  477. \brief Determine point marker symbol for string
  478. Supported markers:
  479. - ST_X
  480. - ST_BOX
  481. - ST_SPHERE
  482. - ST_CUBE
  483. - ST_DIAMOND
  484. - ST_DEC_TREE
  485. - ST_CON_TREE
  486. - ST_ASTER
  487. - ST_GYRO
  488. - ST_HISTOGRAM
  489. \param str string buffer
  490. \return marker code (default: ST_SPHERE)
  491. */
  492. int GP_str_to_marker(const char *str)
  493. {
  494. int marker;
  495. if (strcmp(str, "x") == 0)
  496. marker = ST_X;
  497. else if (strcmp(str, "box") == 0)
  498. marker = ST_BOX;
  499. else if (strcmp(str, "sphere") == 0)
  500. marker = ST_SPHERE;
  501. else if (strcmp(str, "cube") == 0)
  502. marker = ST_CUBE;
  503. else if (strcmp(str, "diamond") == 0)
  504. marker = ST_DIAMOND;
  505. else if (strcmp(str, "dec_tree") == 0)
  506. marker = ST_DEC_TREE;
  507. else if (strcmp(str, "con_tree") == 0)
  508. marker = ST_CON_TREE;
  509. else if (strcmp(str, "aster") == 0)
  510. marker = ST_ASTER;
  511. else if (strcmp(str, "gyro") == 0)
  512. marker = ST_GYRO;
  513. else if (strcmp(str, "histogram") == 0)
  514. marker = ST_HISTOGRAM;
  515. else {
  516. G_warning(_("Unknown icon marker, using \"sphere\""));
  517. marker = ST_SPHERE;
  518. }
  519. return marker;
  520. }