📄 coverage_vis.c
字号:
/* ***************************************************** * * SaVi by Robert Thurman (thurman@geom.umn.edu) and * Patrick Worfolk (worfolk@alum.mit.edu). * * Copyright (c) 1997 by The Geometry Center. * This file is part of SaVi. SaVi is free software; * you can redistribute it and/or modify it only under * the terms given in the file COPYRIGHT which you should * have received along with this file. SaVi may be * obtained from: * http://savi.sourceforge.net/ * http://www.geom.uiuc.edu/locate/SaVi * ***************************************************** * * coverage_vis.c * * Coverage visualization routines. * * $Id: coverage_vis.c,v 1.57 2005/02/08 03:30:39 lloydwood Exp $ */#include <math.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <tk.h>#ifndef NO_ZLIB#include <zlib.h>#endif /* NO_ZLIB */#include "constants.h"#include "globals.h"#include "gv_file.h"#include "gv_utils.h"#include "orbit_utils.h"#include "savi.h"#include "stats_utils.h"#include "coverage_vis.h"extern Tcl_Interp *interp; /* Interpreter for this application. */extern int tcl_script(char[]);extern int no_access_flag;extern int map_flag;extern unsigned int geomview_flag;extern unsigned int earth_on_flag;extern unsigned int earth_geom_exists;extern unsigned int use_fancy_earth;extern unsigned int given_temp_scratchfile;static int current_proj = -1; /* whatever the default, we start by drawing */static char imagename[] = "im_coverage";static const char format1[] = "set coverage \"Current global coverage: %.1f%%\"";static const char format2[] = "set mean_coverage \"Averaged global coverage: %.1f%%\"";static void write_image_as_ppm(FILE *f);#define LENGTH_APPEARANCE_FILE 1024#define LENGTH_TEMPFILE_NAME 256#define LENGTH_LINE 128static char dynamic_description[LENGTH_APPEARANCE_FILE];static char static_description[LENGTH_APPEARANCE_FILE];static char temp_scratchfile[LENGTH_TEMPFILE_NAME];static void append_file_suffix(char * filename);static char * append_string(char * string, const char * add);#ifndef NO_ZLIB/* used only in this file */static void write_image_as_ppm_gz(gzFile *f);static void write_image_to_file_gz(char *name);#endif /* NO_ZLIB */static void set_coverage(int projection, grid *g);static void grid_and_foreground_to_image(int projection, grid * g, int fgOnly);static int new_foreground(int projection, grid * g, unsigned int force);static void draw_sin_map_edges(grid * g);static Tk_PhotoImageBlock *get_image(void);static void overlay_bitmap(unsigned int h, unsigned int w, unsigned char *b, const char *filename);static void latlon_to_grid_index(int grid_index[2], LatLon * pl, int projection, grid * g);static Tk_PhotoImageBlock *image = NULL;static unsigned char *foreground = NULL;#define PIXELSIZE 3 /* 3 for RGB */typedef struct RGB { unsigned char red, green, blue;} RGB;/* Colors for coverage intensity (in RGB values) *//* Any number of colors may be inserted. */static unsigned char colors[] = { 255, 255, 255, /* no coverage */ 255, 255, 0, /* single coverage */ 255, 170, 0, /* double coverage */ 255, 85, 0, /* triple coverage */ 255, 0, 0 /* four or more */};#define num_colors sizeof(colors)/sizeof(unsigned char)/PIXELSIZE/* Color for earth outline and ground track */static unsigned char outline_colors[] = { 160, 192, 240, /* background */ 0, 0, 0, /* earth outline */ 0, 255, 0, /* projected ground track */ 255, 0, 255, /* selected ground track */ 0, 255, 0, /* satellite position */ 0, 255, 0, /* rest of cross */ 255, 0, 255, /* selected satellite */ 255, 0, 255 /* rest of cross */};#define num_outline_colors sizeof(outline_colors)/sizeof(unsigned char)/PIXELSIZE/* Color for noaccess */static unsigned char noaccess_colors[] = { 255, 255, 255, /* no intervals missed */ 0, 0, 255, /* one interval missed */ 0, 0, 217, /* two intervals missed */ 0, 0, 180, /* three intervals missed */ 0, 0, 143 /* >three intervals missed */};#define num_noaccess_colors sizeof(noaccess_colors)/sizeof(unsigned char)/PIXELSIZEstatic unsigned char * COLDIV = &colors[0];static unsigned char * COLDEC = &noaccess_colors[0];/* * color_hex - turn combined RRGGBB byte into three RGB bytes. */static voidcolor_hex(int combined, RGB * color_set) { unsigned int rrggbb = (unsigned int) combined; color_set->blue = rrggbb & 0x0000FF; rrggbb = rrggbb >> 8; color_set->green = rrggbb & 0x0000FF; rrggbb = rrggbb >> 8; color_set->red = rrggbb & 0x0000FF;}/* * coverage_color_copy - slave color arrays to Tcl values */voidcoverage_color_copy(void){ color_hex(DIV1, (RGB *) &COLDIV[3]); color_hex(DIV2, (RGB *) &COLDIV[6]); color_hex(DIV3, (RGB *) &COLDIV[9]); color_hex(DIV4, (RGB *) &COLDIV[12]); color_hex(DEC1, (RGB *) &COLDEC[3]); color_hex(DEC2, (RGB *) &COLDEC[6]); color_hex(DEC3, (RGB *) &COLDEC[9]); color_hex(DEC4, (RGB *) &COLDEC[12]);}intcoverage_uses_zlib(void) {#ifndef NO_ZLIB return TRUE;#else return FALSE;#endif /* NO_ZLIB */}/* * image_init - Set up the Tk image structure based on the coverage grid. */voidimage_init(grid * g){ unsigned int height, width, image_size; height = g->height; width = g->width; image_size = height * width; image = (Tk_PhotoImageBlock *) malloc(sizeof(Tk_PhotoImageBlock)); image->pixelPtr = (unsigned char *) malloc(image_size * PIXELSIZE * sizeof(unsigned char *)); image->width = width; image->height = height; image->pitch = width * PIXELSIZE; image->pixelSize = PIXELSIZE; image->offset[0] = 0; image->offset[1] = 1; image->offset[2] = 2; if (!foreground) { foreground = (unsigned char *) malloc(image_size * sizeof(unsigned char *)); cyl_foreground = (unsigned char *) calloc(sizeof(unsigned char *), image_size); sin_foreground = (unsigned char *) calloc(sizeof(unsigned char *), image_size); unp_foreground = (unsigned char *) calloc(sizeof(unsigned char *), image_size); sph_foreground = (unsigned char *) calloc(sizeof(unsigned char *), image_size); if (width == IMAGE_LARGE_WIDTH) { overlay_bitmap(height, width, cyl_foreground, CYLINDRICAL_LARGE_BITMAP_NAME); overlay_bitmap(height, width, sin_foreground, SINUSOIDAL_LARGE_BITMAP_NAME); overlay_bitmap(height, width, unp_foreground, UNPROJECTED_LARGE_BITMAP_NAME); /* spherical map needs to be added here. */ } else if (width == IMAGE_WIDTH) { overlay_bitmap(height, width, cyl_foreground, CYLINDRICAL_BITMAP_NAME); overlay_bitmap(height, width, sin_foreground, SINUSOIDAL_BITMAP_NAME); overlay_bitmap(height, width, unp_foreground, UNPROJECTED_BITMAP_NAME); /* large spherical map needs to be added here. */ } else { error("no appropriately-sized background map for coverage window."); } draw_sin_map_edges(g); }}static voidwrite_image_as_ppm(FILE *f){ unsigned int w, h, length; unsigned char *p; /* this was grid g->width, but for temporary convenience... */ w = Image_Width; h = Image_Height; /* * Write header file describing grid */ fprintf(f,"P6\n%i %i\n255\n", w, h); p = image->pixelPtr; length = w * h * PIXELSIZE; fwrite(p, sizeof(unsigned char), length, f);}voidwrite_image_to_file(char * name){ FILE *f; if (NULL == (f = fopen(name, "w"))) { fprintf(stderr,"unable to save coverage map to %s", name); return; } write_image_as_ppm(f); fclose(f);}#ifndef NO_ZLIB/* function requires zlib */static voidwrite_image_as_ppm_gz(gzFile *f){ unsigned int w, h, length; unsigned char *p; /* this was grid g->width, but for temporary convenience... */ w = Image_Width; h = Image_Height; /* * Write header file describing grid */ gzprintf(f,"P6\n%i %i\n255\n", w, h); length = w * h * PIXELSIZE * sizeof(unsigned char); p = image->pixelPtr; gzwrite(f, p, length);}/* function requires zlib */static voidwrite_image_to_file_gz(char * name){ gzFile *f; if (NULL == (f = gzopen(name, "w"))) { fprintf(stderr,"unable to save compressed coverage map to %s", name); return; } gzsetparams(name, Z_BEST_COMPRESSION, Z_RLE); /* Z_RLE for PNG-style data */ write_image_as_ppm_gz(f); gzclose(f);}#endif /* NO_ZLIB */static voidappend_file_suffix(char * filename) { char * string; string = filename + strlen(filename); if (coverage_uses_zlib()) { strcpy(string,"-savi.ppm.gz"); } else { strcpy(string,"-savi.ppm"); }}static char *append_string(char * string, const char * add){ strcpy(string, add); return(string + strlen(add));}intcoverage_tempfile_created(void){ char line[LENGTH_LINE]; const char name[] = "oogl/earth.oogl"; const char fallback_tmpnam[] = "coverage"; const char static_name[] = "oogl/Earth.ppm.Z"; const char file_separator[] = "/"; const char file_start[] = "file \""; const char file_end[] = "\"\n"; char *dynamic_description_end, *static_description_end, *string, *path; const char null_char = 0; const char tab_char = 9; const char space_char = 32; const char comment_char = 35; /* # */ unsigned int replaced = 0; unsigned int add_static_length = 0; unsigned int add_dynamic_length = 0; unsigned int incr_length; FILE *f, *g; if (NULL == (f = fopen(name, "r"))) { fprintf(stderr,"unable to open texturemap description %s", name); return(FALSE); } string = tmpnam(NULL); strcpy(temp_scratchfile, string); append_file_suffix(temp_scratchfile); if (NULL == (g = fopen(temp_scratchfile, "wb+"))) { fprintf(stderr,"SaVi couldn't open assigned tempfile %s\n", temp_scratchfile); path = getenv("HOME"); if (!path) { error("couldn't learn home directory $HOME for fallback scratchfile"); return(FALSE); } if (strlen(path) > LENGTH_TEMPFILE_NAME - 16) { error("pathname of home directory $HOME too long to store."); return(FALSE); } string = append_string(temp_scratchfile, path); string = append_string(string, file_separator); string = append_string(string, fallback_tmpnam); append_file_suffix(temp_scratchfile); if (NULL == (g = fopen(temp_scratchfile, "wb+"))) { fprintf(stderr,"SaVi couldn't open fallback tempfile %s", temp_scratchfile); return(FALSE); } } fclose(g); fprintf(stderr,"SaVi: temporary texturemap scratchfile is %s\n", temp_scratchfile); if (!coverage_uses_zlib()) { error("texturemaps will be uncompressed. Compile SaVi with zlib for compressed."); } if (!coverage_large_map) { error("dynamic texture mapping will benefit from large coverage map (-large-map)."); } dynamic_description_end = dynamic_description; static_description_end = static_description; while (fgets(line,100,f) != NULL) { string = line; while ((*string == space_char) || (*string == tab_char)) { /* skip leading whitespace */ string++; } if ((*string == comment_char) || (string == null_char)) { /* skip comments and empty lines */ continue; } if (strstr(string,"Earth.ppm.Z")) { /* replace with our file line */ incr_length = strlen(file_start) + strlen(temp_scratchfile) + strlen(file_end); add_dynamic_length += incr_length; path=getenv("SAVI"); incr_length = strlen(file_start) + strlen(path) + strlen(file_separator) + strlen(static_name) + strlen(file_end); add_static_length += incr_length; if ((add_dynamic_length > LENGTH_APPEARANCE_FILE) || (add_static_length > LENGTH_APPEARANCE_FILE)) { fprintf(stderr, "Tempfile pathname %s is too long to cache.", temp_scratchfile); return(FALSE); } dynamic_description_end = append_string(dynamic_description_end, file_start); dynamic_description_end = append_string(dynamic_description_end, temp_scratchfile); dynamic_description_end = append_string(dynamic_description_end, file_end); static_description_end = append_string(static_description_end, file_start); static_description_end = append_string(static_description_end, path); static_description_end = append_string(static_description_end, file_separator); static_description_end = append_string(static_description_end, static_name); static_description_end = append_string(static_description_end, file_end); replaced++; continue; } incr_length = strlen(string); add_dynamic_length += incr_length; add_static_length += incr_length; if ((add_static_length > LENGTH_APPEARANCE_FILE) || (add_dynamic_length > LENGTH_APPEARANCE_FILE)) { fprintf(stderr, "Earth appearance in %s is too long to cache.", name); return(FALSE); } dynamic_description_end = append_string(dynamic_description_end, string); static_description_end = append_string(static_description_end, string); } if (!replaced) { fprintf(stderr, "SaVi: did not find file \"Earth.ppm.Z\" in %s to replace with temp file location.", name); } else if (replaced > 1) { fprintf(stderr, "SaVi: found multiple instances of file \"Earth.ppm.Z\" in %s. Problems?", name); } return(TRUE);}voidcoverage_tempfile_cleanup(void) { if (given_temp_scratchfile) { remove(temp_scratchfile); fprintf(stderr, "SaVi: cleaned up temporary scratchfile %s\n", temp_scratchfile); }}voidreset_foreground(int projection, grid * g){ if (foreground) new_foreground(projection, g, TRUE);}/* * get_image - Return pointer to the image structure. */static Tk_PhotoImageBlock *get_image(void){ if (!image) { error("get_image: image not yet initialized."); } return image;}/* * update_display - Update the Tk coverage image, given a completed coverage grid. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -