Fix message references for inches and feet
[survex.git] / src / model.h
blob5e6e5b349c61c29bc5a2e71ea530d080fdc61500
1 //
2 // model.h
3 //
4 // Cave survey model.
5 //
6 // Copyright (C) 2000-2003,2005 Mark R. Shinwell
7 // Copyright (C) 2001-2003,2004,2005,2006,2010,2011,2012,2013,2014,2015,2016,2018 Olly Betts
8 //
9 // This program is free software; you can redistribute it and/or modify
10 // it under the terms of the GNU General Public License as published by
11 // the Free Software Foundation; either version 2 of the License, or
12 // (at your option) any later version.
14 // This program is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU General Public License for more details.
19 // You should have received a copy of the GNU General Public License
20 // along with this program; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 #ifndef model_h
25 #define model_h
27 #include "wx.h"
29 #include "labelinfo.h"
30 #include "vector3.h"
32 #include <ctime>
33 #include <list>
34 #include <set>
35 #include <vector>
37 using namespace std;
39 class MainFrm;
41 class PointInfo : public Point {
42 int date = -1;
44 public:
45 PointInfo() : Point() { }
46 explicit PointInfo(const img_point & pt) : Point(pt) { }
47 PointInfo(const img_point & pt, int date_) : Point(pt), date(date_) { }
48 PointInfo(const Point & p, int date_) : Point(p), date(date_) { }
49 int GetDate() const { return date; }
52 class XSect {
53 friend class MainFrm;
54 const LabelInfo* stn;
55 int date;
56 double l, r, u, d;
57 double right_bearing = 0.0;
59 public:
60 XSect(const LabelInfo* stn_, int date_,
61 double l_, double r_, double u_, double d_)
62 : stn(stn_), date(date_), l(l_), r(r_), u(u_), d(d_) { }
63 double GetL() const { return l; }
64 double GetR() const { return r; }
65 double GetU() const { return u; }
66 double GetD() const { return d; }
67 double get_right_bearing() const { return right_bearing; }
68 void set_right_bearing(double right_bearing_) {
69 right_bearing = right_bearing_;
71 int GetDate() const { return date; }
72 const wxString& GetLabel() const { return stn->GetText(); }
73 const Point& GetPoint() const { return *stn; }
74 double GetX() const { return stn->GetX(); }
75 double GetY() const { return stn->GetY(); }
76 double GetZ() const { return stn->GetZ(); }
77 friend Vector3 operator-(const XSect& a, const XSect& b);
80 inline Vector3 operator-(const XSect& a, const XSect& b) {
81 return *(a.stn) - *(b.stn);
84 class traverse : public vector<PointInfo> {
85 public:
86 int n_legs = 0;
87 // Bitmask of img_FLAG_SURFACE, img_FLAG_SPLAY and img_FLAG_DUPLICATE.
88 int flags = 0;
89 // An img_STYLE_* value.
90 int style = 0;
91 double length = 0.0;
92 enum { ERROR_3D = 0, ERROR_H = 1, ERROR_V = 2 };
93 double errors[3] = {-1, -1, -1};
94 wxString name;
96 explicit
97 traverse(const char* name_) : name(name_, wxConvUTF8) {
98 if (name.empty() && !name_[0]) {
99 // If name isn't valid UTF-8 then this conversion will
100 // give an empty string. In this case, assume that the
101 // label is CP1252 (the Microsoft superset of ISO8859-1).
102 static wxCSConv ConvCP1252(wxFONTENCODING_CP1252);
103 name = wxString(name_, ConvCP1252);
104 if (name.empty()) {
105 // Or if that doesn't work (ConvCP1252 doesn't like
106 // strings with some bytes in) let's just go for
107 // ISO8859-1.
108 name = wxString(name_, wxConvISO8859_1);
114 class SurveyFilter {
115 std::set<wxString, std::greater<wxString>> filters;
116 std::set<wxString, std::greater<wxString>> redundant_filters;
117 // Default to the Survex standard separator - then a filter created before
118 // the survey separator is known is likely to not need rebuilding.
119 wxChar separator = '.';
121 public:
122 SurveyFilter() {}
124 void add(const wxString& survey);
126 void remove(const wxString& survey);
128 void clear() { filters.clear(); redundant_filters.clear(); }
130 bool empty() const { return filters.empty(); }
132 void SetSeparator(wxChar separator_);
134 bool CheckVisible(const wxString& name) const;
137 /// Cave model.
138 class Model {
139 list<traverse> traverses[8];
140 mutable list<vector<XSect>> tubes;
142 private:
143 list<LabelInfo*> m_Labels;
145 Vector3 m_Ext;
146 double m_DepthMin, m_DepthExt;
147 int m_DateMin, m_DateExt;
148 bool complete_dateinfo;
149 int m_NumEntrances = 0;
150 int m_NumFixedPts = 0;
151 int m_NumExportedPts = 0;
152 bool m_HasUndergroundLegs = false;
153 bool m_HasSplays = false;
154 bool m_HasDupes = false;
155 bool m_HasSurfaceLegs = false;
156 bool m_HasErrorInformation = false;
157 bool m_IsExtendedElevation = false;
158 mutable bool m_TubesPrepared = false;
160 // Character separating survey levels (often '.')
161 wxChar m_separator;
163 wxString m_Title, m_cs_proj, m_DateStamp;
165 time_t m_DateStamp_numeric;
167 Vector3 m_Offset;
169 // We lazily set the higher bits of LabelInfo::flags to a value to give us
170 // the sort order we want via integer subtraction. This is done the first
171 // time this sort happens after loading a file.
172 bool added_plot_order_keys = false;
174 void do_prepare_tubes() const;
176 void CentreDataset(const Vector3& vmin);
178 public:
179 int Load(const wxString& file, const wxString& prefix);
181 const Vector3& GetExtent() const { return m_Ext; }
183 const wxString& GetSurveyTitle() const { return m_Title; }
185 const wxString& GetDateString() const { return m_DateStamp; }
187 time_t GetDateStamp() const { return m_DateStamp_numeric; }
189 double GetDepthExtent() const { return m_DepthExt; }
190 double GetDepthMin() const { return m_DepthMin; }
192 bool HasCompleteDateInfo() const { return complete_dateinfo; }
193 int GetDateExtent() const { return m_DateExt; }
194 int GetDateMin() const { return m_DateMin; }
196 int GetNumFixedPts() const { return m_NumFixedPts; }
197 int GetNumExportedPts() const { return m_NumExportedPts; }
198 int GetNumEntrances() const { return m_NumEntrances; }
200 bool HasUndergroundLegs() const { return m_HasUndergroundLegs; }
201 bool HasSplays() const { return m_HasSplays; }
202 bool HasDupes() const { return m_HasDupes; }
203 bool HasSurfaceLegs() const { return m_HasSurfaceLegs; }
204 bool HasTubes() const { return !tubes.empty(); }
205 bool HasErrorInformation() const { return m_HasErrorInformation; }
207 bool IsExtendedElevation() const { return m_IsExtendedElevation; }
209 wxChar GetSeparator() const { return m_separator; }
211 const wxString& GetCSProj() const { return m_cs_proj; }
213 const Vector3& GetOffset() const { return m_Offset; }
215 list<traverse>::const_iterator
216 traverses_begin(unsigned flags, const SurveyFilter* filter) const {
217 if (flags >= sizeof(traverses)) return traverses[0].end();
218 auto it = traverses[flags].begin();
219 if (filter) {
220 while (it != traverses[flags].end() &&
221 !filter->CheckVisible(it->name)) {
222 ++it;
225 return it;
228 list<traverse>::const_iterator
229 traverses_next(unsigned flags, const SurveyFilter* filter,
230 list<traverse>::const_iterator it) const {
231 ++it;
232 if (filter) {
233 while (it != traverses[flags].end() &&
234 !filter->CheckVisible(it->name)) {
235 ++it;
238 return it;
241 list<traverse>::const_iterator traverses_end(unsigned flags) const {
242 if (flags >= sizeof(traverses)) flags = 0;
243 return traverses[flags].end();
246 list<vector<XSect>>::const_iterator tubes_begin() const {
247 prepare_tubes();
248 return tubes.begin();
251 list<vector<XSect>>::const_iterator tubes_end() const {
252 return tubes.end();
255 list<vector<XSect>>::iterator tubes_begin() {
256 prepare_tubes();
257 return tubes.begin();
260 list<vector<XSect>>::iterator tubes_end() {
261 return tubes.end();
264 list<LabelInfo*>::const_iterator GetLabels() const {
265 return m_Labels.begin();
268 list<LabelInfo*>::const_iterator GetLabelsEnd() const {
269 return m_Labels.end();
272 list<LabelInfo*>::const_reverse_iterator GetRevLabels() const {
273 return m_Labels.rbegin();
276 list<LabelInfo*>::const_reverse_iterator GetRevLabelsEnd() const {
277 return m_Labels.rend();
280 list<LabelInfo*>::iterator GetLabelsNC() {
281 return m_Labels.begin();
284 list<LabelInfo*>::iterator GetLabelsNCEnd() {
285 return m_Labels.end();
288 void SortLabelsByName();
290 void SortLabelsByPlotOrder();
292 void prepare_tubes() const {
293 if (!m_TubesPrepared) {
294 do_prepare_tubes();
295 m_TubesPrepared = true;
300 #endif