aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--generic/MapInfo.c1289
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(&current_vm, sizeof(VideoMap), 1, file) < 0) {
+ goto error;
+ }
+ cur_id = ntohi(current_vm.id);
+ while (cur_index != index) {
+ if (fread(&current_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(&current_vm);
+ FillMap(map, &current_vm);
+ if ((fread(&current_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(&current_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(&current_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;
+}