Logo Search packages:      
Sourcecode: xastir version File versions

map_dos.c

/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*-
 * $Id: map_dos.c,v 1.13 2004/09/18 20:25:47 we7u Exp $
 *
 * XASTIR, Amateur Station Tracking and Information Reporting
 * Copyright (C) 1999,2000  Frank Giannandrea
 * Copyright (C) 2000-2004  The Xastir Group
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * Look at the README for more information on the program.
 */

#include "config.h"
#include "snprintf.h"

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <ctype.h>
#include <sys/types.h>
#include <pwd.h>
#include <errno.h>

// Needed for Solaris
#include <strings.h>

#include <dirent.h>
#include <netinet/in.h>
#include <Xm/XmAll.h>

#ifdef HAVE_X11_XPM_H
#include <X11/xpm.h>
#ifdef HAVE_LIBXPM // if we have both, prefer the extra library
#undef HAVE_XM_XPMI_H
#endif // HAVE_LIBXPM
#endif // HAVE_X11_XPM_H

#ifdef HAVE_XM_XPMI_H
#include <Xm/XpmI.h>
#endif // HAVE_XM_XPMI_H

#include <X11/Xlib.h>

#include <math.h>

#include "xastir.h"
#include "maps.h"
#include "alert.h"
#include "util.h"
#include "main.h"
#include "datum.h"
#include "draw_symbols.h"
#include "rotated.h"
#include "color.h"
#include "xa_config.h"

#define CHECKMALLOC(m)  if (!m) { fprintf(stderr, "***** Malloc Failed *****\n"); exit(0); }

#define DOS_HDR_LINES 8
#define GRID_MORE 5000

extern int npoints;           /* tsk tsk tsk -- globals */
extern int mag;

/* MAP pointers */

static map_vectors *map_vectors_ptr;
static text_label *map_text_label_ptr;
static symbol_label *map_symbol_label_ptr;

/* MAP counters */

//static long vectors_num;
//static long text_label_num;
//static long object_label_num;




/**********************************************************
 * map_plot()
 *
 * Plots vectors on the map.  If "color" is non-zero,
 * then it draws filled polygons in the color of
 * "object_behavior"?  Weird.
 **********************************************************/
