This is mapdraw.c in view mode; [Download] [Up]
/****************************************************************
* *
* I C A O M a p - *
* *
* A n A v i a t i o n U t i l i t y *
* *
* *
* Copyright (C) 1993, 1994 Martin Pauly *
* *
* N e x t V e r s i o n *
* *
* Copyright (C) 1994 Stefan Leuker & Oliver Meyer *
* *
* This file may be freely distributed only if it includes *
* the above copyright notice. *
* *
****************************************************************/
#import "mapdraw.h"
/* The zone where all map data is mallocated from */
NXZone *theZone = NULL;
FILE *ps;
LOCATION map_origin;
long map_scale;
long map_zeromeridian;
long top, left, bottom, right;
LOCATION topleft, topright, bottomleft, bottomright;
double map_width, map_height;
int mapWidth, mapHeight;
double mapWidthcm, mapHeightcm;
double originx, originy;
double scalefactor;
double mercatorscale; /* additional factor for merctor
* projection */
char map_projection = PROJECT_MERCATOR; /* projection algorithm
* to be used */
double v1, v2;
long scales[] = {
35000, 50000, 75000, 100000, 175000,
250000, 375000, 500000, 750000, 1000000, 1500000, 2500000,
3500000, 5000000};
int numscales = sizeof(scales) / sizeof(long *);
int scale = -1;
extern int NXDrawingStatus;
/* initialize some static vars for later projection */
void
map_initcoord()
{
double latitude, longitude;
/* for mercator projection, adjust scale to gegion being displayed */
mercatorscale = cos(internal2rad(map_origin.latitude));
/* find origin on map */
originx = proj_x(internal2rad(map_origin.latitude),
internal2rad(map_origin.longitude - map_zeromeridian));
originy = proj_y(internal2rad(map_origin.latitude),
internal2rad(map_origin.longitude - map_zeromeridian));
/* get window extents in cm from map.c */
map_width = mapWidthcm;
map_height = mapHeightcm;
/* scalefactor between map (cm) and doubles from proj_x/proj_y */
scalefactor = 100000 * EARTH_RADIUS / map_scale;
/* obere linke Ecke */
plane2sphere(originx - (map_width / scalefactor / 2), originy + (map_height / scalefactor / 2),
&latitude, &longitude);
top = bottom = rad2internal(latitude);
right = left = rad2internal(longitude);
topleft.latitude = rad2internal(latitude);
topleft.longitude = rad2internal(longitude) + map_zeromeridian;
/* obere rechte Ecke */
plane2sphere(originx + (map_width / scalefactor / 2), originy + (map_height / scalefactor / 2),
&latitude, &longitude);
if (top < rad2internal(latitude))
top = rad2internal(latitude);
if (bottom > rad2internal(latitude))
bottom = rad2internal(latitude);
if (left > rad2internal(longitude))
left = rad2internal(longitude);
if (right < rad2internal(longitude))
right = rad2internal(longitude);
topright.latitude = rad2internal(latitude);
topright.longitude = rad2internal(longitude) + map_zeromeridian;
/* untere linke Ecke */
plane2sphere(originx - (map_width / scalefactor / 2), originy - (map_height / scalefactor / 2),
&latitude, &longitude);
if (top < rad2internal(latitude))
top = rad2internal(latitude);
if (bottom > rad2internal(latitude))
bottom = rad2internal(latitude);
if (left > rad2internal(longitude))
left = rad2internal(longitude);
if (right < rad2internal(longitude))
right = rad2internal(longitude);
bottomleft.latitude = rad2internal(latitude);
bottomleft.longitude = rad2internal(longitude) + map_zeromeridian;
/* untere rechte Ecke */
plane2sphere(originx + (map_width / scalefactor / 2), originy - (map_height / scalefactor / 2),
&latitude, &longitude);
if (top < rad2internal(latitude))
top = rad2internal(latitude);
if (bottom > rad2internal(latitude))
bottom = rad2internal(latitude);
if (left > rad2internal(longitude))
left = rad2internal(longitude);
if (right < rad2internal(longitude))
right = rad2internal(longitude);
bottomright.latitude = rad2internal(latitude);
bottomright.longitude = rad2internal(longitude) + map_zeromeridian;
/* Mitte oben */
plane2sphere(originx, originy + (map_height / scalefactor / 2),
&latitude, &longitude);
if (top < rad2internal(latitude))
top = rad2internal(latitude);
if (bottom > rad2internal(latitude))
bottom = rad2internal(latitude);
/* Mitte unten */
plane2sphere(originx, originy - (map_height / scalefactor / 2),
&latitude, &longitude);
if (top < rad2internal(latitude))
top = rad2internal(latitude);
if (bottom > rad2internal(latitude))
bottom = rad2internal(latitude);
left += map_zeromeridian;
right += map_zeromeridian;
/* check what objects are visible in the current map selection */
findvisibleobjects();
}
/* set zeromeridian */
void
map_setzero(long zero)
{
map_zeromeridian = zero;
}
void
map_setscale(double newscale)
{
int i;
map_scale = (long)newscale;
/* try to find that scale in the scale-list */
scale = numscales - 1;
for (i = 0; i < numscales; i++)
if (map_scale >= scales[i])
scale = i;
}
void
map_setorigin(LOCATION origin)
{
map_origin = origin;
}
void
map_setparallels(long par1, long par2)
{
v1 = internal2rad(par1);
v2 = internal2rad(par2);
}
void
map_display()
{
/* sort objects in memory to guarantee 'niceness' */
sort_objects();
}
/*
And now...the actually_draw routine !
*/
void
actually_draw()
{
gp_setcolor(LIGHTGRAY);
coord_drawgrid(1); /* draw coordinate grid */
/* 1 == NX_DRAWING (or see View.h), but don't make this Objective-C */
if (NXDrawingStatus != 1)
drawvisibleobjects(1); /* do CTRs first because they have filled
* polygons */
gp_setcolor(BLACK);
drawvisibleobjects(0); /* in mapobjects.c */
}
void
map_drawline(double xcm1, double ycm1, double xcm2, double ycm2)
{
int x1, y1, x2, y2; /* window coordinates */
/* calculate window coordinates of end points */
x1 = (int)(xcm1 * mapWidth / mapWidthcm + mapWidth / 2);
y1 = (int)-(ycm1 * mapHeight / mapHeightcm - mapHeight / 2);
x2 = (int)(xcm2 * mapWidth / mapWidthcm + mapWidth / 2);
y2 = (int)-(ycm2 * mapHeight / mapHeightcm - mapHeight / 2);
PSW_drawline(x1, y1, x2, y2);
}
/* text print routine for coord_drawgrid to print coordinate information */
void
grid_printleft(double ycm, char *string)
{
int y;
y = (int) -(ycm*mapHeight/mapHeightcm-mapHeight/2);
if ((y>10) && (y<mapHeight))
{
gp_setcolor (BLACK);
gp_smalltextleftaligned (0, y, string);
}
}
void
grid_printunder(double xcm, char *string)
{
int x;
x = (int) (xcm*mapWidth/mapWidthcm+mapWidth/2);
if ((x>10) && (x<mapWidth))
{
gp_setcolor (BLACK);
gp_smalltextleftaligned (x, mapHeight, string);
}
}
void
coord_drawgrid(int printlabels)
{
long latitude, longitude;
int i, j = 0, numi, numj; /* j=0 just to supress Warnings */
double gridx[100][100];
double gridy[100][100];
LOCATION temp;
char str[30];
#define i60000 (map_scale < 1000000 ? 60000 : 180000)
/* distance between lines: 10' = 60000 */
for (i = 0, latitude = (bottom - (i60000 - 1)) / i60000 * i60000; latitude < top + i60000; latitude += i60000, i++)
for (j = 0, longitude = (left - (i60000 - 1)) / i60000 * i60000; longitude < right + i60000; longitude += i60000, j++)
{
temp.latitude = latitude;
temp.longitude = longitude;
internal2cm(temp, &(gridx[i][j]), &(gridy[i][j]));
}
/* save number of calculated points */
numi = i;
numj = j;
gp_setlinestyle (1, SOLID);
for (i = 0; i < numi; i++)
for (j = 0; j < numj; j++)
{
if (i < numi - 1)
map_drawline(gridx[i][j], gridy[i][j], gridx[i + 1][j], gridy[i + 1][j]);
if ((j < numj - 1) && (i > 0))
map_drawline(gridx[i][j], gridy[i][j], gridx[i][j + 1], gridy[i][j + 1]);
}
PSstroke();
/* labels for the coordinate grid */
for (i = 0; i < numi; i++)
for (j = 0; j < numj; j++)
{
temp.latitude = (bottom - (i60000 - 1)) / i60000 * i60000 + i * i60000;
temp.longitude = (left - (i60000 - 1)) / i60000 * i60000 + j * i60000;
strcpy(str, internal2string(temp));
str[6] = str[9];
str[7] = 0;
str[17] = str[20];
str[18] = 0;
if ((i == 0) && (j > 0) && (temp.longitude % (3 * i60000) == 0) && printlabels)
grid_printunder(gridx[i][j], str + 11);
if ((j == 1) && printlabels)
grid_printleft(gridy[i][j], str);
}
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.