GRASS 8 Programmer's Manual  8.5.0dev(2025)-e5e60895a1
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 registered 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  \param color
229  \param width
230  \param size
231  \param symbol
232 
233  \return 1 on success
234  \return -1 on error (point set not found)
235  */
236 int GP_get_style(int id, int *color, int *width, float *size, int *symbol)
237 {
238  geosite *gp;
239 
240  G_debug(4, "GP_get_style(%d)", id);
241 
242  if (NULL == (gp = gp_get_site(id))) {
243  return -1;
244  }
245 
246  *color = gp->style->color;
247  *width = gp->style->width;
248  *symbol = gp->style->symbol;
249  *size = gp->style->size;
250 
251  return 1;
252 }
253 
254 /*!
255  \brief Set point style
256 
257  Supported icon symbols (markers):
258  - ST_X
259  - ST_BOX
260  - ST_SPHERE
261  - ST_CUBE
262  - ST_DIAMOND
263  - ST_DEC_TREE
264  - ST_CON_TREE
265  - ST_ASTER
266  - ST_GYRO
267  - ST_HISTOGRAM
268 
269  \param id point set id
270  \param color icon color
271  \param width icon line width
272  \param size icon size
273  \param symbol icon symbol
274 
275  \return 1 on success
276  \return -1 on error (point set not found)
277  */
278 int GP_set_style(int id, int color, int width, float size, int symbol)
279 {
280  geosite *gp;
281 
282  G_debug(4, "GP_set_style(id=%d, color=%d, width=%d, size=%f, symbol=%d)",
283  id, color, width, size, symbol);
284 
285  if (NULL == (gp = gp_get_site(id))) {
286  return -1;
287  }
288 
289  gp->style->color = color;
290  gp->style->symbol = symbol;
291  gp->style->size = size;
292  gp->style->width = width;
293 
294  return 1;
295 }
296 
297 /*!
298  \brief Set point set style for thematic mapping
299 
300  Updates also style for each geopoint.
301 
302  \param id point set id
303  \param layer layer number for thematic mapping (-1 for undefined)
304  \param color icon color column name
305  \param width icon line width column name
306  \param size icon size column name
307  \param symbol icon symbol column name
308  \param color_rules pointer to Colors structure or NULL
309 
310  \return 1 on success
311  \return -1 on error (point set not found)
312  */
313 int GP_set_style_thematic(int id, int layer, const char *color,
314  const char *width, const char *size,
315  const char *symbol, struct Colors *color_rules)
316 {
317  geosite *gp;
318 
319  G_debug(4,
320  "GP_set_style_thematic(id=%d, layer=%d, color=%s, width=%s, "
321  "size=%s, symbol=%s)",
322  id, layer, color, width, size, symbol);
323 
324  if (NULL == (gp = gp_get_site(id))) {
325  return -1;
326  }
327 
328  if (!gp->tstyle)
330  G_zero(gp->tstyle, sizeof(gvstyle_thematic));
331 
332  gp->tstyle->active = 1;
333  gp->tstyle->layer = layer;
334  if (color)
335  gp->tstyle->color_column = G_store(color);
336  if (symbol)
337  gp->tstyle->symbol_column = G_store(symbol);
338  if (size)
339  gp->tstyle->size_column = G_store(size);
340  if (width)
341  gp->tstyle->width_column = G_store(width);
342 
343  Gp_load_sites_thematic(gp, color_rules);
344 
345  return 1;
346 }
347 
348 /*!
349  \brief Make style for thematic mapping inactive
350 
351  \param id point set id
352 
353  \return 1 on success
354  \return -1 on error (point set not found)
355  */
357 {
358  geosite *gp;
359 
360  G_debug(4, "GP_unset_style_thematic(): id=%d", id);
361 
362  if (NULL == (gp = gp_get_site(id))) {
363  return -1;
364  }
365 
366  if (gp->tstyle) {
367  gp->tstyle->active = 0;
368  }
369 
370  return 1;
371 }
372 
373 /*!
374  \brief Set z mode for point set
375 
376  \param id point set id
377  \param use_z TRUE to use z-coordinaces when vector map is 3D
378 
379  \return 1 on success
380  \return 0 vector map is not 3D
381  \return -1 on error (invalid point set id)
382  */
383 /* I don't see who is using it? Why it's required? */
384 int GP_set_zmode(int id, int use_z)
385 {
386  geosite *gp;
387 
388  G_debug(3, "GP_set_zmode(%d,%d)", id, use_z);
389 
390  if (NULL == (gp = gp_get_site(id))) {
391  return -1;
392  }
393 
394  if (use_z) {
395  if (gp->has_z) {
396  gp->use_z = 1;
397  return 1;
398  }
399 
400  return 0;
401  }
402 
403  gp->use_z = 0;
404  return 1;
405 }
406 
407 /*!
408  \brief Get z-mode
409 
410  \todo Who's using this?
411 
412  \param id point set id
413  \param[out] use_z non-zero code to use z
414 
415  \return -1 on error (invalid point set id)
416  \return 1 on success
417  */
418 int GP_get_zmode(int id, int *use_z)
419 {
420  geosite *gp;
421 
422  G_debug(4, "GP_get_zmode(%d)", id);
423 
424  if (NULL == (gp = gp_get_site(id))) {
425  return -1;
426  }
427 
428  *use_z = gp->use_z;
429  return 1;
430 }
431 
432 /*!
433  \brief Set transformation params
434 
435  \param id point set id
436  \param xtrans,ytrans,ztrans x/y/z values
437  */
438 void GP_set_trans(int id, float xtrans, float ytrans, float ztrans)
439 {
440  geosite *gp;
441 
442  G_debug(3, "GP_set_trans(): id=%d trans=%f,%f,%f", id, xtrans, ytrans,
443  ztrans);
444 
445  gp = gp_get_site(id);
446  if (gp) {
447  gp->x_trans = xtrans;
448  gp->y_trans = ytrans;
449  gp->z_trans = ztrans;
450  }
451 
452  return;
453 }
454 
455 /*!
456  \brief Get transformation params
457 
458  \param id point set id
459  \param[out] xtrans,ytrans,ztrans x/y/z values
460  */
461 void GP_get_trans(int id, float *xtrans, float *ytrans, float *ztrans)
462 {
463  geosite *gp;
464 
465  gp = gp_get_site(id);
466 
467  if (gp) {
468  *xtrans = gp->x_trans;
469  *ytrans = gp->y_trans;
470  *ztrans = gp->z_trans;
471  }
472 
473  G_debug(3, "GP_get_trans(): id=%d, trans=%f,%f,%f", id, *xtrans, *ytrans,
474  *ztrans);
475 
476  return;
477 }
478 
479 /*!
480  \brief Select surface for given point set
481 
482  \param hp point set id
483  \param hs surface id
484 
485  \return 1 surface selected
486  \return -1 on error
487  */
488 int GP_select_surf(int hp, int hs)
489 {
490  geosite *gp;
491 
492  G_debug(3, "GP_select_surf(%d,%d)", hp, hs);
493 
494  if (GP_surf_is_selected(hp, hs)) {
495  return 1;
496  }
497 
498  gp = gp_get_site(hp);
499 
500  if (gp && GS_surf_exists(hs)) {
501  gp->drape_surf_id[gp->n_surfs] = hs;
502  gp->n_surfs += 1;
503  return 1;
504  }
505 
506  return -1;
507 }
508 
509 /*!
510  \brief Unselect surface
511 
512  \param hp point set id
513  \param hs surface id
514 
515  \return 1 surface unselected
516  \return -1 on error
517  */
518 int GP_unselect_surf(int hp, int hs)
519 {
520  geosite *gp;
521  int i, j;
522 
523  G_debug(3, "GP_unselect_surf(%d,%d)", hp, hs);
524 
525  if (!GP_surf_is_selected(hp, hs)) {
526  return 1;
527  }
528 
529  gp = gp_get_site(hp);
530 
531  if (gp) {
532  for (i = 0; i < gp->n_surfs; i++) {
533  if (gp->drape_surf_id[i] == hs) {
534  for (j = i; j < gp->n_surfs - 1; j++) {
535  gp->drape_surf_id[j] = gp->drape_surf_id[j + 1];
536  }
537 
538  gp->n_surfs -= 1;
539  return 1;
540  }
541  }
542  }
543 
544  return -1;
545 }
546 
547 /*!
548  \brief Check if surface is selected
549 
550  \param hp point set id
551  \param hs surface id
552 
553  \return 1 selected
554  \return 0 not selected
555  */
556 int GP_surf_is_selected(int hp, int hs)
557 {
558  int i;
559  geosite *gp;
560 
561  G_debug(3, "GP_surf_is_selected(%d,%d)", hp, hs);
562 
563  gp = gp_get_site(hp);
564 
565  if (gp) {
566  for (i = 0; i < gp->n_surfs; i++) {
567  if (hs == gp->drape_surf_id[i]) {
568  return 1;
569  }
570  }
571  }
572 
573  return 0;
574 }
575 
576 /*!
577  \brief Draw point set
578 
579  \param id point set id
580  */
581 void GP_draw_site(int id)
582 {
583  geosurf *gs;
584  geosite *gp;
585  int i;
586  float n, yo, xo, e;
587 
588  gp = gp_get_site(id);
589  GS_get_region(&n, &yo, &xo, &e);
590 
591  /* kind of sloppy - maybe site files should have an origin, too */
592  if (gp) {
593  if (gp->use_z && gp->has_z) {
594  gpd_3dsite(gp, xo, yo, 0);
595  }
596  else {
597  for (i = 0; i < gp->n_surfs; i++) {
598  gs = gs_get_surf(gp->drape_surf_id[i]);
599 
600  if (gs) {
601  gpd_2dsite(gp, gs, 0);
602  G_debug(5, "Drawing site %d on Surf %d", id,
603  gp->drape_surf_id[i]);
604  }
605  }
606  }
607  }
608 
609  return;
610 }
611 
612 /*!
613  \brief Draw all available point sets
614  */
615 void GP_alldraw_site(void)
616 {
617  int id;
618 
619  for (id = 0; id < Next_site; id++) {
620  GP_draw_site(Site_ID[id]);
621  }
622 
623  return;
624 }
625 
626 /*!
627  \brief Set client data
628 
629  \param id point set id
630  \param clientd client data
631 
632  \return 1 on success
633  \return -1 on error (invalid point set id)
634  */
635 int GP_Set_ClientData(int id, void *clientd)
636 {
637  geosite *gp;
638 
639  gp = gp_get_site(id);
640 
641  if (gp) {
642  gp->clientdata = clientd;
643  return 1;
644  }
645 
646  return -1;
647 }
648 
649 /*!
650  \brief Get client data
651 
652  \param id point set id
653 
654  \return pointer to client data
655  \return NULL on error
656  */
657 void *GP_Get_ClientData(int id)
658 {
659  geosite *gp;
660 
661  gp = gp_get_site(id);
662  if (gp) {
663  return (gp->clientdata);
664  }
665 
666  return NULL;
667 }
668 
669 /*!
670  \brief Determine point marker symbol for string
671 
672  Supported markers:
673  - ST_X
674  - ST_BOX
675  - ST_SPHERE
676  - ST_CUBE
677  - ST_DIAMOND
678  - ST_DEC_TREE
679  - ST_CON_TREE
680  - ST_ASTER
681  - ST_GYRO
682  - ST_HISTOGRAM
683 
684  \param str string buffer
685 
686  \return marker code (default: ST_SPHERE)
687  */
688 int GP_str_to_marker(const char *str)
689 {
690  int marker;
691 
692  if (strcmp(str, "x") == 0)
693  marker = ST_X;
694  else if (strcmp(str, "box") == 0)
695  marker = ST_BOX;
696  else if (strcmp(str, "sphere") == 0)
697  marker = ST_SPHERE;
698  else if (strcmp(str, "cube") == 0)
699  marker = ST_CUBE;
700  else if (strcmp(str, "diamond") == 0)
701  marker = ST_DIAMOND;
702  else if (strcmp(str, "dec_tree") == 0)
703  marker = ST_DEC_TREE;
704  else if (strcmp(str, "con_tree") == 0)
705  marker = ST_CON_TREE;
706  else if (strcmp(str, "aster") == 0)
707  marker = ST_ASTER;
708  else if (strcmp(str, "gyro") == 0)
709  marker = ST_GYRO;
710  else if (strcmp(str, "histogram") == 0)
711  marker = ST_HISTOGRAM;
712  else {
713  G_warning(_("Unknown icon marker, using \"sphere\""));
714  marker = ST_SPHERE;
715  }
716 
717  return marker;
718 }
#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)
Draw 3D point set.
Definition: gpd.c:312
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:45
int gpd_2dsite(geosite *, geosurf *, int)
Draw 2D point set.
Definition: gpd.c:215
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:181
#define _(str)
Definition: glocale.h:10
int GP_select_surf(int hp, int hs)
Select surface for given point set.
Definition: gp2.c:488
int GP_delete_site(int id)
Delete registered 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:461
int GP_get_zmode(int id, int *use_z)
Get z-mode.
Definition: gp2.c:418
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:384
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:438
int GP_Set_ClientData(int id, void *clientd)
Set client data.
Definition: gp2.c:635
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:688
void * GP_Get_ClientData(int id)
Get client data.
Definition: gp2.c:657
int GP_get_style(int id, int *color, int *width, float *size, int *symbol)
Get point set style.
Definition: gp2.c:236
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:556
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:581
void GP_alldraw_site(void)
Draw all available point sets.
Definition: gp2.c:615
int GP_unselect_surf(int hp, int hs)
Unselect surface.
Definition: gp2.c:518
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:313
int GP_set_style(int id, int color, int width, float size, int symbol)
Set point style.
Definition: gp2.c:278
int GP_unset_style_thematic(int id)
Make style for thematic mapping inactive.
Definition: gp2.c:356
OGSF header file (structures)
#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:692
Vector map (points)
Definition: ogsf.h:415
char * filename
Definition: ogsf.h:424
float z_trans
Definition: ogsf.h:426
int drape_surf_id[12]
Definition: ogsf.h:417
float y_trans
Definition: ogsf.h:426
int use_z
Definition: ogsf.h:419
float x_trans
Definition: ogsf.h:426
int gsite_id
Definition: ogsf.h:416
void * clientdata
Definition: ogsf.h:430
gvstyle_thematic * tstyle
thematic mapping
Definition: ogsf.h:433
geopoint * points
Definition: ogsf.h:427
int n_sites
Definition: ogsf.h:418
int has_z
Definition: ogsf.h:422
gvstyle * style
points default look&feel
Definition: ogsf.h:436
int n_surfs
Definition: ogsf.h:418
Definition: ogsf.h:266
Struct for vector map (thematic mapping)
Definition: ogsf.h:341
char * symbol_column
Definition: ogsf.h:346
char * color_column
Definition: ogsf.h:345
char * size_column
Definition: ogsf.h:347
char * width_column
Definition: ogsf.h:348
int color
Line color.
Definition: ogsf.h:309
int symbol
Point symbol/line type.
Definition: ogsf.h:312
float size
Symbol size.
Definition: ogsf.h:318
int width
Line width.
Definition: ogsf.h:325