1*59cc4ca5SDavid du Colombier #include <u.h>
2*59cc4ca5SDavid du Colombier #include <libc.h>
3*59cc4ca5SDavid du Colombier #include <stdio.h>
43e12c5d1SDavid du Colombier #include "map.h"
57dd7cddfSDavid du Colombier #include "iplot.h"
63e12c5d1SDavid du Colombier
73e12c5d1SDavid du Colombier #define NSYMBOL 20
83e12c5d1SDavid du Colombier
93e12c5d1SDavid du Colombier enum flag { POINT,ENDSEG,ENDSYM };
103e12c5d1SDavid du Colombier struct symb {
11219b2ee8SDavid du Colombier double x, y;
123e12c5d1SDavid du Colombier char name[10+1];
133e12c5d1SDavid du Colombier enum flag flag;
143e12c5d1SDavid du Colombier } *symbol[NSYMBOL];
153e12c5d1SDavid du Colombier
163e12c5d1SDavid du Colombier static int nsymbol;
17219b2ee8SDavid du Colombier static double halfrange = 1;
183e12c5d1SDavid du Colombier extern int halfwidth;
19219b2ee8SDavid du Colombier extern int vflag;
203e12c5d1SDavid du Colombier
213e12c5d1SDavid du Colombier static int getrange(FILE *);
223e12c5d1SDavid du Colombier static int getsymbol(FILE *, int);
233e12c5d1SDavid du Colombier static void setrot(struct place *, double, int);
24219b2ee8SDavid du Colombier static void dorot(struct symb *, double *, double *);
253e12c5d1SDavid du Colombier
263e12c5d1SDavid du Colombier
273e12c5d1SDavid du Colombier void
getsyms(char * file)283e12c5d1SDavid du Colombier getsyms(char *file)
293e12c5d1SDavid du Colombier {
303e12c5d1SDavid du Colombier FILE *sf = fopen(file,"r");
313e12c5d1SDavid du Colombier if(sf==0)
323e12c5d1SDavid du Colombier filerror("cannot open", file);
333e12c5d1SDavid du Colombier while(nsymbol<NSYMBOL-1 && getsymbol(sf,nsymbol))
343e12c5d1SDavid du Colombier nsymbol++;
353e12c5d1SDavid du Colombier fclose(sf);
363e12c5d1SDavid du Colombier }
373e12c5d1SDavid du Colombier
383e12c5d1SDavid du Colombier static int
getsymbol(FILE * sf,int n)393e12c5d1SDavid du Colombier getsymbol(FILE *sf, int n)
403e12c5d1SDavid du Colombier {
41219b2ee8SDavid du Colombier double x,y;
423e12c5d1SDavid du Colombier char s[2];
433e12c5d1SDavid du Colombier int i;
443e12c5d1SDavid du Colombier struct symb *sp;
453e12c5d1SDavid du Colombier for(;;) {
463e12c5d1SDavid du Colombier if(fscanf(sf,"%1s",s)==EOF)
473e12c5d1SDavid du Colombier return 0;
483e12c5d1SDavid du Colombier switch(s[0]) {
493e12c5d1SDavid du Colombier case ':':
503e12c5d1SDavid du Colombier break;
513e12c5d1SDavid du Colombier case 'o':
523e12c5d1SDavid du Colombier case 'c': /* cl */
533e12c5d1SDavid du Colombier fscanf(sf,"%*[^\n]");
543e12c5d1SDavid du Colombier continue;
553e12c5d1SDavid du Colombier case 'r':
563e12c5d1SDavid du Colombier if(getrange(sf))
573e12c5d1SDavid du Colombier continue;
583e12c5d1SDavid du Colombier default:
593e12c5d1SDavid du Colombier error("-y file syntax error");
603e12c5d1SDavid du Colombier }
613e12c5d1SDavid du Colombier break;
623e12c5d1SDavid du Colombier }
633e12c5d1SDavid du Colombier sp = (struct symb*)malloc(sizeof(struct symb));
643e12c5d1SDavid du Colombier symbol[n] = sp;
653e12c5d1SDavid du Colombier if(fscanf(sf,"%10s",sp->name)!=1)
663e12c5d1SDavid du Colombier return 0;
673e12c5d1SDavid du Colombier i = 0;
683e12c5d1SDavid du Colombier while(fscanf(sf,"%1s",s)!=EOF) {
693e12c5d1SDavid du Colombier switch(s[0]) {
703e12c5d1SDavid du Colombier case 'r':
713e12c5d1SDavid du Colombier if(!getrange(sf))
723e12c5d1SDavid du Colombier break;
733e12c5d1SDavid du Colombier continue;
743e12c5d1SDavid du Colombier case 'm':
753e12c5d1SDavid du Colombier if(i>0)
763e12c5d1SDavid du Colombier symbol[n][i-1].flag = ENDSEG;
773e12c5d1SDavid du Colombier continue;
783e12c5d1SDavid du Colombier case ':':
793e12c5d1SDavid du Colombier ungetc(s[0],sf);
803e12c5d1SDavid du Colombier break;
813e12c5d1SDavid du Colombier default:
823e12c5d1SDavid du Colombier ungetc(s[0],sf);
833e12c5d1SDavid du Colombier case 'v':
84219b2ee8SDavid du Colombier if(fscanf(sf,"%lf %lf",&x,&y)!=2)
853e12c5d1SDavid du Colombier break;
867dd7cddfSDavid du Colombier sp[i].x = x*halfwidth/halfrange;
877dd7cddfSDavid du Colombier sp[i].y = y*halfwidth/halfrange;
887dd7cddfSDavid du Colombier sp[i].flag = POINT;
893e12c5d1SDavid du Colombier i++;
907dd7cddfSDavid du Colombier sp = symbol[n] = (struct symb*)realloc(symbol[n],
913e12c5d1SDavid du Colombier (i+1)*sizeof(struct symb));
923e12c5d1SDavid du Colombier continue;
933e12c5d1SDavid du Colombier }
943e12c5d1SDavid du Colombier break;
953e12c5d1SDavid du Colombier }
963e12c5d1SDavid du Colombier if(i>0)
973e12c5d1SDavid du Colombier symbol[n][i-1].flag = ENDSYM;
983e12c5d1SDavid du Colombier else
993e12c5d1SDavid du Colombier symbol[n] = 0;
1003e12c5d1SDavid du Colombier return 1;
1013e12c5d1SDavid du Colombier }
1023e12c5d1SDavid du Colombier
1033e12c5d1SDavid du Colombier static int
getrange(FILE * sf)1043e12c5d1SDavid du Colombier getrange(FILE *sf)
1053e12c5d1SDavid du Colombier {
106219b2ee8SDavid du Colombier double x,y,xmin,ymin;
107219b2ee8SDavid du Colombier if(fscanf(sf,"%*s %lf %lf %lf %lf",
1083e12c5d1SDavid du Colombier &xmin,&ymin,&x,&y)!=4)
1093e12c5d1SDavid du Colombier return 0;
1103e12c5d1SDavid du Colombier x -= xmin;
1113e12c5d1SDavid du Colombier y -= ymin;
1123e12c5d1SDavid du Colombier halfrange = (x>y? x: y)/2;
1133e12c5d1SDavid du Colombier if(halfrange<=0)
1143e12c5d1SDavid du Colombier error("bad ra command in -y file");
1153e12c5d1SDavid du Colombier return 1;
1163e12c5d1SDavid du Colombier }
1173e12c5d1SDavid du Colombier
1183e12c5d1SDavid du Colombier /* r=0 upright;=1 normal;=-1 reverse*/
1193e12c5d1SDavid du Colombier int
putsym(struct place * p,char * name,double s,int r)1203e12c5d1SDavid du Colombier putsym(struct place *p, char *name, double s, int r)
1213e12c5d1SDavid du Colombier {
1223e12c5d1SDavid du Colombier int x,y,n;
1233e12c5d1SDavid du Colombier struct symb *sp;
124219b2ee8SDavid du Colombier double dx,dy;
1253e12c5d1SDavid du Colombier int conn = 0;
1263e12c5d1SDavid du Colombier for(n=0; symbol[n]; n++)
1273e12c5d1SDavid du Colombier if(strcmp(name,symbol[n]->name)==0)
1283e12c5d1SDavid du Colombier break;
1293e12c5d1SDavid du Colombier sp = symbol[n];
1303e12c5d1SDavid du Colombier if(sp==0)
1313e12c5d1SDavid du Colombier return 0;
132219b2ee8SDavid du Colombier if(doproj(p,&x,&y)*vflag <= 0)
1333e12c5d1SDavid du Colombier return 1;
1343e12c5d1SDavid du Colombier setrot(p,s,r);
1353e12c5d1SDavid du Colombier for(;;) {
1363e12c5d1SDavid du Colombier dorot(sp,&dx,&dy);
1373e12c5d1SDavid du Colombier conn = cpoint(x+(int)dx,y+(int)dy,conn);
1383e12c5d1SDavid du Colombier switch(sp->flag) {
1393e12c5d1SDavid du Colombier case ENDSEG:
1403e12c5d1SDavid du Colombier conn = 0;
1413e12c5d1SDavid du Colombier case POINT:
1423e12c5d1SDavid du Colombier sp++;
1433e12c5d1SDavid du Colombier continue;
1443e12c5d1SDavid du Colombier case ENDSYM:
1453e12c5d1SDavid du Colombier break;
1463e12c5d1SDavid du Colombier }
1473e12c5d1SDavid du Colombier break;
1483e12c5d1SDavid du Colombier }
1493e12c5d1SDavid du Colombier return 1;
1503e12c5d1SDavid du Colombier }
1513e12c5d1SDavid du Colombier
152219b2ee8SDavid du Colombier static double rot[2][2];
1533e12c5d1SDavid du Colombier
1543e12c5d1SDavid du Colombier static void
setrot(struct place * p,double s,int r)1553e12c5d1SDavid du Colombier setrot(struct place *p, double s, int r)
1563e12c5d1SDavid du Colombier {
157219b2ee8SDavid du Colombier double x0,y0,x1,y1;
1583e12c5d1SDavid du Colombier struct place up;
1593e12c5d1SDavid du Colombier up = *p;
1603e12c5d1SDavid du Colombier up.nlat.l += .5*RAD;
1613e12c5d1SDavid du Colombier sincos(&up.nlat);
1623e12c5d1SDavid du Colombier if(r&&(*projection)(p,&x0,&y0)) {
1633e12c5d1SDavid du Colombier if((*projection)(&up,&x1,&y1)<=0) {
1643e12c5d1SDavid du Colombier up.nlat.l -= RAD;
1653e12c5d1SDavid du Colombier sincos(&up.nlat);
1663e12c5d1SDavid du Colombier if((*projection)(&up,&x1,&y1)<=0)
1673e12c5d1SDavid du Colombier goto unit;
1683e12c5d1SDavid du Colombier x1 = x0 - x1;
1693e12c5d1SDavid du Colombier y1 = y0 - y1;
1703e12c5d1SDavid du Colombier } else {
1713e12c5d1SDavid du Colombier x1 -= x0;
1723e12c5d1SDavid du Colombier y1 -= y0;
1733e12c5d1SDavid du Colombier }
1743e12c5d1SDavid du Colombier x1 = r*x1;
1753e12c5d1SDavid du Colombier s /= hypot(x1,y1);
1763e12c5d1SDavid du Colombier rot[0][0] = y1*s;
1773e12c5d1SDavid du Colombier rot[0][1] = x1*s;
1783e12c5d1SDavid du Colombier rot[1][0] = -x1*s;
1793e12c5d1SDavid du Colombier rot[1][1] = y1*s;
1803e12c5d1SDavid du Colombier } else {
1813e12c5d1SDavid du Colombier unit:
1823e12c5d1SDavid du Colombier rot[0][0] = rot[1][1] = s;
1833e12c5d1SDavid du Colombier rot[0][1] = rot[1][0] = 0;
1843e12c5d1SDavid du Colombier }
1853e12c5d1SDavid du Colombier }
1863e12c5d1SDavid du Colombier
1873e12c5d1SDavid du Colombier static void
dorot(struct symb * sp,double * px,double * py)188219b2ee8SDavid du Colombier dorot(struct symb *sp, double *px, double *py)
1893e12c5d1SDavid du Colombier {
1903e12c5d1SDavid du Colombier *px = rot[0][0]*sp->x + rot[0][1]*sp->y;
1913e12c5d1SDavid du Colombier *py = rot[1][0]*sp->x + rot[1][1]*sp->y;
1923e12c5d1SDavid du Colombier }
193