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 } 190