/**************************************************************************** * * MODULE: ps.map * AUTHOR(S): Paul W. Carlson 1992 (original contributor) * Radim Blazek * Bob Covill , Huidae Cho * , Glynn Clements , Hamish Bowman , Markus Neteler , * Alessandro Frigeri * PURPOSE: This is an enhanced PostScript version of the p.map program * COPYRIGHT: (C) 2003-2006 by the GRASS Development Team * * This program is free software under the GNU General Public * License (>=v2). Read the file COPYING that comes with GRASS * for details. * *****************************************************************************/ #define MAIN #include #include #include #include #include "map_info.h" #include "vector.h" #include "labels.h" #include "header.h" #include "comment.h" #include "colortable.h" #include "decorate.h" #include "ps_info.h" #include "group.h" #include "local_proto.h" FILE *tracefd; FILE *inputfd; int do_mapinfo; int do_vlegend; char *ps_mask_file; #define KEY(x) (strcmp(key,x)==0) static char *help[]= { "rast rastermap setcolor val_range(s) color", "vpoints vector points map scalebar [f|s]", "vlines vector lines map paper [a4|a3|us-letter|...]", "vareas vector areas map maploc x y [width height]", "labels labelfile text east north text", "region regionfile line east north east north", "grid spacing point east north", "geogrid spacing header", "outline mapinfo", "colortable [y|n] vlegend", "comments [unix-file] psfile PostScript include file", "read unix-file eps Encapsulated PostScript file", "verbose [0|1|2] rectangle east north east north", "scale 1:#|# inches|# panels|1 inch = # miles", "" }; int verbose; int rotate_plot; int eps_output; int ps_copies = 1; #include #include int main(int argc,char *argv[]) { char buf[1024]; char name[100], mapset[50]; int i; int iflag; int can_reset_scale ; int copies_set; struct Option *map_scale; struct Option *input_file; struct Option *output_file; struct Option *copies; struct Flag *rflag, *pflag, *eflag; struct GModule *module; static char *def_font = "Helvetica"; /**************** begin ******************************/ verbose = 2; signal (SIGINT, exit); signal (SIGTERM, exit); setbuf (stderr, NULL); G_gisinit(argv[0]) ; /* Set description */ module = G_define_module(); module->keywords = _("postscript, map, printing"); module->description = _("Hardcopy PostScript map output utility."); rflag = G_define_flag(); rflag->key = 'r'; rflag->description = _("Rotate plot 90 degrees"); pflag = G_define_flag(); pflag->key = 'p'; pflag->description = _("Print paper formats ( name width height left right top bottom(margin) )"); eflag = G_define_flag(); eflag->key = 'e'; eflag->description = _("Create EPS (Encapsulated PostScript) instead of PostScript file"); input_file = G_define_option(); input_file->key = "input"; input_file->type = TYPE_STRING; input_file->description = _("File containing mapping instructions (or use input=- to enter from keyboard)"); input_file->gisprompt = "old_file,file,input"; input_file->required = NO; output_file = G_define_option(); output_file->key = "output"; output_file->type = TYPE_STRING; output_file->description = _("PostScript output file"); output_file->required = NO; map_scale = G_define_option(); map_scale->key = "scale"; map_scale->key_desc = "mapscale"; map_scale->type = TYPE_STRING; map_scale->description = _("Scale of the output map, e.g. 1:25000 (default: Auto-sized to fit page)"); copies = G_define_option(); copies->key = "copies"; copies->type = TYPE_STRING; copies->description = _("Number of copies to print"); copies->required = NO; if (!isatty(0)) G_disable_interactive(); if (G_parser(argc, argv)) usage(0); /* Print papers */ if ( pflag->answer ) { print_papers(); exit(EXIT_SUCCESS); } rotate_plot = rflag->answer; eps_output = eflag->answer; /* set default paper */ set_paper ("a4" ); strcpy(buf,"black"); BLACK = get_color_number(buf); strcpy(buf, "white"); WHITE = get_color_number(buf); strcpy(buf, "grey"); GREY = get_color_number(buf); /* initialize */ vector_init(); copies_set = 0; m_info.x = m_info.y = -1.0; vector.x = vector.y = -1.0; ct.x = ct.y = -1.0; ct.width = -1.0; m_info.color = BLACK; m_info.bgcolor = WHITE; hdr.color = BLACK; cmt.color = BLACK; PS.grid_color = BLACK; m_info.font = G_store(def_font); vector.font = G_store(def_font); hdr.font = G_store(def_font); cmt.font = G_store(def_font); ct.font = G_store(def_font); m_info.fontsize = 10; vector.fontsize = 10; hdr.fontsize = 10; cmt.fontsize = 10; ct.fontsize = 10; ct.cols = 1; tracefd = NULL; inputfd = stdin; iflag = 0; labels.count = 0; labels.other = NULL; can_reset_scale = 1; hdr.fp = NULL; grp.do_group = 0; PS.grey = 0; PS.mask_needed = 0; PS.do_header = 0; PS.min_y = 72.0 * (PS.page_height - PS.top_marg); PS.set_y = 100.0 * PS.min_y; PS.startpanel = 0; PS.endpanel = 0; PS.cell_fd = -1; PS.do_outline = 0; PS.do_colortable = 0; PS.do_scalebar = 0; PS.grid = 0; PS.scaletext[0] = 0; PS.celltitle[0] = 0; PS.commentfile = NULL; PS.num_psfiles = 0; PS.mask_color = 0; /* PS.map_* variables are set to 0 (not defined) and then may be reset by 'maploc'. * When script is read, main() should call reset_map_location() to reset map size to fit to paper */ PS.map_width = 0; PS.map_height = 0; PS.map_x_orig = 0; PS.map_y_orig = 0; PS.map_y_loc = 0; /* arguments */ if (input_file->answer && strcmp (input_file->answer, "-")) { if (NULL == freopen(input_file->answer, "r", stdin)) { fprintf(stderr, "%s - ", G_program_name()); perror(input_file->answer); exit(EXIT_FAILURE); } } if (map_scale->answer) { G_warning(_("Using \"scale\" from the command line is depreciated. " "Please use the \"scale\" mapping instruction instead.")); can_reset_scale = isatty(0); if (check_scale(map_scale->answer)) strcpy(PS.scaletext, map_scale->answer); else error(map_scale->answer, "", "illegal scale request"); } if (copies->answer) { if (sscanf(copies->answer, "%d", &ps_copies) != 1 || ps_copies < 1 || ps_copies > 20) { ps_copies = 1; error(copies->answer, "", "illegal copies request"); } copies_set = 1; } if (output_file->answer) { if ((PS.fp = fopen(output_file->answer, "w")) == NULL) { fprintf(stderr, "%s - ", G_program_name()); perror(output_file->answer); exit(EXIT_FAILURE); } } else usage(1); /* get current mapset */ PS.cell_mapset = G_mapset(); /* set current window */ G_get_set_window(&PS.w); if (G_set_window(&PS.w) == -1) G_fatal_error(_("Current region cannot be set.")); while (1) { char *key; char *data; if (!input(1, buf, help)) { if (!iflag) { if(G_getl2(buf, 12, inputfd)) G_warning(_("Data exists after final 'end' instruction!")); break; } iflag = 0; continue; } if (!key_data(buf, &key, &data)) continue ; if (KEY("read")) { if (inputfd != stdin) fclose(inputfd); if (sscanf(data, "%s", name) != 1) { error(key, data, "no file specified"); inputfd = stdin; } else if ((inputfd = fopen(name, "r")) == NULL) { error(key, data, "unable to open"); inputfd = stdin; } else iflag = 1; continue; } if (KEY("verbose")) { if (sscanf(data, "%d", &verbose) != 1) verbose = 2; continue; } if (KEY("paper")) { if ( strlen (data) > 0 ) { set_paper ( data ); } read_paper (); continue; } if (KEY("maploc")) { int n; double x, y, w, h; n = sscanf(data, "%lf %lf %lf %lf", &x, &y, &w, &h); if ( n == 2 || n ==4 ) { PS.map_x_orig = x; PS.map_y_loc = y; if ( n == 4) { PS.map_width = w; PS.map_height = h; } } else { error(key, data, "illegal maploc request"); gobble_input(); } continue; } if (KEY("copies")) { int n, copies; if (copies_set) continue; n = sscanf(data, "%d", &copies); if (n != 1 || copies < 1 || copies > 20) { ps_copies = 1; error(key, data, "illegal copies request"); } ps_copies = copies; continue; } if (KEY("setcolor")) { float R,G,B; int r,g,b; int color; int count; DCELL *val_list; DCELL dmin,dmax; char colorbuf[100]; char catsbuf[100]; if (PS.cell_fd < 0) { error (key,data,"no raster file selected yet"); continue; } if (sscanf (data, "%s %[^\n]", catsbuf, colorbuf) == 2) { color = get_color_number(colorbuf); if (color < 0) { error(key, data, "illegal color"); continue; } get_color_rgb(color, &R, &G, &B); r= 255.0 * R; g = 255.0 * G; b = 255.0 * B; if(strncmp(catsbuf, "null", 4)== 0) { G_set_null_value_color(r,g,b,&PS.colors); continue; } if(strncmp(catsbuf, "default", 7)== 0) { G_set_default_color(r,g,b,&PS.colors); continue; } if ((count = parse_val_list (catsbuf, &val_list)) < 0) { error (key,data,"illegal value list"); continue; } for (i = 0; i < count; i += 2) { dmin = val_list[i]; dmax = val_list[i+1]; G_add_d_raster_color_rule (&dmin, r,g,b, &dmax,r,g,b, &PS.colors); } G_free (val_list); } continue; } if (KEY("colortable")) { PS.do_colortable = 0; /* if (PS.cell_fd < 0) error(key, data, "no raster file selected yet"); else */ PS.do_colortable = yesno(key, data); if (PS.do_colortable) read_colortable(); continue; } if (KEY("scalebar")) { PS.do_scalebar = 1; if (sscanf(data, "%s", sb.type) != 1) strcpy (sb.type, "f"); /* default to fancy scalebar */ read_scalebar(); if (sb.length <= 0.) { error(key, data, "Bad scalebar length"); gobble_input(); } continue; } if (KEY("text")) { double e, n; char east[50], north[50]; char text[1024]; if (sscanf(data, "%s %s %[^\n]", east, north, text) == 3 && (scan_easting(east, &e) && scan_northing(north, &n))) read_text(east, north, text); else { gobble_input(); error(key, data, "illegal text request"); } continue; } if (KEY("point")) { double e, n; char east[50], north[50]; if (sscanf(data, "%s %s", east, north) == 2 && (scan_easting(east, &e) && scan_northing(north, &n))) read_point(e, n); else { gobble_input(); error(key, data, "illegal point request"); } continue; } if (KEY("eps")) { double e, n; char east[50], north[50]; if (sscanf(data, "%s %s", east, north) == 2 && (scan_easting(east, &e) && scan_northing(north, &n))) read_eps(e, n); else { gobble_input(); error(key, data, "illegal eps request"); } continue; } if (KEY("line")) { char east1[50], north1[50]; char east2[50], north2[50]; double e1, n1, e2, n2; if (sscanf(data, "%s %s %s %s", east1, north1, east2, north2) == 4 && (scan_easting(east1, &e1) && scan_easting(east2, &e2) && scan_northing(north1, &n1) && scan_northing(north2, &n2))) read_line(e1, n1, e2, n2); else { gobble_input(); error(key, data, "illegal line request"); } continue; } if (KEY("rectangle")) { char east1[50], north1[50]; char east2[50], north2[50]; double e1, n1, e2, n2; if (sscanf(data, "%s %s %s %s", east1, north1, east2, north2) == 4 && (scan_easting(east1, &e1) && scan_easting(east2, &e2) && scan_northing(north1, &n1) && scan_northing(north2, &n2))) read_rectangle(e1, n1, e2, n2); else { gobble_input(); error(key, data, "illegal rectangle request"); } continue; } if (KEY("comments")) { switch (sscanf(data, "%s %s", name, mapset)) { case 1: read_comment(name); break; case 2: error(key, data, "illegal comments request"); break; default: read_comment(""); break; } continue; } if (KEY("scale")) { if (!can_reset_scale) continue; if (check_scale(data)) strcpy(PS.scaletext, data); else { PS.scaletext[0] = 0; error(key, data, "illegal scale request"); } continue; } if (KEY("labels")) { if (scan_gis("paint/labels", "label", key, data, name, mapset, 1)) read_labels(name, mapset); continue; } if (KEY("header")) { read_header(); PS.do_header = 1; continue; } if (KEY("mapinfo")) { read_info(); do_mapinfo = 1; continue; } if (KEY("vlegend")) { read_vlegend(); do_vlegend = 1; continue; } if (KEY("outline")) { if (PS.cell_fd < 0) { error(key, data, "no raster file selected yet"); gobble_input(); } else read_outline(); continue; } if (KEY("cell") || KEY("rast") || KEY("raster")) { if (scan_gis("cell", "raster", key, data, name, mapset, 0)) read_cell(name, mapset); continue; } if (KEY("greyrast") || KEY("grayrast")) { if (scan_gis("cell", "raster", key, data, name, mapset, 0)) read_cell(name, mapset); PS.grey = 1; continue; } if (KEY("group")) { G_strip(data); if (I_find_group(data)) { grp.group_name = G_store(data); grp.do_group = 1; read_group(); } else error(key, data, "group not found"); continue; } if (KEY("rgb")) { G_strip(data); grp.do_group = 1; read_rgb(key, data); continue; } if (KEY("vpoints")) { if (scan_gis("vector", "vector", key, data, name, mapset, 1)) read_vpoints(name, mapset); continue; } if (KEY("vlines") ) { if (scan_gis("vector", "vector", key, data, name, mapset, 1)) read_vlines(name, mapset); continue; } if (KEY("vareas") ) { if (scan_gis("vector", "vector", key, data, name, mapset, 1)) read_vareas(name, mapset); continue; } if (KEY ("window") || KEY("region")) { if (scan_gis("windows", "region definition", key, data, name, mapset, 1)) read_wind(name, mapset); continue; } if (KEY("grid")) { PS.grid = -1; PS.grid_numbers = 0; sscanf(data, "%d", &PS.grid); if (PS.grid < 0) { PS.grid = 0; error(key, data, "illegal grid spacing"); gobble_input(); } else getgrid(); continue; } if (KEY("geogrid")) { if (G_projection() == PROJECTION_LL || G_projection() == PROJECTION_XY) { error(key, data, "geogrid is not available for this projection"); gobble_input(); } PS.geogrid = -1.; PS.geogrid_numbers = 0; sscanf(data, "%d %s", &PS.geogrid, PS.geogridunit); if (PS.geogrid < 0) { PS.geogrid = 0; error(key, data, "illegal geo-grid spacing"); gobble_input(); } else getgeogrid(); continue; } if (KEY("psfile")) { if (PS.num_psfiles >= MAX_PSFILES) continue; G_strip(data); PS.psfiles[PS.num_psfiles] = G_store(data); PS.num_psfiles++; continue; } if (KEY("maskcolor")) { int ret, r, g, b; ret = G_str_to_color( data, &r, &g, &b); if ( ret == 1 ) { PS.mask_r = r / 255.0; PS.mask_g = g / 255.0; PS.mask_b = b / 255.0; PS.mask_color = 1; continue; } else if ( ret == 2 ) { /* none */ continue; } else { error (key,data,"illegal color request"); } } if (*key) error(key,"","illegal request"); } /* reset map location base on 'paper' on 'location' */ reset_map_location ( ); /* write the PostScript output file */ ps_mask_file = G_tempfile(); ps_map(); if (verbose > 1) { fprintf (stdout,"PS-PAINT: PostScript file \"%s\" successfully written.\n", output_file->answer); fflush(stdout); } unlink (ps_mask_file); exit(EXIT_SUCCESS); } int usage (int full) { if (full) G_usage(); exit(EXIT_FAILURE); }