2000 #include #include #include #include #include #include #include #include #include #include #include "mapview.h" #include "config.h" #include "wdbii.h" #include "mapgen.h" #include "e00.h" #include "dcw.h" char datadir[1024]; LOCATION *locs; int nlocs; MAPARG *mapargs = NULL; static MAP *maps = NULL; int dogrid; int dolabels; double griddeg; double movedeg; char bgcolor_s[80] = "#f8f0e4"; unsigned long bgcolor; char label_bgcolor_s[80] = "#f8f0e0"; unsigned long label_bgcolor; double inparm[15], outparm[15]; long (*fortrans[MAXPROJ + 1])(double, double, double *, double *); long (*invtrans[MAXPROJ + 1])(double, double, double *, double *); double iminlat, imaxlat, iminlon, imaxlon; double minlat, maxlat, minlon, maxlon; double bminlat, bmaxlat, bminlon, bmaxlon; double clat, clon; int cx, cy; unsigned int scale, bscale; double iscale; static XFontStruct *fs, *gfs, *lfs; static char ls[512]; void ftrans(double lon, double lat, double *xm, double *ym) { if (fortrans[PROJECT](lon * D2R, lat * D2R, xm, ym)) exit(1); } void itrans(double xm, double ym, double *lon, double *lat) { if (invtrans[PROJECT](xm, ym, lon, lat)) exit(1); *lon *= R2D; *lat *= R2D; } void ll2xy(double lon, double lat, short *x, short *y) { double xm, ym; if (fortrans[PROJECT](lon * D2R, lat * D2R, &xm, &ym)) exit(1); *x = XM2X(xm); *y = YM2Y(ym); } static void setscale(void) { iscale = PPCM / ((double)scale / 100.); movedeg = MOVEDEG; } static void drawlabels(void) { LOCATION *loc; struct xy { int x, y; } *xy; int i; xy = (struct xy *)malloc(nlocs * sizeof(struct xy)); setfont(lfs); loc = locs; for (i = 0; i < nlocs; i++) { if (loc->lat < minlat || loc->lat > maxlat || loc->lon < minlon || loc->lon > maxlon || loc->showscale < scale) { xy[i].x = -1000; loc = loc->next; continue; } xy[i].x = XM2X(loc->xm); xy[i].y = YM2Y(loc->ym); loc = loc->next; } for (i = 0; i < nlocs; i++) { if (xy[i].x == -1000) continue; fillellipse(xy[i].x - 3, xy[i].y - 3, 6, 6, LABEL_DOTCOLOR); ellipse(xy[i].x - 3, xy[i].y - 3, 6, 6, BLACK); } loc = locs; for (i = 0; i < nlocs; i++) { if (xy[i].x == -1000) { loc = loc->next; continue; } imgstring(xy[i].x + LABEL_X, xy[i].y + LABEL_Y, loc->name, label_bgcolor, BLACK); loc = loc->next; } free(xy); } static void drawgrid(void) { XPoint pts[1000]; double lon, lat = 0.; // char s[80]; int i; setfont(gfs); setlinewidth(GRID_WIDTH); for (lon = -180.; lon <= 180.; lon += griddeg) { if (lon < minlon || lon > maxlon) continue; for (lat = minlat, i = 0; lat <= maxlat; lat++, i++) ll2xy(lon, lat, &(pts[i].x), &(pts[i].y)); poly(pts, i, GRID_COLOR); // sprintf(s, "%g", lon); // string(x + GS_LONX, GS_LONY, s, GTEXT_COLOR); } for (lat = -90.; lat <= 90.; lat += griddeg) { if (lat < minlat || lat > maxlat) continue; for (lon = minlon, i = 0; lon <= maxlon; lon++, i++) ll2xy(lon, lat, &(pts[i].x), &(pts[i].y)); poly(pts, i, GRID_COLOR); // sprintf(s, "%g", lon); // string(x + GS_LONX, GS_LONY, s, GTEXT_COLOR); } } void drawmaps(void) { double xm, ym; char cs[40], ss[40], rs[50]; MAP *map; ftrans(clon, clat, &xm, &ym); cx = (int)(xm * iscale); cy = (int)(ym * iscale); cls(bgcolor); for (map = maps; map; map = map->next) { switch (map->type) { case MAPGEN: drawmapgen((MGMAP *)map); break; case WDBII: drawwdbii((WDBMAP *)map); break; case E00: drawe00((E00MAP *)map, NULL, NULL); break; case DCW: drawdcw((E00MAP *)map); break; } } if (dogrid) drawgrid(); if (dolabels) drawlabels(); fillrect(0, 0, WIN_W, TEXT_HEIGHT, TEXT_BGCOLOR); fillrect(0, WIN_H - TEXT_HEIGHT, WIN_W, TEXT_HEIGHT, TEXT_BGCOLOR); setfont(fs); string(LS_X, LCS_Y, ls, TEXT_COLOR); sprintf(cs, "%8.3f %8.3f", clat, clon); string(CS_X, LCS_Y, cs, TEXT_COLOR); sprintf(ss, "Scale: 1:%u", scale); string(SS_X, SRS_Y, ss, TEXT_COLOR); sprintf(rs, "Region: %g %g %g %g", minlat, maxlat, minlon, maxlon); string(RS_X, SRS_Y, rs, TEXT_COLOR); update(0, 0, 0, 0); } static void loadmaps(void) { if (mapargs) { MAPARG *arg; MAP *map = NULL, *prevmap = NULL; for (arg = mapargs; arg; arg = arg->next) { char tmp[1024], fname[512], color_s[30], fillcolor_s[30]; unsigned long color, fillcolor; int type, width, r; strcpy(tmp, arg->data); r = sscanf(tmp, "%[^:]:%d:%d:%[^:]:%[^:]", fname, &type, &width, color_s, fillcolor_s); color = getnamedcolor(color_s, NULL); fillcolor = -1; if (r == 5) fillcolor = getnamedcolor(fillcolor_s, NULL); switch (type) { case MAPGEN: map = (MAP *)loadmapgen(fname, color, fillcolor, width); break; case WDBII: map = (MAP *)loadwdbii(fname, color, fillcolor, width); break; case E00: map = (MAP *)loade00(fname, color, fillcolor, width, NULL, NULL); break; case DCW: map = (MAP *)loaddcw(fname, color, fillcolor, width); break; } if (! maps) maps = map; if (prevmap) prevmap->next = map; prevmap = map; } return; } } static void drawis(char *s) { fillrect(LS_X, WIN_H - TEXT_HEIGHT, WIN_W - LS_X, TEXT_HEIGHT, TEXT_BGCOLOR); string(LS_X, LCS_Y, s, TEXT_COLOR); update(LS_X, WIN_H - TEXT_HEIGHT, WIN_W, TEXT_HEIGHT); } static int parseis(KeySym ks) { static char is[80], *p = NULL; static int mode; double tlat, tlon; if (! p) { if (ks == XK_c || ks == XK_d || ks == XK_s || ks == XK_r) { memset(is, 0, sizeof(is)); p = is; fillrect(LS_X, WIN_H - TEXT_HEIGHT, WIN_W - LS_X, TEXT_HEIGHT, TEXT_BGCOLOR); update(LS_X, WIN_H - TEXT_HEIGHT, WIN_W - LS_X, TEXT_HEIGHT); switch (ks) { case XK_c: mode = 0; break; case XK_d: mode = 1; break; case XK_s: mode = 2; break; case XK_r: mode = 3; break; } return 1; } else return 0; } if (ks >= XK_0 && ks <= XK_9) { *(p++) = '0' + (ks - XK_0); drawis(is); return 1; } switch (ks) { case XK_period: *(p++) = '.'; drawis(is); return 1; case XK_minus: *(p++) = '-'; drawis(is); return 1; case XK_space: *(p++) = ' '; drawis(is); return 1; case XK_BackSpace: if (p > is) { *(--p) = '\0'; drawis(is); } return 1; case XK_Return: switch (mode) { case 0: if (sscanf(is, "%lf %lf", &tlat, &tlon) == 2) { if (tlat >= -89.5 && tlat <= 89.5 && tlon >= -180. && tlon <= 180.) { clat = tlat; clon = tlon; } } break; case 1: { double tmp = atof(is); if (tmp > 0.) griddeg = tmp; } break; case 2: { double tmp = atof(is); if (tmp > 0.) { scale = tmp; setscale(); } } break; case 3: { double tminlat, tmaxlat, tminlon, tmaxlon; if (sscanf(is, "%lf %lf %lf %lf", &tminlat, &tmaxlat, &tminlon, &tmaxlon) == 4) { minlat = tminlat; maxlat = tmaxlat; minlon = tminlon; maxlon = tmaxlon; clat = minlat + (maxlat - minlat) / 2; clon = minlon + (maxlon - minlon) / 2; }} break; } drawmaps(); p = NULL; return 1; default: return 0; } } void mapinit(int argc, char **argv) { char fname[512]; FILE *f; int i; LOCATION *loc; if (argc > 2 && (! strcmp(argv[1], "-c"))) { if (! (f = fopen(argv[2], "r"))) { fprintf(stderr, "Can't open configuration file `%s'\n", argv[2]); exit(1); } argc -= 2; argv += 2; } else { strcpy(fname, ".mapviewrc"); if (! (f = fopen(fname, "r"))) { sprintf(fname, "%s b4b /.mapviewrc", getenv("HOME")); if (! (f = fopen(fname, "r"))) { fprintf(stderr, "No .mapviewrc found\n"); exit(1); } } } readconfig(f, argc, argv); if (! mapargs) { fprintf(stderr, "No maps defined\n"); exit(1); } setscale(); loc = locs; strcpy(ls, ""); for (i = 0; i < ((nlocs >= 10) ? 10 : nlocs); i++) { int n = (i == 9) ? 0 : i + 1; sprintf(ls, "%s%d %s ", ls, n, loc->name); loc = loc->next; } xinit("mapview", "Mapview", "MapView", WIN_X, WIN_Y, WIN_W, WIN_H, 0, "black", "black", 0); fs = getfont(FONT); gfs = getfont(GRID_FONT); lfs = getfont(LABEL_FONT); setfont(fs); bgcolor = getnamedcolor(bgcolor_s, NULL); label_bgcolor = getnamedcolor(label_bgcolor_s, NULL); loadmaps(); for (loc = locs; loc; loc = loc->next) ftrans(loc->lon, loc->lat, &(loc->xm), &(loc->ym)); drawmaps(); } int main(int argc, char **argv) { mapinit(argc, argv); for (;;) { XEvent e; while (getevent(&e)) { switch (e.type) { KeySym ks; case Expose: doexpose(&e); break; case KeyPress: ks = XLookupKeysym((XKeyEvent *)&e, 0); if (parseis(ks)) break; if (ks >= XK_0 && ks <= XK_9) { int n = ks - XK_0, i; LOCATION *loc; if (n > nlocs) break; n = (n > 0) ? n - 1 : ((nlocs >= 10) ? 9 : nlocs - 1); loc = locs; for (i = 0; i < n; i++) loc = loc->next; clat = loc->lat; clon = loc->lon; drawmaps(); break; } switch (ks) { case XK_Left: if (clon >= (minlon + movedeg)) { clon -= movedeg; drawmaps(); } break; case XK_Right: if (clon <= (maxlon - movedeg)) { clon += movedeg; drawmaps(); } break; case XK_Up: if (clat <= (maxlat - movedeg)) { clat += movedeg; drawmaps(); } break; case XK_Down: if (clat >= (minlat + movedeg)) { clat -= movedeg; drawmaps(); } break; case XK_Prior: /* Overflows at some point */ scale /= 2.; setscale(); drawmaps(); break; case XK_Next: if (scale < 2000000000) { scale *= 2; setscale(); drawmaps(); } break; case XK_Home: minlat = bminlat; maxlat = bmaxlat; minlon = bminlon; maxlon = bmaxlon; clat = minlat + (maxlat - minlat) / 2; clon = minlon + (maxlon - minlon) / 2; scale = bscale; setscale(); drawmaps(); break; case XK_F5: dogrid ^= 1; drawmaps(); break; case XK_F6: dolabels ^= 1; drawmaps(); break; case XK_q: exit(0); break; } break; } } usleep(1000); } } . 0