|
|
1.1 root 1: #include "map.h"
2: #include <stdio.h>
3: #include <iplot.h>
4: #define NTRACK 10
5: #define NFILE 30
6: #define HALFWIDTH 8192
7: #define SCALERATIO 10
8: #define RESOL 2.
9: #define TWO_THRD 0.66666666666666667
10:
11: static int (*projection)();
12: double atof(), floor(), ceil(), fmin(), fmax();
13: extern char *getenv(), *malloc();
14: float reduce();
15: short getshort();
16:
17: #define map(x) int (*x())()
18:
19: static char *mapdir = "/usr/dict";
20: static char *file[NFILE+1] = {
21: "world",
22: 0
23: };
24: map(azequidistant);
25: map(mercator);
26: map(sp_mercator);
27: map(cylindrical);
28: map(rectangular);
29: map(orthographic);
30: map(sinusoidal);
31: map(mollweide);
32: map(aitoff);
33: map(azequalarea);
34: map(stereographic);
35: map(laue);
36: map(gilbert);
37: map(gnomonic);
38: map(perspective);
39: map(cylequalarea);
40: map(conic);
41: map(polyconic);
42: map(bonne);
43: map(lambert);
44: map(albers);
45: map(sp_albers);
46: map(mecca);
47: map(homing);
48: map(guyou);
49: map(square);
50: map(tetra);
51: map(hex);
52: map(elliptic);
53: map(bicentric);
54: int Xguyou();
55: int Xsquare();
56: int Xtetra();
57:
58: int nocut();
59: int picut();
60: int guycut();
61: int tetracut();
62: int hexcut();
63:
64:
65: static struct {
66: char *name;
67: int (*(*prog)())();
68: int npar;
69: int (*cut)();
70: int poles;/*1 S pole is a line, 2 N pole is, 3 both*/
71: int spheroid; /* poles must be at 90 deg */
72: } index[] = {
73: {"azequidistant", azequidistant, 0, nocut, 1, 0},
74: {"mercator", mercator, 0, picut, 0, 0},
75: {"sp_mercator", sp_mercator, 0, picut, 0, 1},
76: {"cylindrical", cylindrical, 0, picut, 0, 0},
77: {"rectangular", rectangular, 0, picut, 3, 0},
78: {"orthographic", orthographic, 0, nocut, 0, 0},
79: {"sinusoidal", sinusoidal, 0, picut, 0, 0},
80: {"mollweide", mollweide, 0, picut, 0, 0},
81: {"aitoff", aitoff, 0, picut, 0, 0},
82: {"azequalarea", azequalarea, 0, nocut, 1, 0},
83: {"stereographic", stereographic, 0, nocut, 0, 0},
84: {"laue", laue, 0, nocut, 0, 0},
85: {"gilbert",gilbert,0,picut,0, 0},
86: {"gnomonic", gnomonic, 0, nocut, 0, 0},
87: {"perspective", perspective, 1, nocut, 0, 0},
88: {"cylequalarea", cylequalarea, 1, picut, 3, 0},
89: {"conic", conic, 1, picut, 0, 0},
90: {"polyconic", polyconic, 0, picut, 0, 0},
91: {"bonne", bonne, 1, picut, 0, 0},
92: {"lambert", lambert, 2, picut, 0, 0},
93: {"albers", albers, 2, picut, 3, 0},
94: {"sp_albers", sp_albers, 2, picut, 3, 1},
95: {"mecca", mecca, 1, picut, 0, 0},
96: {"homing", homing, 1, picut, 0, 0},
97: {"guyou", guyou, 0, guycut, 0, 0},
98: {"square", square, 0, picut, 0, 0},
99: {"tetra", tetra, 0, tetracut, 0, 0},
100: {"hex", hex, 0, hexcut, 0, 0},
101: {"elliptic", elliptic, 1, nocut, 0, 0},
102: {"bicentric", bicentric, 1, nocut, 0, 0},
103: 0
104: };
105:
106: static int (*cut)();
107: static int poles;
108: static float orientation[3] = { 90., 0., 0. };
109: static oriented;
110: static int delta = 1;
111: static float limits[4] = {
112: -90., 90., -180., 180.
113: };
114: static int limcase;
115: static float rlimits[4];
116: static float lolat, hilat, lolon, hilon;
117: static float window[4] = {
118: -90., 90., -180., 180.
119: };
120: static float rwindow[4];
121: static float params[2];
122: static float xmin = 100.;
123: static float xmax = -100.;
124: static float ymin = 100.;
125: static float ymax = -100.;
126: static float xcent, ycent;
127: float xrange, yrange;
128: static int left = -HALFWIDTH;
129: static int right = HALFWIDTH;
130: static int bottom = -HALFWIDTH;
131: static int top = HALFWIDTH;
132: static int bflag = 1;
133: static int sflag = 0;
134: static int rflag = 0;
135: static int mflag = 0;
136: static float position[3];
137: static float center[2] = {0., 0.};
138: static float grid[3] = { 10., 10., RESOL };
139: static float dlat, dlon;
140: static float scaling;
141: static struct track {
142: int tracktyp;
143: char *tracknam;
144: } track[NTRACK];
145: static int ntrack;
146:
147: main(argc,argv)
148: char **argv;
149: {
150: int i,k;
151: char *s, *t;
152: float x, y, lat, lon;
153: float dd;
154: if(sizeof(short)!=2)
155: abort(); /* getshort() won't work */
156: s = getenv("MAP");
157: if(s)
158: file[0] = s;
159: s = getenv("MAPDIR");
160: if(s)
161: mapdir = s;
162: if(argc<=1)
163: error("usage: map projection params options");
164: for(k=0;index[k].name;k++) {
165: s = index[k].name;
166: t = argv[1];
167: while(*s == *t){
168: if(*s==0) goto found;
169: s++;
170: t++;
171: }
172: }
173: fprintf(stderr,"projections:\n");
174: for(i=0;index[i].name;i++)
175: fprintf(stderr,"%s\n",index[i].name);
176: exit(1);
177: found:
178: argv += 2;
179: argc -= 2;
180: cut = index[k].cut;
181: for(i=0;i<index[k].npar;i++) {
182: if(i>=argc||option(argv[i])) {
183: fprintf(stderr,"%s needs %d params\n",index[k].name,index[k].npar);
184: exit(1);
185: }
186: params[i] = atof(argv[i]);
187: }
188: argv += i;
189: argc -= i;
190: while(argc>0&&option(argv[0])) {
191: argc--;
192: argv++;
193: switch(argv[-1][1]) {
194: case 'm':
195: i = 0;
196: if(!mflag) while(file[i]!=0)
197: i++;
198: for(i=0;i<NFILE&&argc>i&&!option(argv[i]);i++)
199: file[i] = argv[i];
200: file[i] = 0;
201: mflag++;
202: argc -= i;
203: argv += i;
204: break;
205: case 'b':
206: bflag = 0;
207: break;
208: case 'g':
209: for(i=0;i<3&&argc>i&&!option(argv[i]);i++)
210: grid[i] = atof(argv[i]);
211: switch(i) {
212: case 0:
213: grid[0] = grid[1] = 0.;
214: break;
215: case 1:
216: grid[1] = grid[0];
217: }
218: argc -= i;
219: argv += i;
220: break;
221: case 't':
222: case 'u':
223: for(i=0;ntrack<NTRACK&&argc>i&&!option(argv[i]);i++) {
224: track[ntrack].tracktyp = argv[-1][1];
225: track[ntrack++].tracknam = argv[i];
226: }
227: argc -= i;
228: argv +=i;
229: break;
230: case 'r':
231: rflag++;
232: break;
233: case 's':
234: sflag++;
235: break;
236: case 'o':
237: for(i=0;i<3&&i<argc&&!option(argv[i]);i++)
238: orientation[i] = atof(argv[i]);
239: oriented++;
240: argv += i;
241: argc -= i;
242: break;
243: case 'l':
244: for(i=0;i<argc&&i<4&&!option(argv[i]);i++)
245: limits[i] = atof(argv[i]);
246: argv += i;
247: argc -= i;
248: break;
249: case 'd':
250: if(argc>0&&!option(argv[0])) {
251: delta = atoi(argv[0]);
252: argv++;
253: argc--;
254: }
255: break;
256: case 'w':
257: for(i=0;i<argc&&i<4&&!option(argv[i]);i++)
258: window[i] = atof(argv[i]);
259: argv += i;
260: argc -= i;
261: break;
262: case 'c':
263: for(i=0;i<2&&argc>i&&!option(argv[i]);i++)
264: center[i] = atof(argv[i]);
265: argc -= i;
266: argv += i;
267: break;
268: case 'p':
269: for(i=0;i<3&&argc>i&&!option(argv[i]);i++)
270: position[i] = atof(argv[i]);
271: argc -= i;
272: argv += i;
273: if(i!=3||position[2]<=0)
274: error("incomplete positioning");
275: break;
276: }
277: }
278: if(argc>0)
279: error("error in arguments");
280: pathnames();
281: radbds(limits,rlimits);
282: limcase = limits[2]<-180.?0:
283: limits[3]>180.?2:
284: 1;
285: if(
286: window[0]>=window[1]||
287: window[2]>=window[3]||
288: window[0]>90.||
289: window[1]<-90.||
290: window[2]>180.||
291: window[3]<-180.)
292: error("unreasonable window");
293: radbds(window,rwindow);
294: if(index[k].spheroid && fabs(orientation[0])!=90)
295: error("can't tilt the spheroid");
296: if(limits[2]>limits[3])
297: limits[3] += 360;
298: if(!oriented)
299: orientation[2] = (limits[2]+limits[3])/2;
300: orient(orientation[0],orientation[1],orientation[2]);
301: projection = (*index[k].prog)(params[0],params[1]);
302: if(projection == 0)
303: error("unreasonable projection parameters");
304: grid[0] = fabs(grid[0]);
305: grid[1] = fabs(grid[1]);
306: lolat = limits[0];
307: hilat = limits[1];
308: lolon = limits[2];
309: hilon = limits[3];
310: if(lolon>=hilon||lolat>=hilat||lolat<-90.||hilat>90.)
311: error("unreasonable limits");
312: dlat = fmin(hilat-lolat,window[1]-window[0])/16;
313: dlon = fmin(hilon-lolon,window[3]-window[2])/32;
314: dd = fmax(dlat,dlon);
315: while(grid[2]>fmin(dlat,dlon)/2)
316: grid[2] /= 2;
317: for(lat=lolat;lat<hilat+dd-FUZZ;lat+=dd) {
318: if(lat>hilat)
319: lat = hilat;
320: for(lon=lolon;lon<hilon+dd-FUZZ;lon+=dd) {
321: if(lon>hilon)
322: lon = hilon;
323: if(normproj(lat,lon,&x,&y)<=0)
324: continue;
325: if(x<xmin) xmin = x;
326: if(x>xmax) xmax = x;
327: if(y<ymin) ymin = y;
328: if(y>ymax) ymax = y;
329: }
330: }
331: xrange = xmax - xmin;
332: yrange = ymax - ymin;
333: if(xrange<=0||yrange<=0)
334: error("map seems to be empty");
335: scaling = (2*HALFWIDTH)*0.9;
336: if(position[2]!=0) {
337: if(normproj(position[0]-.5,position[1],&xcent,&ycent)<=0||
338: normproj(position[0]+.5,position[1],&x,&y)<=0)
339: error("unreasonable position");
340: scaling /= (position[2]*hypot(x-xcent,y-ycent));
341: if(normproj(position[0],position[1],&xcent,&ycent)<=0)
342: error("unreasonable position");
343: } else {
344: scaling /= (xrange>yrange?xrange:yrange);
345: xcent = (xmin+xmax)/2;
346: ycent = (ymin+ymax)/2;
347: }
348: xcent -= center[0]/2;
349: ycent -= center[1]/2;
350: openpl();
351: range(left,bottom,right,top);
352: if(!sflag)
353: erase();
354: pen("dotted");
355: if(grid[0]>0.)
356: for(lat=ceil(lolat/grid[0])*grid[0];
357: lat<=hilat;lat+=grid[0])
358: dogrid(lat,lat,lolon,hilon,0);
359: if(grid[1]>0.)
360: for(lon=ceil(lolon/grid[1])*grid[1];
361: lon<=hilon;lon+=grid[1])
362: dogrid(lolat,hilat,lon,lon,0);
363: pen("solid");
364: if(bflag) {
365: if(lolat>-90)
366: dogrid(lolat+FUZZ,lolat+FUZZ,lolon,hilon,0);
367: if(hilat<90)
368: dogrid(hilat-FUZZ,hilat-FUZZ,lolon,hilon,0);
369: if(hilon-lolon<360) {
370: dogrid(lolat,hilat,lolon+FUZZ,lolon+FUZZ,0);
371: dogrid(lolat,hilat,hilon-FUZZ,hilon-FUZZ,0);
372: }
373: if(poles&1)
374: dogrid(window[0]+FUZZ,window[0]+FUZZ,window[2],window[3],1);
375: if(poles&2)
376: dogrid(window[1]-FUZZ,window[1]-FUZZ,window[2],window[3],1);
377: if(window[3]-window[2]<360) {
378: dogrid(window[0],window[1],window[2]+FUZZ,window[2]+FUZZ,1);
379: dogrid(window[0],window[1],window[3]-FUZZ,window[3]-FUZZ,1);
380: }
381: }
382: lolat = floor(limits[0]/10)*10;
383: hilat = ceil(limits[1]/10)*10;
384: lolon = floor(limits[2]/10)*10;
385: hilon = ceil(limits[3]/10)*10;
386: if(lolon>hilon)
387: hilon += 360.;
388: /*do tracks first so as not to lose the standard input*/
389: for(i=0;i<ntrack;i++)
390: satellite(&track[i]);
391: pen("solid");
392: for(i=0;file[i];i++)
393: getdata(file[i]);
394:
395: move(right,bottom);
396: closepl();
397: return(0);
398: }
399:
400:
401: normproj(lat,lon,x,y)
402: float lat,lon;
403: float *x, *y;
404: {
405: int i;
406: struct place geog;
407: latlon(lat,lon,&geog);
408: /*
409: printp(&geog);
410: */
411: normalize(&geog);
412: if(!inwindow(&geog))
413: return(-1);
414: i = (*projection)(&geog,x,y);
415: if(rflag)
416: *x = -*x;
417: /*
418: printp(&geog);
419: fprintf(stderr,"%d %.3f %.3f\n",i,*x,*y);
420: */
421: return(i);
422: }
423:
424: inwindow(geog)
425: struct place *geog;
426: {
427: if(geog->nlat.l<rwindow[0]||
428: geog->nlat.l>rwindow[1]||
429: geog->wlon.l<rwindow[2]||
430: geog->wlon.l>rwindow[3])
431: return(0);
432: else return(1);
433: }
434:
435: inlimits(g)
436: struct place *g;
437: {
438: if(rlimits[0]>g->nlat.l||
439: rlimits[1]<g->nlat.l)
440: return(0);
441: switch(limcase) {
442: case 0:
443: if(rlimits[2]+TWOPI>g->wlon.l&&
444: rlimits[3]<g->wlon.l)
445: return(0);
446: break;
447: case 1:
448: if(rlimits[2]>g->wlon.l||
449: rlimits[3]<g->wlon.l)
450: return(0);
451: break;
452: case 2:
453: if(rlimits[2]>g->wlon.l&&
454: rlimits[3]-TWOPI<g->wlon.l)
455: return(0);
456: break;
457: }
458: return(1);
459: }
460:
461: option(s)
462: char *s;
463: {
464:
465: if(s[0]=='-' && (s[1]<'0'||s[1]>'9'))
466: return(s[1]!='.'&&s[1]!=0);
467: else
468: return(0);
469: }
470:
471:
472: long patch[18][36];
473:
474: getdata(mapfile)
475: char *mapfile;
476: {
477: char indexfile[32];
478: int cx,cy;
479: int kx,ky;
480: int k;
481: long b;
482: long *p;
483: int ip, jp;
484: int n;
485: struct place g;
486: int i, j;
487: float lat, lon;
488: int conn;
489: FILE *ifile, *xfile;
490:
491: for(i=0;indexfile[i]=mapfile[i];i++);
492: indexfile[i++] = '.';
493: indexfile[i++] = 'x';
494: indexfile[i] = 0;
495: xfile = fopen(indexfile,"r");
496: if(xfile==NULL)
497: filerror("can't find map index", indexfile);
498: for(i=0,p=patch[0];i<18*36;i++,p++)
499: *p = 1;
500: while(!feof(xfile) && fscanf(xfile,"%d%d%ld",&i,&j,&b)==3)
501: patch[i+9][j+18] = b;
502: fclose(xfile);
503: ifile = fopen(mapfile,"r");
504: if(ifile==NULL)
505: filerror("can't find map data", mapfile);
506: for(lat=lolat;lat<hilat;lat+=10.)
507: for(lon=lolon;lon<hilon;lon+=10.) {
508: if(!seeable(lat,lon))
509: continue;
510: i = pnorm(lat);
511: j = pnorm(lon);
512: if((b=patch[i+9][j+18])&1)
513: continue;
514: fseek(ifile,b,0);
515: while((ip=getc(ifile))>=0&&(jp=getc(ifile))>=0){
516: if(ip!=(i&0377)||jp!=(j&0377))
517: break;
518: n = getshort(ifile);
519: conn = 0;
520: if(n > 0) { /* absolute coordinates */
521: for(k=0;k<n;k++){
522: kx = SCALERATIO*getshort(ifile);
523: ky = SCALERATIO*getshort(ifile);
524: if(k%delta!=0&&k!=n-1)
525: continue;
526: conv(kx,&g.nlat);
527: conv(ky,&g.wlon);
528: conn = plotpt(&g,conn);
529: }
530: } else { /* differential, scaled by SCALERATI0 */
531: n = -n;
532: kx = SCALERATIO*getshort(ifile);
533: ky = SCALERATIO*getshort(ifile);
534: for(k=0; k<n; k++) {
535: kx += (char)getc(ifile);
536: ky += (char)getc(ifile);
537: if(k%delta!=0&&k!=n-1)
538: continue;
539: conv(kx,&g.nlat);
540: conv(ky,&g.wlon);
541: conn = plotpt(&g,conn);
542: }
543: }
544: if(k==1) {
545: conv(kx,&g.nlat);
546: conv(ky,&g.wlon);
547: conn = plotpt(&g,conn);
548: }
549: }
550: }
551: fclose(ifile);
552: }
553:
554: seeable(lat0,lon0)
555: float lat0,lon0;
556: {
557: float x, y;
558: float lat, lon;
559: for(lat=lat0;lat<=lat0+10;lat+=grid[2])
560: for(lon=lon0;lon<=lon0+10;lon+=grid[2])
561: if(normproj(lat,lon,&x,&y)>0)
562: return(1);
563: return(0);
564: }
565:
566: char lbl[50];
567: satellite(t)
568: struct track *t;
569: {
570: int visible, skip;
571: register conn;
572: float lat,lon;
573: struct place place;
574: static FILE *ifile = stdin;
575: register char *s;
576: if(t->tracknam[0]!='-'||t->tracknam[1]!=0) {
577: fclose(ifile);
578: if(fopen(t->tracknam,"r")==NULL)
579: filerror("can't find track", t->tracknam);
580: }
581: pen(t->tracktyp=='t'?"dotdash":"solid");
582: visible = 0;
583: for(;;) {
584: conn = 0;
585: while(!feof(ifile) && fscanf(ifile,"%f%f",&lat,&lon)==2){
586: latlon(lat,lon,&place);
587: conn = plotpt(&place,conn);
588: visible = conn;
589: }
590: skip = 1;
591: s = lbl;
592: for(;;) {
593: if(feof(ifile) || fscanf(ifile,"%c",s) == EOF)
594: return;
595: if(*s=='\n')
596: break;
597: if(skip) switch(*s) {
598: case '"':
599: skip = 0;
600: continue;
601: case ' ':
602: case '\t':
603: continue;
604: default:
605: skip = 0;
606: }
607: s++;
608: }
609: *s = 0;
610: if(visible)
611: text(lbl);
612: }
613: }
614:
615: pnorm(x)
616: float x;
617: {
618: int i;
619: i = x/10.;
620: i %= 36;
621: if(i>=18) return(i-36);
622: if(i<-18) return(i+36);
623: return(i);
624: }
625:
626: conv(k,g)
627: struct coord *g;
628: {
629: g->l = (0.0001/SCALERATIO)*k;
630: sincos(g);
631: }
632:
633: error(s)
634: char *s;
635: {
636: closepl();
637: fprintf(stderr,"map: \r\n%s\n",s);
638: exit(1);
639: }
640:
641: filerror(s,f)
642: char *s, *f;
643: {
644: closepl();
645: fprintf(stderr,"\r\n%s %s\n",s,f);
646: exit(1);
647: }
648:
649: cpoint(xi,yi,conn)
650: {
651: if(xi<left||xi>=right)
652: return(0);
653: if(yi<bottom||yi>=top)
654: return(0);
655: if(!conn)
656: move(xi,yi);
657: else
658: vec(xi,yi);
659: return(1);
660: }
661:
662:
663: struct place oldg;
664: plotpt(g,conn)
665: struct place *g;
666: {
667: if(!inlimits(g))
668: return(0);
669: normalize(g);
670: return(plotwin(g,conn));
671: }
672:
673: plotwin(g,conn)
674: struct place *g;
675: {
676: int kx,ky;
677: int ret;
678: float cutlon;
679: if(!inwindow(g))
680: return(0);
681: switch((*cut)(g,&oldg,&cutlon)) {
682: case 2:
683: if(conn) {
684: ret = duple(g,cutlon)|duple(g,cutlon);
685: copyplace(g,&oldg);
686: return(ret);
687: }
688: case 0:
689: conn = 0;
690: case 1:
691: copyplace(g,&oldg);
692: if(doproj(g,&kx,&ky)<=0)
693: return(0);
694: return(cpoint(kx,ky,conn));
695: }
696: /*NOTREACHED*/
697: }
698:
699: doproj(g,kx,ky)
700: struct place *g;
701: int *kx,*ky;
702: {
703: float x,y;
704: /*fprintf(stderr,"dopr1 %f %f \n",g->nlat.l,g->wlon.l);*/
705: if((*projection)(g,&x,&y)<=0)
706: return(0);
707: if(rflag)
708: x = -x;
709: /*fprintf(stderr,"dopr2 %f %f\n",x,y);*/
710: *kx = (x-xcent)*scaling;
711: *ky = (y-ycent)*scaling;
712: return(1);
713: }
714:
715: duple(g,cutlon)
716: struct place *g;
717: float cutlon;
718: {
719: int kx,ky;
720: int okx,oky;
721: struct place ig;
722: revlon(g,cutlon);
723: revlon(&oldg,cutlon);
724: copyplace(g,&ig);
725: invert(&ig);
726: if(!inlimits(&ig))
727: return(0);
728: if(doproj(g,&kx,&ky)<=0 || doproj(&oldg,&okx,&oky)<=0)
729: return(0);
730: line(okx,oky,kx,ky);
731: return(1);
732: }
733:
734: revlon(g,cutlon)
735: struct place *g;
736: float cutlon;
737: {
738: g->wlon.l = reduce(cutlon-reduce(g->wlon.l-cutlon));
739: sincos(&g->wlon);
740: }
741:
742:
743: /* recognize problems of cuts
744: * move a point across cut to side of its predecessor
745: * if its very close to the cut
746: * return(0) if cut interrupts the line
747: * return(1) if line is to be drawn normally
748: * return(2) if line is so close to cut as to
749: * be properly drawn on both sheets
750: */
751:
752: picut(g,og,cutlon)
753: struct place *g,*og;
754: float *cutlon;
755: {
756: *cutlon = PI;
757: return(ckcut(g,og,PI));
758: }
759:
760: nocut(g,og,cutlon)
761: struct place *g,*og;
762: float *cutlon;
763: {
764: return(1);
765: }
766:
767: ckcut(g1,g2,lon)
768: struct place *g1, *g2;
769: float lon;
770: {
771: float d1, d2;
772: float f1, f2;
773: int kx,ky;
774: extern float diddle();
775: d1 = reduce(g1->wlon.l -lon);
776: d2 = reduce(g2->wlon.l -lon);
777: if((f1=fabs(d1))<FUZZ)
778: d1 = diddle(g1,lon,d2);
779: if((f2=fabs(d2))<FUZZ) {
780: d2 = diddle(g2,lon,d1);
781: if(doproj(g2,&kx,&ky)>0)
782: move(kx,ky);
783: }
784: if(f1<FUZZ&&f2<FUZZ)
785: return(2);
786: if(f1>PI*TWO_THRD||f2>PI*TWO_THRD)
787: return(1);
788: return(d1*d2>=0);
789: }
790:
791: float diddle(g,lon,d)
792: struct place *g;
793: float d,lon;
794: {
795: float d1;
796: d1 = FUZZ/2;
797: if(d<0)
798: d1 = -d1;
799: g->wlon.l = reduce(lon+d1);
800: sincos(&g->wlon);
801: return(d1);
802: }
803:
804: float reduce(lon)
805: float lon;
806: {
807: if(lon>PI)
808: lon -= 2*PI;
809: else if(lon<-PI)
810: lon += 2*PI;
811: return(lon);
812: }
813:
814:
815: float tetrapt = 35.26438968; /* atan(1/sqrt(2)) */
816:
817: dogrid(lat0,lat1,lon0,lon1,inv)
818: float lat0,lat1,lon0,lon1;
819: {
820: float slat,slon,dd;
821: register int conn;
822: slat = slon = 0;
823: if(lat1>lat0)
824: slat = fmin(grid[2],dlat);
825: else
826: slon = fmin(grid[2],dlon);;
827: conn = 0;
828: while(lat0<=lat1&&lon0<=lon1) {
829: conn = gridpt(lat0,lon0,conn,inv);
830: if(projection==Xguyou&&slat>0) {
831: if(lat0<-45&&lat0+slat>-45)
832: conn = gridpt(-45.,lon0,conn,inv);
833: else if(lat0<45&&lat0+slat>45)
834: conn = gridpt(45.,lon0,conn,inv);
835: } else if(projection==Xtetra&&slat>0) {
836: if(lat0<-tetrapt&&lat0+slat>-tetrapt) {
837: gridpt(-tetrapt-.001,lon0,conn,inv);
838: conn = gridpt(-tetrapt+.001,lon0,0,inv);
839: }
840: else if(lat0<tetrapt&&lat0+slat>tetrapt) {
841: gridpt(tetrapt-.001,lon0,conn,inv);
842: conn = gridpt(tetrapt+.001,lon0,0,inv);
843: }
844: }
845: lat0 += slat;
846: lon0 += slon;
847: }
848: gridpt(lat1,lon1,conn,inv);
849: }
850:
851: gridpt(lat,lon,conn,inv)
852: float lat,lon;
853: {
854: struct place g;
855: struct place p;
856: /*fprintf(stderr,"%f %f\n",lat,lon);*/
857: latlon(lat,lon,&g);
858: if(inv) {
859: copyplace(&g,&p);
860: invert(&p);
861: if(!inlimits(&p))
862: return(0);
863: return(plotpt(&p,conn));
864: }
865: return(plotpt(&g,conn));
866: }
867:
868: radbds(w,rw)
869: float *w,*rw;
870: {
871: register i;
872: for(i=0;i<4;i++)
873: rw[i] = w[i]*RAD;
874: rw[0] -= FUZZ;
875: rw[1] += FUZZ;
876: rw[2] -= FUZZ;
877: rw[3] += FUZZ;
878: }
879:
880: short
881: getshort(f)
882: FILE *f;
883: {
884: register c;
885: c = getc(f);
886: return(c | getc(f)<<8);
887: }
888:
889: double
890: fmin(x,y)
891: double x,y;
892: {
893: return(x<y?x:y);
894: }
895:
896: double
897: fmax(x,y)
898: double x,y;
899: {
900: return(x>y?x:y);
901: }
902:
903: pathnames()
904: {
905: int i;
906: char *t;
907: for(i=0; i<NFILE && file[i]; i++) {
908: if(*file[i]=='/' || access(file[i],04)==0)
909: continue;
910: t = malloc(strlen(file[i])+strlen(mapdir)+2);
911: strcpy(t,mapdir);
912: strcat(t,"/");
913: strcat(t,file[i]);
914: file[i] = t;
915: }
916: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.