source: git/src/model.h @ fc43dda

Last change on this file since fc43dda was fc43dda, checked in by Olly Betts <olly@…>, 7 weeks ago

Allow colouring by horizontal or vertical error

  • Property mode set to 100644
File size: 8.0 KB
Line 
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.
13//
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.
18//
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
22//
23
24#ifndef model_h
25#define model_h
26
27#include "wx.h"
28
29#include "labelinfo.h"
30#include "vector3.h"
31
32#include <ctime>
33#include <list>
34#include <set>
35#include <vector>
36
37using namespace std;
38
39class MainFrm;
40
41class PointInfo : public Point {
42    int date;
43
44public:
45    PointInfo() : Point(), date(-1) { }
46    explicit PointInfo(const img_point & pt) : Point(pt), date(-1) { }
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; }
50};
51
52class XSect {
53    friend class MainFrm;
54    const LabelInfo* stn;
55    int date;
56    double l, r, u, d;
57    double right_bearing;
58
59public:
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_), right_bearing(0) { }
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_;
70    }
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);
78};
79
80inline Vector3 operator-(const XSect& a, const XSect& b) {
81    return *(a.stn) - *(b.stn);
82}
83
84class 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    double length = 0.0;
90    enum { ERROR_3D = 0, ERROR_H = 1, ERROR_V = 2 };
91    double errors[3] = {0, 0, 0};
92    wxString name;
93
94    explicit
95    traverse(const char* name_) : name(name_, wxConvUTF8) {
96        if (name.empty() && !name_[0]) {
97            // If name isn't valid UTF-8 then this conversion will
98            // give an empty string.  In this case, assume that the
99            // label is CP1252 (the Microsoft superset of ISO8859-1).
100            static wxCSConv ConvCP1252(wxFONTENCODING_CP1252);
101            name = wxString(name_, ConvCP1252);
102            if (name.empty()) {
103                // Or if that doesn't work (ConvCP1252 doesn't like
104                // strings with some bytes in) let's just go for
105                // ISO8859-1.
106                name = wxString(name_, wxConvISO8859_1);
107            }
108        }
109    }
110};
111
112class SurveyFilter {
113    std::set<wxString, std::greater<wxString>> filters;
114    std::set<wxString, std::greater<wxString>> redundant_filters;
115    // Default to the Survex standard separator - then a filter created before
116    // the survey separator is known is likely to not need rebuilding.
117    wxChar separator = '.';
118
119  public:
120    SurveyFilter() {}
121
122    void add(const wxString& survey);
123
124    void remove(const wxString& survey);
125
126    void clear() { filters.clear(); redundant_filters.clear(); }
127
128    bool empty() const { return filters.empty(); }
129
130    void SetSeparator(wxChar separator_);
131
132    bool CheckVisible(const wxString& name) const;
133};
134
135/// Cave model.
136class Model {
137    list<traverse> traverses[8];
138    mutable list<vector<XSect>> tubes;
139
140  public: // FIXME
141    list<LabelInfo*> m_Labels;
142
143  private:
144    Vector3 m_Ext;
145    double m_DepthMin, m_DepthExt;
146    int m_DateMin, m_DateExt;
147    bool complete_dateinfo;
148    int m_NumEntrances = 0;
149    int m_NumFixedPts = 0;
150    int m_NumExportedPts = 0;
151    bool m_HasUndergroundLegs = false;
152    bool m_HasSplays = false;
153    bool m_HasDupes = false;
154    bool m_HasSurfaceLegs = false;
155    bool m_HasErrorInformation = false;
156    bool m_IsExtendedElevation = false;
157    mutable bool m_TubesPrepared = false;
158
159    // Character separating survey levels (often '.')
160    wxChar m_separator;
161
162    wxString m_Title, m_cs_proj, m_DateStamp;
163
164    time_t m_DateStamp_numeric;
165
166    Vector3 m_Offset;
167
168    void do_prepare_tubes() const;
169
170  public:
171    int Load(const wxString& file, const wxString& prefix);
172
173    void CentreDataset(const Vector3& vmin);
174
175    const Vector3& GetExtent() const { return m_Ext; }
176
177    const wxString& GetSurveyTitle() const { return m_Title; }
178
179    const wxString& GetDateString() const { return m_DateStamp; }
180
181    time_t GetDateStamp() const { return m_DateStamp_numeric; }
182
183    double GetDepthExtent() const { return m_DepthExt; }
184    double GetDepthMin() const { return m_DepthMin; }
185
186    bool HasCompleteDateInfo() const { return complete_dateinfo; }
187    int GetDateExtent() const { return m_DateExt; }
188    int GetDateMin() const { return m_DateMin; }
189
190    int GetNumFixedPts() const { return m_NumFixedPts; }
191    int GetNumExportedPts() const { return m_NumExportedPts; }
192    int GetNumEntrances() const { return m_NumEntrances; }
193
194    bool HasUndergroundLegs() const { return m_HasUndergroundLegs; }
195    bool HasSplays() const { return m_HasSplays; }
196    bool HasDupes() const { return m_HasDupes; }
197    bool HasSurfaceLegs() const { return m_HasSurfaceLegs; }
198    bool HasTubes() const { return !tubes.empty(); }
199    bool HasErrorInformation() const { return m_HasErrorInformation; }
200
201    bool IsExtendedElevation() const { return m_IsExtendedElevation; }
202
203    wxChar GetSeparator() const { return m_separator; }
204
205    const wxString& GetCSProj() const { return m_cs_proj; }
206
207    const Vector3& GetOffset() const { return m_Offset; }
208
209    list<traverse>::const_iterator
210    traverses_begin(unsigned flags, const SurveyFilter* filter) const {
211        if (flags >= sizeof(traverses)) return traverses[0].end();
212        auto it = traverses[flags].begin();
213        if (filter) {
214            while (it != traverses[flags].end() &&
215                   !filter->CheckVisible(it->name)) {
216                ++it;
217            }
218        }
219        return it;
220    }
221
222    list<traverse>::const_iterator
223    traverses_next(unsigned flags, const SurveyFilter* filter,
224                   list<traverse>::const_iterator it) const {
225        ++it;
226        if (filter) {
227            while (it != traverses[flags].end() &&
228                   !filter->CheckVisible(it->name)) {
229                ++it;
230            }
231        }
232        return it;
233    }
234
235    list<traverse>::const_iterator traverses_end(unsigned flags) const {
236        if (flags >= sizeof(traverses)) flags = 0;
237        return traverses[flags].end();
238    }
239
240    list<vector<XSect>>::const_iterator tubes_begin() const {
241        prepare_tubes();
242        return tubes.begin();
243    }
244
245    list<vector<XSect>>::const_iterator tubes_end() const {
246        return tubes.end();
247    }
248
249    list<vector<XSect>>::iterator tubes_begin() {
250        prepare_tubes();
251        return tubes.begin();
252    }
253
254    list<vector<XSect>>::iterator tubes_end() {
255        return tubes.end();
256    }
257
258    list<LabelInfo*>::const_iterator GetLabels() const {
259        return m_Labels.begin();
260    }
261
262    list<LabelInfo*>::const_iterator GetLabelsEnd() const {
263        return m_Labels.end();
264    }
265
266    list<LabelInfo*>::const_reverse_iterator GetRevLabels() const {
267        return m_Labels.rbegin();
268    }
269
270    list<LabelInfo*>::const_reverse_iterator GetRevLabelsEnd() const {
271        return m_Labels.rend();
272    }
273
274    list<LabelInfo*>::iterator GetLabelsNC() {
275        return m_Labels.begin();
276    }
277
278    list<LabelInfo*>::iterator GetLabelsNCEnd() {
279        return m_Labels.end();
280    }
281
282    void prepare_tubes() const {
283        if (!m_TubesPrepared) {
284            do_prepare_tubes();
285            m_TubesPrepared = true;
286        }
287    }
288};
289
290#endif
Note: See TracBrowser for help on using the repository browser.