grass  7.8.6
About: GRASS (Geographic Resources Analysis Support System) is a raster- and vector-based GIS, image processing system, graphics production system and spatial modeling system.
  Fossies Dox: grass-7.8.6.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

read.c
Go to the documentation of this file.
1/****************************************************************************
2*
3* MODULE: Symbol library
4*
5* AUTHOR(S): Radim Blazek
6*
7* PURPOSE: Read symbol from a file to internal structure
8*
9* COPYRIGHT: (C) 2001 by the GRASS Development Team
10*
11* This program is free software under the GNU General Public
12* License (>=v2). Read the file COPYING that comes with GRASS
13* for details.
14*
15*****************************************************************************/
16
17#include <stdlib.h>
18#include <string.h>
19#include <dirent.h>
20#include <grass/gis.h>
21#include <grass/symbol.h>
22#include <grass/glocale.h>
23
24static char key[100], data[500];
25
26/* Define currently processed part */
27#define OBJ_NONE 0
28#define OBJ_STRING 1
29#define OBJ_POLYGON 2
30#define OBJ_RING 3
31
32/* stores input to key an data */
33void get_key_data(char *buf)
34{
35 char *p;
36
37 G_debug(3, " get_key_data(): %s", buf);
38
39 data[0] = '\0';
40
41 strcpy(key, buf);
42 p = strchr(key, ' ');
43 if (p == NULL)
44 return;
45
46 p[0] = '\0';
47
48 p++;
49 if (strlen(p) > 0) {
50 strcpy(data, p);
51 G_chop(data);
52 }
53 G_debug(3, " key = %s data = %s", key, data);
54}
55
56/* --- SYMBOL --- */
57/* create new empty symbol */
59{
60 SYMBOL *p;
61
62 p = (SYMBOL *) G_malloc(sizeof(SYMBOL));
63 p->scale = 1.0;
64 p->count = 0;
65 p->alloc = 0;
66 p->part = NULL;
67 return p;
68}
69
70/* add part to symbol */
72{
73 if (s->count == s->alloc) {
74 s->alloc += 10;
75 s->part =
76 (SYMBPART **) G_realloc(s->part, s->alloc * sizeof(SYMBPART *));
77 }
78 s->part[s->count] = p;
79 s->count++;
80}
81
82/* --- PART --- */
83/* create new empty part */
85{
86 SYMBPART *p;
87
88 p = (SYMBPART *) G_malloc(sizeof(SYMBPART));
89 p->type = type;
90 p->count = 0;
91 p->alloc = 0;
92 p->chain = NULL;
95 return p;
96}
97
98/* add chain to part */
100{
101 if (p->count == p->alloc) {
102 p->alloc += 10;
103 p->chain =
104 (SYMBCHAIN **) G_realloc(p->chain,
105 p->alloc * sizeof(SYMBCHAIN *));
106 }
107 p->chain[p->count] = s;
108 p->count++;
109}
110
111
112/* --- CHAIN --- */
113/* create new empty chain */
115{
116 SYMBCHAIN *p;
117
118 p = (SYMBCHAIN *) G_malloc(sizeof(SYMBCHAIN));
119 p->count = 0;
120 p->alloc = 0;
121 p->elem = NULL;
122 p->scount = 0;
123 p->salloc = 0;
124 p->sx = NULL;
125 p->sy = NULL;
126 return p;
127}
128
129/* add element to chain */
131{
132 if (s->count == s->alloc) {
133 s->alloc += 10;
134 s->elem = (SYMBEL **) G_realloc(s->elem, s->alloc * sizeof(SYMBEL *));
135 }
136 s->elem[s->count] = e;
137 s->count++;
138}
139
140/* --- ELEMENT --- */
141/* create new empty line */
143{
144 SYMBEL *p;
145
146 p = (SYMBEL *) G_malloc(sizeof(SYMBEL));
147 p->type = S_LINE;
148 p->coor.line.count = 0;
149 p->coor.line.alloc = 0;
150 p->coor.line.x = NULL;
151 p->coor.line.y = NULL;
152 return p;
153}
154
155/* add point to line */
156void add_point(SYMBEL * el, double x, double y)
157{
158 if (el->coor.line.count == el->coor.line.alloc) {
159 el->coor.line.alloc += 10;
160 el->coor.line.x =
161 (double *)G_realloc(el->coor.line.x,
162 el->coor.line.alloc * sizeof(double));
163 el->coor.line.y =
164 (double *)G_realloc(el->coor.line.y,
165 el->coor.line.alloc * sizeof(double));
166 }
167 el->coor.line.x[el->coor.line.count] = x;
168 el->coor.line.y[el->coor.line.count] = y;
169 el->coor.line.count++;
170}
171
172/* create new arc */
173SYMBEL *new_arc(double x, double y, double r, double a1, double a2, int c)
174{
175 SYMBEL *p;
176
177 p = (SYMBEL *) G_malloc(sizeof(SYMBEL));
178 p->type = S_ARC;
179 p->coor.arc.clock = c;
180 p->coor.arc.x = x;
181 p->coor.arc.y = y;
182 p->coor.arc.r = r;
183 p->coor.arc.a1 = a1;
184 p->coor.arc.a2 = a2;
185 return p;
186}
187
188/* read line coordinates */
189void read_coor(FILE * fp, SYMBEL * e)
190{
191 char buf[501];
192 double x, y;
193
194 G_debug(5, " read_coor()");
195
196 while (G_getl2(buf, 500, fp) != 0) {
197 G_chop(buf);
198
199 /* skip empty and comment lines */
200 if ((buf[0] == '#') || (buf[0] == '\0'))
201 continue;
202
203 get_key_data(buf);
204
205 if (strcmp(key, "END") == 0) {
206 G_debug(5, " LINE END");
207 return;
208 }
209
210 if (sscanf(buf, "%lf %lf", &x, &y) != 2) {
211 G_warning(_("Cannot read symbol line coordinates: %s"), buf);
212 return;
213 }
214 G_debug(5, " x = %f y = %f", x, y);
215 add_point(e, x, y);
216 }
217}
218
219/* close file free symbol, print message, return NULL */
220SYMBOL *err(FILE * fp, SYMBOL * s, char *msg)
221{
222 fclose(fp);
223 G_free(s); /* TODO: free all */
224 G_warning(msg, "%s");
225 return NULL;
226}
227
228/*
229 * Read symbol specified by name.
230 * Name: group/name | group/name@mapset
231 * (later add syntax to prefer symbol from GISBASE)
232 * S_read() searches first in mapsets (standard GRASS search) and
233 * then in GISBASE/etc/symbol/
234 */
235SYMBOL *S_read(const char *sname)
236{
237 int i, j, k, l;
238 FILE *fp;
239 char group[500], name[500], buf[2001];
240 const char *ms;
241 char *c;
242 double x, y, x2, y2, rad, ang1, ang2;
243 int r, g, b;
244 double fr, fg, fb;
245 int ret;
246 char clock;
247 SYMBOL *symb;
248 int current; /* current part_type */
249 SYMBPART *part; /* current part */
250 SYMBCHAIN *chain; /* current chain */
251 SYMBEL *elem; /* current element */
252
253 G_debug(3, "S_read(): sname = %s", sname);
254
255 /* Find file */
256 /* Get group and name */
257 strcpy(group, sname);
258 c = strchr(group, '/');
259 if (c == NULL) {
260 G_warning(_("Incorrect symbol name: '%s' (should be: group/name or group/name@mapset)"),
261 sname);
262 return NULL;
263 }
264 c[0] = '\0';
265
266 c++;
267 strcpy(name, c);
268
269 G_debug(3, " group: '%s' name: '%s'", group, name);
270
271 /* Search in mapsets */
272 sprintf(buf, "symbol/%s", group);
273 ms = G_find_file(buf, name, NULL);
274
275 if (ms != NULL) { /* Found in mapsets */
276 fp = G_fopen_old(buf, name, ms);
277 }
278 else { /* Search in GISBASE */
279 sprintf(buf, "%s/etc/symbol/%s", G_gisbase(), sname);
280 fp = fopen(buf, "r");
281 }
282
283 if (fp == NULL) {
284 G_warning(_("Cannot find/open symbol: '%s'"), sname);
285 return NULL;
286 }
287
288 /* create new symbol */
289 symb = new_symbol();
290
291 current = OBJ_NONE; /* no part */
292
293 /* read file */
294 while (G_getl2(buf, 2000, fp) != 0) {
295 G_chop(buf);
296 G_debug(3, " BUF: [%s]", buf);
297
298 /* skip empty and comment lines */
299 if ((buf[0] == '#') || (buf[0] == '\0'))
300 continue;
301
302 get_key_data(buf);
303
304 if (strcmp(key, "VERSION") == 0) {
305 if (strcmp(data, "1.0") != 0) {
306 sprintf(buf, "Wrong symbol version: '%s'", data);
307 return (err(fp, symb, buf));
308 }
309 }
310 else if (strcmp(key, "BOX") == 0) {
311 if (sscanf(data, "%lf %lf %lf %lf", &x, &y, &x2, &y2) != 4) {
312 sprintf(buf, "Incorrect box definition: '%s'", data);
313 return (err(fp, symb, buf));
314 }
315 symb->xscale = 1 / (x2 - x);
316 symb->yscale = 1 / (y2 - y);
317 if (x2 - x > y2 - y) {
318 symb->scale = symb->xscale;
319 }
320 else {
321 symb->scale = symb->yscale;
322 }
323 }
324 else if (strcmp(key, "STRING") == 0) {
325 G_debug(4, " STRING >");
327 part = new_part(S_STRING);
328 add_part(symb, part);
329
330 chain = new_chain();
331 add_chain(part, chain);
332 }
333 else if (strcmp(key, "POLYGON") == 0) {
334 G_debug(4, " POLYGON >");
336 part = new_part(S_POLYGON);
337 add_part(symb, part);
338
339 }
340 else if (strcmp(key, "RING") == 0) {
341 G_debug(4, " RING >");
343 chain = new_chain();
344 add_chain(part, chain);
345
346 }
347 else if (strcmp(key, "LINE") == 0) {
348 G_debug(4, " LINE >");
349 elem = new_line();
350 add_element(chain, elem);
351 read_coor(fp, elem);
352
353 }
354 else if (strcmp(key, "ARC") == 0) {
355 G_debug(4, " ARC");
356 ret =
357 sscanf(data, "%lf %lf %lf %lf %lf %c", &x, &y, &rad, &ang1,
358 &ang2, &clock);
359 if (ret < 5) {
360 sprintf(buf, "Incorrect arc definition: '%s'", buf);
361 return (err(fp, symb, buf));
362 }
363 if (ret == 6 && (clock == 'c' || clock == 'C'))
364 i = 1;
365 else
366 i = 0;
367 elem = new_arc(x, y, rad, ang1, ang2, i);
368 add_element(chain, elem);
369
370 }
371 else if (strcmp(key, "END") == 0) {
372 switch (current) {
373 case OBJ_STRING:
374 G_debug(4, " STRING END");
376 break;
377 case OBJ_POLYGON:
378 G_debug(4, " POLYGON END");
380 break;
381 case OBJ_RING:
382 G_debug(4, " RING END");
384 break;
385 }
386 }
387 else if (strcmp(key, "COLOR") == 0) {
388 if (G_strcasecmp(data, "NONE") == 0) {
389 part->color.color = S_COL_NONE;
390 }
391 else if (sscanf(data, "%d %d %d", &r, &g, &b) == 3) {
392 if (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255)
393 G_warning(_("Incorrect symbol color: '%s', using default."),
394 buf);
395 else {
396 fr = r / 255.0;
397 fg = g / 255.0;
398 fb = b / 255.0;
399 part->color.color = S_COL_DEFINED;
400 part->color.r = r;
401 part->color.g = g;
402 part->color.b = b;
403 part->color.fr = fr;
404 part->color.fg = fg;
405 part->color.fb = fb;
406 G_debug(4, " color [%d %d %d] = [%.3f %.3f %.3f]", r, g,
407 b, fr, fg, fb);
408 }
409 }
410 else {
411 G_warning(_("Incorrect symbol color: '%s', using default."),
412 buf);
413 }
414 }
415 else if (strcmp(key, "FCOLOR") == 0) {
416 if (G_strcasecmp(data, "NONE") == 0) {
417 part->fcolor.color = S_COL_NONE;
418 }
419 else if (sscanf(data, "%d %d %d", &r, &g, &b) == 3) {
420 if (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255)
421 G_warning(_("Incorrect symbol color: '%s', using default."),
422 buf);
423 else {
424 fr = r / 255.0;
425 fg = g / 255.0;
426 fb = b / 255.0;
427 part->fcolor.color = S_COL_DEFINED;
428 part->fcolor.r = r;
429 part->fcolor.g = g;
430 part->fcolor.b = b;
431 part->fcolor.fr = fr;
432 part->fcolor.fg = fg;
433 part->fcolor.fb = fb;
434 G_debug(4, " color [%d %d %d] = [%.3f %.3f %.3f]", r, g,
435 b, fr, fg, fb);
436 }
437 }
438 else {
439 G_warning(_("Incorrect symbol color: '%s', using default."),
440 buf);
441 }
442 }
443 else {
444 sprintf(buf, "Unknown keyword in symbol: '%s'", buf);
445 return (err(fp, symb, buf));
446 break;
447 }
448 }
449
450 /* Debug output */
451
452 G_debug(3, "Number of parts: %d", symb->count);
453 for (i = 0; i < symb->count; i++) {
454 part = symb->part[i];
455 G_debug(4, " Part %d: type: %d number of chains: %d", i, part->type,
456 part->count);
457 G_debug(4, " color: %d: fcolor: %d", part->color.color,
458 part->fcolor.color);
459 for (j = 0; j < part->count; j++) {
460 chain = part->chain[j];
461 G_debug(4, " Chain %d: number of elements: %d", j,
462 chain->count);
463 for (k = 0; k < chain->count; k++) {
464 elem = chain->elem[k];
465 G_debug(4, " Element %d: type: %d", k, elem->type);
466 if (elem->type == S_LINE) {
467 G_debug(4, " Number of points %d",
468 elem->coor.line.count);
469 for (l = 0; l < elem->coor.line.count; l++) {
470 G_debug(4, " x, y: %f %f",
471 elem->coor.line.x[l], elem->coor.line.y[l]);
472 }
473 }
474 else {
475 G_debug(4, " arc r = %f", elem->coor.arc.r);
476 }
477 }
478 }
479 }
480
481 fclose(fp);
482
483 return symb;
484}
#define NULL
Definition: ccmath.h:32
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition: debug.c:65
const char * G_find_file(const char *element, char *name, const char *mapset)
Searches for a file from the mapset search list or in a specified mapset.
Definition: find_file.c:203
static int type
Definition: fpxdr.c:101
int G_getl2(char *buf, int n, FILE *fd)
Gets a line of text from a file of any pedigree.
Definition: getl.c:64
void G_free(void *buf)
Free allocated memory.
Definition: alloc.c:149
void G_warning(const char *msg,...)
Print a warning message to stderr.
Definition: error.c:204
FILE * G_fopen_old(const char *element, const char *name, const char *mapset)
Open a database file for reading.
Definition: open.c:253
const char * G_gisbase(void)
Get full path name of the top level module directory.
Definition: gisbase.c:41
#define _(str)
Definition: glocale.h:13
static const uint32 a1
Definition: lrand48.c:37
static const uint32 a2
Definition: lrand48.c:38
static uint16 x2
Definition: lrand48.c:35
float g
Definition: named_colr.c:8
const char * name
Definition: named_colr.c:7
double b
Definition: r_raster.c:39
double l
Definition: r_raster.c:39
double r
Definition: r_raster.c:39
char * G_chop(char *line)
Chop leading and trailing white spaces.
Definition: strings.c:286
int G_strcasecmp(const char *x, const char *y)
String compare ignoring case (upper or lower)
Definition: strings.c:46
int count
Definition: symbol.h:51
int alloc
Definition: symbol.h:51
double * sy
Definition: symbol.h:54
int scount
Definition: symbol.h:53
SYMBEL ** elem
Definition: symbol.h:52
int salloc
Definition: symbol.h:53
double * sx
Definition: symbol.h:54
int b
Definition: symbol.h:25
double fr
Definition: symbol.h:26
int r
Definition: symbol.h:25
double fb
Definition: symbol.h:26
int color
Definition: symbol.h:24
int g
Definition: symbol.h:25
double fg
Definition: symbol.h:26
Definition: symbol.h:31
struct SYMBEL::@6::@8 arc
int type
Definition: symbol.h:32
int count
Definition: symbol.h:37
double * x
Definition: symbol.h:38
double r
Definition: symbol.h:43
double a2
Definition: symbol.h:43
union SYMBEL::@6 coor
int alloc
Definition: symbol.h:37
struct SYMBEL::@6::@7 line
double * y
Definition: symbol.h:38
double a1
Definition: symbol.h:43
int clock
Definition: symbol.h:42
Definition: symbol.h:68
double scale
Definition: symbol.h:69
int count
Definition: symbol.h:72
double xscale
Definition: symbol.h:71
double yscale
Definition: symbol.h:70
int alloc
Definition: symbol.h:72
SYMBPART ** part
Definition: symbol.h:73
int alloc
Definition: symbol.h:63
SYMBCHAIN ** chain
Definition: symbol.h:64
SYMBCOLOR fcolor
Definition: symbol.h:62
SYMBCOLOR color
Definition: symbol.h:61
int type
Definition: symbol.h:60
int count
Definition: symbol.h:63
static char key[100]
Definition: read.c:24
void get_key_data(char *buf)
Definition: read.c:33
SYMBCHAIN * new_chain(void)
Definition: read.c:114
#define OBJ_NONE
Definition: read.c:27
SYMBPART * new_part(int type)
Definition: read.c:84
#define OBJ_STRING
Definition: read.c:28
#define OBJ_POLYGON
Definition: read.c:29
SYMBEL * new_line(void)
Definition: read.c:142
SYMBEL * new_arc(double x, double y, double r, double a1, double a2, int c)
Definition: read.c:173
void add_part(SYMBOL *s, SYMBPART *p)
Definition: read.c:71
void add_chain(SYMBPART *p, SYMBCHAIN *s)
Definition: read.c:99
static char data[500]
Definition: read.c:24
#define OBJ_RING
Definition: read.c:30
void read_coor(FILE *fp, SYMBEL *e)
Definition: read.c:189
SYMBOL * new_symbol(void)
Definition: read.c:58
SYMBOL * S_read(const char *sname)
Definition: read.c:235
void add_point(SYMBEL *el, double x, double y)
Definition: read.c:156
SYMBOL * err(FILE *fp, SYMBOL *s, char *msg)
Definition: read.c:220
void add_element(SYMBCHAIN *s, SYMBEL *e)
Definition: read.c:130
#define S_STRING
Definition: symbol.h:15
#define S_COL_DEFAULT
Definition: symbol.h:18
#define S_COL_NONE
Definition: symbol.h:19
#define S_LINE
Definition: symbol.h:11
#define S_POLYGON
Definition: symbol.h:16
#define S_ARC
Definition: symbol.h:12
#define S_COL_DEFINED
Definition: symbol.h:20
static unsigned int s
Definition: unfl.c:9
static unsigned int c
Definition: unfl.c:8
static int current
Definition: intersect.c:515
#define x