VR-Forces Developer's Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
indexingFeatureSet.h
Go to the documentation of this file.
1 /******************************************************************************
2  * Copyright (c) 2015 MAK Technologies, Inc.
3  * All rights reserved.
4  ******************************************************************************/
5 
9 
10 #pragma once
11 
13 #include <features/featureSet.h>
16 #include <features/tileFeature.h>
17 
19 
20 #include <tbb/atomic.h>
21 
22 namespace MAKVRinTerra
23 {
24  template <typename FS, typename S = typename FS::Sink>
26  : public FS
27  , public boost::enable_shared_from_this<DtIndexingFeatureSet<FS,S> >
28  {
29  public:
30  typedef boost::shared_ptr<DtIndexingFeatureSet> Ptr;
31  typedef boost::shared_ptr<const DtIndexingFeatureSet> CPtr;
32  typedef boost::weak_ptr<DtIndexingFeatureSet> WPtr;
33 
34  typedef typename FS::Feature Feature;
35  typedef typename FS::ForEachFunction ForEachFunction;
36  typedef typename FS::LoadedCallback LoadedCallback;
37  typedef typename FS::DetachCallback DetachCallback;
38 
39  typedef S Sink;
40  typedef typename Sink::Ptr SinkPtr;
41 
44  {
45  public:
46  typedef boost::shared_ptr<Config> Ptr;
47 
48  explicit Config(FS* input)
49  : inputSink(Sink::Make(input))
50  {
51  }
52 
53  explicit Config(const SinkPtr& input)
54  : inputSink(input ? input : Sink::Make(0))
55  {
56  }
57 
58  explicit Config(const Config& cfg)
60  , inputSink(cfg.inputSink)
61  {
62  static_cast<DtTerrainInterfaceConfig&>(*this) = cfg;
63  }
64 
65  void addTile(const DtFeature& feature)
66  {
67  if (tileFeatures)
68  tileFeatures->addFeature(feature);
69  }
70 
71  boost::shared_ptr<DtFeatureSet::Source> tileFeatures;
72 
74  };
75 
76  static FS* Make(const Config& cfg, const DtProj::Bounds& bounds)
77  {
78  return Make(new Config(cfg), bounds);
79  }
80 
81  static FS* Make(Config* cfg, const DtProj::Bounds& bounds)
82  {
83  return Make(boost::shared_ptr<Config>(cfg), bounds);
84  }
85 
86  static FS* Make(const boost::shared_ptr<Config>& cfg, const DtProj::Bounds& bounds)
87  {
88  Ptr set(new DtIndexingFeatureSet(typename Config::Ptr(cfg), bounds));
89  set->init();
90 
91  return FS::Wrap(set);
92  }
93 
95  {
96  //myTileFeature.setDeleted();
97  }
98 
99  FS* clone() const
100  {
101  return FS::Wrap(this->shared_from_this());
102  }
103 
104  std::string label() const
105  {
106  return myConfig->inputSink->label() + " index level "
107  + boost::lexical_cast<std::string>(myLevel);
108  }
109 
110  bool loaded(double timeout) const
111  {
112  return myFeatures->loaded(timeout);
113  }
114 
116  {
117  return myFeatures->addLoadedCallback(cb);
118  }
119 
120  unsigned numberOfFeatures() const
121  {
122  return myFeatures->numberOfFeatures();
123  }
124 
125  bool elided() const
126  {
127  return myFeatures->elided();
128  }
129 
130  bool empty() const
131  {
132  return myFeatures->empty();
133  }
134 
135  FS* filter(
136  const DtQuery& query,
137  const boost::optional<DtFeatureGeometry>& geometry,
138  DtLoadType load) const
139  {
141  if (!geometry)
142  return myFeatures->filter(query, boost::none_t(), load);
143 
145  if (myState != ACTIVE)
146  return myFeatures->filter(query, geometry, load);
147 
148  bool covers[4] = { false, false, false, false };
149  bool intersections[4] = { false, false, false, false };
150  size_t lastIntersection = 0;
151  unsigned numIntersects = 0;
152 
155  switch (geometry->type())
156  {
158  for (unsigned i=0; i != 4; ++i)
159  {
160  if (!geometry->intersects(this->getSubtile(i).geometry()))
161  continue;
162 
163  intersections[i] = true;
164  ++numIntersects;
165  lastIntersection = i;
166  break;
167  }
168 
169  break;
170 
172  for (unsigned i=0; i != 4; ++i)
173  {
174  if (!geometry->intersects(this->getSubtile(i).geometry()))
175  continue;
176 
177  intersections[i] = true;
178  ++numIntersects;
179  lastIntersection = i;
180  }
181 
182  break;
183 
184  default:
185  for (unsigned i=0; i != 4; ++i)
186  {
187  std::auto_ptr<DtFeatureGeometry::RelationshipMatrix> matrix
188  = geometry->relate(this->getSubtile(i).geometry());
189 
190  if (!matrix->intersects())
191  continue;
192 
194  if (matrix->touches())
195  continue;
196 
197  intersections[i] = true;
198  ++numIntersects;
199  lastIntersection = i;
200 
202  if (matrix->covers())
203  covers[i] = true;
204 
206  if (matrix->coveredBy())
207  break;
208  }
209  }
210 
213  switch (numIntersects)
214  {
215  case 0: return 0;
216  case 1: return getSubtile(lastIntersection).indexedFeatures().filter(
217  query,
218  !covers[lastIntersection] ? geometry : boost::none_t(),
219  load);
220  }
221 
223  std::auto_ptr< DtFeatureSetList<FS> > list(new DtFeatureSetList<FS>(4));
224  for (size_t i=0; i != 4; ++i)
225  {
226  if (!intersections[i])
227  continue;
228 
229  list->add(getSubtile(i).indexedFeatures().filter(
230  query,
231  !covers[i] ? geometry : boost::none_t(),
232  load));
233  }
234 
235  return list.release();
236  }
237 
238  void forEachFeatureParallel(const ForEachFunction& func) const
239  {
240  myFeatures->forEachFeatureParallel(func);
241  }
242 
244  {
245  return myFeatures->forEachFeatureAsync(func);
246  }
247 
248  protected:
249  class Subtile;
250 
251  DtIndexingFeatureSet(const Ptr& parent, const Subtile& subtile)
252  : myConfig(parent->myConfig)
253  , myLevel(parent->myLevel + 1)
254  , myParent(parent)
255  , myTileGeometry(subtile.geometry())
256  , myFeatures(subtile.sink())
257  , mySubtile0(*myFeatures, subtile.bounds(), 0)
258  , mySubtile1(*myFeatures, subtile.bounds(), 1)
259  , mySubtile2(*myFeatures, subtile.bounds(), 2)
260  , mySubtile3(*myFeatures, subtile.bounds(), 3)
261  //, myTileFeature(myTileGeometry.boundary(), 0xAA00FF, 1)
262  {
263  myState = START;
264  //myConfig->addTile(myTileFeature);
265  }
266 
268  const boost::shared_ptr<Config>& cfg,
269  const DtProj::Bounds& bounds)
270  : myConfig(cfg)
271  , myLevel(0)
272  , myTileGeometry(DtFeatureGeometry::MakeBox(bounds))
273  , myFeatures(cfg->inputSink)
274  , mySubtile0(*myFeatures, bounds, 0)
275  , mySubtile1(*myFeatures, bounds, 1)
276  , mySubtile2(*myFeatures, bounds, 2)
277  , mySubtile3(*myFeatures, bounds, 3)
278  //, myTileFeature(myTileGeometry.boundary(), 0xAA00FF, 1)
279  {
280  myState = START;
281  }
282 
283  const Subtile& getSubtile(unsigned i) const
284  {
285  switch (i)
286  {
287  case 0: return mySubtile0;
288  case 1: return mySubtile1;
289  case 2: return mySubtile2;
290  case 3: return mySubtile3;
291  }
292 
293  assert(false);
294  DtTHROW_NEW(DtException, "Tile index out of bounds");
295  }
296 
298  void init()
299  {
300  Ptr This(this->shared_from_this());
301 
302  mySubtile0.init(This);
303  mySubtile1.init(This);
304  mySubtile2.init(This);
305  mySubtile3.init(This);
306  }
307 
310  {
313  if (myState.compare_and_swap(ACTIVATING, START) != START)
314  return false;
315 
316  try
317  {
318  Ptr This(this->shared_from_this());
319  mySubtile0.activate(This);
320  mySubtile1.activate(This);
321  mySubtile2.activate(This);
322  mySubtile3.activate(This);
323  }
324  catch (...)
325  {
326  myState = FAULT;
327  throw;
328  }
329 
330  if (myState.compare_and_swap(ACTIVE, ACTIVATING) != ACTIVATING)
331  {
332  DtWarn << "Error activating subtile" << std::endl;
333  myState = FAULT;
334  return false;
335  }
336 
337  return true;
338  }
339 
341  const boost::shared_ptr<Config> myConfig;
342 
344  const int myLevel;
345 
347  const WPtr myParent;
348 
351 
354 
356  class Subtile
357  {
361  boost::shared_ptr<DtIndexingFeatureSet> myIndexingSet;
362 
363  public:
364  const DtFeatureGeometry& geometry() const { return myGeometry; }
365  const DtProj::Bounds& bounds() const { return myBounds; }
366  const SinkPtr& sink() const { return mySink; }
367  const FS& indexedFeatures() const { return *myIndexingSet; }
368 
369  Subtile(const Sink& parentFeatures, const DtProj::Bounds& pbounds, unsigned i)
370  : myBounds(pbounds.makeSubBounds(i,2,2))
371  , myGeometry(DtFeatureGeometry::MakeBox(bounds()))
372  , mySink(Sink::Make(parentFeatures, geometry()))
373  {
374  }
375 
376  void init(const Ptr& parent)
377  {
378  Caller caller(parent, *this);
379  mySink->addLoadedCallback(caller);
380 
381  checkIndex(*parent);
382  }
383 
384  void activate(const Ptr& parent)
385  {
386  myIndexingSet.reset(new DtIndexingFeatureSet(parent, *this));
387  myIndexingSet->init();
388  }
389 
390  private:
392  {
393  try
394  {
395  if (!mySink->loaded())
396  return;
397  }
399  {
400  return;
401  }
402 
403  if (parent.myLevel >= parent.myConfig->featuresMaxIndexLOD)
404  return;
405 
406  size_t pc = parent.numberOfFeatures();
407  size_t c = mySink->numberOfFeatures();
408 
409  assert(pc >= c);
410 
412  if (pc <= parent.myConfig->minFeaturesToIndexTile)
413  return;
414 
415  if (c > 0)
416  {
417  if (pc/(double)c >= parent.myConfig->featuresIndexRatio)
418  parent.activateSubtiles();
419  }
420  else
421  {
423  //if (pc > 0)
425  }
426  }
427 
428  class Caller
429  {
430  public:
431  explicit Caller(const Ptr& set, Subtile& subtile)
432  : set(set), subtile(subtile)
433  {
434  }
435 
436  void operator()() const
437  {
438  Ptr p(set.lock());
439  if (p)
440  subtile.checkIndex(*p);
441  }
442 
443  private:
446  };
447  };
448 
449  friend class Subtile;
450 
455 
456  enum State
457  {
459  };
460 
461  tbb::atomic<State> myState;
462 
463  //DtTileFeature myTileFeature;
464  };
465 }
boost::shared_ptr< DtFeatureSet::Source > tileFeatures
Definition: indexingFeatureSet.h:71
Definition: indexingFeatureSet.h:458
friend class Subtile
Definition: indexingFeatureSet.h:449
Class DtTerrainInterfaceConfig is a readable-writable class holding terrain interface configuration o...
Definition: terrainInterfaceConfig.h:32
static const int PathType
Definition: featureGeometry.h:57
Definition: indexingFeatureSet.h:25
tbb::atomic< State > myState
Definition: indexingFeatureSet.h:461
Sink::Ptr SinkPtr
Definition: indexingFeatureSet.h:40
static FS * Make(const Config &cfg, const DtProj::Bounds &bounds)
Definition: indexingFeatureSet.h:76
void init()
Delayed init needed b/c we need a shared_ptr to ourself.
Definition: indexingFeatureSet.h:298
boost::shared_ptr< const DtIndexingFeatureSet > CPtr
Definition: indexingFeatureSet.h:31
void operator()() const
Definition: indexingFeatureSet.h:436
Definition: indexingFeatureSet.h:458
FS * filter(const DtQuery &query, const boost::optional< DtFeatureGeometry > &geometry, DtLoadType load) const
Definition: indexingFeatureSet.h:135
boost::shared_ptr< DtIndexingFeatureSet > Ptr
Definition: indexingFeatureSet.h:30
Subtile mySubtile3
Definition: indexingFeatureSet.h:454
void init(const Ptr &parent)
Definition: indexingFeatureSet.h:376
const int myLevel
Level in hierarchy.
Definition: indexingFeatureSet.h:344
FS::DetachCallback DetachCallback
Definition: indexingFeatureSet.h:37
const Subtile & getSubtile(unsigned i) const
Definition: indexingFeatureSet.h:283
const boost::shared_ptr< Config > myConfig
Configuration data for this node.
Definition: indexingFeatureSet.h:341
Definition: featureGeometry.h:60
Subtile mySubtile2
Definition: indexingFeatureSet.h:453
Definition: proj.h:68
FS::ForEachFunction ForEachFunction
Definition: indexingFeatureSet.h:35
bool elided() const
Definition: indexingFeatureSet.h:125
Subtile(const Sink &parentFeatures, const DtProj::Bounds &pbounds, unsigned i)
Definition: indexingFeatureSet.h:369
Definition: indexingFeatureSet.h:458
Subtile mySubtile1
Definition: indexingFeatureSet.h:452
boost::shared_ptr< Config > Ptr
Definition: indexingFeatureSet.h:46
const FS & indexedFeatures() const
Definition: indexingFeatureSet.h:367
bool empty() const
Definition: indexingFeatureSet.h:130
Subtile & subtile
Definition: indexingFeatureSet.h:445
DetachCallback forEachFeatureAsync(const ForEachFunction &func) const
Definition: indexingFeatureSet.h:243
const WPtr myParent
Weak pointer to parent node.
Definition: indexingFeatureSet.h:347
SinkPtr myFeatures
Features in this tile.
Definition: indexingFeatureSet.h:353
Represents a set of characeters a DtFeature object can have. DtQuery objects are the way to communica...
Definition: query.h:38
const DtFeatureGeometry & geometry() const
Definition: indexingFeatureSet.h:364
Subtile mySubtile0
Definition: indexingFeatureSet.h:451
boost::weak_ptr< DtIndexingFeatureSet > WPtr
Definition: indexingFeatureSet.h:32
void checkIndex(DtIndexingFeatureSet &parent)
Definition: indexingFeatureSet.h:391
FS::LoadedCallback LoadedCallback
Definition: indexingFeatureSet.h:36
static const int PointType
Definition: featureGeometry.h:56
Definition: indexingFeatureSet.h:428
static FS * Make(const boost::shared_ptr< Config > &cfg, const DtProj::Bounds &bounds)
Definition: indexingFeatureSet.h:86
Set of subtiles.
Definition: indexingFeatureSet.h:356
const SinkPtr inputSink
Definition: indexingFeatureSet.h:73
State
Definition: indexingFeatureSet.h:456
bool loaded(double timeout) const
Definition: indexingFeatureSet.h:110
boost::shared_ptr< DtIndexingFeatureSet > myIndexingSet
Definition: indexingFeatureSet.h:361
static FS * Make(Config *cfg, const DtProj::Bounds &bounds)
Definition: indexingFeatureSet.h:81
Caller(const Ptr &set, Subtile &subtile)
Definition: indexingFeatureSet.h:431
~DtIndexingFeatureSet()
Definition: indexingFeatureSet.h:94
void forEachFeatureParallel(const ForEachFunction &func) const
Definition: indexingFeatureSet.h:238
std::string label() const
Definition: indexingFeatureSet.h:104
FS * clone() const
Definition: indexingFeatureSet.h:99
S Sink
Definition: indexingFeatureSet.h:39
DtProj::Bounds myBounds
Definition: indexingFeatureSet.h:358
Configuration information.
Definition: indexingFeatureSet.h:43
Config(FS *input)
Definition: indexingFeatureSet.h:48
DtLoadType
Used to indicate whether to load features. See DtFeatureSetTemplate::filter.
Definition: featureSet.h:36
const DtFeatureGeometry::Area myTileGeometry
Geometry object representing this tile.
Definition: indexingFeatureSet.h:350
const DtProj::Bounds & bounds() const
Definition: indexingFeatureSet.h:365
DtIndexingFeatureSet(const Ptr &parent, const Subtile &subtile)
Definition: indexingFeatureSet.h:251
WPtr set
Definition: indexingFeatureSet.h:444
Config(const Config &cfg)
Definition: indexingFeatureSet.h:58
Definition: indexingFeatureSet.h:458
DtFeatureSet used to combine multiple feature sets into one. This class allows all feature set algori...
Definition: featureSetList.h:26
void addTile(const DtFeature &feature)
Definition: indexingFeatureSet.h:65
SinkPtr mySink
Definition: indexingFeatureSet.h:360
void activate(const Ptr &parent)
Definition: indexingFeatureSet.h:384
Represents a GIS feature. Features consist of a DtFeatureGeometry (2.5D geometric vector data) and a ...
Definition: feature.h:37
DtIndexingFeatureSet(const boost::shared_ptr< Config > &cfg, const DtProj::Bounds &bounds)
Definition: indexingFeatureSet.h:267
DetachCallback addLoadedCallback(const LoadedCallback &cb) const
Definition: indexingFeatureSet.h:115
FS::Feature Feature
Definition: indexingFeatureSet.h:34
Config(const SinkPtr &input)
Definition: indexingFeatureSet.h:53
DtFeatureGeometry myGeometry
Definition: indexingFeatureSet.h:359
Represents a feature geometry.
Definition: featureGeometry.h:39
unsigned numberOfFeatures() const
Definition: indexingFeatureSet.h:120
bool activateSubtiles()
Mark subtiles and read to use.
Definition: indexingFeatureSet.h:309
const SinkPtr & sink() const
Definition: indexingFeatureSet.h:366

Document ID: Generated on Wed Mar 27 22:49:11 EDT 2024 from SVN revision 264633
Copyright © 2005-2024 MAK Technologies. All Rights Reserved (www.mak.com)