diff options
Diffstat (limited to 'generic')
-rw-r--r-- | generic/MapInfo.c | 1289 |
1 files changed, 1289 insertions, 0 deletions
diff --git a/generic/MapInfo.c b/generic/MapInfo.c new file mode 100644 index 0000000..be4c4ae --- /dev/null +++ b/generic/MapInfo.c @@ -0,0 +1,1289 @@ +/* + * MapInfo.c -- MapInfo interface. + * + * Authors : Patrick Lecoanet. + * Creation date : + * + * $Id$ + */ + +/* + * Copyright (c) 1993 - 1999 CENA, Patrick Lecoanet -- + * + * This code is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This code 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this code; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <netinet/in.h> +#include <sys/param.h> + +#include "MapInfo.h" + +#include <memory.h> +#include <math.h> + +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <netinet/in.h> +#include <sys/param.h> + + +static const char rcsid[] = "$Id$"; +static const char compile_id[]="$Compile: " __FILE__ " " __DATE__ " " __TIME__ " $"; + + +/* + *----------------------------------------------------------------------- + * + * New types + * + *----------------------------------------------------------------------- + */ +typedef struct { + RadarPtr tag; + MapInfoLineStyle style; + int width; + MapInfoPointStruct center; + unsigned int radius; + int start_angle; + int extend; +} MapInfoArcStruct, *MapInfoArc; + +typedef struct { + RadarPtr tag; + MapInfoLineStyle style; + int width; + MapInfoPointStruct from; + MapInfoPointStruct to; + unsigned int num_marks; + MapInfoPoint marks; +} MapInfoLineStruct, *MapInfoLine; + +typedef struct { + RadarPtr tag; + MapInfoPointStruct at; + char symbol[2]; +} MapInfoSymbolStruct, *MapInfoSymbol; + +typedef struct { + RadarPtr tag; + MapInfoTextStyle text_style; + MapInfoLineStyle line_style; + MapInfoPointStruct at; + char *text; +} MapInfoTextStruct, *MapInfoText; + +typedef struct { + char *name; + RadarList lines; + RadarList symbols; + RadarList texts; + RadarList arcs; +} MapInfoStruct, *MapInfo; + + +#define MARKERS_SPACING 80.0 /* 10 nautic miles in 1/8 of a mile */ +#define BASE_ALLOC_SIZE 8 + + +/* + *----------------------------------------------------------------------- + * + * Macros. + * + *----------------------------------------------------------------------- + */ +#define NOT_MARKED_STYLE(style) \ +((style) == MapInfoLineMarked ? MapInfoLineSimple : (style)); + + +/* + *----------------------------------------------------------------------- + * + * ComputeLineMarks -- + * Add marks to a line in the marks substructure. + * + *----------------------------------------------------------------------- + */ + +static void +ComputeLineMarks(MapInfoLine marked_line) +{ + double length; + unsigned int j; + int x_from = marked_line->from.x; + int y_from = marked_line->from.y; + int x_to = marked_line->to.x; + int y_to = marked_line->to.y; + int delta_x = x_from - x_to; + int delta_y = y_from - y_to; + int step_x, step_y; + + length = sqrt((double)((delta_x) * (delta_x) + (delta_y) * (delta_y))); + step_x = (int) ((x_to - x_from) * MARKERS_SPACING / length); + step_y = (int) ((y_to - y_from) * MARKERS_SPACING / length); + marked_line->num_marks = (int) length / MARKERS_SPACING; + + /* We don't want markers at ends, so we get rid of the last one + if it is at an end */ + if (fmod(length, MARKERS_SPACING) == 0.0) { + (marked_line->num_marks)--; + } + + if (marked_line->num_marks) { + marked_line->marks = (MapInfoPoint) RadarMalloc(marked_line->num_marks * sizeof(MapInfoPointStruct)); + } + + for (j = 0; j < marked_line->num_marks; j++) { + marked_line->marks[j].x = x_from + ((j + 1) * step_x); + marked_line->marks[j].y = y_from + ((j + 1) * step_y); + } +} + + +MapInfoId +MapInfoCreate(char *name) +{ + MapInfo new_map; + + new_map = (MapInfo) RadarMalloc(sizeof(MapInfoStruct)); + memset((char *) new_map, 0, sizeof(MapInfoStruct)); + if (!name) { + name = ""; + } + new_map->name = (char *) RadarMalloc(strlen(name)+1); + strcpy(new_map->name, name); + + return((MapInfoId) new_map); +} + + +char * +MapInfoName(MapInfoId map_info) +{ + if (!map_info) { + return ""; + } + return ((MapInfo) map_info)->name; +} + + +MapInfoId +MapInfoDuplicate(MapInfoId map_info) +{ + MapInfo cur_map = (MapInfo) map_info; + MapInfo new_map; + int i, num_lines, num_texts; + MapInfoText new_texts, cur_texts; + MapInfoLine new_lines, cur_lines; + + if (!cur_map) { + return ((MapInfoId) NULL); + } + + new_map = (MapInfo) MapInfoCreate(cur_map->name); + + if (cur_map->lines) { + new_map->lines = RadarListDuplicate(cur_map->lines); + + cur_lines = (MapInfoLine) RadarListArray(cur_map->lines); + new_lines = (MapInfoLine) RadarListArray(new_map->lines); + num_lines = RadarListSize(cur_map->lines); + + for (i = 0; i < num_lines; i++) { + if (new_lines[i].style == MapInfoLineMarked) { + new_lines[i].marks = (MapInfoPoint) RadarMalloc(new_lines[i].num_marks * + sizeof(MapInfoPointStruct)); + memcpy((char *) new_lines[i].marks, + (char *) cur_lines[i].marks, + new_lines[i].num_marks * sizeof(MapInfoPointStruct)); + } + } + } + if (cur_map->symbols) { + new_map->symbols = RadarListDuplicate(cur_map->symbols); + } + if (cur_map->texts) { + new_map->texts = RadarListDuplicate(cur_map->texts); + + cur_texts = (MapInfoText) RadarListArray(cur_map->texts); + new_texts = (MapInfoText) RadarListArray(new_map->texts); + num_texts = RadarListSize(cur_map->texts); + + for (i = 0; i < num_texts; i++) { + new_texts[i].text = (char *) RadarMalloc(strlen(cur_texts[i].text) + 1); + strcpy(new_texts[i].text, cur_texts[i].text); + } + } + if (cur_map->arcs) { + new_map->arcs = RadarListDuplicate(cur_map->arcs); + } + + return((MapInfoId) new_map); +} + + +void +MapInfoDelete(MapInfoId map_info) +{ + MapInfo cur_map = (MapInfo) map_info; + int i, num_texts, num_lines; + MapInfoText cur_texts; + MapInfoLine cur_lines; + + if (cur_map) { + if (cur_map->texts) { + num_texts = RadarListSize(cur_map->texts); + cur_texts = (MapInfoText) RadarListArray(cur_map->texts); + + for (i = 0; i < num_texts; i++) { + RadarFree((char *) cur_texts[i].text); + } + + RadarListFree(cur_map->texts); + } + + if (cur_map->lines) { + num_lines = RadarListSize(cur_map->lines); + cur_lines = (MapInfoLine) RadarListArray(cur_map->lines); + + for (i = 0; i < num_lines; i++) { + if (cur_lines[i].style == MapInfoLineMarked) { + RadarFree((char *) cur_lines[i].marks); + } + } + + RadarListFree(cur_map->lines); + } + + if (cur_map->symbols) { + RadarListFree(cur_map->symbols); + } + + if (cur_map->arcs) { + RadarListFree(cur_map->arcs); + } + + RadarFree(cur_map->name); + RadarFree(cur_map); + } +} + +void +MapInfoEmpty(MapInfoId map_info) +{ + MapInfo cur_map = (MapInfo) map_info; + + if (cur_map) { + if (cur_map->texts) { + RadarListEmpty(cur_map->texts); + } + if (cur_map->lines) { + RadarListEmpty(cur_map->lines); + } + if (cur_map->symbols) { + RadarListEmpty(cur_map->symbols); + } + if (cur_map->arcs) { + RadarListEmpty(cur_map->arcs); + } + } +} + + +void +MapInfoAddLine(MapInfoId map_info, + unsigned int index, + RadarPtr tag, + MapInfoLineStyle line_style, + int line_width, + int x_from, + int y_from, + int x_to, + int y_to) +{ + MapInfo cur_map = (MapInfo) map_info; + MapInfoLineStruct line_struct; + + if (cur_map) { + if (!cur_map->lines) { + cur_map->lines = RadarListNew(16, sizeof(MapInfoLineStruct)); + } + + line_struct.style = line_style; + if (line_width == 1) { + line_struct.width = 0; + } + else { + line_struct.width = line_width; + } + line_struct.tag = tag; + line_struct.from.x = x_from; + line_struct.from.y = y_from; + line_struct.to.x = x_to; + line_struct.to.y = y_to; + + if (line_style == MapInfoLineMarked) { + ComputeLineMarks(&line_struct); + } + + RadarListAdd(cur_map->lines, &line_struct, index); + } +} + + +void +MapInfoReplaceLine(MapInfoId map_info, + unsigned int index, + RadarPtr tag, + MapInfoLineStyle line_style, + int line_width, + int x_from, + int y_from, + int x_to, + int y_to) +{ + MapInfo cur_map = (MapInfo) map_info; + MapInfoLine line_ptr; + + if (cur_map && cur_map->lines) { + line_ptr = (MapInfoLine) RadarListAt(cur_map->lines, index); + if (line_ptr) { + if (line_ptr->style == MapInfoLineMarked) { + RadarFree((char *) line_ptr->marks); + } + + line_ptr->style = line_style; + if (line_width == 1) { + line_ptr->width = 0; + } + else { + line_ptr->width = line_width; + } + line_ptr->tag = tag; + line_ptr->from.x = x_from; + line_ptr->from.y = y_from; + line_ptr->to.x = x_to; + line_ptr->to.y = y_to; + + if (line_ptr->style == MapInfoLineMarked) { + ComputeLineMarks(line_ptr); + } + } + } +} + + +void +MapInfoRemoveLine(MapInfoId map_info, + unsigned int index) +{ + MapInfo cur_map = (MapInfo) map_info; + MapInfoLine line_ptr; + + if (cur_map && cur_map->lines) { + line_ptr = (MapInfoLine) RadarListAt(cur_map->lines, index); + if (line_ptr) { + if (line_ptr->style == MapInfoLineMarked) { + RadarFree((char *) line_ptr->marks); + } + + RadarListDelete(cur_map->lines, index); + } + } +} + + +void +MapInfoGetLine(MapInfoId map_info, + unsigned int index, + RadarPtr *tag, + MapInfoLineStyle *line_style, + int *line_width, + int *x_from, + int *y_from, + int *x_to, + int *y_to) +{ + MapInfo cur_map = (MapInfo) map_info; + MapInfoLine line_ptr; + + if (cur_map && cur_map->lines) { + line_ptr = (MapInfoLine) RadarListAt(cur_map->lines, index); + if (line_ptr) { + if (tag) { + *tag = line_ptr->tag; + } + if (line_style) { + *line_style = line_ptr->style; + } + if (line_width) { + if (line_ptr->width == 1) { + *line_width = 0; + } + else { + *line_width = line_ptr->width; + } + } + if (x_from) { + *x_from = line_ptr->from.x; + } + if (y_from) { + *y_from = line_ptr->from.y; + } + if (x_to) { + *x_to = line_ptr->to.x; + } + if (y_to) { + *y_to = line_ptr->to.y; + } + } + } +} + + +void +MapInfoGetMarks(MapInfoId map_info, + unsigned int index, + MapInfoPoint *marks, + unsigned int *num_marks) +{ + MapInfo cur_map = (MapInfo) map_info; + MapInfoLine line_ptr; + + if (cur_map && cur_map->lines) { + line_ptr = (MapInfoLine) RadarListAt(cur_map->lines, index); + if (line_ptr && line_ptr->style == MapInfoLineMarked) { + if (marks) { + *marks = line_ptr->marks; + } + if (num_marks) { + *num_marks = line_ptr->num_marks; + } + } + } +} + + +unsigned int +MapInfoNumLines(MapInfoId map_info) +{ + MapInfo cur_map = (MapInfo) map_info; + + if (cur_map && cur_map->lines) { + return RadarListSize(cur_map->lines); + } + else { + return 0; + } +} + + +void +MapInfoAddSymbol(MapInfoId map_info, + unsigned int index, + RadarPtr tag, + int x, + int y, + char symbol) +{ + MapInfo cur_map = (MapInfo) map_info; + MapInfoSymbolStruct symbol_struct; + + if (cur_map) { + if (!cur_map->symbols) { + cur_map->symbols = RadarListNew(16, sizeof(MapInfoSymbolStruct)); + } + + symbol_struct.tag = tag; + symbol_struct.at.x = x; + symbol_struct.at.y = y; + symbol_struct.symbol[0] = symbol; + symbol_struct.symbol[1] = '\0'; + + RadarListAdd(cur_map->symbols, &symbol_struct, index); + } +} + + +void +MapInfoReplaceSymbol(MapInfoId map_info, + unsigned int index, + RadarPtr tag, + int x, + int y, + char symbol) +{ + MapInfo cur_map = (MapInfo) map_info; + MapInfoSymbolStruct symbol_struct; + + if (cur_map && cur_map->symbols) { + symbol_struct.tag = tag; + symbol_struct.at.x = x; + symbol_struct.at.y = y; + symbol_struct.symbol[0] = symbol; + symbol_struct.symbol[1] = '\0'; + + RadarListAtPut(cur_map->symbols, &symbol_struct, index); + } +} + + +void +MapInfoRemoveSymbol(MapInfoId map_info, + unsigned int index) +{ + MapInfo cur_map = (MapInfo) map_info; + + if (cur_map && cur_map->symbols) { + RadarListDelete(cur_map->symbols, index); + } +} + + +void +MapInfoGetSymbol(MapInfoId map_info, + unsigned int index, + RadarPtr *tag, + int *x, + int *y, + char *symbol) +{ + MapInfo cur_map = (MapInfo) map_info; + MapInfoSymbol symbol_ptr; + + if (cur_map && cur_map->symbols) { + symbol_ptr = (MapInfoSymbol) RadarListAt(cur_map->symbols, index); + if (symbol_ptr) { + if (tag) { + *tag = symbol_ptr->tag; + } + if (x) { + *x = symbol_ptr->at.x; + } + if (y) { + *y = symbol_ptr->at.y; + } + if (symbol) { + *symbol = symbol_ptr->symbol[0]; + } + } + } +} + + +unsigned int +MapInfoNumSymbols(MapInfoId map_info) +{ + MapInfo cur_map = (MapInfo) map_info; + + if (cur_map && cur_map->symbols) { + return RadarListSize(cur_map->symbols); + } + else { + return 0; + } +} + + +void +MapInfoAddText(MapInfoId map_info, + unsigned int index, + RadarPtr tag, + MapInfoTextStyle text_style, + MapInfoLineStyle line_style, + int x, + int y, + char *text) +{ + MapInfo cur_map = (MapInfo) map_info; + MapInfoTextStruct text_struct; + + if (cur_map) { + if (!cur_map->texts) { + cur_map->texts = RadarListNew(16, sizeof(MapInfoTextStruct)); + } + + text_struct.tag = tag; + text_struct.text_style = text_style; + text_struct.line_style = NOT_MARKED_STYLE(line_style); + text_struct.at.x = x; + text_struct.at.y = y; + text_struct.text = (char *) RadarMalloc(strlen(text) + 1); + strcpy(text_struct.text, text); + + RadarListAdd(cur_map->texts, &text_struct, index); + } +} + + +void +MapInfoReplaceText(MapInfoId map_info, + unsigned int index, + RadarPtr tag, + MapInfoTextStyle text_style, + MapInfoLineStyle line_style, + int x, + int y, + char *text) +{ + MapInfo cur_map = (MapInfo) map_info; + MapInfoText text_ptr; + + if (cur_map && cur_map->texts) { + text_ptr = (MapInfoText) RadarListAt(cur_map->texts, index); + if (text_ptr) { + RadarFree(text_ptr->text); + + text_ptr->tag = tag; + text_ptr->text_style = text_style; + text_ptr->line_style = NOT_MARKED_STYLE(line_style); + text_ptr->at.x = x; + text_ptr->at.y = y; + text_ptr->text = (char *) RadarMalloc(strlen(text) + 1); + strcpy(text_ptr->text, text); + } + } +} + + +void +MapInfoRemoveText(MapInfoId map_info, + unsigned int index) +{ + MapInfo cur_map = (MapInfo) map_info; + MapInfoText text_ptr; + + if (cur_map && cur_map->texts) { + text_ptr = (MapInfoText) RadarListAt(cur_map->texts, index); + if (text_ptr) { + RadarFree(text_ptr->text); + + RadarListDelete(cur_map->texts, index); + } + } +} + + +void +MapInfoGetText(MapInfoId map_info, + unsigned int index, + RadarPtr *tag, + MapInfoTextStyle *text_style, + MapInfoLineStyle *line_style, + int *x, + int *y, + char **text) +{ + MapInfo cur_map = (MapInfo) map_info; + MapInfoText text_ptr; + + if (cur_map && cur_map->texts) { + text_ptr = (MapInfoText) RadarListAt(cur_map->texts, index); + if (text_ptr) { + if (tag) { + *tag = text_ptr->tag; + } + if (text_style) { + *text_style = text_ptr->text_style; + } + if (line_style) { + *line_style = text_ptr->line_style; + } + if (x) { + *x = text_ptr->at.x; + } + if (y) { + *y = text_ptr->at.y; + } + if (text) { + *text = text_ptr->text; + } + } + } +} + + +unsigned int +MapInfoNumTexts(MapInfoId map_info) +{ + MapInfo cur_map = (MapInfo) map_info; + + if (cur_map && cur_map->texts) { + return RadarListSize(cur_map->texts); + } + else { + return 0; + } +} + + +void +MapInfoAddArc(MapInfoId map_info, + unsigned int index, + RadarPtr tag, + MapInfoLineStyle line_style, + int line_width, + int center_x, + int center_y, + unsigned int radius, + int start_angle, + int extend) +{ + MapInfo cur_map = (MapInfo) map_info; + MapInfoArcStruct arc_struct; + + if (cur_map) { + if (!cur_map->arcs) { + cur_map->arcs = RadarListNew(16, sizeof(MapInfoArcStruct)); + } + + arc_struct.style = NOT_MARKED_STYLE(line_style); + if (line_width == 1) { + arc_struct.width = 0; + } + else { + arc_struct.width = line_width; + } + arc_struct.tag = tag; + arc_struct.center.x = center_x; + arc_struct.center.y = center_y; + arc_struct.radius = radius; + arc_struct.start_angle = start_angle; + arc_struct.extend = extend; + + RadarListAdd(cur_map->arcs, &arc_struct, index); + } +} + + +void +MapInfoReplaceArc(MapInfoId map_info, + unsigned int index, + RadarPtr tag, + MapInfoLineStyle line_style, + int line_width, + int center_x, + int center_y, + unsigned int radius, + int start_angle, + int extend) +{ + MapInfo cur_map = (MapInfo) map_info; + MapInfoArc arc_ptr; + + if (cur_map && cur_map->arcs) { + arc_ptr = (MapInfoArc) RadarListAt(cur_map->arcs, index); + if (arc_ptr) { + arc_ptr->style = NOT_MARKED_STYLE(line_style); + if (line_width == 1) { + arc_ptr->width = 0; + } + else { + arc_ptr->width = line_width; + } + arc_ptr->tag = tag; + arc_ptr->center.x = center_x; + arc_ptr->center.y = center_y; + arc_ptr->radius = radius; + arc_ptr->start_angle = start_angle; + arc_ptr->extend = extend; + } + } +} + + +void +MapInfoRemoveArc(MapInfoId map_info, + unsigned int index) +{ + MapInfo cur_map = (MapInfo) map_info; + MapInfoArc arc_ptr; + + if (cur_map && cur_map->arcs) { + arc_ptr = (MapInfoArc) RadarListAt(cur_map->arcs, index); + if (arc_ptr) { + RadarListDelete(cur_map->arcs, index); + } + } +} + + +void +MapInfoGetArc(MapInfoId map_info, + unsigned int index, + RadarPtr *tag, + MapInfoLineStyle *line_style, + int *line_width, + int *center_x, + int *center_y, + unsigned int *radius, + int *start_angle, + int *extend) +{ + MapInfo cur_map = (MapInfo) map_info; + MapInfoArc arc_ptr; + + if (cur_map && cur_map->arcs) { + arc_ptr = (MapInfoArc) RadarListAt(cur_map->arcs, index); + if (arc_ptr) { + if (tag) { + *tag = arc_ptr->tag; + } + if (line_style) { + *line_style = arc_ptr->style; + } + if (line_width) { + if (arc_ptr->width == 1) { + *line_width = 0; + } + else { + *line_width = arc_ptr->width; + } + } + if (center_x) { + *center_x = arc_ptr->center.x; + } + if (center_y) { + *center_y = arc_ptr->center.y; + } + if (radius) { + *radius = arc_ptr->radius; + } + if (start_angle) { + *start_angle = arc_ptr->start_angle; + } + if (extend) { + *extend = arc_ptr->extend; + } + } + } +} + +unsigned int +MapInfoNumArcs(MapInfoId map_info) +{ + MapInfo cur_map = (MapInfo) map_info; + + if (cur_map && cur_map->arcs) { + return RadarListSize(cur_map->arcs); + } + else { + return 0; + } +} + +void +MapInfoScale(MapInfoId map_info, + double factor) +{ + MapInfo mp = (MapInfo) map_info; + int i, num; + MapInfoLine line_ptr; + MapInfoSymbol sym_ptr; + MapInfoText text_ptr; + MapInfoArc arc_ptr; + + if (mp && mp->lines) { + num = RadarListSize(mp->lines); + line_ptr = (MapInfoLine) RadarListArray(mp->lines); + for (i = 0; i < num; i++, line_ptr++) { + line_ptr->from.x *= factor; + line_ptr->from.y *= factor; + line_ptr->to.x *= factor; + line_ptr->to.y *= factor; + } + } + if (mp && mp->symbols) { + num = RadarListSize(mp->symbols); + sym_ptr = (MapInfoSymbol) RadarListArray(mp->symbols); + for (i = 0; i < num; i++, sym_ptr++) { + sym_ptr->at.x *= factor; + sym_ptr->at.y *= factor; + } + } + if (mp && mp->texts) { + num = RadarListSize(mp->texts); + text_ptr = (MapInfoText) RadarListArray(mp->texts); + for (i = 0; i < num; i++, text_ptr++) { + text_ptr->at.x *= factor; + text_ptr->at.y *= factor; + } + } + if (mp && mp->arcs) { + num = RadarListSize(mp->arcs); + arc_ptr = (MapInfoArc) RadarListArray(mp->arcs); + for (i = 0; i < num; i++, arc_ptr++) { + arc_ptr->center.x *= factor; + arc_ptr->center.y *= factor; + arc_ptr->radius *= factor; + } + } +} + +void +MapInfoTranslate(MapInfoId map_info, + int x, + int y) +{ + MapInfo mp = (MapInfo) map_info; + int i, num; + MapInfoLine line_ptr; + MapInfoSymbol sym_ptr; + MapInfoText text_ptr; + MapInfoArc arc_ptr; + + if (mp && mp->lines) { + num = RadarListSize(mp->lines); + line_ptr = (MapInfoLine) RadarListArray(mp->lines); + for (i = 0; i < num; i++, line_ptr++) { + line_ptr->from.x += x; + line_ptr->from.y += y; + line_ptr->to.x += x; + line_ptr->to.y += y; + } + } + if (mp && mp->symbols) { + num = RadarListSize(mp->symbols); + sym_ptr = (MapInfoSymbol) RadarListArray(mp->symbols); + for (i = 0; i < num; i++, sym_ptr++) { + sym_ptr->at.x += x; + sym_ptr->at.y += y; + } + } + if (mp && mp->texts) { + num = RadarListSize(mp->texts); + text_ptr = (MapInfoText) RadarListArray(mp->texts); + for (i = 0; i < num; i++, text_ptr++) { + text_ptr->at.x += x; + text_ptr->at.y += y; + } + } + if (mp && mp->arcs) { + num = RadarListSize(mp->arcs); + arc_ptr = (MapInfoArc) RadarListArray(mp->arcs); + for (i = 0; i < num; i++, arc_ptr++) { + arc_ptr->center.x += x; + arc_ptr->center.y += y; + } + } +} + + + +#define TEXT_SIZE 256 +#define ntohi(n) ntohl((n)) + +/* + *----------------------------------------------------------------------- + * + * Videomap record definition. Ints are assumed to be 4 bytes. + * + *----------------------------------------------------------------------- + */ + +typedef struct { + int id; /* Map id (internal) */ + int dashed; /* Tell if vectors are dashed (exclusive with marked) */ + int expanded; /* Device coordinates or world coordinates (ignored now) */ + int marked; /* Tell if vectors are marked (exclusive with dashed) */ + int color; /* drawing color (ignored now) */ + int elements[50]; /* Element type ('P', 'V', 'T') */ + int x[50]; /* Coordinates if 'P' or 'V' */ + int y[50]; + int symbol[50]; /* Filled if 'P' or 'V' */ + int text[50]; /* Low order byte is ascii char if 'T' */ + int num_elements; /* Number of elements */ +} VideoMap; + +/* + *----------------------------------------------------------------------- + * + * ReorderVidomap - reorder integers according to the endianess + * + *----------------------------------------------------------------------- + */ + +static void +ReorderVidomap(VideoMap *vm) +{ + int loop; + + vm->id = ntohi(vm->id); + vm->dashed = ntohi(vm->dashed); + vm->expanded = ntohi(vm->expanded); + vm->marked = ntohi(vm->marked); + vm->color = ntohi(vm->color); + for (loop = 0; loop < 50; loop++) { + vm->elements[loop] = ntohi(vm->elements[loop]); + vm->x[loop] = ntohi(vm->x[loop]); + vm->y[loop] = ntohi(vm->y[loop]); + vm->symbol[loop] = ntohi(vm->symbol[loop]); + vm->text[loop] = ntohi(vm->text[loop]); + } + vm->num_elements = ntohi(vm->num_elements); +} + +/* + *----------------------------------------------------------------------- + * + * FillMap - Fill map with data in Videomap record vm. + * + *----------------------------------------------------------------------- + */ + +static void FillMap(MapInfoId map, VideoMap *vm) +{ + unsigned int i; + RadarBool has_start_pos = False; + int x_cur=0, y_cur=0; + char ch; + int text_x=0, text_y=0; + char text[TEXT_SIZE]; + RadarBool in_text = False; + RadarBool in_mod_text = False; + unsigned int text_size=0; + + for (i = 0; i < vm->num_elements; i++) { + switch(vm->elements[i] & 0xFF) { + case 'p': + case 'P': + if (in_text) { + in_text = in_mod_text = False; + while (text[text_size - 1] == ' ') { + text_size--; + } + text[text_size] = (char) 0; + MapInfoAddText(map, MapInfoNumTexts(map), NULL, MapInfoNormalText, + MapInfoLineSimple, text_x, text_y, text); + } + + x_cur = (int) (short) vm->x[i]; + y_cur = (int) (short) vm->y[i]; + has_start_pos = True; + + if (vm->symbol[i]) { + MapInfoAddSymbol(map, MapInfoNumSymbols(map), NULL, x_cur, y_cur, vm->symbol[i]); + } + break; + + /* We gather consecutive 'T' elements in a text. We skip + leading and trailing spaces and mod texts (between '@' + and now obsolete) */ + + case 't': + case 'T': + if (!has_start_pos) { + RadarWarning("Bloc carte incorrect, il est elimine"); + return; + } + + if (in_text == False) { + ch = (char) vm->text[i] & 0xFF; + if (ch == '@') { + if (in_mod_text == True) { + in_mod_text = False; + } + else { + in_mod_text = True; + } + } + else if (in_mod_text == False) { + in_text = True; + text_size = 0; + text_x = x_cur; + text_y = y_cur; + text[0] = (char) 0; + } + } + if (in_text) { + text[text_size] = (char) vm->text[i] & 0xFF; + text_size++; + } + break; + + case 'v': + case 'V': + if (!has_start_pos) { + RadarWarning("Bloc carte incorrect, il est elimine"); + return; + } + + if (in_text) { + in_text = in_mod_text = False; + while (text[text_size - 1] == ' ') { + text_size--; + } + text[text_size] = (char) 0; + MapInfoAddText(map, MapInfoNumTexts(map), NULL, MapInfoNormalText, + MapInfoLineSimple, text_x, text_y, text); + } + + if (vm->dashed) { + MapInfoAddLine(map, MapInfoNumLines(map), NULL, MapInfoLineDashed, 0, + x_cur, y_cur, + (int) (short) vm->x[i], (int) (short) vm->y[i]); + } + else if (vm->marked) { + MapInfoAddLine(map, MapInfoNumLines(map), NULL, MapInfoLineMarked, 0, + x_cur, y_cur, + (int) (short) vm->x[i], (int) (short) vm->y[i]); + } + else { + MapInfoAddLine(map, MapInfoNumLines(map), NULL, MapInfoLineSimple, 0, + x_cur, y_cur, + (int) (short) vm->x[i], (int) (short) vm->y[i]); + } + + x_cur = (int) (short) vm->x[i]; + y_cur = (int) (short) vm->y[i]; + + if (vm->symbol[i]) { + MapInfoAddSymbol(map, MapInfoNumSymbols(map), NULL, x_cur, y_cur, vm->symbol[i]); + } + break; + } + } + + if (in_text) { + in_text = in_mod_text = False; + while (text[text_size - 1] == ' ') { + text_size--; + } + text[text_size] = (char) 0; + MapInfoAddText(map, MapInfoNumTexts(map), NULL, MapInfoNormalText, + MapInfoLineSimple, text_x, text_y, text); + } +} + +/* + *----------------------------------------------------------------------- + * + * MapInfoGetVideomap - Load a mapinfo with the content of a videomap + * file named 'filename'. Only the sub map 'index' will be loaded. + * If successful a new mapinfo is returned, NULL otherwise. The + * index is zero based. + * + *----------------------------------------------------------------------- + */ +int +MapInfoGetVideomap(MapInfoId map, + char *filename, + int index) +{ + VideoMap current_vm; + FILE *file; + int cur_index, cur_id; + + /* Open the specified map file. */ + file = fopen(filename, "r"); + if (file == NULL) { + return RADAR_ERROR; + } + + /* Load the map */ + + /* First skip the leading maps up to index. */ + cur_index = 0; + if (fread(¤t_vm, sizeof(VideoMap), 1, file) < 0) { + goto error; + } + cur_id = ntohi(current_vm.id); + while (cur_index != index) { + if (fread(¤t_vm, sizeof(VideoMap), 1, file) < 0) { + goto error; + } + if (cur_id != ntohi(current_vm.id)) { + cur_index++; + cur_id = ntohi(current_vm.id); + } + }; + + /* Then load all the map modules. */ + do { + ReorderVidomap(¤t_vm); + FillMap(map, ¤t_vm); + if ((fread(¤t_vm, sizeof(VideoMap), 1, file) != 1) && !feof(file)) { + goto error; + } + } + while ((cur_id == ntohi(current_vm.id)) && !feof(file)); + + fclose(file); + return RADAR_OK; + +error: + fclose(file); + return RADAR_ERROR; +} + +/* + *----------------------------------------------------------------------- + * + * MapInfoVideomapIds - Return the list of sub map ids contained in a + * videomap file. This makes it possible to iterate through such + * a file without stumbling on an error, to know how much maps + * are there and to sort them according to their ids. + * + *----------------------------------------------------------------------- + */ + +RadarList +MapInfoVideomapIds(char *filename) +{ + FILE *file; + VideoMap current_vm; + int cur_id; + RadarList ids; + + /* Open the specified map file. */ + file = fopen(filename, "r"); + if (file == NULL) { + return NULL; + } + + if (fread(¤t_vm, sizeof(VideoMap), 1, file) < 0) { + goto error; + } + cur_id = ntohi(current_vm.id); + ids = RadarListNew(16, sizeof(int)); + /*printf("id %d\n", cur_id);*/ + RadarListAdd(ids, &cur_id, RadarListTail); + + do { + if (fread(¤t_vm, sizeof(VideoMap), 1, file) < 0) { + goto error; + } + if (cur_id != ntohi(current_vm.id)) { + cur_id = ntohi(current_vm.id); + /*printf("id %d\n", cur_id);*/ + RadarListAdd(ids, &cur_id, RadarListTail); + } + } + while (!feof(file)); + + fclose(file); + return ids; + +error: + fclose(file); + RadarListFree(ids); + return NULL; +} |