/* * Usage: jpd2else [-jpdfile name] [-output name] * [-format type] [-ascii type] * [-continents list] [-types list] * [-verbose] [-silent] * where format type is one of NONE (default), TEXT, REZ, VMF * where ascii type is one of DXDY (default), INT, REAL * */ #include #include #include #include #include #ifdef ZLIB #include #endif #define BIT32 int #define BIT16 short #define DEFAULT_JPD_FILE "/usr/share/rmap/CIA_WDB2.jpd" #define MAXSTROKES 6000000 /* conservative upper estimate */ #define JPD_TOTALSEG 31844 #define JPD_MAGIC "!JPD1.0\n" #define REZ_MAGIC 0x86460346 enum { AFRICA=0, ASIA, EUROPE, NAMERICA, SAMERICA }; enum { BDY=0, PBY, RIV, CIL }; enum {NONE=0, TEXT, REZ, VMF}; enum {DX_DY=0, INT, REAL}; char *cont_name[] = { "Africa", "Asia", "Europe", "North America", "South America" }; char *feature[] = { "int", "nat", "riv", "cil" }; int rez_type[4] = { 2, 0, 1, 3 }; int rez_rank[4][12] = { { 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 13, 0 }, { 1, 2, 3, 4, 6, 7, 8, 9, 10, 13, 14, 15 } }; struct Header { char magic[12]; unsigned char maxlength[4]; unsigned char index[560]; }; struct Segment_index { unsigned char minlong[3]; unsigned char maxlong[3]; unsigned char minlat[3]; unsigned char maxlat[3]; unsigned char address[4]; }; static int str3toint(unsigned char *str) { if (str[2]<=127) return (int) (str[2]<<16)|(str[1]<<8)|str[0]; else return (int) (0xff<<24)|(str[2]<<16)|(str[1]<<8)|str[0]; } static int str4toint(unsigned char *str) { return (int) (str[3]<<24)|(str[2]<<16)|(str[1]<<8)|str[0]; } void fpr4(FILE * fd, int n) { fprintf(fd, "%c%c%c%c", n&255, (n>>8)&255, (n>>16)&255, n>>24); } void prascii(FILE *fd, int x, int y) { while (x<=-648000) x += 1296000; while (x>648000) x -= 1296000; fprintf(fd, "%7.3f %8.3f", y/3600.0, x/3600.0); } void usage() { fprintf(stderr, "Usage: jpd2else [-jpdfile name] [-output name]\n" " [-format type] [-ascii type] [-spacing val]\n" " [-continents list] [-types list]\n" " [-verbose] [-silent]\n" "where format type is one of NONE, TEXT (default), REZ, VMF\n" "and ascii type is one of DXDY (default), INT, REAL\n\n"); exit(-1); } int main (argc, argv) int argc; char **argv; { #ifdef ZLIB gzFile *ff; #else int ff; #endif FILE *fd; char *jpd_file = NULL; char * output = NULL; char * list_cont = NULL, * list_types = NULL; struct Header * header; struct Segment_index * segment_index = NULL; signed char * segment_buffer = NULL; int i, j, u, v, w, verbose, format, text_output_type; int cont, numf; int numseg, maxlength, maxwidth, maxheight; int readseg, printedpt, countpt, spacing; int minlong, maxlong, minlat, maxlat, nstrokes, x, y, dx, dy; int addr, address0, address1, address2, index1, index2; format = NONE; text_output_type = DX_DY; verbose = 1; spacing = 1; for (j=1; jmagic, JPD_MAGIC)) { fprintf(stderr, "File %s has wrong magic string %s\n" "instead of %s . Aborting !!\n", jpd_file, header->magic, JPD_MAGIC); exit(-2); } maxlength = str4toint(header->maxlength); numseg = str4toint(&header->index[556]); segment_index = (struct Segment_index *) malloc(numseg * sizeof(struct Segment_index)); segment_buffer = (char *) malloc(6+2*maxlength); #ifdef ZLIB gzseek(ff, sizeof(struct Header), SEEK_SET); gzread(ff, segment_index, numseg * sizeof(struct Segment_index)); #else lseek(ff, sizeof(struct Header), SEEK_SET); read(ff, segment_index, numseg * sizeof(struct Segment_index)); #endif address0 = sizeof(struct Header) + numseg*sizeof(struct Segment_index); if (format==TEXT) { fprintf(fd, "%s%s\n", JPD_MAGIC, "(Text format)"); fprintf(fd, "Number of segments for each continent/category\n"); } if (format==REZ) { fpr4(fd, REZ_MAGIC); fpr4(fd, 12); fpr4(fd, numseg); addr = 12 + numseg*32; } for (u=0; u<140; u++) { cont = u/28; /* number of continent */ w = u%28; if (w<3) { v=0; numf=w; } else if (w<5) { v=1; numf=w-3; } else if (w<16) { v=2; numf=w-5; } else { v=3; numf=w-16; } if (u==0) index1 = 0; else index1 = str4toint(&header->index[4*(u-1)]); index2 = str4toint(&header->index[4*u]); if (format==TEXT) fprintf(fd, "%s, %s %d : %d\n", cont_name[cont], feature[v], numf, index2-index1); if (format==REZ) { for (i=index1; iindex[4*(u-1)]); index2 = str4toint(&header->index[4*u]); for (i=index1; i %s (%s %d)\nJPD address: %d\n", i, cont_name[cont], feature[v], numf, address1); if (text_output_type == REAL) fprintf(fd, "Box [%4.6f %4.6f] [%3.6f %3.6f]\nStrokes %d\n", minlong/3600.0, maxlong/3600.0, minlat/3600.0, maxlat/3600.0, nstrokes); else fprintf(fd, "Box [%d %d] [%d %d]\nStrokes %d\n", minlong, maxlong, minlat, maxlat, nstrokes); } #ifdef ZLIB gzseek(ff, address1, SEEK_SET); gzread(ff, segment_buffer, address2-address1); #else lseek(ff, address1, SEEK_SET); read(ff, segment_buffer, address2-address1); #endif x = str3toint(segment_buffer); y = str3toint(&segment_buffer[3]); if (format==TEXT) { if (text_output_type == REAL) fprintf(fd, "Origin %4.6f %3.6f\n", x/3600.0, y/3600.0); else fprintf(fd, "Origin %d %d\n", x, y); } if (format==REZ) { fpr4(fd, x); fpr4(fd, y); fpr4(fd, nstrokes); } if (format==VMF) { fprintf(fd, "#%d %d\n", readseg, u+1); prascii(fd, x, y); printedpt = 1; countpt = 0; } if (nstrokes>maxlength) maxlength = nstrokes; for (j=0; j