2000 #include #include #include #include #include #include "mapview.h" #include "e00.h" static E00MAP *map; static POLY *polys; static void utm2geo(double *lon, double *lat) { double xm = *lon, ym = *lat; if (invtrans[UTM](xm, ym, lon, lat)) exit(1); *lon *= R2D; *lat *= R2D; } static void clipcoord(double *lat, double *lon) { if (*lat < minlat) *lat = minlat; if (*lat > maxlat) *lat = maxlat; if (*lon < minlon) *lon = minlon; if (*lon > maxlon) *lon = maxlon; } void drawe00(E00MAP *map, unsigned long (*getiscolor)(), unsigned long (*getfillcolor)()) { static XPoint p[MAXPOINTS]; ARC *arc; POLY *ply; int i, j, np; unsigned long fillcolor, iscolor; if (map->fillcolor == -1) goto lines; iscolor = bgcolor; if (getiscolor) iscolor = getiscolor(map); for (ply = map->polys; ply; ply = ply->next) { if (ply->minlat > maxlat || ply->maxlat < minlat || ply->minlon > maxlon || ply->maxlon < minlon) continue; fillcolor = map->fillcolor; if (getfillcolor) fillcolor = getfillcolor(map, ply); np = 0; for (i = 0; i < ply->narcs; i++) { if (ply->arcids[i] == 0) { if (np) { if (np > 1) fillpoly(p, np, fillcolor); else pset(p[0].x, p[0].y, fillcolor); } arc = map->arcs[abs(ply->arcids[++i]) - 1]; np = 0; if (ply->arcids[i] < 0) { for (j = arc->nnodes - 1; j > -1; j--) { double lat = arc->nodes[j].lat; double lon = arc->nodes[j].lon; clipcoord(&lat, &lon); ll2xy(lon, lat, &(p[np].x), &(p[np].y)); np++; } } else { for (j = 0; j < arc->nnodes; j++) { double lat = arc->nodes[j].lat; double lon = arc->nodes[j].lon; clipcoord(&lat, &lon); ll2xy(lon, lat, &(p[np].x), &(p[np].y)); np++; } } if (np > 1) fillpoly(p, np, iscolor); else pset(p[0].x, p[0].y, iscolor); arc->done = TRUE; np = 0; continue; } arc = map->arcs[abs(ply->arcids[i]) - 1]; if (ply->arcids[i] < 0) { for (j = arc->nnodes - 1; j > -1; j--) { double lat = arc->nodes[j].lat; double lon = arc->nodes[j].lon; clipcoord(&lat, &lon); ll2xy(lon, lat, &(p[np].x), &(p[np].y)); np++; } } else { for (j = 0; j < arc->nnodes; j++) { double lat = arc->nodes[j].lat; double lon = arc->nodes[j].lon; clipcoord(&lat, &lon); ll2xy(lon, lat, &(p[np].x), &(p[np].y)); np++; } } arc->done = TRUE; } if (np) { if (np > 1) fillpoly(p, np, fillcolor); else pset(p[0].x, p[0].y, fillcolor); } } lines: setlinewidth(map->width); for (i = 0; i < map->narcs; i++) { arc = map->arcs[i]; if (arc->done) continue; np = 0; for (j = 0; j < arc->nnodes; j++) { if (arc->nodes[j].lat < minlat || arc->nodes[j].lat > maxlat || arc->nodes[j].lon < minlon || arc->nodes[j].lon > maxlon) { if (np) { if (np > 1) poly(p, np, map->color); else pset(p[0].x, p[0].y, map->color); } np = 0; continue; } ll2xy(arc->nodes[j].lon, arc->nodes[j].lat, &(p[np].x), &(p[np].y)); np++; } if (np) { if (np > 1) poly(p, np, map->color); else pset(p[0].x, p[0].y, map->color); } } } static void parsearc(FILE *f, int prec) { char s[100]; int na = 0; for (;;) { ARC *arc; int cnum, cid, fnode, tnode, lpoly, rpoly, nnodes; double lon1, lat1, lon2, lat2; int i, nn; fgets(s, 100, f); sscanf(s, "%d %d %d %d %d %d %d", &cnum, &cid, &fnode, &tnode, &lpoly, &rpoly, &nnodes); if (cnum == -1) break; arc = (ARC *)malloc(sizeof(ARC)); arc->nodes = (NODE *)malloc(nnodes * sizeof(NODE)); arc->nnodes = nnodes; arc->done = FALSE; nn = 0; for (i = 0; i < nnodes / ((prec == 2) ? 2 : 1); i++) { fgets(s, 100, f); if (prec == 2) sscanf(s, "%lf %lf %lf %lf", &lon1, &lat1, &lon2, &lat2); else sscanf(s, "%lf %lf", &lon1, &lat1); arc->nodes[nn].lon = lon1; arc->nodes[nn].lat = lat1; nn++; if (prec == 2) { arc->nodes[nn].lon = lon2; arc->nodes[nn].lat = lat2; nn++; } } if (prec == 2 && (nnodes % 2)) { fgets(s, 100, f); sscanf(s, "%lf %lf", &lon1, &lat1); arc->nodes[nn].lon = lon1; arc->nodes[nn].lat = lat1; nn++; } map->arcs[na++] = arc; } map->narcs = na; } static void parsepal(FILE *f) { char s[100]; POLY *ply, *prevply; int na, np; int first = TRUE; polys = prevply = NULL; np = 0; for (;;) { int narcs; double xmin, ymin, xmax, ymax; int a1id, a1fnode, a1ap, a2id, a2fnode, a2ap; int i; fgets(s, 100, f); sscanf(s, "%d %lf %lf %lf %lf", &narcs, &xmin, &ymin, &xmax, &ymax); if (narcs == -1) break; /* Skip universal polygon */ if (first) { for (i = 0; i < narcs / 2; i++) fgets(s, 100, f); if (narcs % 2) fgets(s, 100, f); first = FALSE; continue; } ply = (POLY *)malloc(sizeof(POLY)); ply->arcids = (int *)malloc(narcs * sizeof(int)); ply->minlat = ymin; ply->maxlat = ymax; ply->minlon = xmin; ply->maxlon = xmax; na = 0; for (i = 0; i < narcs / 2; i++) { fgets(s, 100, f); sscanf(s, "%d %d %d %d %d %d", &a1id, &a1fnode, &a1ap, &a2id, &a2fnode, &a2ap); ply->arcids[na++] = a1id; ply->arcids[na++] = a2id; } if (narcs % 2) { fgets(s, 100, f); sscanf(s, "%d %d %d", &a1id, &a1fnode, &a1ap); ply->arcids[na++] = a1id; } ply->narcs = na; ply->next = NULL; if (! polys) polys = ply; if (prevply) prevply->next = ply; prevply = ply; np++; } map->polys = polys; map->npolys = np; } static void parseprj(FILE *f) { char s[100]; char label[50]; char proj[50], datum[50], zunits[50], units[50], spheroid[50]; int zone; double xshift, yshift; long outdatum = 0, indatum = 0; long iflag; int i; for (;;) { fgets(s, 100, f); if (! strncmp(s, "EOP", 3)) break; if (! strncmp(s, "Projection", 10)) { sscanf(s, "%s %s", label, proj); if (! strcmp(proj, "GEOGRAPHIC")) map->proj = PROJ_GEO; else if (! strcmp(proj, "UTM")) map->proj = PROJ_UTM; else { fprintf(stderr, "Unsupported projection type\n"); exit(1); } continue; } if (! strncmp(s, "Zone", 4)) { sscanf(s, "%s %d", label, &zone); continue; } if (! strncmp(s, "Datum", 5)) { sscanf(s, "%s %s", label, datum); continue; } if (! strncmp(s, "Zunits", 6)) { sscanf(s, "%s %s", label, zunits); continue; } if (! strncmp(s, "Units", 5)) { sscanf(s, "%s %s", label, units); if (map->proj == PROJ_GEO && strcmp(units, "DD")) { fprintf(stderr, "Unsupported unit `%s' for " "GEOGRAPHIC projection\n", units); exit(1); } else if (map->proj == PROJ_UTM && strcmp(units, "METERS")) { fprintf(stderr, "Unsupported unit `%s' for " "UTM projection\n", units); exit(1); } continue; } if (! strncmp(s, "Spheroid", 8)) { sscanf(s, "%s %s", label, spheroid); if (! strcmp(spheroid, "CLARKE1866")) outdatum = indatum = 0; else if (! strcmp(spheroid, "BESSEL")) outdatum = indatum = 2; else if (! strcmp(spheroid, "GRS1980")) outdatum = indatum = 8; else if (! strcmp(spheroid, "WGS84")) outdatum = indatum = 12; else { fprintf(stderr, "Unsupported spheroid\n"); exit(1); } continue; } if (! strncmp(s, "Xshift", 6)) { sscanf(s, "%s %lf", label, &xshift); continue; } if (! strncmp(s, "Yshift", 6)) { sscanf(s, "%s %lf", label, &yshift); continue; } } for_init(PROJECT, 0, outparm, outdatum, NULL, NULL, &iflag, fortrans); if (iflag) exit(1); if (map->proj == PROJ_UTM) { ARC *arc; POLY *ply; for (i = 0; i < 15; i++) inparm[i] = 0.; inv_init(UTM, zon 80c e, inparm, indatum, NULL, NULL, &iflag, invtrans); if (iflag) exit(1); for (i = 0; i < map->narcs; i++) { int j; arc = map->arcs[i]; for (j = 0; j < arc->nnodes; j++) utm2geo(&(arc->nodes[j].lon), &(arc->nodes[j].lat)); } for (ply = map->polys; ply; ply = ply->next) { utm2geo(&(ply->minlon), &(ply->minlat)); utm2geo(&(ply->maxlon), &(ply->maxlat)); } } else { inv_init(PROJECT, 0, inparm, indatum, NULL, NULL, &iflag, invtrans); if (iflag) exit(1); } } E00MAP *loade00(char *fname, unsigned long color, unsigned long fillcolor, int width, void (*parseaat)(), void (*parsepat)()) { FILE *f; char s[100]; int arcdone = FALSE, paldone = FALSE, prjdone = FALSE, aatdone = FALSE, patdone = FALSE; char *covname; if (! (f = fopen(fname, "r"))) { perror("fopen"); exit(1); } fgets(s, 100, f); if (strncmp(s, "EXP", 3)) { fprintf(stderr, "Not an Arc/Info export format file\n"); exit(1); } map = (E00MAP *)malloc(sizeof(E00MAP)); map->narcs = 0; map->polys = NULL; while (fgets(s, 100, f)) { char arc[5]; int prec; if ((! arcdone) && (! strncmp(s, "ARC", 3))) { sscanf(s, "%s %d", arc, &prec); parsearc(f, prec); arcdone++; } if ((! paldone) && (! strncmp(s, "PAL", 3))) { parsepal(f); paldone++; } if ((! prjdone) && (! strncmp(s, "PRJ", 3))) { parseprj(f); prjdone++; } if (parseaat && (! aatdone) && strstr(s, ".AAT")) { parseaat(f, s, map); aatdone++; } if (parsepat && (! patdone) && strstr(s, ".PAT")) { parsepat(f, s, map); patdone++; } } fclose(f); map->type = E00; map->color = color; map->fillcolor = fillcolor; map->width = width; if (! (covname = strrchr(fname, '/'))) covname = fname; else covname++; *(strchr(covname, '.')) = '\0'; map->covname = (char *)malloc(strlen(covname) + 1); strcpy(map->covname, covname); map->next = NULL; return map; } . 0