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