/*
* 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 <string.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/file.h>
#ifdef ZLIB
#include <zlib.h>
#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; j<argc; j++) {
if (j<argc-1 && !strcmp(argv[j],"-jpdfile"))
jpd_file = (char *)strdup(argv[++j]);
else
if (j<argc-1 && !strcmp(argv[j],"-output"))
output = (char *)strdup(argv[++j]);
else
if (j<argc-1 && !strcmp(argv[j],"-spacing")) {
spacing = atoi(argv[++j]);
if (spacing<=0) spacing = 1;
} else
if (j<argc-1 && !strcmp(argv[j], "-format")) {
++j;
if (!strcasecmp(argv[j], "none")) format = NONE;
if (!strcasecmp(argv[j], "text")) format = TEXT;
if (!strcasecmp(argv[j], "rez")) format = REZ;
if (!strcasecmp(argv[j], "vmf")) format = VMF;
}
else
if (j<argc-1 && !strcmp(argv[j], "-ascii")) {
++j;
if (!strcmp(argv[j], "dxdy")) text_output_type = DX_DY;
if (!strcmp(argv[j], "int")) text_output_type = INT;
if (!strcmp(argv[j], "real")) text_output_type = REAL;
}
else
if (j<argc-1 && !strcmp(argv[j], "-continents")) {
++j;
list_cont = strdup(argv[j]);
}
else
if (j<argc-1 && !strcmp(argv[j], "-types")) {
++j;
list_types = strdup(argv[j]);
}
else
if (!strcmp(argv[j], "-verbose")) verbose = 1;
else
if (!strcmp(argv[j], "-silent")) verbose = 0;
else
usage();
}
if (!output) {
fprintf(stderr,
"No -output specified, using stdout as default\n\n");
fd = stdout;
} else
fd = fopen(output, "w");
numseg = 0;
maxlength = 0;
maxwidth = 0;
maxheight = 0;
if (!jpd_file) {
fprintf(stderr, "No input JPD file has been specified\n"
"Trying default %s\n\n", DEFAULT_JPD_FILE);
jpd_file = DEFAULT_JPD_FILE;
}
#ifdef ZLIB
ff = gzopen(jpd_file, "r");
if (!ff) {
fprintf(stderr, "Cannot open JPD file %s !!\n", jpd_file);
exit(-1);
}
#else
ff = open(jpd_file, O_RDONLY, 0);
if (ff==-1) {
fprintf(stderr, "Cannot open JPD file %s !!\n", jpd_file);
exit(-1);
}
#endif
header = (struct Header *) malloc(sizeof(struct Header));
#ifdef ZLIB
gzread(ff, header, sizeof(struct Header));
#else
read(ff, header, sizeof(struct Header));
#endif
if (strcmp(header->magic, 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; i<index2; i++) {
if (i)
address1 = str4toint(segment_index[i-1].address);
else
address1 = address0;
address2 = str4toint(segment_index[i].address);
nstrokes = (address2-address1-6)/2;
minlong = str3toint(segment_index[i].minlong);
maxlong = str3toint(segment_index[i].maxlong);
minlat = str3toint(segment_index[i].minlat);
maxlat = str3toint(segment_index[i].maxlat);
fpr4(fd, maxlat);
fpr4(fd, minlat);
fpr4(fd, maxlong);
fpr4(fd, minlong);
fpr4(fd, addr);
fpr4(fd, 1<<u);
fpr4(fd, 1<<rez_type[v]);
fpr4(fd, rez_rank[v][numf]);
addr += 12 + 8*nstrokes;
}
}
}
readseg = 0;
maxlength = 0;
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 (list_cont && !index(list_cont, '0'+cont)) continue;
if (list_types && !index(list_types, '0'+v)) continue;
if (u==0)
index1 = 0;
else
index1 = str4toint(&header->index[4*(u-1)]);
index2 = str4toint(&header->index[4*u]);
for (i=index1; i<index2; i++) {
if (i)
address1 = str4toint(segment_index[i-1].address);
else
address1 = address0;
address2 = str4toint(segment_index[i].address);
nstrokes = (address2-address1-6)/2;
minlong = str3toint(segment_index[i].minlong);
maxlong = str3toint(segment_index[i].maxlong);
minlat = str3toint(segment_index[i].minlat);
maxlat = str3toint(segment_index[i].maxlat);
if (format==TEXT) {
fprintf(fd, "<%d> %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<nstrokes; j++) {
/* iterate and draw all the appropriate points */
dx = (int)segment_buffer[6+2*j];
dy = (int)segment_buffer[7+2*j];
if (format==TEXT) {
if (text_output_type == DX_DY)
fprintf(fd, "%d %d\n", dx, dy);
else {
x += dx;
y += dy;
if (text_output_type == INT)
fprintf(fd, "%d %d\n", x, y);
else
fprintf(fd, "%4.6f %3.6f\n", x/3600.0, y/3600.0);
}
}
if (format==REZ) {
fpr4(fd, dx);
fpr4(fd, dy);
}
if (format==VMF) {
x += dx;
y += dy;
++countpt;
if (countpt%spacing==0 || j==nstrokes-1) {
if (printedpt%4==0)
fprintf(fd, "\n");
else
fprintf(fd, " ");
prascii(fd, x, y);
++printedpt;
}
}
}
if (format==VMF)
fprintf(fd, "\n;\n\n");
++readseg;
}
}
fclose(fd);
close(ff);
fprintf(stderr, "Read %d segments, max length = %d\n", readseg, maxlength);
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1