void map_plot (Widget w, long max_x, long max_y, long x_long_cord,
        long y_lat_cord, unsigned char color, long object_behavior,
        int destination_pixmap, int draw_filled) {

    static int redraw_check;
    static XPoint points[MAX_MAP_POINTS];
    static unsigned char last_color = (unsigned char)0;
    static unsigned char last_behavior = (unsigned char)0, first_behavior = (unsigned char)0;
    long x, y;
    int draw_ok;
    unsigned char line_behavior, fill_color;
    char warning[200];

    /* don't ever go over MAX_MAP_POINTS have a bad map not a crashed program */
    if (npoints > MAX_MAP_POINTS) {
        xastir_snprintf(warning, sizeof(warning), "Warning line point count overflow: map_plot\b\n");
        XtAppWarning (app_context, warning);
        npoints = MAX_MAP_POINTS;
    }

    /* if map_color_levels are on see if we should draw the line? */
    draw_ok = 0;
    if (map_color_levels)   // Decide which colors to display at this zoom level
        switch (color) {
            case (0x01):
            case (0x14):
            case (0x18):
                if (mag < 100)
                    draw_ok = 1;
                break;
            case (0x15):
            case (0x19):
                if (mag < 600)
                    draw_ok = 1;
                break;
            case (0x16):
                if (mag < 800)
                    draw_ok = 1;
                break;
            default:
                draw_ok = 1;
                break;
        }
    else    // Display all colors
        draw_ok = 1;

    if (draw_ok) {
        x = ((x_long_cord - x_long_offset) / scale_x);
        y = ((y_lat_cord  - y_lat_offset)  / scale_y);
        if (x < -MAX_OUTBOUND)
            x = -MAX_OUTBOUND;

        if (y < -MAX_OUTBOUND)
            y = -MAX_OUTBOUND;

        if (x > max_x)
            x = max_x;

        if (y > max_y)
            y = max_y;

        if (debug_level & 16)
            fprintf(stderr," MAP Plot - max_x: %ld, max_y: %ld, x: %ld, y: %ld, color: %d, behavior: %lx, points: %d\n",
                    max_x, max_y, x, y, (int)color, (unsigned long)object_behavior, npoints);

        if ( (last_color != color) || (color == (unsigned char)0xff) ) {
            if (npoints && (last_color != (unsigned char)0xff) ) {
                line_behavior = last_behavior;
                if (last_behavior & 0x80) {
                    if (color) {
                        fill_color = (last_behavior & ~0x80) + (unsigned char)0x60;
                        if (fill_color > (unsigned char)0x69)
                            fill_color = (unsigned char)0x60;
                    } else
                        fill_color = (unsigned char)object_behavior;


                    // Here's where we draw filled areas using fill_color.

                    (void)XSetForeground (XtDisplay (w), gc, colors[(int)fill_color]);

                    switch (destination_pixmap) {

                    case DRAW_TO_PIXMAP:
                        // We must be drawing maps 'cuz this is the pixmap we use for it.
                        if (map_color_fill && draw_filled) {

                            if (npoints >= 3) {
                                (void)XFillPolygon(XtDisplay(w),
                                    pixmap,
                                    gc,
                                    points,
                                    npoints,
                                    Nonconvex,
                                    CoordModeOrigin);
                            }
                            else {
//                                fprintf(stderr,
//                                    "map_plot:Too few points:%d, Skipping XFillPolygon()",
//                                    npoints);
                            }
                        }
                        break;

                    case DRAW_TO_PIXMAP_ALERTS:
                        fprintf(stderr,"You're calling the wrong routine to draw weather alerts!\n");
                        break;

                    case DRAW_TO_PIXMAP_FINAL:
                        // We must be drawing symbols/tracks 'cuz this is the pixmap we use for it.

                        if (npoints >= 3) {
                            (void)XFillPolygon(XtDisplay(w),
                                pixmap_final,
                                gc,
                                points,
                                npoints,
                                Nonconvex,
                                CoordModeOrigin);
                        }
                        else {
//                            fprintf(stderr,
//                                "map_plot:Too few points:%d, Skipping XFillPolygon()",
//                                npoints);
                        }
                        break;
                    }

                    line_behavior = first_behavior;
                }
                if (line_behavior & 0x01)
                    (void)XSetLineAttributes (XtDisplay (w), gc, 2, LineSolid, CapButt,JoinMiter);
                else
                    (void)XSetLineAttributes (XtDisplay (w), gc, 1, LineSolid, CapButt,JoinMiter);

                if (color == (unsigned char)0x56)
                    (void)XSetLineAttributes (XtDisplay (w), gc, 10, LineSolid, CapButt,JoinMiter);

                // Set the color for drawing lines/borders
                (void)XSetForeground (XtDisplay (w), gc, colors[(int)last_color]);

                switch (destination_pixmap) {

                case DRAW_TO_PIXMAP_FINAL:
                    (void)XDrawLines (XtDisplay (w), pixmap_final, gc, points, npoints,CoordModeOrigin);
                    break;

                case DRAW_TO_PIXMAP:
                    (void)XDrawLines (XtDisplay (w), pixmap, gc, points, npoints,CoordModeOrigin);
                    break;

                case DRAW_TO_PIXMAP_ALERTS:
                    fprintf(stderr,"You're calling the wrong routine to draw weather alerts!\n");
                    break;
                }

                npoints = 0;

                /* check to see if we have been away from the screen too long */
                if (redraw_check > 1000) {
                    redraw_check = 0;
                    XmUpdateDisplay (XtParent (da));
                }
                redraw_check++;
            }
            last_color = color;
            if (color == (unsigned char)0xff) {
                npoints = 0;
                first_behavior = (unsigned char)object_behavior;
            }
            points[npoints].x = (short)x;
            points[npoints].y = (short)y;
            if (    (points[npoints].x > (-MAX_OUTBOUND))
                 && (points[npoints].x < (short)max_x)
                 && (points[npoints].y > (-MAX_OUTBOUND))
                 && (points[npoints].y < (short)max_y)
                 && (color != (unsigned char)0) )

                npoints++;

            last_behavior = (unsigned char)object_behavior;
            return;
        }
        points[npoints].x = (short)x;
        points[npoints].y = (short)y;
        last_behavior = (unsigned char)object_behavior;

        if (points[npoints].x != points[npoints - 1].x || points[npoints].y != points[npoints - 1].y) {
            if (last_behavior & 0x80)
                npoints++;

            else if (points[npoints].x > (-MAX_OUTBOUND)
                     && points[npoints].x < (short)max_x
                     && points[npoints].y > (-MAX_OUTBOUND)
                     && points[npoints].y < (short)max_y)
                npoints++;

        }
    } else {
        npoints = 0;
    }
}   /* map_plot */





