This is IcaoObjects.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 "IcaoObjects.h" #define max(a,b) (a>b)?a:b static LOCATION *templist; /* collect points before object is created */ static int nextpoint = 0; /* counter for above list */ static char order[5000];/* used to sort objects */ OBJECT **objectlist; /* array of pointers to OBJECTs */ int objectno; /* no. of objects that was created last (-1 * if none created yet) */ LOCATION curr_location; /* current (when reading the world file) * location */ double curr_elev = UNKNOWN; /* current elevation */ TABLEENTRY *nametable; int tableentries; char **namearray; int db_objects; /* exported database information */ int db_visible; extern int currentline; int objects_init() { int i; initmapobjects(); /* preset global variables to assure consistance on parse */ nextpoint = 0; curr_location.longitude = 0; curr_location.latitude = 0; curr_elev = UNKNOWN; currentline = 1; if (!templist) templist = (LOCATION *) malloc(MAXPOINTS * sizeof(LOCATION)); if (!templist) return 1; db_objects = db_visible = 0; objectno = -1; objectlist = (OBJECT **) NXZoneMalloc(theZone, MAXOBJECTS * sizeof(OBJECT *)); if (objectlist) { for (i = 0; i < MAXOBJECTS; i++) objectlist[i] = NULL; return 0; } else return 1; } /* sort objects in memory */ int sortcomp(const void * a, const void * b) { return order[(*(OBJECT **)a)->type] - order[(*(OBJECT **)b)->type]; } int compname(const void * a, const void * b) { return strcmp(((TABLEENTRY *)a)->name, ((TABLEENTRY *)b)->name); } int compstr(const void *a, const void *b) { return strcmp(*(char **)a, *(char **)b); } char * strdup(char *ein) { char *ptr = NULL; if (ein != NULL) { ptr = (char *)NXZoneMalloc(theZone, strlen(ein) + 1); strcpy(ptr, ein); } return ptr; } void sort_objects() { int i; //, j, length; char tempstr[100]; /* build order array for objects */ for (i = 0; i < 5000; i++) order[i] = 0; order[O_CTR] = -60; order[O_TOWN] = -50; order[O_RIVER] = -40; order[O_HIGHWAY] = order[O_ROAD] = -30; order[O_CVFR] = -20; order[O_VILLAGE] = -10; for (i = O_VOR; i <= O_BASIC_RADIO_FACILITY; i++) order[i] = 10; order[O_WAYPOINT] = 20; for (i = O_INTLAIRPORT; i <= O_FREE_BALLON_SITE; i++) order[i] = 30; qsort(objectlist, objectno + 1, sizeof(OBJECT *),sortcomp); /* this is also the time to build the alphabetical name index */ tableentries = 0; nametable = (TABLEENTRY *) NXZoneMalloc(theZone, sizeof(TABLEENTRY) * 2 * db_objects); for (i = 0; i < db_objects; i++) if (objectlist[i]->name) if (strlen(objectlist[i]->name)) if ((objectlist[i]->type < 300) || (objectlist[i]->type == O_WAYPOINT) || (objectlist[i]->type == O_LAKE) || (objectlist[i]->type == O_VILLAGE) || (objectlist[i]->type == O_ISLAND) || (objectlist[i]->type == O_TOWN)) { if (objectlist[i]->type != O_WAYPOINT) { sprintf(tempstr, "%s (%s)", objectlist[i]->name, objecttypestring(objectlist[i]->type)); nametable[tableentries].name = strdup(tempstr); nametable[tableentries].index = i; tableentries++; } else { if (objectlist[i]->alias) { sprintf(tempstr, "%s %s", objectlist[i]->name, objectlist[i]->alias); nametable[tableentries].name = strdup(tempstr); nametable[tableentries].index = i; tableentries++; sprintf(tempstr, "%s %s", objectlist[i]->alias, objectlist[i]->name); nametable[tableentries].name = strdup(tempstr); nametable[tableentries].index = i; tableentries++; } else { nametable[tableentries].name = objectlist[i]->name; nametable[tableentries].index = i; tableentries++; } } } qsort(nametable, tableentries, sizeof(TABLEENTRY), compname); /* build array of strings for browser */ namearray = (char **)NXZoneMalloc(theZone, (1 + tableentries) * sizeof(char *)); namearray[0] = IO_CLEARENTRY; for (i = 0; i < tableentries; i++) namearray[i + 1] = nametable[i].name; tableentries++; /* convert underscores in names to blanks */ #ifdef oliver for (i = 0; i < tableentries; i++) { length = strlen(namearray[i]); for (j = 0; j < length; j++) if (namearray[i][j] == '_') namearray[i][j] = ' '; } qsort(namearray, tableentries, sizeof(char *), compstr); #endif } /* return pointer to an object by index of string in browser */ OBJECT * objectfromnamelist(int listindex) { if (listindex) return objectlist[nametable[listindex - 1].index]; else return NULL; } int objectThatMatches(const char *input) { int nearest = -1; int pos, first, last, brk, len; /* * This iterally tests first fopr the full length of input, and * then step by step a character less. */ len = strlen(input); while (nearest == -1) { if (!len) nearest = 0; first = -1; last = tableentries; pos = last / 2; while ((first+1 < last) && (nearest == -1)) { brk = strncasecmp(namearray[pos], input, len); if (brk == 0) nearest = pos; if (brk > 0) { last = pos; pos = (first + pos) / 2; } if (brk < 0) { first = pos; pos = (pos + last) / 2; } } if (nearest != -1) { do { nearest--; } while ((nearest > 0) && (strncasecmp(namearray[nearest], input, len) == 0)); nearest++; } else { len--; } } return nearest; } /* get object type string from type number */ char * objecttypestring(int objecttype) { static char string[30]; switch (objecttype) { case O_INTLAIRPORT: strcpy(string, "International Airport"); break; case O_AIRPORT: strcpy(string, "Airport"); break; case O_AIRPORT_CIV_MIL: strcpy(string, "Civil/Military Airport"); break; case O_AIRPORT_MIL: strcpy(string, "Military Airport"); break; case O_AIRFIELD: strcpy(string, "Public Airfield"); break; case O_SPECIAL_AIRFIELD: strcpy(string, "Special Airfield"); break; case O_HELIPORT: strcpy(string, "Heliport"); break; case O_HELIPORT_AMB: strcpy(string, "Ambulance Heliport"); break; case O_GLIDER_SITE: strcpy(string, "Glider Site"); break; case O_HANG_GLIDER_SITE: strcpy(string, "Hang Glider Site"); break; case O_PARACHUTE_JUMPING_SITE: strcpy(string, "Parachute Site"); break; case O_FREE_BALLON_SITE: strcpy(string, "Ballon Site"); break; case O_VOR: strcpy(string, "VOR"); break; case O_VOR_DME: strcpy(string, "VOR/DME"); break; case O_VORTAC: strcpy(string, "VORTAC"); break; case O_TACAN: strcpy(string, "TACAN"); break; case O_NDB: strcpy(string, "NDB"); break; case O_MARKER_BEACON: strcpy(string, "Marker Beacon"); break; case O_BASIC_RADIO_FACILITY: strcpy(string, "Radio Facility"); break; case O_OBSTRUCTION: strcpy(string, "Obstruction"); break; case O_GROUP_OBSTRUCTION: strcpy(string, "Obstructions"); break; case O_FIRED_OBSTRUCTION: strcpy(string, "Fired Obstruction"); break; case O_FIRED_GROUP_OBSTRUCTION: strcpy(string, "Fired Obstructions"); break; case O_AERO_GROUND_LIGHT: strcpy(string, "Ground Light"); break; case O_REPORTING_POINT: strcpy(string, "Reporting Point"); break; case O_CTR: strcpy(string, "CTR"); break; case O_CVFR: strcpy(string, "CVFR"); break; case O_RIVER: strcpy(string, "River"); break; case O_LAKE: strcpy(string, "Lake"); break; case O_HIGHWAY: strcpy(string, "Highway"); break; case O_VILLAGE: strcpy(string, "Village"); break; case O_ISLAND: strcpy (string, "Island"); break; case O_BORDER: strcpy (string, "Border"); break; case O_STATE_BORDER: strcpy (string, "State Border"); break; case O_COUNTRY: strcpy (string, "Country"); break; case O_STATE: strcpy (string, "State"); break; case O_TOWN: strcpy(string, "Town"); break; case O_WAYPOINT: strcpy(string, "Waypoint"); break; default: strcpy(string, "unknown type"); } return string; } /* call-back routines for the parser */ void new_location(LOCATION loc) { curr_location = loc; } void new_elev(double elev) { curr_elev = elev; } void new_object(int objecttype, char *identifier) { int i; if (objectno < MAXOBJECTS - 1)/* check if we have a spare pointer */ { objectno++; /* allocate memory for new object and see if that was successful... */ objectlist[objectno] = (OBJECT *) NXZoneMalloc(theZone, sizeof(OBJECT)); if (objectlist[objectno] == NULL) { printf("Out of memory - %s not saved!\n", identifier); objectno--; } else { /* * Added by Oliver because of the lakes. * initialize to null */ memset(objectlist[objectno], 0, sizeof(OBJECT)); db_objects = objectno + 1; objectlist[objectno]->type = objecttype; objectlist[objectno]->name = identifier; objectlist[objectno]->msl = curr_elev; curr_elev = UNKNOWN; objectlist[objectno]->top_msl = curr_elev; objectlist[objectno]->range = UNKNOWN; objectlist[objectno]->location = curr_location; objectlist[objectno]->runways = NULL; objectlist[objectno]->numpoints = 0; objectlist[objectno]->points = NULL; /* check for waiting polygon or list of points */ if (nextpoint) { #define CO objectlist[objectno] CO->topleft = templist[0]; CO->bottomright = templist[0]; objectlist[objectno]->points = (LOCATION *) NXZoneMalloc(theZone, nextpoint * sizeof(LOCATION)); objectlist[objectno]->numpoints = nextpoint; for (i = 0; i < nextpoint; i++) /* copy points from templist to * object */ { objectlist[objectno]->points[i] = templist[i]; /* get bounding rectangle */ if (CO->topleft.latitude < templist[i].latitude) CO->topleft.latitude = templist[i].latitude; if (CO->topleft.longitude > templist[i].longitude) CO->topleft.longitude = templist[i].longitude; if (CO->bottomright.latitude > templist[i].latitude) CO->bottomright.latitude = templist[i].latitude; if (CO->bottomright.longitude < templist[i].longitude) CO->bottomright.longitude = templist[i].longitude; } nextpoint = 0; /* delete temporary list */ } } } else printf("Too many objects - %s not saved!\n", identifier); } void add_point(LOCATION point) { if (nextpoint < MAXPOINTS - 1) { templist[nextpoint] = point; nextpoint++; } } void set_frequency(double freq) { objectlist[objectno]->frequency = freq; } void set_alias(char *name) { objectlist[objectno]->alias = name; } void set_topmsl(double height) { objectlist[objectno]->top_msl = height; } void set_range(double range) { objectlist[objectno]->range = range; } void add_runway(int direction, int length, char surface) { RUNWAYDEF *next_rwy, *tmp; next_rwy = (RUNWAYDEF *) NXZoneMalloc(theZone, sizeof(RUNWAYDEF)); if (!next_rwy) /* not enough memory */ puts("Out of memory."); else { tmp = objectlist[objectno]->runways; if (!tmp) /* first object? */ objectlist[objectno]->runways = next_rwy; else { while (tmp->next) tmp = (RUNWAYDEF *) tmp->next; /* go to end of list */ tmp->next = next_rwy; } next_rwy->direction = direction; next_rwy->length = length; next_rwy->surface = surface; next_rwy->next = NULL; /* mark end of list */ } } int digi_valid = 0; static FILE *serialport = NULL; static double offsetx, offsety; /* digitizer -> map * coordinates */ static double a, b, c, d; /* conversion matrix */ static double x, y; /* map origin offset in cm */ static int u, v; /* and in digitizer pixels */ /* wait for button and get position, return button number */ int digi_getpos(int *x, int *y) { char line[256]; int readx, ready, readbutton; fgets(line, 255, serialport); sscanf(line, "%d,%d,%d", &readx, &ready, &readbutton); *x = readx; *y = ready; return readbutton; } /* calibrate digitizer so that current map can be treated parameters: the two reference points that have to be 'shot at' */ void digi_calibrate(LOCATION ref1, LOCATION ref2) { int u1, v1, u2, v2; /* digitizer coordinations of reference * points */ double x1, y1, x2, y2; /* map coordinates (cm) of the same * reference points */ /* init map data */ mapWidthcm = mapHeightcm = 20;/* ca. size of map */ map_initcoord(); /* check if digitier input file is open, if not: open it */ if (!serialport) { serialport = fopen("/dev/podscat", "r"); } if (!serialport) { puts("Unable to open digitzer input port!"); } else { puts("\ndigitizer calibration:"); printf("Please move to map origin (%s) and press a button!\n", internal2string(map_origin)); digi_getpos(&u, &v); printf("Please move to %s and press a button!\n", internal2string(ref1)); digi_getpos(&u1, &v1); printf("Please move to %s and press a button!\n", internal2string(ref2)); digi_getpos(&u2, &v2); /* * get respective map coordinates (in cm) of the origin and reference * points */ internal2cm(map_origin, &x, &y); internal2cm(ref1, &x1, &y1); internal2cm(ref2, &x2, &y2); offsetx = x - u; /* translate to map origin */ offsety = y - v; /* * get digitizer and cm coordinates of reference points relativ to map * origin */ u1 -= u; u2 -= u; x1 -= x; x2 -= x; v1 -= v; v2 -= v; y1 -= y; y2 -= y; /* calculate matrix of conversion function */ a = -(v1 * x2 - v2 * x1) / (-v1 * u2 + v2 * u1); b = -(-v2 * y1 + y2 * v1) / (-v1 * u2 + v2 * u1); c = (u1 * x2 - x1 * u2) / (-v1 * u2 + v2 * u1); d = (-u2 * y1 + u1 * y2) / (-v1 * u2 + v2 * u1); puts("Thank you, calibration was successful!\n"); digi_valid = 1; } } int is_digi_valid() { return digi_valid; } /* read coordinates from digitizer using current map attributes */ LOCATION digi_input() { int xx, yy, bb; double xcm, ycm; bb = digi_getpos(&xx, &yy); xx -= u; yy -= v; xcm = a * xx + c * yy + x; ycm = b * xx + d * yy + y; printf("%s\n", cm2string(xcm, ycm)); digi_input(); return cm2internal(xcm, ycm); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.