GRASS GIS 8 Programmer's Manual 8.4.1(2025)-45ca3179ab
Loading...
Searching...
No Matches
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
26static int Site_ID[MAX_SITES];
27static 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 */
37int 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 */
64int GP_new_site(void)
65{
66 geosite *np;
67
68 if (Next_site < MAX_SITES) {
69 np = gp_get_new_site();
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 */
87int 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 */
102int *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 */
132int 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 */
173int 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 */
209int 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 */
232int 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 */
274int 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 */
309int 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)
325 gp->tstyle = (gvstyle_thematic *)G_malloc(sizeof(gvstyle_thematic));
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? */
380int 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 */
414int 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 */
434void 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 */
457void 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 */
484int 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 */
514int 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 */
552int 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 */
577void 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 */
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 */
631int 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 */
653void *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 */
684int 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
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition debug.c:66
void G_warning(const char *msg,...)
Print a warning message to stderr.
Definition gis/error.c:203
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
int GP_get_style(int id, int *color, int *width, float *size, int *symbol)
Get point set style.
Definition gp2.c:232
int GP_surf_is_selected(int hp, int hs)
Check if surface is selected.
Definition gp2.c:552
int * GP_get_site_list(int *numsites)
Get list of point sets.
Definition gp2.c:102
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_Get_ClientData(int id)
Get client data.
Definition gp2.c:653
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
geopoint * Gp_load_sites(const char *name, int *nsites, int *has_z)
Load to points to memory.
Definition gp3.c:40
int Gp_load_sites_thematic(geosite *gp, struct Colors *colors)
Load styles for geopoints based on thematic mapping.
Definition gp3.c:171
void gp_delete_site(int id)
Delete point set and remove from list.
Definition gp.c:238
geosite * gp_get_site(int id)
Get geosite struct.
Definition gp.c:33
void gp_free_sitemem(geosite *fp)
Free geosite (lower level)
Definition gp.c:310
geosite * gp_get_new_site(void)
Create new geosite instance and add it to list.
Definition gp.c:119
int gp_set_defaults(geosite *gp)
Set default value for geosite struct.
Definition gp.c:189
int gp_num_sites(void)
Get number of loaded point sets.
Definition gp.c:76
int gpd_2dsite(geosite *gp, geosurf *gs, int do_fast UNUSED)
Draw 2D point set.
Definition gpd.c:215
int gpd_3dsite(geosite *gp, float xo, float yo, int do_fast UNUSED)
Draw 3D point set.
Definition gpd.c:312
int GS_get_region(float *n, float *s, float *w, float *e)
Get 2D region extent.
Definition gs2.c:156
int GS_surf_exists(int id)
Definition gs2.c:194
geosurf * gs_get_surf(int id)
Get geosurf struct.
Definition gs.c:63
char * G_store(const char *s)
Copy string to allocated memory.
Definition strings.c:87
void G_zero(void *buf, int i)
Zero out a buffer, buf, of length i.
Definition zero.c:23