|
|
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.