|
|
1.1 root 1: #include "map.h"
2:
3: #define NSYMBOL 20
4:
5: enum flag { POINT,ENDSEG,ENDSYM };
6: struct symb {
7: double x, y;
8: char name[10+1];
9: enum flag flag;
10: } *symbol[NSYMBOL];
11:
12: static int nsymbol;
13: static double halfrange = 1;
14: extern int halfwidth;
15: extern int vflag;
16:
17: static int getrange(FILE *);
18: static int getsymbol(FILE *, int);
19: static void setrot(struct place *, double, int);
20: static void dorot(struct symb *, double *, double *);
21:
22:
23: void
24: getsyms(char *file)
25: {
26: FILE *sf = fopen(file,"r");
27: if(sf==0)
28: filerror("cannot open", file);
29: while(nsymbol<NSYMBOL-1 && getsymbol(sf,nsymbol))
30: nsymbol++;
31: fclose(sf);
32: }
33:
34: static int
35: getsymbol(FILE *sf, int n)
36: {
37: double x,y;
38: char s[2];
39: int i;
40: struct symb *sp;
41: for(;;) {
42: if(fscanf(sf,"%1s",s)==EOF)
43: return 0;
44: switch(s[0]) {
45: case ':':
46: break;
47: case 'o':
48: case 'c': /* cl */
49: fscanf(sf,"%*[^\n]");
50: continue;
51: case 'r':
52: if(getrange(sf))
53: continue;
54: default:
55: error("-y file syntax error");
56: }
57: break;
58: }
59: sp = (struct symb*)malloc(sizeof(struct symb));
60: symbol[n] = sp;
61: if(fscanf(sf,"%10s",sp->name)!=1)
62: return 0;
63: i = 0;
64: while(fscanf(sf,"%1s",s)!=EOF) {
65: switch(s[0]) {
66: case 'r':
67: if(!getrange(sf))
68: break;
69: continue;
70: case 'm':
71: if(i>0)
72: symbol[n][i-1].flag = ENDSEG;
73: continue;
74: case ':':
75: ungetc(s[0],sf);
76: break;
77: default:
78: ungetc(s[0],sf);
79: case 'v':
80: if(fscanf(sf,"%lf %lf",&x,&y)!=2)
81: break;
82: sp->x = x*halfwidth/halfrange;
83: sp->y = y*halfwidth/halfrange;
84: sp->flag = POINT;
85: i++;
86: symbol[n] = (struct symb*)realloc(symbol[n],
87: (i+1)*sizeof(struct symb));
88: sp++;
89: continue;
90: }
91: break;
92: }
93: if(i>0)
94: symbol[n][i-1].flag = ENDSYM;
95: else
96: symbol[n] = 0;
97: return 1;
98: }
99:
100: static int
101: getrange(FILE *sf)
102: {
103: double x,y,xmin,ymin;
104: if(fscanf(sf,"%*s %lf %lf %lf %lf",
105: &xmin,&ymin,&x,&y)!=4)
106: return 0;
107: x -= xmin;
108: y -= ymin;
109: halfrange = (x>y? x: y)/2;
110: if(halfrange<=0)
111: error("bad ra command in -y file");
112: return 1;
113: }
114:
115: /* r=0 upright;=1 normal;=-1 reverse*/
116: int
117: putsym(struct place *p, char *name, double s, int r)
118: {
119: int x,y,n;
120: struct symb *sp;
121: double dx,dy;
122: int conn = 0;
123: for(n=0; symbol[n]; n++)
124: if(strcmp(name,symbol[n]->name)==0)
125: break;
126: sp = symbol[n];
127: if(sp==0)
128: return 0;
129: if(doproj(p,&x,&y)*vflag <= 0)
130: return 1;
131: setrot(p,s,r);
132: for(;;) {
133: dorot(sp,&dx,&dy);
134: conn = cpoint(x+(int)dx,y+(int)dy,conn);
135: switch(sp->flag) {
136: case ENDSEG:
137: conn = 0;
138: case POINT:
139: sp++;
140: continue;
141: case ENDSYM:
142: break;
143: }
144: break;
145: }
146: return 1;
147: }
148:
149: static double rot[2][2];
150:
151: static void
152: setrot(struct place *p, double s, int r)
153: {
154: double x0,y0,x1,y1;
155: struct place up;
156: up = *p;
157: up.nlat.l += .5*RAD;
158: sincos(&up.nlat);
159: if(r&&(*projection)(p,&x0,&y0)) {
160: if((*projection)(&up,&x1,&y1)<=0) {
161: up.nlat.l -= RAD;
162: sincos(&up.nlat);
163: if((*projection)(&up,&x1,&y1)<=0)
164: goto unit;
165: x1 = x0 - x1;
166: y1 = y0 - y1;
167: } else {
168: x1 -= x0;
169: y1 -= y0;
170: }
171: x1 = r*x1;
172: s /= hypot(x1,y1);
173: rot[0][0] = y1*s;
174: rot[0][1] = x1*s;
175: rot[1][0] = -x1*s;
176: rot[1][1] = y1*s;
177: } else {
178: unit:
179: rot[0][0] = rot[1][1] = s;
180: rot[0][1] = rot[1][0] = 0;
181: }
182: }
183:
184: static void
185: dorot(struct symb *sp, double *px, double *py)
186: {
187: *px = rot[0][0]*sp->x + rot[0][1]*sp->y;
188: *py = rot[1][0]*sp->x + rot[1][1]*sp->y;
189: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.