#include #include #include #include #include #include "local_proto.h" /* ********************************************************************** * * MODULE: r.support (GRASS core) * * AUTHOR(S): Original by Michael Shapiro - CERL * Preliminary parser support by Markus Neteler * Port to 6.x by Brad Douglas * * PURPOSE: Build support files for raster map * - Edit header * - Update status (histogram, range) * * COPYRIGHT: (C) 2000-2005 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. * **********************************************************************/ /* two less than lib/gis/put_title.c G_put_cell_title() if only one less a newline gets appended in the cats file. bug? */ #define MAX_TITLE_LEN 1022 int main(int argc, char *argv[]) { char *rname = NULL; /* Reclassed map name */ char *rmapset = NULL; /* Reclassed mapset */ char *mapset; /* Raster mapset */ struct Cell_head cellhd; struct GModule *module; struct Option *raster, *title_opt, *history_opt; char element[255]; char buf[512]; int cellhd_ok; /* Is cell header OK? */ int is_reclass; /* Is raster reclass? */ char *infile; char title[MAX_TITLE_LEN+1]; struct History hist; /* Initialize GIS engine */ G_gisinit(argv[0]); module = G_define_module(); module->keywords = _("raster"); module->description = _("Allows creation and/or modification of " "raster map layer support files."); raster = G_define_standard_option(G_OPT_R_INPUT); raster->key = "map"; raster->required = YES; title_opt = G_define_option(); title_opt->key = "title"; title_opt->key_desc = "\"phrase\""; title_opt->type = TYPE_STRING; title_opt->required = NO; title_opt->description = _("Text to use for new map title"); history_opt = G_define_option(); history_opt->key = "history"; history_opt->key_desc = "\"phrase\""; history_opt->type = TYPE_STRING; history_opt->required = NO; history_opt->description = _("Text to append to the next line of the map's metadata file"); /* Parse command-line options */ if (G_parser(argc,argv)) exit(EXIT_FAILURE); /* Make sure raster exists and set mapset */ infile = raster->answer; mapset = G_find_cell2(infile, ""); if (mapset == NULL) G_fatal_error(_("Unable to find [%s]."), infile); cellhd_ok = (G_get_cellhd(raster->answer, mapset, &cellhd) >= 0); is_reclass = (G_is_reclass(raster->answer, mapset, rname, rmapset) > 0); if(title_opt->answer) { strncpy(title, title_opt->answer, MAX_TITLE_LEN); title[MAX_TITLE_LEN] = '\0'; /* strncpy doesn't null terminate oversized input */ G_strip(title); G_debug(3, "map title= [%s] (%d chars)", title, strlen(title)); G_put_cell_title(raster->answer, title); if(! history_opt->answer) exit(EXIT_SUCCESS); } if(history_opt->answer) { G_read_history (raster->answer, mapset, &hist); if(hist.edlinecnt >= MAXEDLINES) G_fatal_error(_("Not enough room in history file.")); /* two less than defined as if only one less a newline gets appended in the hist file. bug? */ if(strlen(history_opt->answer) > RECORD_LEN -2) G_warning(_("History line too long: truncating to %d characters"), RECORD_LEN-2); strncpy(hist.edhist[hist.edlinecnt], history_opt->answer, RECORD_LEN-2); /* strncpy doesn't null terminate oversized input */ hist.edhist[hist.edlinecnt][RECORD_LEN-2] = '\0'; G_debug(4, "new history line= [%s] (%d chars)", hist.edhist[hist.edlinecnt], strlen(hist.edhist[hist.edlinecnt]) ); hist.edlinecnt++; G_write_history(raster->answer, &hist); exit(EXIT_SUCCESS); } /* Cell header */ sprintf(buf, _("Edit header for [%s]? "), raster->answer); if (is_reclass) { G_message(_("\nNOTE: [%s] is a reclass of [%s in %s]"), raster->answer, rname, rmapset); } else if (G_yes(buf, cellhd_ok ? 0 : 1)) { G_clear_screen(); run_etc_support("modhead", G_fully_qualified_name(raster->answer, mapset)); if ((cellhd_ok = G_get_cellhd(raster->answer, mapset, &cellhd) > 0)) { hitreturn(); G_clear_screen(); } else if (!cellhd_ok) G_fatal_error(_("Canceling from edit header.")); } /* Check the histogram and range */ check_stats(raster->answer, mapset); /* Category file */ sprintf(buf, _("Edit the category file for [%s]? "), raster->answer); if (G_yes(buf, 0)) { G_clear_screen(); run_etc_support("modcats", G_fully_qualified_name(raster->answer, mapset)); hitreturn(); G_clear_screen(); } /* Color table */ sprintf(buf, _("Create/Update the color table for [%s]? "), raster->answer); if (G_yes(buf, 0)) { G_clear_screen(); run_etc_support("modcolr", G_fully_qualified_name(raster->answer, mapset)); hitreturn(); G_clear_screen(); } /* History file */ sprintf(buf, _("Edit the history file for [%s]? "), raster->answer); if (G_yes(buf, 0)) { G_clear_screen(); run_etc_support("modhist", G_fully_qualified_name(raster->answer, mapset)); hitreturn(); G_clear_screen(); } /* null file */ G_message(_("\nThe null file for [%s] may indicate that some " "cells contain\n no data. If the null file for [%s] " "doesn't exist, zero cells in\n it are treated by " "GRASS application programs as no data."), raster->answer, raster->answer); sprintf(buf, _("\nDo you want to create/reset the null file " "for [%s] so that null cell values are considered valid data? "), raster->answer); if (G_yes(buf, 0)) { unsigned char *null_bits; int row, col; int null_fd; if (is_reclass) G_fatal_error(_("[%s] is a reclass of another map. Exiting."), raster->answer); G_clear_screen(); /* Create a file of no-nulls */ null_bits = G__allocate_null_bits(cellhd.cols); for (col = 0; col < G__null_bitstream_size(cellhd.cols); col++) null_bits[col] = 0; /* Open null file for writing */ sprintf(element, "cell_misc/%s", raster->answer); null_fd = G_open_new(element, "null"); G_message(_("Writing new null file for [%s]... "), raster->answer); for (row = 0; row < cellhd.rows; row++) { G_percent(row, cellhd.rows, 1); if (G__write_null_bits(null_fd, null_bits, row, cellhd.cols, 0) < 0) G_fatal_error(_("Error writing null row [%d]."), row); } G_percent(row, cellhd.rows, 1); /* Cleanup */ close(null_fd); G_free(null_bits); hitreturn(); G_clear_screen(); } sprintf(buf, _("\nDo you want to delete the null file for [%s]\n" "(all zero cells will then be considered no data)? "), raster->answer); if (G_yes(buf, 0)) { int null_fd; char path[400]; if (is_reclass) G_fatal_error(_("[%s] is a reclass of another map. Exiting."), raster->answer); G_clear_screen(); /* Write a file of no-nulls */ G_message(_("Removing null file for [%s]...\n"), raster->answer); G_snprintf(element, sizeof(element), "cell_misc/%s", raster->answer); null_fd = G_open_new(element, "null"); G__file_name(path, element, "null", mapset); unlink(path); close(null_fd); G_done_msg(_("Done.")); } return EXIT_SUCCESS; }