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