Annotation of researchv8dc/cmd/map/map.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.