This is mapobjects.m 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 "mapobjects.h"
#import "geometry.h"
#import <dpsclient/dpsNeXT.h>
#import <appkit/appkit.h>
/*
this is where the display of currently visible objects is handled
*/
/* current route to be drawn */
int drawroutenumpoints = 0;
LOCATION drawroutepoints[100];
int visiblelist[2000];
int visiblenumber;
static int px[10000], py[10000]; /* global because of size */
#define max(a,b) (a>b)?a:b
OBJECT *saveobj;
/* flags for objects to be visible (1) or not (0) */
int vis_com = 1; /* communications */
int vis_roads = 1; /* roads */
int vis_airspace = 1; /* airspace structure */
int vis_cities = 1; /* cities */
int vis_waypoints = 1; /* waypoints */
int vis_airfield = 1; /* smaller airfields */
int vis_water = 1; /* rivers, lakes */
int vis_villages = 1; /* villages */
char *visstring[] = {"Intl. Airports", "Airports", "Public Airfields",
"Special Airfields", "Glider Sites", "Heliports",
"Ballon Sites", "VORs", "NDBs", "Obstacles",
"Reporting Points", "CTRs", "CVFRs", "Rivers", "Lakes",
"Highways", "Roads", "Towns", "Villages", "Waypoints",
"Intl. Borders", "State Borders", "Islands"};
int visobj[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0,
1, 1, 1};
int numvis = sizeof (visstring) / sizeof (char*);
/* init pieces */
void initmapobjects()
{
/* do nothing at the moment... */
}
/* make integer window coordinates from LOCATION */
void internal2window (LOCATION point, int *x, int *y)
{
double xcm, ycm;
internal2cm (point, &xcm, &ycm);
*x = (int) (xcm*mapWidth/mapWidthcm+mapWidth/2);
*y = (int) -(ycm*mapHeight/mapHeightcm-mapHeight/2);
}
/* make internal format from integer window coordinates */
LOCATION window2internal (int x, int y)
{
double xcm, ycm;
xcm = ((double)x-mapWidth/2)/mapWidth*mapWidthcm;
ycm = ((double)mapHeight/2-y)/mapHeight*mapHeightcm;
return cm2internal (xcm, ycm);
}
/* get distance in km between two window coordinates */
double dist (int x1, int y1, int x2, int y2)
{
LOCATION a, b;
a = window2internal (x1, y1);
b = window2internal (x2, y2);
return distance (a, b);
}
/* check if a point is inside the diplayed area (1) or not (0) */
int isvisible (LOCATION point)
{
return (point.latitude > bottom)
&& (point.latitude < top)
&& (point.longitude > left)
&& (point.longitude < right);
}
/*
return piece number in which location appears
*/
int piecenumber (LOCATION loc)
{
int x, y, pn;
x = (int) ((double) (loc.longitude - left) * HOR_SLICES / (right - left));
y = (int) ((double) (loc.latitude - top) * VER_SLICES / (bottom - top));
pn = x + HOR_SLICES * y;
return pn;
}
/*
go through object list and check which objects are currently
visible. put these objects into a list.
*/
void findvisibleobjects()
{
int i, j, flag, pn, visible, t;
visiblenumber = 0;
for (i=0; i<=objectno; i++)
{
objectlist[i]->piece = -1; /* default: in no piece */
/* check if user wants to see that type of object */
/* if ((objectlist[i]->type < O_VOR) ||
((objectlist[i]->type / 100 == 1) && (vis_com)) ||
((objectlist[i]->type / 100 == 2) && (1)) ||
((objectlist[i]->type / 100 == 3) && (vis_airspace)) ||
((objectlist[i]->type / 100 == 4) && (vis_waypoints)) ||
((objectlist[i]->type / 100 == 10) && (vis_roads)) ||
((objectlist[i]->type / 100 == 20) && (1))) */
visible = 0;
t = objectlist[i]->type;
if ((t == O_INTLAIRPORT) && visobj[0])
visible = 1;
if ((t >= O_AIRPORT) && (t <= O_AIRPORT_MIL) && visobj[1])
visible = 1;
if ((t == O_AIRFIELD) && visobj[2])
visible = 1;
if ((t == O_SPECIAL_AIRFIELD) && visobj[3])
visible = 1;
if ((t >= O_HELIPORT) && (t <= O_HELIPORT_AMB) && visobj[5])
visible = 1;
if ((t >= O_GLIDER_SITE) && (t <= O_HANG_GLIDER_SITE) && visobj[4])
visible = 1;
if ((t >= O_PARACHUTE_JUMPING_SITE) && (t <= O_FREE_BALLON_SITE) && visobj[6])
visible = 1;
if ((t >= O_VOR) && (t <= O_TACAN) && visobj[7])
visible = 1;
if ((t >= O_NDB) && (t <= O_BASIC_RADIO_FACILITY) && visobj[8])
visible = 1;
if ((t >= O_OBSTRUCTION) && (t <= O_AERO_GROUND_LIGHT) && visobj[9])
visible = 1;
if ((t == O_REPORTING_POINT) && visobj[10])
visible = 1;
if ((t == O_CTR) && visobj[11])
visible = 1;
if ((t == O_CVFR) && visobj[12])
visible = 1;
if ((t == O_RIVER) && visobj[13])
visible = 1;
if ((t == O_LAKE) && visobj[14])
visible = 1;
if ((t == O_HIGHWAY) && visobj[15])
visible = 1;
if ((t == O_ROAD) && visobj[16])
visible = 1;
if ((t == O_TOWN) && visobj[17])
visible = 1;
if ((t == O_VILLAGE) && visobj[18])
visible = 1;
if ((t == O_WAYPOINT) && visobj[19])
visible = 1;
if ((t == O_BORDER) && visobj[20])
visible = 1;
if ((t == O_STATE_BORDER) && visobj[21])
visible = 1;
if ((t == O_ISLAND) && visobj[22])
visible = 1;
if ((t == O_ISOGONE))
visible = 1;
if (visible)
{
if (isvisible (objectlist[i]->location))
{
visiblelist[visiblenumber] = i;
visiblenumber++;
/* save piece number of objects */
pn = piecenumber (objectlist[i]->location);
objectlist[i]->piece = pn;
}
else /* check for polygon or point list */
{
flag = 1;
if (objectlist[i]->numpoints)
for (j=0; flag && (j<objectlist[i]->numpoints); j++)
if (isvisible (objectlist[i]->points[j]))
{
visiblelist[visiblenumber] = i;
visiblenumber++;
flag = 0; /* don't add a single object more than once */
}
}
}
}
db_visible = visiblenumber;
}
int nearpiece (int p1, int p2)
{
if (p1 == p2) return 1;
if (p1-1 == p2) return 1;
if (p1+1 == p2) return 1;
if (p1-HOR_SLICES == p2) return 1;
if (p1+HOR_SLICES == p2) return 1;
if (p1-HOR_SLICES+1 == p2) return 1;
if (p1+HOR_SLICES+1 == p2) return 1;
if (p1-HOR_SLICES-1 == p2) return 1;
if (p1+HOR_SLICES-1 == p2) return 1;
return 0;
}
/* find object that is 'close' to a cursor position */
char *nearobject (int x, int y)
{
static char line[60];
LOCATION cursor;
double dist, mindist;
OBJECT *closeobj = NULL; /* Initilization just to supress Warnings */
int i;
double snapdist;
cursor = window2internal (x, y);
/* find visible object with minimum distance */
mindist = -1;
for (i=0; i<visiblenumber; i++)
#ifdef USE_PIECES
if (nearpiece (objectlist[visiblelist[i]]->piece, piecenumber (cursor)))
#endif
if (objectlist[visiblelist[i]]->type / 10 != 35) /* don't snap to areas */
{
dist = distance (objectlist[visiblelist[i]]->location, cursor);
if ((dist <= mindist) || (mindist < 0))
{
closeobj = objectlist[visiblelist[i]];
mindist = dist;
}
}
/* calculate distance between cursor and object, about 1cm */
snapdist = (double) max (map_scale / 200000, 2.5);
if ((mindist < snapdist) && (mindist != -1))
{
if (closeobj->type == O_WAYPOINT)
{
if (closeobj->alias)
sprintf (line, "%s %s", closeobj->alias, closeobj->name);
else
sprintf (line, "%s", closeobj->name);
}
else
sprintf (line, "%s (%s)", closeobj->name, objecttypestring(closeobj->type));
saveobj = closeobj;
return line;
}
#define CU objectlist[visiblelist[i]]
/* check if cursor is inside a CTRs */
if (vis_airspace)
for (i=0; i<visiblenumber; i++)
if (objectlist[visiblelist[i]]->type == O_CTR)
{
/* rough check with bounding box */
if ((CU->topleft.latitude > cursor.latitude) &&
(CU->bottomright.latitude < cursor.latitude) &&
(CU->topleft.longitude < cursor.longitude) &&
(CU->bottomright.longitude > cursor.longitude))
{
POINT polygon[2+objectlist[visiblelist[i]]->numpoints], loc;
int j;
for (j=0; j<objectlist[visiblelist[i]]->numpoints; j++)
internal2window (objectlist[visiblelist[i]]->points[j],
&(polygon[j+1].x), &(polygon[j+1].y));
loc.x = x; loc.y = y;
if (ppcontains (loc, polygon, objectlist[visiblelist[i]]->numpoints))
{
sprintf (line, "CTR %s", objectlist[visiblelist[i]]->name);
saveobj = objectlist[visiblelist[i]];
return line;
}
}
}
/* check if cursor is inside a CVFRs */
if (vis_airspace)
for (i=0; i<visiblenumber; i++)
if (objectlist[visiblelist[i]]->type == O_CVFR)
{
/* rough check with bounding box */
if ((CU->topleft.latitude > cursor.latitude) &&
(CU->bottomright.latitude < cursor.latitude) &&
(CU->topleft.longitude < cursor.longitude) &&
(CU->bottomright.longitude > cursor.longitude))
{
POINT polygon[2+objectlist[visiblelist[i]]->numpoints], loc;
int j;
for (j=0; j<objectlist[visiblelist[i]]->numpoints; j++)
internal2window (objectlist[visiblelist[i]]->points[j],
&(polygon[j+1].x), &(polygon[j+1].y));
loc.x = x; loc.y = y;
if (ppcontains (loc, polygon, objectlist[visiblelist[i]]->numpoints))
{
sprintf (line, "CVFR %s", objectlist[visiblelist[i]]->name);
saveobj = objectlist[visiblelist[i]];
return line;
}
}
}
saveobj = NULL;
return 0;
}
/*
physically draw visible objects when requested by an expose event,
called from within map.c
if polygons is 1, draw only polygons. otherwise, only other objects
*/
void drawvisibleobjects(int polygons)
{
OBJECT *current;
int i, x, y, heading;
for (i=0; i<visiblenumber; i++)
{
current = objectlist[visiblelist[i]];
if (((current->type == O_CTR) && (polygons)) ||
((current->type != O_CTR) && (!polygons)))
{
internal2window (current->location, &x, &y);
/* let's see if this object has got a runway (default: no) */
heading = -1;
if (current->runways)
heading = current->runways->direction +
truenorthoffset (objectlist[visiblelist[i]]->location);
switch (current->type) {
case O_AIRPORT :
case O_INTLAIRPORT :
draw_airport (x, y, heading, current->name, current->numpoints,
current->points, current->runways);
break;
case O_AIRPORT_CIV_MIL :
draw_airport_civ_mil (x, y, heading, current->name);
break;
case O_AIRPORT_MIL :
draw_airport_mil (x, y, heading, current->name);
break;
case O_AIRFIELD :
draw_airfield (x, y, heading, current->name);
break;
case O_SPECIAL_AIRFIELD :
draw_specialairfield (x, y, heading, current->name);
break;
case O_GLIDER_SITE :
draw_glider_site (x, y, current->name);
break;
case O_HELIPORT:
case O_HELIPORT_AMB:
draw_heliport (x, y, current->name);
break;
case O_NDB :
draw_ndb (x, y, current->name, current->frequency);
break;
case O_VOR :
draw_vor (x, y, current->name, current->frequency,
truenorthoffset (current->location));
break;
case O_VOR_DME :
draw_vor_dme (x, y, current->name, current->frequency,
truenorthoffset (current->location));
break;
case O_VORTAC :
draw_vortac (x, y, current->name, current->frequency,
truenorthoffset (current->location));
break;
case O_TACAN :
draw_vortac (x, y, current->name, current->frequency,
truenorthoffset (current->location));
break;
case O_RIVER :
draw_river (x, y, current->name, current->numpoints, current->points);
break;
case O_ISLAND :
draw_island (current->name, current->numpoints, current->points);
break;
case O_BORDER :
draw_border (current->numpoints, current->points);
break;
case O_STATE_BORDER :
draw_stateborder (current->numpoints, current->points);
break;
case O_LAKE :
draw_lake (current->name, current->numpoints, current->points);
break;
case O_HIGHWAY :
draw_highway (current->numpoints, current->points);
break;
case O_CTR :
draw_ctr (x, y, current->name, current->numpoints, current->points);
break;
case O_CVFR :
draw_cvfr (x, y, current->name, current->numpoints, current->points);
break;
case O_WAYPOINT :
draw_waypoint (x, y, current->name, current->alias);
break;
case O_VILLAGE :
draw_village (x, y, current->name);
break;
case O_TOWN :
draw_town (current->name, current->numpoints, current->points);
break;
}
}
}
}
void draw_airport (int x, int y, int heading, char *name, int numpoints,
LOCATION *points, RUNWAYDEF *runways)
{
int i, x1, y1, x2, y2, numrwy;
RUNWAYDEF *current;
if (((map_scale > 550000) && (media == SCREEN)) || (numpoints == 0))
{
draw_airfield (x, y, heading, name); /* use small symbol */
gp_setlinestyle (1, SOLID);
gp_setcolor (NAVYBLUE);
gp_drawfilledrect (x-2, y-12, x+2, y-9);
gp_drawfilledrect (x-2, y+9, x+2, y+12);
gp_drawfilledrect (x-12, y-2, x-9, y+2);
gp_drawfilledrect (x+9, y-2, x+12, y+2);
}
else
{
/* use first points as runway ends, others as airport area
count runways: */
numrwy = 0;
current = runways;
while (current)
{
current = current->next;
numrwy++;
}
/* draw area */
gp_setcolor (BLACK);
for (i=2*numrwy; i<numpoints; i++)
internal2window (points[i], &(px[i-2*numrwy]), &(py[i-2*numrwy]));
gp_drawarea (px, py, numpoints - 2*numrwy);
/* draw runways */
gp_setlinestyle (map_scale < 280000 ? 3 : 2, SOLID);
gp_setcolor (WHITE);
for (i=0; i<numrwy; i++)
{
internal2window (points[2*i], &x1, &y1);
internal2window (points[2*i+1], &x2, &y2);
gp_drawline (x1, y1, x2, y2);
}
}
}
void draw_ctr (int x, int y, char *name, int numpoints, LOCATION *points)
{
int i, lastx, lasty;
/* calculate window coordinates and store them in px/py */
if (numpoints > 19999)
numpoints = 19999; /* just in case... */
for (i=0; i<numpoints; i++)
internal2window (points[i], &(px[i]), &(py[i]));
/* draw area, distinguish between extended and normal color system */
gp_setcolor (PINK);
gp_drawarea (px, py, numpoints);
/* draw bounding box */
gp_setcolor (NAVYBLUE);
gp_setlinestyle (1, DASH);
gp_smalltext (x, y, name);
lastx = px[numpoints-1];
lasty = py[numpoints-1];
for (i=0; i<numpoints; i++)
{
gp_drawline (lastx, lasty, px[i], py[i]);
lastx = px[i];
lasty = py[i];
}
}
void draw_cvfr (int x, int y, char *name, int numpoints, LOCATION *points)
{
int i, lastx, lasty;
/* calculate window coordinates and store them in px/py */
if (numpoints > 19999)
numpoints = 19999; /* just in case... */
for (i=0; i<numpoints; i++)
internal2window (points[i], &(px[i]), &(py[i]));
/* draw bounding box */
gp_setcolor (LIGHTGREEN);
gp_setlinestyle (map_scale < 270000 ? 5 : 3, SOLID);
lastx = px[numpoints-1];
lasty = py[numpoints-1];
for (i=0; i<numpoints; i++)
{
gp_drawline (lastx, lasty, px[i], py[i]);
lastx = px[i];
lasty = py[i];
}
}
void draw_river (int x, int y, char *name, int numpoints, LOCATION *points)
{
int i, px, py, lastx, lasty;
switch (media) {
case SCREEN:
gp_setcolor (SKYBLUE);
gp_setlinestyle (2, SOLID);
break;
case POSTSCRIPT:
gp_setcolor (BLACK);
gp_setlinestyle (2, SOLID);
break;
}
gp_smalltext (x, y, name);
internal2window (points[0], &lastx, &lasty);
for (i=1; i<numpoints; i++)
{
internal2window (points[i], &px, &py);
gp_drawline (lastx, lasty, px, py);
lastx = px;
lasty = py;
}
}
void draw_border (int numpoints, LOCATION *points)
{
int i, px, py, lastx, lasty;
switch (media) {
case SCREEN:
case POSTSCRIPT:
gp_setcolor (BLACK);
gp_setlinestyle (1, SOLID);
break;
}
internal2window (points[0], &lastx, &lasty);
for (i=1; i<numpoints; i++)
{
internal2window (points[i], &px, &py);
gp_drawline (lastx, lasty, px, py);
lastx = px;
lasty = py;
}
}
void draw_stateborder (int numpoints, LOCATION *points)
{
int i, px, py, lastx, lasty;
switch (media) {
case SCREEN:
case POSTSCRIPT:
gp_setcolor (LIGHTGRAY);
gp_setlinestyle (1, SOLID);
break;
}
internal2window (points[0], &lastx, &lasty);
for (i=1; i<numpoints; i++)
{
internal2window (points[i], &px, &py);
gp_drawline (lastx, lasty, px, py);
lastx = px;
lasty = py;
}
}
void draw_highway (int numpoints, LOCATION *points)
{
int i, px, py, lastx, lasty;
internal2window (points[0], &lastx, &lasty);
gp_setlinestyle (3, SOLID);
gp_setcolor (RED);
for (i=1; i<numpoints; i++)
{
internal2window (points[i], &px, &py);
gp_drawline (lastx, lasty, px, py);
lastx = px;
lasty = py;
}
internal2window (points[0], &lastx, &lasty);
gp_setlinestyle (1, SOLID);
gp_setcolor (WHITE);
for (i=1; i<numpoints; i++)
{
internal2window (points[i], &px, &py);
gp_drawline (lastx, lasty, px, py);
lastx = px;
lasty = py;
}
}
void draw_airport_mil (int x, int y, int runwayheading, char *name)
{
draw_airfield (x, y, runwayheading, name);
gp_setcolor (NAVYBLUE);
gp_setlinestyle (1, SOLID);
gp_drawcircle (x, y, 10);
gp_setlinestyle (1, SOLID);
}
void draw_airport_civ_mil (int x, int y, int runwayheading, char *name)
{
draw_airport_mil (x, y, runwayheading, name);
gp_setcolor (NAVYBLUE);
gp_drawrect (x-2, y-12, x+2, y-9);
gp_drawrect (x-2, y+9, x+2, y+12);
gp_drawrect (x-12, y-2, x-9, y+2);
gp_drawrect (x+9, y-2, x+12, y+2);
}
void draw_airfield (int x, int y, int runwayheading, char *name)
{
int xrwy, yrwy;
gp_setcolor (NAVYBLUE);
gp_setlinestyle (3, SOLID);
gp_drawcircle (x, y, 18);
if (runwayheading != -1)
{
gp_setlinestyle (5, SOLID);
xrwy = (int) (sin((double) runwayheading*PI/180)*16);
yrwy = (int) (cos((double) runwayheading*PI/180)*16);
gp_drawline (x+xrwy, y-yrwy, x-xrwy, y+yrwy);
}
gp_setcolor (BLACK);
gp_smalltext (x, y+30, name);
}
void draw_specialairfield (int x, int y, int runwayheading, char *name)
{
int xrwy, yrwy;
gp_setcolor (NAVYBLUE);
gp_setlinestyle (3, SOLID);
gp_drawcircle (x, y, 18);
if (runwayheading != -1)
{
gp_setlinestyle (5, SOLID);
xrwy = (int) (sin((double) runwayheading*PI/180)*16);
yrwy = (int) (cos((double) runwayheading*PI/180)*16);
gp_drawline (x+xrwy, y-yrwy, x-xrwy, y+yrwy);
gp_setlinestyle (3, SOLID);
xrwy = (int) (sin((double) runwayheading*PI/180)*14);
yrwy = (int) (cos((double) runwayheading*PI/180)*14);
gp_setcolor (WHITE);
gp_drawline (x+xrwy, y-yrwy, x-xrwy, y+yrwy);
gp_setcolor (BLACK);
}
gp_setcolor (BLACK);
gp_smalltext (x, y+30, name);
}
void draw_glider_site (int x, int y, char *name)
{
/* Must be 0 to become correctly set */
static int glideUPath = 0;
static float ptsGlide[]={
-16, -16, 16, 16, /* setbbox */
0, 0, 8, 0, 360, /* arc */
-12, 3, /* moveto */
-3, -2, /* lineto */
0, 2, /* lineto */
3, -2, /* lineto */
12, 3, /* lineto */
0, 2, /* moveto */
-2, 4 /* lineto */
};
static char opsGlide[]={ dps_ucache, dps_setbbox, dps_arc
, dps_moveto, dps_lineto, dps_lineto, dps_lineto, dps_lineto
, dps_moveto, dps_lineto};
if (!glideUPath || (NXDrawingStatus != NX_DRAWING) )
{
/* If not drawing define the object again, and again.. */
PSW_SetUpath(ptsGlide, sizeof(ptsGlide)/sizeof(float), opsGlide
, sizeof(opsGlide)/sizeof(char));
glideUPath = DPSDefineUserObject(glideUPath);
}
gp_setcolor (NAVYBLUE);
gp_setlinestyle (2, SOLID);
PSW_UpathStroke(x, y, glideUPath);
/* gp_drawcircle (x, y, 16);
gp_drawline (x-12, y+3, x-3, y-2);
gp_drawline (x-3, y-2, x, y+2);
gp_drawline (x, y+2, x+3, y-2);
gp_drawline (x+12, y+3, x+3, y-2);
gp_drawline (x, y+2, x-2, y+4);
*/
gp_setcolor (BLACK);
gp_smalltext (x, y+22, name);
}
void draw_heliport (int x, int y, char *name)
{
/* Must be 0 to become correctly set */
static int heliUPath = 0;
static float ptsHeli[]={
-16, -16, 16, 16, /* setbbox */
0, 0, 9, 0, 360, /* arc */
-3, 5, /* moveto */
-3, -5, /* lineto */
3, 5, /* moveto */
3, -5, /* lineto */
-3, 0, /* moveto */
3, 0 /* lineto */
};
static char opsHeli[]={ dps_ucache, dps_setbbox, dps_arc
, dps_moveto, dps_lineto, dps_moveto, dps_lineto, dps_moveto
, dps_lineto};
/* 1 == NX_DRAWING (or see View.h), but don't make this Objective-C */
if (!heliUPath || (NXDrawingStatus != 1) )
{
/* If not drawing define the object again, and again.. */
PSW_SetUpath(ptsHeli, sizeof(ptsHeli)/sizeof(float), opsHeli
, sizeof(opsHeli)/sizeof(char));
heliUPath = DPSDefineUserObject(heliUPath);
}
gp_setcolor (NAVYBLUE);
gp_setlinestyle (2, SOLID);
PSW_UpathStroke(x, y, heliUPath);
gp_setcolor (BLACK);
gp_smalltext (x, y+22, name);
}
void draw_vor (int x, int y, char *name, double freq, int northoffset)
{
char label[40];
int i;
gp_setcolor (NAVYBLUE);
gp_setlinestyle (1, SOLID);
gp_drawcircle (x, y, 1);
gp_drawline (x-3, y-5, x+3, y-5);
gp_drawline (x+3, y-5, x+6, y);
gp_drawline (x+6, y, x+3, y+5);
gp_drawline (x+3, y+5, x-3, y+5);
gp_drawline (x-3, y+5, x-6, y);
gp_drawline (x-6, y, x-3, y-5);
gp_drawcircle (x, y, 100);
for (i = northoffset; i<360+northoffset; i+=10)
gp_drawline (x+1+50*sin(i*PI/180), y+1-50*cos(i*PI/180),
x+1+((i-northoffset)%30?46:i!=northoffset?40:20)*sin(i*PI/180),
y+1-((i-northoffset)%30?46:i!=northoffset?40:20)*cos(i*PI/180));
gp_setcolor (BLACK);
sprintf (label, "%s %6.2f", name, freq);
gp_smalltext (x, y+62, label);
}
void draw_vor_dme (int x, int y, char *name, double freq, int northoffset)
{
draw_vor (x, y, name, freq, northoffset);
gp_setcolor (NAVYBLUE);
gp_drawline (x-7, y-5, x+7, y-5);
gp_drawline (x+7, y-5, x+7, y+5);
gp_drawline (x+7, y+5, x-7, y+5);
gp_drawline (x-7, y+5, x-7, y-5);
}
void draw_vortac (int x, int y, char *name, double freq, int northoffset)
{
int px[4], py[4];
draw_vor (x, y, name, freq, northoffset);
gp_setcolor (NAVYBLUE);
px[0] = x-3; py[0] = y+5;
px[1] = x+3; py[1] = y+5;
px[2] = x+3; py[2] = y+11;
px[3] = x-3; py[3] = y+11;
gp_drawarea (px, py, 4);
/* gp_drawfilledrect(x-3, y+5, x+3, y+11); <= this is slower. why?*/
px[0] = x-3; py[0] = y-5;
px[1] = x-6; py[1] = y;
px[2] = x-11; py[2] = y-3;
px[3] = x-8; py[3] = y-8;
gp_drawarea (px, py, 4);
px[0] = x+3; py[0] = y-5;
px[1] = x+6; py[1] = y;
px[2] = x+11; py[2] = y-3;
px[3] = x+8; py[3] = y-8;
gp_drawarea (px, py, 4);
}
void draw_ndb (int x, int y, char *name, double freq)
{
char label[40];
gp_setcolor (NAVYBLUE);
gp_setlinestyle (1, SOLID);
gp_drawcircle (x, y, 5);
gp_setlinestyle (1, DOT);
switch (media) {
case SCREEN:
gp_drawcircle (x, y, 10);
gp_drawcircle (x, y, 14);
gp_drawcircle (x, y, 18);
gp_drawcircle (x, y, 22);
break;
case POSTSCRIPT:
gp_drawcircle (x, y, 10);
gp_drawcircle (x, y, 16);
gp_drawcircle (x, y, 22);
gp_drawcircle (x, y, 28);
break;
}
gp_setcolor (BLACK);
if (freq - (int) freq)
sprintf (label, "%s %5.1f", name, freq);
else
sprintf (label, "%s %3.0f", name, freq);
switch (media) {
case SCREEN:
gp_smalltext (x, y-10, label);
break;
case POSTSCRIPT:
gp_smalltext (x, y-17, label);
break;
}
}
void draw_waypoint (int x, int y, char *label, char *alias)
{
gp_setlinestyle (1, SOLID);
gp_setcolor (NAVYBLUE);
gp_drawline (x, y, x+3, y+5); /* draw a W */
gp_drawline (x, y, x-3, y+5);
gp_drawline (x+3, y+5, x+6, y-4);
gp_drawline (x-3, y+5, x-6, y-4);
gp_drawcircle (x, y, 17);
if (alias)
{
gp_smalltext (x, y+22, alias);
gp_smalltext (x, y+32, label);
}
else
gp_smalltext (x, y+22, label);
}
void draw_village (int x, int y, char *label)
{
gp_setlinestyle (1, SOLID);
gp_setcolor (BLACK);
gp_drawcircle (x, y, 7);
if (label)
gp_smalltext (x, y+14, label);
}
void draw_town (char *name, int numpoints, LOCATION *points)
{
int i, y, lastx, lasty;
long sx;
/* calculate window coordinates and store them in px/py */
if (numpoints > 19999)
numpoints = 19999; /* just in case... */
for (i=0; i<numpoints; i++)
internal2window (points[i], &(px[i]), &(py[i]));
/* draw area */
gp_setcolor (YELLOW);
gp_drawarea (px, py, numpoints);
/* draw bounding box */
gp_setcolor (BLACK);
gp_setlinestyle (1, SOLID);
lastx = px[numpoints-1];
lasty = py[numpoints-1];
sx = 0;
y = py[0];
for (i=0; i<numpoints; i++)
{
if (py[i] < y) y = py[i];
sx += px[i];
gp_drawline (lastx, lasty, px[i], py[i]);
lastx = px[i];
lasty = py[i];
}
gp_smalltext ((int) sx/numpoints, y, name);
}
void draw_island (char *name, int numpoints, LOCATION *points)
{
int i, y, lastx, lasty;
long sx;
/* calculate window coordinates and store them in px/py */
if (numpoints > 19999)
numpoints = 19999; /* just in case... */
for (i=0; i<numpoints; i++)
internal2window (points[i], &(px[i]), &(py[i]));
/* draw bounding box */
gp_setcolor (BLACK);
gp_setlinestyle (1, SOLID);
lastx = px[numpoints-1];
lasty = py[numpoints-1];
sx = 0;
y = py[0];
for (i=0; i<numpoints; i++)
{
if (py[i] < y) y = py[i];
sx += px[i];
gp_drawline (lastx, lasty, px[i], py[i]);
lastx = px[i];
lasty = py[i];
}
gp_smalltext ((int) sx/numpoints, y, name);
}
void draw_lake (char *name, int numpoints, LOCATION *points)
{
int i, y;
long sx;
/* calculate window coordinates and store them in px/py */
if (numpoints > 19999)
numpoints = 19999; /* just in case... */
for (i=0; i<numpoints; i++)
internal2window (points[i], &(px[i]), &(py[i]));
/* draw area */
gp_setcolor (SKYBLUE);
gp_drawarea (px, py, numpoints);
gp_setcolor (BLACK);
sx = 0;
y = py[0];
for (i=0; i<numpoints; i++)
{
if (py[i] < y) y = py[i];
sx += px[i];
}
gp_smalltext ((int) sx/numpoints, y, name);
}
/* make text lines describing the object near to the cursor, numlines = 0 if none */
void objectdescription(char **lines, int *numlines, int x, int y, int *range)
{
int count = 0;
char *line;
RUNWAYDEF *rwy;
*range = 0;
if (line = nearobject (x, y))
{
*range = saveobj->range;
sprintf (lines[count++], "%s", line);
switch (saveobj->type) {
default:
if (saveobj->type != O_WAYPOINT)
if (saveobj->alias)
sprintf (lines[count++], "ID: %s", saveobj->alias);
if (saveobj->frequency)
if (saveobj->type == O_NDB)
{
if (saveobj->frequency - (int) saveobj->frequency)
sprintf (lines[count++], "Frequency: %5.1f", saveobj->frequency);
else
sprintf (lines[count++], "Frequency: %3.0f", saveobj->frequency);
}
else
sprintf (lines[count++], "Frequency: %6.2f", saveobj->frequency);
rwy = saveobj->runways;
while (rwy)
{
if (rwy->length)
sprintf (lines[count], "Runway: %3d LDG %4.1f %s %s"
, rwy->direction
,(rwy->length)*UNIT_CHANGE(IPD_RUNWAYUNIT)/1852
, UNIT_NAME(IPD_RUNWAYUNIT)
, rwy->surface == 'G' ? "Gras"
: rwy->surface == 'A' ? "Asphalt":"Concrete");
else
sprintf (lines[count], "Runway: %3d T/O only %s",
rwy->direction,
rwy->surface == 'G' ? "Gras" : rwy->surface == 'A' ? "Asphalt"
: "Concrete");
/* leading zeros */
if (lines[count][8] == ' ') lines[count][8] = '0';
if (lines[count][9] == ' ') lines[count][9] = '0';
count++;
rwy = rwy->next;
}
if (saveobj->type < O_CTR)
sprintf (lines[count++], "Location: %s"
,internal2string(saveobj->location));
if (saveobj->range != UNKNOWN)
sprintf (lines[count++], "Range: %1.0f %s"
, saveobj->range*UNIT_CHANGE(IPD_RANGEUNIT), UNIT_NAME(IPD_RANGEUNIT));
if (saveobj->msl != UNKNOWN)
sprintf (lines[count++], "Elev: %1.0f %s"
, (saveobj->msl)*UNIT_CHANGE(IPD_ELEVATIONUNIT)/6076.115
, UNIT_NAME(IPD_ELEVATIONUNIT));
}
*numlines = count;
}
else
*numlines = 0;
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.