127e #include #include #include #include #include #include #include #include #include #include "mapview.h" #include "wdbii.h" static POINT *pts; static int npts = 0; static int penup = TRUE; static MAP *map; static MAPREC *recs, *prevrec; static void addrec(SEGDICT *sd) { MAPREC *rec = (MAPREC *)malloc(sizeof(MAPREC)); rec->rank = (char)sd->rank; rec->pts = (POINT *)malloc(npts * sizeof(POINT)); rec->npts = npts; rec->minlat = (float)sd->minlat / 3600.; rec->maxlat = (float)sd->maxlat / 3600.; rec->minlon = (float)sd->minlon / 3600.; rec->maxlon = (float)sd->maxlon / 3600.; rec->next = NULL; memcpy(rec->pts, pts, npts * sizeof(POINT)); if (! recs) recs = rec; if (prevrec) prevrec->next = rec; prevrec = rec; } static void pendn(double lon, double lat, SEGDICT *sd) { double xm, ym; static SEGDICT *prevsd; if (penup) { if (npts) addrec(prevsd); npts = 0; penup = FALSE; } if (fortrans[PROJECT](lon * D2R, lat * D2R, &xm, &ym)) exit(1); pts[npts].xm = (float)xm; pts[npts].ym = (float)ym; if (++npts == MAXPOINTS) { addrec(sd); npts = 0; } prevsd = sd; } MAP *loadwdbii(char *name) { char fname[512]; int fd, segcount, idx, idy, segbufsize, olt, oln, k, stroke, iseg; char *databuf; BIT32 i32; BIT16 *segbuf; double lastlon = 0.; double lon, lat; struct stat st; int pos; CBDHEAD *header; SEGDICT *sd, *sdbuf; SEGBUF sb; recs = prevrec = NULL; sprintf(fname, "%s/%s.cbd", DATADIR, name); if ((fd = open(fname, O_RDONLY)) < 0) { perror("open"); exit(1); } if (fstat(fd, &st) < 0) { perror("fstat"); exit(1); } pts = (POINT *)malloc(MAXPOINTS * sizeof(POINT)); databuf = (char*)malloc(st.st_size); read(fd, databuf, st.st_size); close(fd); /* * Check the file header for the correct magic number, * and learn the address of the segment dictionary */ header = (CBDHEAD *)databuf; if (header->magic != CBD_MAGIC) { fprintf(stderr, "File has bad magic number %X != %X\n", header->magic, CBD_MAGIC); exit(1); } /* allocate space for the segment buffer */ segbufsize = 2 * header->segmax; segbuf = (BIT16 *) malloc (50 + segbufsize); /* allocate space for the segment dictionary */ sdbuf = (SEGDICT *) malloc (100 + (header->segsize)); sd = sdbuf; sd++; /* Get the segment dictionary (it's at the end of the file) */ memcpy(sd, databuf + header->dictaddr, header->segsize); /* * Now look at each segment and decide if we're * going to keep it or not */ segcount = header->segcount; npts = 0; sd = sdbuf; for (iseg = 1; iseg <= segcount; iseg++) { sd++; /* does this really work? wow! */ pos = sd->absaddr; memcpy(&sb, databuf + pos, sizeof(sb)); pos += sizeof(sb); if (sd->nbytes > segbufsize) { fprintf(stderr, "Segment %d needs %d bytes; buffer limit is %d.\n", iseg, sd->nbytes, segbufsize); exit(1); } memcpy(segbuf, databuf + pos, sd->nbytes); k = 0; oln = sb.orgx; olt = sb.orgy; lon = oln / 3600.; lat = olt / 3600.; penup = TRUE; pendn(lon, lat, sd); lastlon = lon; for (stroke = 1; stroke <= sb.nstrokes; stroke++) { if (segbuf[k] & SHORTFLAG) { /* Flag bit on: unpack a 16-bit field into dx and dy */ i32 = segbuf[k++]; if (i32 > 0) i32 &= ~SHORTFLAG; idy = i32 & 0xFF; if (idy & 0x80) idy |= ~0xFF; /* extend sign */ idx = i32 >> 8; if (idx & 0x80) idx |= ~0xBF; /* extend sign */ } else { /* Flag bit off: take dx and dy from 32-bit fields. */ idx = segbuf[k++]; if (idx < 0) idx |= SHORTFLAG; idx = (idx << 16) | (unsigned short) segbuf[k]; k++; idy = segbuf[k]; k++; if (idy < 0) idy |= SHORTFLAG; idy = (idy << 16) | segbuf[k]; k++; } oln = (oln + idx); olt = (olt + idy); lon = oln / 3600.; lat = olt / 3600.; if (fabs(lastlon - lon) > 180.) penup = TRUE; pendn(lon, lat, sd); lastlon = lon; } } if (npts) addrec(sd); free(sdbuf); free(segbuf); free(databuf); free(pts); map = (MAP *)malloc(sizeof(MAP)); if (strstr(fname, "cil.")) map->type = CIL; else if (strstr(fname, "riv.")) map->type = RIV; else if (strstr(fname, "bdy.")) map->type = BDY; else map->type = PBY; map->recs = recs; return map; } . 0