releasing package survex version 1.4.11-3
[survex.git] / src / pos.cc
blob01cad57e692b839f9c914e266f7c4df24d8cfb87
1 /* pos.cc
2 * Export from Aven as Survex .pos or .csv.
3 */
4 /* Copyright (C) 2001-2024 Olly Betts
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 #include <config.h>
23 #include "pos.h"
25 #include "export.h" // For LABELS, etc
27 #include <algorithm>
28 #include <stdio.h>
29 #include <string.h>
31 #include "message.h"
32 #include "namecompare.h"
33 #include "useful.h"
35 using namespace std;
37 static void
38 csv_quote(const char* s, FILE* fh)
40 size_t i = 0;
41 while (true) {
42 switch (s[i]) {
43 case '\0':
44 fputs(s, fh);
45 return;
46 case ',':
47 case '"':
48 case '\r':
49 case '\n':
50 break;
52 ++i;
54 PUTC('"', fh);
55 fwrite(s, i, 1, fh);
56 while (s[i]) {
57 // Double up any " in the string to escape them.
58 if (s[i] == '"')
59 PUTC(s[i], fh);
60 PUTC(s[i], fh);
61 ++i;
63 PUTC('"', fh);
66 POS::~POS()
68 vector<pos_label*>::const_iterator i;
69 for (i = todo.begin(); i != todo.end(); ++i) {
70 free(*i);
72 todo.clear();
75 const int *
76 POS::passes() const
78 static const int default_passes[] = { LABELS|ENTS|FIXES|EXPORTS, 0 };
79 return default_passes;
82 void POS::header(const char *, const char *, time_t,
83 double, double, double, double, double, double)
85 if (csv) {
86 bool comma = false;
87 for (int msgno : { /*Easting*/378,
88 /*Northing*/379,
89 /*Altitude*/335,
90 /*Station Name*/100 }) {
91 if (comma) PUTC(',', fh);
92 csv_quote(msg(msgno), fh);
93 comma = true;
95 PUTC('\n', fh);
96 } else {
97 /* TRANSLATORS: Heading line for .pos file. Please try to ensure the
98 * “,”s (or at least the columns) are in the same place */
99 fputsnl(msg(/*( Easting, Northing, Altitude )*/195), fh);
103 void
104 POS::label(const img_point *p, const wxString& str, int /*sflags*/, int /*type*/)
106 const char* s = str.utf8_str();
107 size_t len = strlen(s);
108 pos_label * l = (pos_label*)malloc(offsetof(pos_label, name) + len + 1);
109 if (l == NULL)
110 throw std::bad_alloc();
111 l->x = p->x;
112 l->y = p->y;
113 l->z = p->z;
114 memcpy(l->name, s, len + 1);
115 todo.push_back(l);
118 class pos_label_ptr_cmp {
119 char separator;
121 public:
122 explicit pos_label_ptr_cmp(char separator_) : separator(separator_) { }
124 bool operator()(const POS::pos_label* a, const POS::pos_label* b) {
125 return name_cmp(a->name, b->name, separator) < 0;
129 void
130 POS::footer()
132 sort(todo.begin(), todo.end(), pos_label_ptr_cmp(separator));
133 vector<pos_label*>::const_iterator i;
134 for (i = todo.begin(); i != todo.end(); ++i) {
135 if (csv) {
136 fprintf(fh, "%.2f,%.2f,%.2f,", (*i)->x, (*i)->y, (*i)->z);
137 csv_quote((*i)->name, fh);
138 PUTC('\n', fh);
139 } else {
140 fprintf(fh, "(%8.2f, %8.2f, %8.2f ) %s\n",
141 (*i)->x, (*i)->y, (*i)->z, (*i)->name);