📄 map.c
字号:
for(lon=lolon;lon<hilon;lon+=10.) { if(!seeable(lat,lon)) continue; i = pnorm(lat); j = pnorm(lon); if((b=patch[i+9][j+18])&1) continue; fseek(ifile,b,0); while((ip=getc(ifile))>=0&&(jp=getc(ifile))>=0){ if(ip!=(i&0377)||jp!=(j&0377)) break; n = getshort(ifile); conn = 0; if(n > 0) { /* absolute coordinates */ kx = ky = 0; /* set */ for(k=0;k<n;k++){ kx = SCALERATIO*getshort(ifile); ky = SCALERATIO*getshort(ifile); if (((k%delta) != 0) && (k != (n-1))) continue; conv(kx,&g.nlat); conv(ky,&g.wlon); conn = plotpt(&g,conn); } } else { /* differential, scaled by SCALERATI0 */ n = -n; kx = SCALERATIO*getshort(ifile); ky = SCALERATIO*getshort(ifile); for(k=0; k<n; k++) { c = getc(ifile); if(c&0200) c|= ~0177; kx += c; c = getc(ifile); if(c&0200) c|= ~0177; ky += c; if(k%delta!=0&&k!=n-1) continue; conv(kx,&g.nlat); conv(ky,&g.wlon); conn = plotpt(&g,conn); } } if(k==1) { conv(kx,&g.nlat); conv(ky,&g.wlon); plotpt(&g,conn); } } } fclose(ifile);}intseeable(double lat0, double lon0){ double x, y; double lat, lon; for(lat=lat0;lat<=lat0+10;lat+=2*grid[2]) for(lon=lon0;lon<=lon0+10;lon+=2*grid[2]) if(normproj(lat,lon,&x,&y)*vflag>0) return(1); return(0);}voidsatellite(struct file *t){ char sym[50]; char lbl[50]; double scale; register conn; double lat,lon; struct place place; static FILE *ifile = stdin; if(t->name[0]!='-'||t->name[1]!=0) { fclose(ifile); if((ifile=fopen(t->name,"r"))==NULL) filerror("can't find track", t->name); } comment("track",t->name); colorx(t->color); pen(t->style); for(;;) { conn = 0; while(!feof(ifile) && fscanf(ifile,"%lf%lf",&lat,&lon)==2){ latlon(lat,lon,&place); if(fscanf(ifile,"%1s",lbl) == 1) { if(strchr("+-.0123456789",*lbl)==0) break; ungetc(*lbl,ifile); } conn = plotpt(&place,conn); } if(feof(ifile)) return; fscanf(ifile,"%[^\n]",lbl+1); switch(*lbl) { case '"': if(plotpt(&place,conn)) text(lbl+1); break; case ':': case '!': if(sscanf(lbl+1,"%s %lf",sym,&scale) <= 1) scale = 1; if(plotpt(&place,conn?conn:-1)) { int r = *lbl=='!'?0:rflag?-1:1; pen(SOLID); if(putsym(&place,sym,scale,r) == 0) text(lbl); pen(t->style); } break; default: if(plotpt(&place,conn)) text(lbl); break; } }}intpnorm(double x){ int i; i = x/10.; i %= 36; if(i>=18) return(i-36); if(i<-18) return(i+36); return(i);}voiderror(char *s){ fprintf(stderr,"map: \r\n%s\n",s); exits("error");}voidfilerror(char *s, char *f){ fprintf(stderr,"\r\n%s %s\n",s,f); exits("error");}char *mapindex(char *s){ char *t = malloc(strlen(s)+3); strcpy(t,s); strcat(t,".x"); return t;}#define NOPT 32767static ox = NOPT, oy = NOPT;intcpoint(int xi, int yi, int conn){ int dx = abs(ox-xi); int dy = abs(oy-yi); if(!xflag && (xi<left||xi>=right || yi<bottom||yi>=top)) { ox = oy = NOPT; return 0; } if(conn == -1) /* isolated plotting symbol */ {} else if(!conn) point(xi,yi); else { if(dx+dy>longlines) { ox = oy = NOPT; /* don't leap across cuts */ return 0; } if(dx || dy) vec(xi,yi); } ox = xi, oy = yi; return dx+dy<=2? 2: 1; /* 2=very near; see dogrid */}struct place oldg;intplotpt(struct place *g, int conn){ int kx,ky; int ret; double cutlon; if(!inlimits(g)) { return(0);} normalize(g); if(!inwindow(g)) { return(0);} switch((*cut)(g,&oldg,&cutlon)) { case 2: if(conn) { ret = duple(g,cutlon)|duple(g,cutlon); oldg = *g; return(ret); } case 0: conn = 0; default: /* prevent diags about bad return value */ case 1: oldg = *g; ret = doproj(g,&kx,&ky); if(ret==0 || !onlimb && ret*vflag<=0) return(0); ret = cpoint(kx,ky,conn); return ret; }}intdoproj(struct place *g, int *kx, int *ky){ int i; double x,y,x1,y1;/*fprintf(stderr,"dopr1 %f %f \n",g->nlat.l,g->wlon.l);*/ i = fixproj(g,&x,&y); if(i == 0) return(0); if(rflag) x = -x;/*fprintf(stderr,"dopr2 %f %f\n",x,y);*/ if(!inpoly(x,y)) { return 0;} x1 = x - xcent; y1 = y - ycent; x = (x1*crot.c - y1*crot.s + xoff)*scaling; y = (x1*crot.s + y1*crot.c + yoff)*scaling; *kx = x + (x>0?.5:-.5); *ky = y + (y>0?.5:-.5); return(i);}intduple(struct place *g, double cutlon){ int kx,ky; int okx,oky; struct place ig; revlon(g,cutlon); revlon(&oldg,cutlon); ig = *g; invert(&ig); if(!inlimits(&ig)) return(0); if(doproj(g,&kx,&ky)*vflag<=0 || doproj(&oldg,&okx,&oky)*vflag<=0) return(0); cpoint(okx,oky,0); cpoint(kx,ky,1); return(1);}voidrevlon(struct place *g, double cutlon){ g->wlon.l = reduce(cutlon-reduce(g->wlon.l-cutlon)); sincos(&g->wlon);}/* recognize problems of cuts * move a point across cut to side of its predecessor * if its very close to the cut * return(0) if cut interrupts the line * return(1) if line is to be drawn normally * return(2) if line is so close to cut as to * be properly drawn on both sheets*/intpicut(struct place *g, struct place *og, double *cutlon){ *cutlon = PI; return(ckcut(g,og,PI));}intnocut(struct place *g, struct place *og, double *cutlon){ USED(g, og, cutlon);/*#pragma ref g#pragma ref og#pragma ref cutlon*/ return(1);}intckcut(struct place *g1, struct place *g2, double lon){ double d1, d2; double f1, f2; int kx,ky; d1 = reduce(g1->wlon.l -lon); d2 = reduce(g2->wlon.l -lon); if((f1=fabs(d1))<FUZZ) d1 = diddle(g1,lon,d2); if((f2=fabs(d2))<FUZZ) { d2 = diddle(g2,lon,d1); if(doproj(g2,&kx,&ky)*vflag>0) cpoint(kx,ky,0); } if(f1<FUZZ&&f2<FUZZ) return(2); if(f1>PI*TWO_THRD||f2>PI*TWO_THRD) return(1); return(d1*d2>=0);}doublediddle(struct place *g, double lon, double d){ double d1; d1 = FUZZ/2; if(d<0) d1 = -d1; g->wlon.l = reduce(lon+d1); sincos(&g->wlon); return(d1);}doublereduce(double lon){ if(lon>PI) lon -= 2*PI; else if(lon<-PI) lon += 2*PI; return(lon);}double tetrapt = 35.26438968; /* atan(1/sqrt(2)) */voiddogrid(double lat0, double lat1, double lon0, double lon1){ double slat,slon,tlat,tlon; register int conn, oconn; slat = tlat = slon = tlon = 0; if(lat1>lat0) slat = tlat = fmin(grid[2],dlat); else slon = tlon = fmin(grid[2],dlon);; conn = oconn = 0; while(lat0<=lat1&&lon0<=lon1) { conn = gridpt(lat0,lon0,conn); if(projection==Xguyou&&slat>0) { if(lat0<-45&&lat0+slat>-45) conn = gridpt(-45.,lon0,conn); else if(lat0<45&&lat0+slat>45) conn = gridpt(45.,lon0,conn); } else if(projection==Xtetra&&slat>0) { if(lat0<-tetrapt&&lat0+slat>-tetrapt) { gridpt(-tetrapt-.001,lon0,conn); conn = gridpt(-tetrapt+.001,lon0,0); } else if(lat0<tetrapt&&lat0+slat>tetrapt) { gridpt(tetrapt-.001,lon0,conn); conn = gridpt(tetrapt+.001,lon0,0); } } if(conn==0 && oconn!=0) { if(slat+slon>.05) { lat0 -= slat; /* steps too big */ lon0 -= slon; /* or near bdry */ slat /= 2; slon /= 2; conn = oconn = gridpt(lat0,lon0,conn); } else oconn = 0; } else { if(conn==2) { slat = tlat; slon = tlon; conn = 1; } oconn = conn; } lat0 += slat; lon0 += slon; } gridpt(lat1,lon1,conn);}static gridinv; /* nonzero when doing window bounds */intgridpt(double lat, double lon, int conn){ struct place g;/*fprintf(stderr,"%f %f\n",lat,lon);*/ latlon(lat,lon,&g); if(gridinv) invert(&g); return(plotpt(&g,conn));}/* win=0 ordinary grid lines, win=1 window lines */voiddobounds(double lolat, double hilat, double lolon, double hilon, int win){ gridinv = win; if(lolat>-90 || win && (poles&1)!=0) dogrid(lolat+FUZZ,lolat+FUZZ,lolon,hilon); if(hilat<90 || win && (poles&2)!=0) dogrid(hilat-FUZZ,hilat-FUZZ,lolon,hilon); if(hilon-lolon<360 || win && cut==picut) { dogrid(lolat,hilat,lolon+FUZZ,lolon+FUZZ); dogrid(lolat,hilat,hilon-FUZZ,hilon-FUZZ); } gridinv = 0;}static voiddolimb(void){ double lat, lon; double res = fmin(dlat, dlon)/4; int conn = 0; int newconn; if(limb == 0) return; onlimb = gridinv = 1; for(;;) { newconn = (*limb)(&lat, &lon, res); if(newconn == -1) break; conn = gridpt(lat, lon, conn*newconn); } onlimb = gridinv = 0;}voidradbds(double *w, double *rw){ int i; for(i=0;i<4;i++) rw[i] = w[i]*RAD; rw[0] -= FUZZ; rw[1] += FUZZ; rw[2] -= FUZZ; rw[3] += FUZZ;}voidwindlim(void){ double center = orientation[0]; double colat; if(center>90) center = 180 - center; if(center<-90) center = -180 - center; if(fabs(center)>90) error("unreasonable orientation"); colat = 90 - window[0]; if(center-colat>limits[0]) limits[0] = center - colat; if(center+colat<limits[1]) limits[1] = center + colat;}shortgetshort(FILE *f){ int c, r; c = getc(f); r = (c | getc(f)<<8); if (r&0x8000) r |= ~0xFFFF; /* in case short > 16 bits */ return r;}doublefmin(double x, double y){ return(x<y?x:y);}doublefmax(double x, double y){ return(x>y?x:y);}voidclamp(double *px, double v){ *px = (v<0?fmax:fmin)(*px,v);}voidpathnames(void){ int i; char *t, *indexfile, *name; FILE *f, *fx; for(i=0; i<nfile; i++) { name = file[i].name; if(*name=='/') continue; indexfile = mapindex(name); /* ansi equiv of unix access() call */ f = fopen(name, "r"); fx = fopen(indexfile, "r"); if(f) fclose(f); if(fx) fclose(fx); free(indexfile); if(f && fx) continue; t = malloc(strlen(name)+strlen(mapdir)+2); strcpy(t,mapdir); strcat(t,"/"); strcat(t,name); file[i].name = t; }}voidclipinit(void){ register i; double s,t; if(nvert<=0) return; for(i=0; i<nvert; i++) { /*convert latlon to xy*/ if(normproj(v[i].x,v[i].y,&v[i].x,&v[i].y)==0) error("invisible clipping vertex"); } if(nvert==2) { /*rectangle with diag specified*/ nvert = 4; v[2] = v[1]; v[1].x=v[0].x, v[1].y=v[2].y, v[3].x=v[2].x, v[3].y=v[0].y; } v[nvert] = v[0]; v[nvert+1] = v[1]; s = 0; for(i=1; i<=nvert; i++) { /*test for convexity*/ t = (v[i-1].x-v[i].x)*(v[i+1].y-v[i].y) - (v[i-1].y-v[i].y)*(v[i+1].x-v[i].x); if(t<-FUZZ && s>=0) s = 1; if(t>FUZZ && s<=0) s = -1; if(-FUZZ<=t&&t<=FUZZ || t*s>0) { s = 0; break; } } if(s==0) error("improper clipping polygon"); for(i=0; i<nvert; i++) { /*edge equation ax+by=c*/ e[i].a = s*(v[i+1].y - v[i].y); e[i].b = s*(v[i].x - v[i+1].x); e[i].c = s*(v[i].x*v[i+1].y - v[i].y*v[i+1].x); }}intinpoly(double x, double y){ register i; for(i=0; i<nvert; i++) { register struct edge *ei = &e[i]; double val = x*ei->a + y*ei->b - ei->c; if(val>10*FUZZ) return(0); } return 1;}voidrealcut(){ struct place g; double lat; if(cut != picut) /* punt on unusual cuts */ return; for(lat=window[0]; lat<=window[1]; lat+=grid[2]) { g.wlon.l = PI; sincos(&g.wlon); g.nlat.l = lat*RAD; sincos(&g.nlat); if(!inwindow(&g)) { break;} invert(&g); if(inlimits(&g)) { return;} } longlines = shortlines = LONGLINES; cut = nocut; /* not necessary; small eff. gain */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -