|
|
1.1 root 1: # include "stdio.h"
2: # include "cbt.h"
3: # include "ctype.h"
4: # include "assert.h"
5: # include "math.h"
6: # define SAME 0
7: # define torad 0.0174532925
8:
9: double dist(), atof();
10: double clat, clng;
11: double radius=50.0;
12: char countypat[100];
13: char *countyname = "/usr/spool/town/countymap";
14: char statepname[100];
15: char *statename = "/usr/spool/town/statemap";
16: double radlat, radlong;
17: int labx[500];
18: int laby[500];
19: int nlab=0;
20: int ctyflg=0;
21: int countyline=0, numnames=1000;
22:
23: # define abs(x) ( (t=(x))>= 0 ? t : -t )
24: main(argc,argv)
25: char *argv[];
26: {
27: char line[100], request[100], rka[100], rra[300];
28: char *s, *strchr();
29: long l1, l2;
30: char nline[100];
31: mbuf key, rkey, rrec;
32: bfile *townfile;
33: FILE *cntypat, *countyf, *namepat, *namef, *pointf=NULL;
34: FILE *statepat, *state, *patch, *fdata, *bigname, *bigpat;
35: double lat, lng;
36: int townfind, x, y, j, use, a1, a2;
37: townfile = bopen("/usr/spool/town/ustowns", 0);
38: argc--; argv++;
39: while (argc-- > 0)
40: {
41: if (argv[0][0]=='-')
42: switch(argv[0][1])
43: {
44: case 'f':
45: countyname = statename = argv[1];
46: argv++; argc--;
47: break;
48: case 'n':
49: numnames = atoi(argv[0]+2);
50: break;
51: case 'c':
52: countyline = atoi(argv[0]+2);
53: ctyflg = 1;
54: break;
55: }
56: argv++;
57: }
58: if (townfile==NULL)
59: {
60: fprintf(stderr, "No town list\n");
61: exit(1);
62: }
63: sprintf(countypat, "%s.pat", countyname);
64: sprintf(statepname, "%s.pat", statename);
65: cntypat = fopen(countypat, "r");
66: assert(cntypat!=NULL);
67: countyf = fopen(countyname, "r");
68: assert(countyf!=NULL);
69: namepat = fopen("/usr/spool/town/ftownpat", "r");
70: assert(namepat!=NULL);
71: namef = fopen("/usr/spool/town/ftown", "r");
72: assert(namef!=NULL);
73: bigpat = fopen("/usr/spool/town/bigpat", "r");
74: assert(bigpat!=NULL);
75: bigname = fopen("/usr/spool/town/big", "r");
76: assert(bigname!=NULL);
77: state = fopen(statename, "r");
78: assert(state!=NULL);
79: statepat = fopen(statepname, "r");
80: assert(statepat!=NULL);
81: rkey.mdata = rka; rrec.mdata = rra;
82: openpl();
83: while (gets(request))
84: {
85: s = strchr(request, '\t');
86: if (s!=NULL)
87: {
88: *s++ = 0;
89: radius= atof(s);
90: s = strchr(s, ' ');
91: if (s!=NULL)
92: {
93: while (*s==' ')
94: s++;
95: if (*s)
96: pointf = fopen(s, "r");
97: }
98: }
99: if (strlen(request)==0)
100: continue;
101: lcase(request);
102: townfind=0;
103: if (ctyflg == 0) countyline = (radius<100.);
104: nlab=0;
105: key.mdata = request; key.mlen = strlen(request);
106: bseek(townfile, key);
107: while (bread(townfile, &rkey, &rrec)==NULL)
108: {
109: rkey.mdata[rkey.mlen]=0;
110: rrec.mdata[rrec.mlen]=0;
111: if (strncmp(rkey.mdata, request, key.mlen)!=SAME)
112: break;
113: sscanf(rra, "%lf%lf", &lat, &lng);
114: townfind++;
115: }
116: if (townfind==0)
117: {
118: fprintf(stderr, "Can't find that place\n");
119: continue;
120: }
121: if (townfind>1)
122: {
123: fprintf(stderr, "Ambiguous - specify state, please\n");
124: continue;
125: }
126: erase();
127: space(-5000, -5000, 5000, 5000);
128: caps(rka);
129: clat = lat; clng=lng;
130: /* standard correction latitude = 40.0 N*/
131: clng = clng * cos(torad*40.0);
132: radlat = radius/dist(clat, clng, clat+1., clng);
133: radlong = radius*cos(torad*40.0)/dist(clat, clng, clat, clng+1.);
134: a1 = lat/4.; a2 = lng/4.;
135: use=0;
136: if (countyline)
137: {
138: patch = cntypat; fdata = countyf;
139: }
140: else
141: {
142: patch = statepat; fdata = state;
143: }
144: rewind(patch);
145: fgets(line, 100, patch);
146: while (fgets(nline, 100, patch))
147: {
148: x = atoi(line);
149: y = atoi(line+3);
150: if (okpat(x, y, lat, lng))
151: {
152: ctydraw( atol(line+6), atol(nline+6), fdata);
153: use++;
154: }
155: if (x==a1 && y==a2)
156: {l1 = atol(line+6); l2 = atol(nline+6);}
157: strcpy(line, nline);
158: }
159: if (use==0)
160: ctydraw (l1, l2, fdata);
161: lcase(rka);
162: if (radius > 200.)
163: {
164: patch = bigpat; fdata = bigname;
165: }
166: else
167: {
168: patch = namepat; fdata = namef;
169: }
170: if (patch!=NULL && numnames>0)
171: {
172: rewind(patch);
173: use=0;
174: fgets(line, 100, patch);
175: while (fgets(nline, 100, patch))
176: {
177: x = atoi(line);
178: y = atoi(line+3);
179: if (okpat(x,y, lat, lng))
180: {
181: ckcit (atol(line+6), atol(nline+6), fdata);
182: use++;
183: }
184: if (a1==x && a2==y)
185: {l1 = atol(line+6); l2 = atol(nline+6);}
186: strcpy(line, nline);
187: }
188: if (use==0)
189: {
190: ckcit( l1, l2, fdata);
191: }
192: }
193: if (pointf!=NULL)
194: {
195: pltpts(pointf);
196: fclose(pointf);
197: }
198: for(j=0; j<10; j++)
199: {
200: move(-5000,4999);
201: move (-5000, 5000);
202: }
203: /* that hopes to flush out tek */
204: fflush(stdout);
205: }
206: exit(0);
207: }
208: okpat(ax, ay, lat, lng)
209: double lat, lng;
210: {
211: double d;
212: d = dist(ax*4., ay*4., lat, lng);
213: if (d<radius) return(1);
214: d = dist((ax+1)*4., ay*4., lat, lng);
215: if (d<radius) return(1);
216: d = dist(ax*4., (ay+1)*4., lat, lng);
217: if (d<radius) return(1);
218: d = dist((ax+1)*4., (ay+1)*4., lat, lng);
219: if (d<radius) return(1);
220: return(0);
221: }
222: ctydraw (pos1, pos2, ff)
223: FILE *ff;
224: long pos1, pos2;
225: {
226: float a[4];
227: int x0, y0, x1, y1;
228: register int t;
229: double alat, alng, blat, blng;
230: fseek (ff, pos1, 0);
231: while (fread (a, 4, sizeof(float), ff))
232: {
233: if (ftell(ff)>= pos2) break;
234: alat = a[0];
235: alng = a[1];
236: blat = a[2];
237: blng = a[3];
238:
239: x0 = (clng - alng)*5000/radlong;
240: y0 = (alat - clat)*5000/radlat;
241: x1 = (clng - blng)*5000/radlong;
242: y1 = (blat - clat)*5000/radlat;
243: if (abs(x0)<5000 && abs(x1)<5000 && abs(y0)<5000 && abs(y1)<5000)
244: {
245: line(x0,y0,x1,y1);
246: continue;
247: }
248: if ((abs(x0)<5000 && abs(y0)<5000) || (abs(x1)<5000 && abs(y1)<5000) )
249: {
250: partial(&x0, &y0, &x1, &y1);
251: line(x0, y0, x1, y1);
252: }
253: }
254: }
255: double
256: dist (aplat, aplon, bplat, bplon)
257: double aplon, aplat, bplon, bplat;
258: {
259: /* this code is from the picadad manual. I don't pretend
260: to understand it. */
261: double as, bs, ac, bc, p, cd, d, er;
262: double rad=0.0174532925;
263: er = aplon-bplon;
264: if (er<0) er= -er;
265: if (er<0.001)
266: {
267: d = aplat-bplat;
268: if (d<0) d= -d;
269: return(d*69.055);
270: }
271: as = sin(rad*aplat);
272: bs = sin(rad*bplat);
273: ac = cos(rad*aplat);
274: bc = cos(rad*bplat);
275: p = cos(er*rad);
276: cd = (as*bs+ac*bc*p);
277: return( acos(cd)*3956.56);
278: }
279: lcase (s)
280: char *s;
281: {
282: int c;
283: for( ; c= *s; s++)
284: if (isupper(c))
285: *s = tolower(c);
286: }
287: caps(s)
288: char *s;
289: {
290: int c;
291: if (islower(*s)) *s = toupper(*s);
292: for( s++; c= *s; s++)
293: {
294: if (islower(c) && (s[-1]==' ' || s[-1]=='-'))
295: if (strncmp(s, "of ", 3)!=SAME)
296: *s = toupper(c);
297: if (*s==',') break;
298: }
299: for(s++; c= *s; s++)
300: if (islower(c)) *s=toupper(c);
301: }
302: ckcit(pos1, pos2, countyf)
303: FILE *countyf;
304: long pos1, pos2;
305: {
306: char nam[50], *s;
307: int x0, y0, i, xthres, ythres, sz;
308: register int t;
309: double alat, alng;
310: float a[2];
311: fseek (countyf, pos1, 0);
312: while (fread(a, 2, sizeof(float), countyf))
313: {
314: if (ftell(countyf) >=pos2) break;
315: alat = a[0];
316: alng = a[1];
317: sz = getc(countyf);
318: s=nam;
319: while (i= getc(countyf))
320: {
321: if (i=='\n' || i==0) break;
322: *s++ = i;
323: }
324: *s=0;
325: switch (sz)
326: {
327: case '9': xthres=0; ythres=0; break;
328: case '8': xthres=500; ythres=150; break;
329: case '7': xthres=1000; ythres=300; break;
330: case '6': xthres=1500; ythres=400; break;
331: default : xthres=2000; ythres=400; break;
332: }
333: x0 = (clng-alng)*5000/radlong;
334: y0 = (alat-clat)*5000/radlat;
335: if (abs(x0)<5000 && abs(y0)<5000)
336: {
337: for(i=0; i<nlab; i++)
338: {
339: if (abs(x0-labx[i])<xthres && abs(y0-laby[i])<ythres)
340: break;
341: }
342: if (i<nlab) continue;
343: labx[nlab]=x0; laby[nlab]=y0;
344: nlab++;
345: assert(nlab<500);
346: point(x0,y0);
347: caps(nam);
348: label(nam);
349: }
350: if (nlab>numnames) break;
351: }
352: }
353: pltpts(fi)
354: FILE *fi;
355: {
356: char ln[100], *s;
357: double alat, alng;
358: int x, y;
359: register int t;
360: while (fgets(ln, 100, fi))
361: {
362: trimnl(s=ln);
363: while (isspace(*s)) s++;
364: alat = atof(s);
365: while (*s && !isspace(*s))s++;
366: while (isspace(*s))s++;
367: alng = atof(s);
368: while (*s && !isspace(*s)) s++;
369: while (isspace(*s)) s++;
370: if (s==NULL || alat <0.0 || alng < 0.0)
371: continue;
372: alng = alng * cos(torad*40.0); /* crummy map projection */
373: x = (clng - alng)*5000/radlong;
374: y = (alat - clat)*5000/radlat;
375: if (abs(x)<5000 && abs(y)<5000)
376: {
377: move(x,y);
378: label(s);
379: }
380: }
381: }
382: partial (x0, y0, x1, y1)
383: int *x0, *y0, *x1, *y1;
384: { /* pick part of line within 5000 limit */
385: int ax, ay, bx, by, cx, cy;
386: double a, b; /* y= ax + b*/
387: register int t;
388: ax = *x0; ay= *y0; bx = *x1; by = *y1;
389: if (abs(ax)>5000 || abs(ay)>5000)
390: {
391: cx = ax; ax = bx; bx = cx;
392: cy = ay; ay = by; by = cy;
393: }
394: /* ax, ay is inside; bx, by is outside */
395: if (ax == bx) /* vertical line*/
396: {
397: if (by>5000) by=5000;
398: else
399: if (by< -5000) by= -5000;
400: }
401: else
402: if (ay == by) /* horizontal line */
403: {
404: if (bx>5000) bx=5000;
405: else
406: if (bx< -5000) bx= -5000;
407: }
408: else
409: {/* normal case, with slope */
410: a = ( (double) (by-ay) ) / (bx-ax);
411: b = ay - a*ax;
412: if (bx>5000)
413: {
414: bx=5000;
415: by = a*bx+b;
416: }
417: else
418: if (bx< -5000)
419: {
420: bx = -5000;
421: by = a*bx+b;
422: }
423: /* now bx is in range. what about by */
424: if (by> 5000)
425: {
426: by = 5000;
427: bx = (by -b)/a;
428: }
429: else
430: if (by< -5000)
431: {
432: by = -5000;
433: bx = (by - b) /a;
434: }
435: }
436: *x0 = ax;
437: *x1 = bx;
438: *y0 = ay;
439: *y1 = by;
440: }
441: trimnl(s)
442: char *s;
443: {
444: while (*s)s++;
445: if (*--s== '\n')*s=0;
446: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.