void draw_dos_map(Widget w,
             char *dir,
             char *filenm,
             alert_entry *alert,
             u_char alert_color,
             int destination_pixmap,
             int draw_filled) {  
  FILE *f;
  char file[MAX_FILENAME];
  char short_filenm[MAX_FILENAME];
  char map_it[MAX_FILENAME];
  
  /* map header info */
  char map_type[5];
  char map_version[5];
  char file_name[33];
//  char *ext;
  char map_title[33];
  char map_creator[8];
  unsigned long creation_date;
  unsigned long left_boundary;
  unsigned long right_boundary;
  unsigned long top_boundary;
  unsigned long bottom_boundary;
  char map_reserved1[9];
  long total_vector_points;
  long total_labels;
  char map_reserved2[141];
  char Buffer[2049];
  char *ptr;
  int dos_labels;
  int dos_flag;
  long temp;
  int points_per_degree;
  int map_range;
  
  /* vector info */
  unsigned char vector_start;
  unsigned char object_behavior;
  unsigned long x_long_cord;
  unsigned long y_lat_cord;
  
  /* label data */
  char label_type[3];
  unsigned long label_x_cord;
  unsigned long label_y_cord;
  int temp_mag;
  int label_mag;
  char label_symbol_del;
  char label_symbol_char;
  char label_text_color;
  char label_text[50];
  
  unsigned long year;
  unsigned long days;
  long count;
  int label_length;
  int i;
  int map_maxed_vectors;
  int map_maxed_text_labels;
  int map_maxed_symbol_labels;
  map_vectors *vectors_ptr;
  text_label *text_ptr;
  symbol_label *symbol_ptr;
  int line_width;
  int x, y;
  int color;
  long max_x, max_y;
  int in_window = 0;
  char symbol_table;
  char symbol_id;
  char symbol_color;
  int embedded_object;
  
  x = 0;
  y = 0;
  color = -1;
  line_width = 1;
  mag = (1 * scale_y) / 2;    // determines if details are drawn
  
  /* MAP counters */
  vectors_ptr = map_vectors_ptr;
  text_ptr = map_text_label_ptr;
  symbol_ptr = map_symbol_label_ptr;
  
  map_maxed_vectors = 0;
  map_maxed_text_labels = 0;
  map_maxed_symbol_labels = 0;
  npoints = 0;
  
  xastir_snprintf(file, sizeof(file), "%s/%s", dir, filenm);

  // Create a shorter filename for display (one that fits the
  // status line more closely).  Subtract the length of the
  // "Indexing " and/or "Loading " strings as well.
  if (strlen(filenm) > (41 - 9)) {
      int avail = 41 - 11;
      int new_len = strlen(filenm) - avail;

      xastir_snprintf(short_filenm,
          sizeof(short_filenm),
          "..%s",
          &filenm[new_len]);
  }
  else {
      xastir_snprintf(short_filenm,
          sizeof(short_filenm),
          "%s",
          filenm);
  }

  f = fopen (file, "r");
  if (f != NULL) {
    (void)fread (map_type, 4, 1, f);
    map_type[4] = '\0';
    dos_labels = FALSE;
    points_per_degree = 300;
    
    // DOS-type map header portion of the code.
    if (strtod (map_type, &ptr) > 0.01 && (*ptr == '\0' || *ptr == ' ' || *ptr == ',')) {
      int j;
      
      if (debug_level & 512)
          fprintf(stderr,"\nDOS Map\n");
      
      top_boundary = left_boundary = bottom_boundary = right_boundary = 0;
      rewind (f);
      map_title[0] = map_creator[0] = Buffer[0] = '\0';
      // set map_type for DOS ASCII maps
      xastir_snprintf(map_type,sizeof(map_type),"DOS ");
      map_type[4] = '\0';
      xastir_snprintf(file_name,sizeof(file_name),"%s",filenm);
      total_vector_points = 200000;
      total_labels = 2000;

      for (j = 0; j < DOS_HDR_LINES; strlen(Buffer) ? 1 : j++) {
        
        (void)fgets (&Buffer[strlen (Buffer)],(int)sizeof (Buffer) - (strlen (Buffer)), f);

//      if (!strlen(Buffer))
//        j++;
 
        while ((ptr = strpbrk (Buffer, "\r\n")) != NULL && j < DOS_HDR_LINES) {
          *ptr = '\0';
          for (ptr++; *ptr == '\r' || *ptr == '\n'; ptr++) ;
          switch (j) {
          case 0:
//fprintf(stderr,"top_boundary: %s\n", Buffer);
            top_boundary = (unsigned long) (-atof (Buffer) * 360000 + 32400000);
            break;
            
          case 1:
//fprintf(stderr,"left_boundary: %s\n", Buffer);
            left_boundary = (unsigned long) (-atof (Buffer) * 360000 + 64800000);
            break;
            
          case 2:
//fprintf(stderr,"points_per_degree: %s\n", Buffer);
            points_per_degree = (int) atof (Buffer);
            break;
            
          case 3:
//fprintf(stderr,"bottom_boundary: %s\n", Buffer);
            bottom_boundary = (unsigned long) (-atof (Buffer) * 360000 + 32400000);
            bottom_boundary = bottom_boundary + bottom_boundary - top_boundary;
            break;
            
          case 4:
//fprintf(stderr,"right_boundary: %s\n", Buffer);
            right_boundary = (unsigned long) (-atof (Buffer) * 360000 + 64800000);
            right_boundary = right_boundary + right_boundary - left_boundary;
            break;
            
          case 5:
//fprintf(stderr,"map_range: %s\n", Buffer);
            map_range = (int) atof (Buffer);
            break;
            
          case 7:
//fprintf(stderr,"Map Version: %s\n", Buffer);
          xastir_snprintf(map_version,sizeof(map_version),"%s",Buffer);
//fprintf(stderr,"MAP VERSION: %s\n", map_version);
            break;
            }
        xastir_snprintf(Buffer,sizeof(Buffer),"%s",ptr);

//        if (strlen (Buffer))
//          j++;

          }
      }   // End of DOS-type map header portion
    } else {
      // Windows-type map header portion
      
      if (debug_level & 512)
        fprintf(stderr,"\nWindows map\n");
      
      (void)fread (map_version, 4, 1, f);
      map_version[4] = '\0';
      
      (void)fread (file_name, 32, 1, f);
      file_name[32] = '\0';
      
      (void)fread (map_title, 32, 1, f);
      map_title[32] = '\0';
      if (debug_level & 16)
        fprintf(stderr,"Map Title %s\n", map_title);
      
      (void)fread (map_creator, 8, 1, f);
      map_creator[8] = '\0';
      if (debug_level & 16)
        fprintf(stderr,"Map Creator %s\n", map_creator);
      
      (void)fread (&temp, 4, 1, f);
      creation_date = ntohl (temp);
      if (debug_level & 16)
        fprintf(stderr,"Creation Date %lX\n", creation_date);
      
      year = creation_date / 31536000l;
      days = (creation_date - (year * 31536000l)) / 86400l;
      if (debug_level & 16)
        fprintf(stderr,"year is %ld + days %ld\n", 1904l + year, (long)days);
      
      (void)fread (&temp, 4, 1, f);
      left_boundary = ntohl (temp);
      
      (void)fread (&temp, 4, 1, f);
      right_boundary = ntohl (temp);
      
      (void)fread (&temp, 4, 1, f);
      top_boundary = ntohl (temp);
      
      (void)fread (&temp, 4, 1, f);
      bottom_boundary = ntohl (temp);
      
      if (strcmp (map_version, "2.00") != 0) {
        left_boundary *= 10;
        right_boundary *= 10;
        top_boundary *= 10;
        bottom_boundary *= 10;
      }
      (void)fread (map_reserved1, 8, 1, f);
      (void)fread (&temp, 4, 1, f);
      total_vector_points = (long)ntohl (temp);
      (void)fread (&temp, 4, 1, f);
      total_labels = (long)ntohl (temp);
      (void)fread (map_reserved2, 140, 1, f);
      
    }   // End of Windows-type map header portion
      
      
    // Done processing map header info.  The rest of this
    // function performs the actual drawing of both DOS-type
    // and Windows-type maps to the screen.
    
    
    if (debug_level & 16) {
      fprintf(stderr,"Map Type: %s, Version: %s, Filename: %s\n", map_type, map_version, file_name);
      fprintf(stderr,"Left Boundary: %ld, Right Boundary: %ld\n", (long)left_boundary,(long)right_boundary);
      fprintf(stderr,"Top Boundary: %ld, Bottom Boundary: %ld\n", (long)top_boundary,(long)bottom_boundary);
      fprintf(stderr,"Total vector points: %ld, total labels: %ld\n",total_vector_points, total_labels);
    }

 
    // Check whether we're indexing or drawing the map
    if ( (destination_pixmap == INDEX_CHECK_TIMESTAMPS)
         || (destination_pixmap == INDEX_NO_TIMESTAMPS) ) {
      
      // We're indexing only.  Save the extents in the index.
      index_update_xastir(filenm, // Filename only
                          bottom_boundary,        // Bottom
                          top_boundary,           // Top
                          left_boundary,          // Left
                          right_boundary);        // Right
      
      (void)fclose (f);

      // Update the statusline 
      xastir_snprintf(map_it,
          sizeof(map_it),
          langcode ("BBARSTA039"),
          short_filenm);
      statusline(map_it,0);       // Loading/Indexing ...
     
      return; // Done indexing this file
    }
      
    HandlePendingEvents(app_context);
    if (interrupt_drawing_now) {
        (void)fclose(f);

        // Update to screen
        (void)XCopyArea(XtDisplay(da),pixmap,XtWindow(da),gc,0,0,screen_width,screen_height,0,0);
        return;
    }
   
    in_window = map_onscreen(left_boundary, right_boundary, top_boundary, bottom_boundary, 1);
      
    if (in_window) {
      unsigned char last_behavior, special_fill = (unsigned char)FALSE;


      // Update the statusline
      xastir_snprintf(map_it,
          sizeof(map_it),
          langcode ("BBARSTA028"),
          short_filenm);
      statusline(map_it,0);       // Loading/Indexing ...

      object_behavior = '\0';


      
      if (debug_level & 16)
        fprintf(stderr,"in Boundary %s\n", map_it);
      
      (void)XSetLineAttributes (XtDisplay (w), gc, line_width, LineSolid, CapButt,JoinMiter);
      
      /* read vectors */
      max_x = screen_width  + MAX_OUTBOUND;
      max_y = screen_height + MAX_OUTBOUND;
 
      HandlePendingEvents(app_context);
      if (interrupt_drawing_now) {
          (void)fclose(f);

          // Update to screen
          (void)XCopyArea(XtDisplay(da),pixmap,XtWindow(da),gc,0,0,screen_width,screen_height,0,0);
          return;
      }
      
      x_long_cord = 0;
      y_lat_cord  = 0;
      color = 0;
      dos_flag = 0;
      for (count = 0l;count < total_vector_points && !feof (f) && !dos_labels; count++) {

        if (strncmp ("DOS ", map_type, 4) == 0) {
          (void)fgets (&Buffer[strlen (Buffer)],(int)sizeof (Buffer) - (strlen (Buffer)), f);
          while ((ptr = strpbrk (Buffer, "\r\n")) != NULL && !dos_labels) {
            long LatHld = 0, LongHld;
            char *trailer;
            *ptr = '\0';
            for (ptr++; *ptr == '\r' || *ptr == '\n'; ptr++) ;
            
          process:
            
            if (strncasecmp ("Line", map_version, 4) == 0) {
              int k;
              color = (int)strtol (Buffer, &trailer, 0);
              if (trailer && (*trailer == ',' || *trailer == ' ')) {
                trailer++;
                if (color == -1) {
                  dos_labels = (int)TRUE;
                  xastir_snprintf(Buffer,sizeof(Buffer),"%s",ptr);
                  break;
                }
                for (k = strlen (trailer) - 1; k >= 0; k--)
                  trailer[k] = (char)( (int)trailer[k] - 27 );
                
                while (*trailer) {
                  LongHld = (long)( (int)(*(unsigned char *)trailer) * 16);
                  trailer++;
                  LatHld = (long)( (int)(*(unsigned char *)trailer) * 8);
                  trailer++;
                  LongHld += (long)((*trailer >> 3) & 0xf);
                  LatHld += (long)( (*trailer) & 0x7);
                  trailer++;
                  LatHld = ((double)LatHld * 360000.0) / points_per_degree;
                  LongHld = ((double)LongHld * 360000.0) / points_per_degree;
                  x_long_cord = LongHld + left_boundary;
                  y_lat_cord = LatHld + top_boundary;
                  map_plot (w,
                            max_x,
                            max_y,
                            (long)x_long_cord,
                            (long)y_lat_cord,
                            (unsigned char)color,
                            0,
                            destination_pixmap,
                            draw_filled);
                }
                map_plot (w,
                          max_x,
                          max_y,
                          (long)x_long_cord,
                          (long)y_lat_cord,
                          '\0',
                          0,
                          destination_pixmap,
                          draw_filled);
              }
            } else if (strncasecmp ("ASCII", map_version, 4) == 0) {
              if (color == 0) {
                color = (int)strtol (Buffer, &trailer, 0);
                if (trailer && strpbrk (trailer, ", ")) {
                  for (; *trailer == ',' || *trailer == ' '; trailer++) ;
                  dos_flag = (int)strtol (trailer, &trailer, 0);
                  if (dos_flag == -1)
                    dos_labels = (int)TRUE;
                }
              } else {
                LongHld = strtol (Buffer, &trailer, 0);
                if (trailer && strpbrk (trailer, ", ")) {
                  for (; *trailer == ',' || *trailer == ' '; trailer++) ;
                  LatHld = strtol (trailer, &trailer, 0);
                } else if (LongHld == 0 && *trailer != '\0') {
                  xastir_snprintf(map_version,sizeof(map_version),"Comp");
                  map_version[4] = '\0';
                  goto process;
                }
                if (LongHld == 0 && LatHld == 0) {
                  color = 0;
                  map_plot (w,
                            max_x,
                            max_y,
                            (long)x_long_cord,
                            (long)y_lat_cord,
                            (unsigned char)color,
                            0,
                            destination_pixmap,
                            draw_filled);
                } else if (LongHld == 0 && LatHld == -1) {
                  dos_labels = (int)TRUE;
                  map_plot (w,
                            max_x,
                            max_y,
                            (long)x_long_cord,
                            (long)y_lat_cord,
                            '\0',
                            0,
                            destination_pixmap,
                            draw_filled);
                } else {
                  LatHld = ((double)LatHld * 360000.0) / points_per_degree;
                  LongHld = ((double)LongHld * 360000.0) / points_per_degree;
                  x_long_cord = LongHld + left_boundary;
                  y_lat_cord = LatHld + top_boundary;
                  map_plot (w,
                            max_x,
                            max_y,
                            (long)x_long_cord,
                            (long)y_lat_cord,
                            (unsigned char)color,
                            0,
                            destination_pixmap,
                            draw_filled);
                }
              }
            } else if (strncasecmp ("Comp", map_version, 4) == 0) {
              char Tag[81];
              int k;
              Tag[80] = '\0';
              if (color == 0) {
                color = (int)strtol (Buffer, &trailer, 0);
                if (trailer && strpbrk (trailer, ", ")) {
                  for (; *trailer == ',' || *trailer == ' '; trailer++) ;
                  dos_flag = (int)strtol (trailer, &trailer, 0);
                  xastir_snprintf(Tag,sizeof(Tag),"%s",trailer);
                  Tag[79] = '\0';
                  if (dos_flag == -1)
                    dos_labels = (int)TRUE;
                }
              } else {
                LongHld = strtol (Buffer, &trailer, 0);
                for (; *trailer == ',' || *trailer == ' '; trailer++) ;
                LatHld = strtol (trailer, &trailer, 0);
                if (LatHld == 0 && *trailer != '\0')
                  LatHld = 1;
                
                if (LongHld == 0 && LatHld == 0) {
                  color = 0;
                  map_plot (w,
                            max_x,
                            max_y,
                            (long)x_long_cord,
                            (long)y_lat_cord,
                            (unsigned char)color,
                            0,
                            destination_pixmap,
                            draw_filled);
                } else if (LongHld == 0 && LatHld == -1) {
                  dos_labels = (int)TRUE;
                  map_plot (w,
                            max_x,
                            max_y,
                            (long)x_long_cord,
                            (long)y_lat_cord,
                            (unsigned char)color,
                            0,
                            destination_pixmap,
                            draw_filled);
                }
                
                if (color && !dos_labels) {
                  trailer = Buffer;
                  for (k = strlen (trailer) - 1; k >= 0; k--)
                    trailer[k] = (char)((int)trailer[k] - 27);
                  
                  while (*trailer) {
                    LongHld = (long)( (int)(*(unsigned char *)trailer) * 16);
                    trailer++;
                    LatHld = (long)( (int)(*(unsigned char *)trailer) * 8);
                    trailer++;
                    LongHld += (long)((*(unsigned char *)trailer >> 3) & 0xf);
                    LatHld += (*trailer) & 7l;
                    trailer++;
                    LatHld = ((double)LatHld * 360000.0) / points_per_degree;
                    LongHld = ((double)LongHld * 360000.0) / points_per_degree;
                    x_long_cord = LongHld + left_boundary;
                    y_lat_cord = LatHld + top_boundary;
                    map_plot (w,
                              max_x,
                              max_y,
                              (long)x_long_cord,
                              (long)y_lat_cord,
                              (unsigned char)color,
                              0,
                              destination_pixmap,
                              draw_filled);
                  }
                }
              }
            } else {
              LongHld = strtol (Buffer, &trailer, 0);
              if (trailer) {
                if (*trailer == ',' || *trailer == ' ') {
                  if (LongHld == 0)
                    xastir_snprintf(map_version,sizeof(map_version),"ASCII");
                    map_version[4] = '\0';
                  
                  trailer++;
                  dos_flag = (int)strtol (trailer, &trailer, 0);
                  if (dos_flag == -1)
                    dos_labels = (int)TRUE;
                  
                  if (dos_flag == 0 && *trailer != '\0') {
                    xastir_snprintf(map_version,sizeof(map_version),"Line");
                    map_version[4] = '\0';
                    goto process;
                  }
                  color = (int)LongHld;
                }
              } else
                xastir_snprintf(map_version,sizeof(map_version),"Comp");
                map_version[4] = '\0';
            }
            xastir_snprintf(Buffer,sizeof(Buffer),"%s",ptr);
          }
        } else {    // Windows map...
          last_behavior = object_behavior;
          (void)fread (&vector_start, 1, 1, f);
          (void)fread (&object_behavior, 1, 1, f);      // Fill Color?
          if (strcmp (map_type, "COMP") == 0) {
            short temp_short;
            long LatOffset, LongOffset;
            LatOffset  = (long)(top_boundary  - top_boundary  % 6000);
            LongOffset = (long)(left_boundary - left_boundary % 6000);
            (void)fread (&temp_short, 2, 1, f);
            x_long_cord = (ntohs (temp_short) * 10 + LongOffset);
            (void)fread (&temp_short, 2, 1, f);
            y_lat_cord  = (ntohs (temp_short) * 10 + LatOffset);
          } else {
            (void)fread (&temp, 4, 1, f);
            x_long_cord = ntohl (temp);
            if (strcmp (map_version, "2.00") != 0)
              x_long_cord *= 10;
            
            (void)fread (&temp, 4, 1, f);
            y_lat_cord = ntohl (temp);
            if (strcmp (map_version, "2.00") != 0)
              y_lat_cord *= 10;
          }
          if (alert_color && last_behavior & 0x80 && (int)vector_start == 0xff) {
            map_plot (w,
                      max_x,
                      max_y,
                      (long)x_long_cord,
                      (long)y_lat_cord,
                      '\0',
                      (long)alert_color,
                      destination_pixmap,
                      draw_filled);
            //special_fill = TRUE;
          }
          map_plot (w,
                    max_x,
                    max_y,
                    (long)x_long_cord,
                    (long)y_lat_cord,
                    vector_start,
                    (long)object_behavior,
                    destination_pixmap,
                    draw_filled);
        }
      }
      if (alert_color)
        map_plot (w,
                  max_x,
                  max_y,
                  0,
                  0,
                  '\0',
                  special_fill ? (long)0xfd : (long)alert_color,
                  destination_pixmap,
                  draw_filled);
      else
        map_plot (w,
                  max_x,
                  max_y,
                  0,
                  0,
                  (unsigned char)0xff,
                  0,
                  destination_pixmap,
                  draw_filled);
      
      (void)XSetForeground (XtDisplay (w), gc, colors[20]);
      line_width = 2;
      (void)XSetLineAttributes (XtDisplay (w), gc, line_width, LineSolid, CapButt,JoinMiter);

      
      // Here is the map label section of the code for both DOS & Windows-type maps
      if (map_labels) {

        HandlePendingEvents(app_context);
        if (interrupt_drawing_now) {
            (void)fclose(f);

            // Update to screen
            (void)XCopyArea(XtDisplay(da),pixmap,XtWindow(da),gc,0,0,screen_width,screen_height,0,0);
            return;
        }


        /* read labels */
        for (count = 0l; count < total_labels && !feof (f); count++) {

          //DOS-Type Map Labels
          embedded_object = 0;
          if (strcmp (map_type, "DOS ") == 0) {   // Handle DOS-type map labels/embedded objects
            char *trailer;
            (void)fgets (&Buffer[strlen (Buffer)],(int)sizeof (Buffer) - (strlen (Buffer)), f);
            for (; (ptr = strpbrk (Buffer, "\r\n")) != NULL;xastir_snprintf(Buffer,sizeof(Buffer),"%s",ptr)) {

              *ptr = '\0';
              label_type[0] = (char)0x08;
              for (ptr++; *ptr == '\r' || *ptr == '\n'; ptr++) ;
              trailer = strchr (Buffer, ',');
              if (trailer && strncmp (Buffer, "0", 1) != 0) {
                *trailer = '\0';
                trailer++;
                xastir_snprintf(label_text,sizeof(label_text),"%s",Buffer);
                
                // Check for '#' or '$' as the first character of the label.
                // If found, we have an embedded symbol and colored text to display.
                symbol_table = ' ';
                symbol_id = ' ';
                symbol_color = '0';
                if ( (label_text[0] == '$') || (label_text[0] == '#') ) {
                  // We found an embedded map object
                  embedded_object = 1;                        // Set the flag
                  if (label_text[0] == '$') {                  // Old format: $xC
                    symbol_table = '/';
                    symbol_id = label_text[1];
                    symbol_color = label_text[2];
                    // Take the object out of the label text
                    xastir_snprintf(label_text,sizeof(label_text),"%s",Buffer+3);
                  }
                  else {  // Could be in new or old format with a leading '#' character
                    symbol_table = label_text[1];
                    if (symbol_table == '/' || symbol_table == '\\') {  // New format: #/xC
                      symbol_id = label_text[2];
                      symbol_color = label_text[3];
                      // Take the object out of the label text
                      xastir_snprintf(label_text,sizeof(label_text),"%s",Buffer+4);
                    }
                    else {                                  // Old format: #xC
                      symbol_table = '\\';
                      symbol_id = label_text[1];
                      symbol_color = label_text[2];
                      // Take the object out of the label text
                      xastir_snprintf(label_text,sizeof(label_text),"%s",Buffer+3);
                    }
                  }
                  if (debug_level & 512)
                    fprintf(stderr,"Found embedded object: %c %c %c %s\n",symbol_table,symbol_id,symbol_color,label_text);
                }
                
                
                label_length = (int)strlen (label_text);
                label_y_cord = (unsigned long) (-strtod (trailer, &trailer) * 360000) + 32400000;
                trailer++;
                label_x_cord = (unsigned long) (-strtod (trailer, &trailer) * 360000) + 64800000;
                trailer++;
                label_mag = (int)strtol (trailer, &trailer, 0) * 20;
                if ((label_type[0] & 0x80) == '\0') /* left of coords */
                  x = ((label_x_cord - x_long_offset) / scale_x) - (label_length * 6);
                else  /* right of coords */
                  x = ((label_x_cord - x_long_offset) / scale_x);
                
                y = ((label_y_cord - y_lat_offset) / scale_y);
                if (x > (0) && (x < (int)screen_width)) {
                  if (y > (0) && (y < (int)screen_height)) {
                    /*fprintf(stderr,"Label mag %d mag %d\n",label_mag,(scale_x*2)-1); */
                    //if (label_mag > (int)((scale_x * 2) - 1) || label_mag == 0)
                    if (label_mag > (int)((scale_x) - 1) || label_mag == 0) {
                      if (embedded_object) {
                        // NOTE: 0x21 is the first color for the area object or "DOS" colors
                        draw_label_text (w, x+10, y+5, label_length,colors[0x21 + symbol_color],label_text);
                        symbol(w,0,symbol_table,symbol_id,' ',pixmap,1,x-10,y-10,' ');
                      }
                      else {
                        draw_label_text (w, x, y, label_length,colors[(int)(label_type[0] & 0x7f)],label_text);
                      }
                    }
                  }
                }
              }
            }
          } else {    // Handle Windows-type map labels/embedded objects
            int rotation = 0;
            char rotation_factor[5];
            
            // Windows-Type Map Labels
            char label_type_1[2], label_type_2[2];
            
            // Snag first two bytes of label
            (void)fread (label_type_1, 1, 1, f);
            (void)fread (label_type_2, 1, 1, f);
            
            if (label_type_2[0] == '\0') {  // Found a label
              
              // Found text label
              (void)fread (&temp, 4, 1, f);           /* x */
              label_x_cord = ntohl (temp);
              if (strcmp (map_version, "2.00") != 0)
                label_x_cord *= 10;
              
              (void)fread (&temp, 4, 1, f);           /* y */
              label_y_cord = ntohl (temp);
              if (strcmp (map_version, "2.00") != 0)
                label_y_cord *= 10;
              
              (void)fread (&temp_mag, 2, 1, f);       /* mag */
              label_mag = (int)ntohs (temp_mag);
              if (strcmp (map_version, "2.00") != 0)
                label_mag *= 10;
              
              if (strcmp (map_type, "COMP") == 0) {
                for (i = 0; i < 32; i++) {
                  (void)fread (&label_text[i], 1, 1, f);
                  if (label_text[i] == '\0') {
                    break;
                  }
                }
                label_text[32] = '\0';  // Make sure we have a terminator
              }
              else {
                (void)fread (label_text, 32, 1, f);   /* text */
                label_text[32] = '\0';  // Make sure we have a terminator
              }
              
              
              // Special strings like: "#123" are rotation factors for labels
              // in degrees.  This is not documented in the windows-type map
              // format documents that I could find.
              if (label_text[0] == '#') {
                int i,j;
                if (debug_level & 512)
                  fprintf(stderr,"%s\n",label_text);
                
                // Save the rotation factor in "rotation"
                for ( i=1; i<4; i++ )
                  rotation_factor[i-1] = label_text[i];
                rotation_factor[3] = '\0';
                rotation = atoi(rotation_factor);
                
                // Take rotation factor out of label string
                for ( i=4, j=0; i < (int)(strlen(label_text)+1); i++,j++)
                  label_text[j] = label_text[i];
                
                //fprintf(stderr,"Windows label: %s, rotation factor: %d\n",label_text, rotation);
              }
              
              
              label_length = (int)strlen (label_text);
              
              for (i = (label_length - 1); i > 0; i--) {
                if (label_text[i] == ' ')
                  label_text[i] = '\0';
                else
                  break;
              }
              
              label_length = (int)strlen (label_text);
              /*fprintf(stderr,"labelin:%s\n",label_text); */
              
              if ((label_type_1[0] & 0x80) == '\0') {
                /* left of coords */
                x = ((label_x_cord - x_long_offset) / scale_x) - (label_length * 6);
                x = 0;  // ??????
              } else {
                /* right of coords */
                x = ((label_x_cord - x_long_offset) / scale_x);
              }
              
              y = ((label_y_cord - y_lat_offset) / scale_y);
              
              if (x > (0) && (x < (int)screen_width)) {
                if (y > (0) && (y < (int)screen_height)) {
                  /*fprintf(stderr,"Label mag %d mag %d\n",label_mag,(scale_x*2)-1); */
                  //if (label_mag > (int)((scale_x * 2) - 1) || label_mag == 0)
                  if (label_mag > (int)((scale_x) - 1) || label_mag == 0) {
                    // Note: We're not drawing the labels in the right colors
                    if (rotation == 0) {    // Non-rotated label
                      //                                                draw_label_text (w,
                      //                                                    x,
                      //                                                    y,
                      //                                                    label_length,
                      //                                                    colors[(int)(label_type_1[0] & 0x7f)],
                      //                                                    label_text);
                      draw_rotated_label_text (w,
                                               -90.0,
                                               x,
                                               y,
                                               label_length,
                                               colors[(int)(label_type_1[0] & 0x7f)],
                                               label_text,
                                               FONT_DEFAULT);
                    }
                    else {  // Rotated label
                      draw_rotated_label_text (w,
                                               rotation,
                                               x,
                                               y,
                                               label_length,
                                               colors[(int)(label_type_1[0] & 0x7f)],
                                               label_text,
                                               FONT_DEFAULT);
                    }
                  }
                }
              }
            } else if (label_type_2[0] == '\1' && label_type_1[0] == '\0'){ // Found an embedded object
              
              //fprintf(stderr,"Found windows embedded symbol\n");
              
              /* label is an embedded symbol */
              (void)fread (&temp, 4, 1, f);
              label_x_cord = ntohl (temp);
              if (strcmp (map_version, "2.00") != 0)
                label_x_cord *= 10;
              
              (void)fread (&temp, 4, 1, f);
              label_y_cord = ntohl (temp);
              if (strcmp (map_version, "2.00") != 0)
                label_y_cord *= 10;
              
              (void)fread (&temp_mag, 2, 1, f);
              label_mag = (int)ntohs (temp_mag);
              if (strcmp (map_version, "2.00") != 0)
                label_mag *= 10;
              
              (void)fread (&label_symbol_del, 1, 1, f);   // Snag symbol table char
              (void)fread (&label_symbol_char, 1, 1, f);  // Snag symbol char
              (void)fread (&label_text_color, 1, 1, f);   // Snag text color (should be 1-9, others should default to black)
              if (label_text_color < '1' && label_text_color > '9')
                label_text_color = '0'; // Default to black
              
              x = ((label_x_cord - x_long_offset) / scale_x);
              y = ((label_y_cord - y_lat_offset) / scale_y);
              
              // Read the label text portion
              if (strcmp (map_type, "COMP") == 0) {
                for (i = 0; i < 32; i++) {
                  (void)fread (&label_text[i], 1, 1, f);
                  if (label_text[i] == '\0')
                    break;
                }
              }
              else {
                (void)fread (label_text, 29, 1, f);
              }
              
              // NOTE: 0x21 is the first color for the area object or "DOS" colors
              draw_label_text (w, x+10, y+5, strlen(label_text),colors[0x21 + label_text_color],label_text);
              symbol(w,0,label_symbol_del,label_symbol_char,' ',pixmap,1,x-10,y-10,' ');
              
              if (debug_level & 512)
                fprintf(stderr,"Windows map, embedded object: %c %c %c %s\n",
                        label_symbol_del,label_symbol_char,label_text_color,label_text);
            }
            else {
              if (debug_level & 512)
                fprintf(stderr,"Weird label in Windows map, neither a plain label nor an object: %d %d\n",
                        label_type_1[0],label_type_2[0]);
            }
          }
        }
      }       // if (map_labels)
    }
    (void)fclose (f);
  }
  else
    fprintf(stderr,"Couldn't open file: %s\n", file);
}



Generated by  Doxygen 1.6.0   Back to index