FlightGear next
PolyLine.cxx
Go to the documentation of this file.
1
3
4// Written by James Turner, started 2013.
5//
6// Copyright (C) 2013 James Turner <zakalawe@mac.com>
7//
8// This program is free software; you can redistribute it and/or
9// modify it under the terms of the GNU General Public License as
10// published by the Free Software Foundation; either version 2 of the
11// License, or (at your option) any later version.
12//
13// This program is distributed in the hope that it will be useful, but
14// WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16// General Public License for more details.
17//
18// You should have received a copy of the GNU General Public License
19// along with this program; if not, write to the Free Software
20// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21
22#ifdef HAVE_CONFIG_H
23 #include "config.h"
24#endif
25
26#include "PolyLine.hxx"
27
28#include <cassert>
29
30#include <simgear/math/sg_geodesy.hxx>
31#include <simgear/structure/exception.hxx>
32
34
35using namespace flightgear;
36
37PolyLine::PolyLine(Type aTy, const SGGeodVec& aPoints) :
38 m_type(aTy),
39 m_data(aPoints)
40{
41 assert(!aPoints.empty());
42}
43
48
49unsigned int PolyLine::numPoints() const
50{
51 return m_data.size();
52}
53
54SGGeod PolyLine::point(unsigned int aIndex) const
55{
56 assert(aIndex <= m_data.size());
57 return m_data[aIndex];
58}
59
61{
62 PolyLineList result;
63 if (aRawPoints.size() < 2) {
64 return result;
65 }
66
67 const double maxDistanceSquaredM = 40000 * 40000; // 40km to start with
68
69 SGVec3d chunkStartCart = SGVec3d::fromGeod(aRawPoints.front());
70 SGGeodVec chunk;
71 SGGeodVec::const_iterator it = aRawPoints.begin();
72
73 while (it != aRawPoints.end()) {
74 SGVec3d ptCart = SGVec3d::fromGeod(*it);
75 double d2 = distSqr(chunkStartCart, ptCart);
76
77 // distance check, but also ensure we generate actual valid line segments.
78 if ((chunk.size() >= 2) && (d2 > maxDistanceSquaredM)) {
79 chunk.push_back(*it); // close the segment
80 result.push_back(new PolyLine(aTy, chunk));
81 chunkStartCart = ptCart;
82 chunk.clear();
83 }
84
85 chunk.push_back(*it++); // add to open chunk
86 }
87
88 // if we have a single trailing point, we already added it as the last
89 // point of the previous chunk, so we're ok. Otherwise, create the
90 // final chunk's polyline
91 if (chunk.size() > 1) {
92 result.push_back(new PolyLine(aTy, chunk));
93 }
94
95 return result;
96}
97
99{
100 return new PolyLine(aTy, aRawPoints);
101}
102
103void PolyLine::bulkAddToSpatialIndex(PolyLineList::const_iterator begin,
104 PolyLineList::const_iterator end)
105{
106 flightgear::PolyLineList::const_iterator it;
107 for (it=begin; it != end; ++it) {
108 (*it)->addToSpatialIndex();
109 }
110}
111
113{
115 node->addPolyLine(const_cast<PolyLine*>(this));
116}
117
119{
120 SGBoxd result;
121 SGGeodVec::const_iterator it;
122 for (it = m_data.begin(); it != m_data.end(); ++it) {
123 SGVec3d cart = SGVec3d::fromGeod(*it);
124 result.expandBy(cart);
125 }
126
127 return result;
128}
129
131{
132public:
134 m_type(aTy)
135 { }
136
137 virtual bool pass(PolyLine::Type aTy) const
138 { return (aTy == m_type); }
139private:
140 PolyLine::Type m_type;
141};
142
143PolyLineList PolyLine::linesNearPos(const SGGeod& aPos, double aRangeNm, Type aTy)
144{
145 return linesNearPos(aPos, aRangeNm, SingleTypeFilter(aTy));
146}
147
148
149PolyLineList PolyLine::linesNearPos(const SGGeod& aPos, double aRangeNm, const TypeFilter& aFilter)
150{
151 std::set<PolyLineRef> resultSet;
152
153 SGVec3d cart = SGVec3d::fromGeod(aPos);
154 double cutoffM = aRangeNm * SG_NM_TO_METER;
156 deque.push_back(Octree::globalTransientOctree());
157
158 while (!deque.empty()) {
159 Octree::Node* nd = deque.front();
160 deque.pop_front();
161
162 PolyLineList lines;
163 nd->visitForLines(cart, cutoffM, lines, deque);
164
165 // merge into result set, filtering as we go.
166 for (auto ref : lines) {
167 if (aFilter.pass(ref->type())) {
168 resultSet.insert(ref);
169 }
170 }
171 } // of deque iteration
172
173 PolyLineList result;
174 result.insert(result.end(), resultSet.begin(), resultSet.end());
175 return result;
176}
std::vector< SGGeod > SGGeodVec
virtual bool pass(PolyLine::Type aTy) const
Definition PolyLine.cxx:137
SingleTypeFilter(PolyLine::Type aTy)
Definition PolyLine.cxx:133
Octree node base class, tracks its bounding box and provides various queries relating to it.
void addPolyLine(const PolyLineRef &)
virtual void visitForLines(const SGVec3d &aPos, double aCutoff, PolyLineList &aLines, FindLinesDeque &aQ) const
virtual Node * findNodeForBox(const SGBoxd &box) const
virtual bool pass(Type aTy) const =0
unsigned int numPoints() const
number of points in this line - at least two.
Definition PolyLine.cxx:49
void addToSpatialIndex() const
Definition PolyLine.cxx:112
SGGeod point(unsigned int aIndex) const
Definition PolyLine.cxx:54
static PolyLineList linesNearPos(const SGGeod &aPos, double aRangeNm, Type aTy)
retrieve all the lines within a range of a search point.
Definition PolyLine.cxx:143
static void bulkAddToSpatialIndex(PolyLineList::const_iterator begin, PolyLineList::const_iterator end)
Definition PolyLine.cxx:103
SGBoxd cartesianBox() const
Definition PolyLine.cxx:118
static PolyLineList createChunked(Type aTy, const SGGeodVec &aRawPoints)
create poly line objects from raw input points and a type.
Definition PolyLine.cxx:60
static PolyLineRef create(Type aTy, const SGGeodVec &aRawPoints)
Definition PolyLine.cxx:98
std::deque< Node * > FindLinesDeque
FlightPlan.hxx - defines a full flight-plan object, including departure, cruise, arrival information ...
Definition Addon.cxx:53
std::vector< PolyLineRef > PolyLineList
Definition PolyLine.hxx:41
std::vector< SGGeod > SGGeodVec
Definition PolyLine.hxx:36
SGSharedPtr< PolyLine > PolyLineRef
Definition PolyLine.hxx:40