ftp.nice.ch/pub/next/science/cartography/ICAO.0.7b.s.tar.gz#/ICAOfNEXT.0.7b/mapdraw.c

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.