VR-Forces Developer's Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
feature.h
Go to the documentation of this file.
1 /******************************************************************************
2  * Copyright (c) 2014 MAK Technologies, Inc.
3  * All rights reserved.
4  ******************************************************************************/
8 
9 #pragma once
10 
13 
14 #include <boost/function.hpp>
15 #include <boost/variant.hpp>
16 #include <boost/lexical_cast.hpp>
17 #include <boost/signals2.hpp>
18 
19 #include <tbb/spin_mutex.h>
20 
21 #include <vrfutil/objectCounter.h>
22 
23 #include <vlutil/vlPrint.h>
24 
25 namespace MAKVRinTerra
26 {
37 #ifdef DtObjectDebugger_Enable
38  : public DtObjectDebugger<DtFeature>
39 #endif
40  {
41  public:
42  static const char* TypeName;
43 
44  typedef std::shared_ptr<DtFeature> Ptr;
45  typedef std::shared_ptr<const DtFeature> CPtr;
46 
47  DtFeature() {};
48 
50  typedef boost::variant<
51  std::string,
52  long long,
53  bool,
54  double
55  > Attribute;
56 
58  template <typename T>
59  static boost::optional<T> ConvertAttribute(const Attribute& attr)
60  {
61  return boost::apply_visitor(AttributeConverter<T>(), attr);
62  }
63 
68  {
71  {
72  public:
73  String();
74  String(const std::string&);
75  String(const char*);
76 
78  const char* c_str() const;
79 
81  const std::string& str() const;
82 
83  bool operator==(const String&) const;
84  bool operator!=(const String&) const;
85  bool operator<(const String&) const;
86 
87  private:
88  std::string myString;
89  };
90 
91  Key(const std::string& name, unsigned index = 0);
92  Key(const String& name, unsigned index = 0);
93  Key(const char* name, unsigned index = 0);
94  Key(const Key& key, unsigned index = 0);
95 
96  bool operator== (const Key&) const;
97  bool operator!= (const Key&) const;
98  bool operator< (const Key&) const;
99 
101  unsigned index;
102  };
103 
106  static bool Equal(const Attribute&, const Attribute&);
107  static bool NotEqual(const Attribute&, const Attribute&);
108  static bool Less(const Attribute&, const Attribute&);
109  static bool LessOrEqual(const Attribute&, const Attribute&);
110  static bool Greater(const Attribute&, const Attribute&);
111  static bool GreaterOrEqual(const Attribute&, const Attribute&);
112  static bool Regex(const Attribute& text, const Attribute& pattern);
114 
116  static std::string TypeOfAttribute(const Attribute&);
117 
119  static std::unique_ptr<DtFeature> CreateEmptyFeature();
120 
122  static std::unique_ptr<DtFeature> CreateGeometryFeature(const DtFeatureGeometry&);
123 
126  static std::unique_ptr<DtFeature> CreateGeometryFeature(
127  const DtFeatureGeometry&,
128  unsigned char red, unsigned char green, unsigned char blue);
129 
132  static std::unique_ptr<DtFeature> CreateCopy(const DtFeature& feature);
133 
135  virtual ~DtFeature();
136 
143  virtual DtFeature* clone() const;
144 
150  virtual DtFeatureGeometry geometry() const { return DtFeatureGeometry(); };
151 
153  typedef boost::function<void (const Key&, const Attribute&)> ForEachFunction;
154 
156  virtual void forEachAttribute(ForEachFunction f) const {};
157 
159  virtual unsigned numberOfAttributes(const Key::String &) const { return 0; };
160 
162  virtual bool hasAttribute(const Key & k) const;
163 
165  virtual boost::optional<Attribute> attribute(const Key &) const {return boost::none;};
166 
168  template <typename T>
169  boost::optional<T> attributeAs(const Key& k) const
170  {
171  if (boost::optional<Attribute> attr = attribute(k))
172  return boost::apply_visitor(AttributeConverter<T>(), *attr);
173 
174  return boost::none;
175  }
176 
179  typedef boost::function<void ()> DetachCallback;
180 
182  typedef boost::function<void ()> DeleteCallback;
183 
193  const DeleteCallback& callback) const { return callback; };
194 
199  virtual bool isDeleted() const { return false; };
200 
201  public:
202  //Defining copy ctor here to satisfy boost::bind & compiler. However, we pass all DtFeature objects by reference so this function should
203  //never be hit. (used in attributeConfigParser.cxx::stringParser ctor)
204  DtFeature(const DtFeature&) { throw std::runtime_error("DtFeature copy ctor, should not hit! At " __FILE__ ":" + __LINE__); };
205 
206  private:
209  template <typename T>
210  struct AttributeConverter : public boost::static_visitor< boost::optional<T> >
211  {
212  template <typename From>
213  boost::optional<T> operator()(const From& from) const
214  {
215  try
216  {
217  return boost::lexical_cast<T>(from);
218  }
219  catch (boost::bad_lexical_cast&)
220  {
221  return boost::optional<T>();
222  }
223  }
224  };
225  };
226 
227  template <typename Feature, typename Inner = Feature>
228  class DtFeatureRefWrapper : public Feature
229  {
230  public:
231  typedef typename Feature::ForEachFunction ForEachFunction;
232  typedef typename Feature::Attribute Attribute;
233  typedef typename Feature::Key Key;
234 
235  typedef typename Inner::DetachCallback DetachCallback;
236 
238  {
239  return myFeature.geometry();
240  }
241 
243  {
244  myFeature.forEachAttribute(func);
245  }
246 
247  unsigned numberOfAttributes(const typename Key::String& str) const
248  {
249  return myFeature.numberOfAttributes(str);
250  }
251 
252  boost::optional<Attribute> attribute(const Key& key) const
253  {
254  return myFeature.attribute(key);
255  }
256 
258  const typename Inner::DeleteCallback& callback) const
259  {
260  return myFeature.addDeleteCallback(callback);
261  }
262 
263  bool isDeleted() const
264  {
265  return myFeature.isDeleted();
266  }
267 
268  Feature* clone() const
269  {
270  return myFeature.clone();
271  }
272 
275  : myFeature(from.myFeature)
276  {
277  }
278 
279  explicit DtFeatureRefWrapper(const Inner& feature)
280  : myFeature(feature)
281  {
282  }
283 
284  //protected:
285  //Inner& wrappedFeature() { return myFeature; }
286  //const Inner& wrappedFeature() const { return myFeature; }
287 
288  protected:
289  const Inner& myFeature;
290  };
291 
299  template <typename Feature, typename Inner = Feature>
300  class DtFeatureWrapper : public Feature
301  {
302  public:
303  typedef std::shared_ptr<DtFeatureWrapper> Ptr;
304  typedef std::shared_ptr<const DtFeatureWrapper> CPtr;
305 
306  typedef typename Feature::ForEachFunction ForEachFunction;
307  typedef typename Feature::Attribute Attribute;
308  typedef typename Feature::Key Key;
309 
310  typedef typename Inner::DetachCallback DetachCallback;
311 
313  {
316  myConnection.disconnect();
317  }
318 
320  {
321  return myData->feature->geometry();
322  }
323 
325  {
326  myData->feature->forEachAttribute(func);
327  }
328 
329  unsigned numberOfAttributes(const typename Key::String& str) const
330  {
331  return myData->feature->numberOfAttributes(str);
332  }
333 
334  boost::optional<Attribute> attribute(const Key& key) const
335  {
336  return myData->feature->attribute(key);
337  }
338 
340 #ifdef DtObjectDebugger_Enable
341  : public DtObjectDebugger<DeletedCounter>
342 #endif
343  {
344  const typename Inner::DeleteCallback callback;
345  explicit DeletedCounter(const typename Inner::DeleteCallback& cb) : callback(cb) { }
346  void operator()() const { callback(); }
347  };
348 
350  const typename Inner::DeleteCallback& callback) const
351  {
352  if (!callback)
353  return DetachCallback();
354 
355  Mutex::scoped_lock lock(myData->mutex);
356  if (myData->deleted)
357  {
358  lock.release();
359  callback();
360  return DetachCallback();
361  }
362 
363  Connection conn = mySignal.connect(
364  DeletedCounter(callback), boost::signals2::at_front);
365 
366  return boost::bind(&Connection::disconnect, conn);
367  }
368 
369  bool isDeleted() const
370  {
371  Mutex::scoped_lock lock(myData->mutex);
372  return myData->deleted;
373  }
374 
376  {
377  return new DtFeatureWrapper(*this);
378  }
379 
380  void setDeleted()
381  {
382  typename Data::SPtr d(myData);
383  d->deletedCallback();
384  }
385 
387  explicit DtFeatureWrapper(const DtFeatureWrapper& from)
388  : myData(from.myData)
389  , myConnection()
390  {
391  Mutex::scoped_lock lock(myData->mutex);
392  if (!myData->deleted)
393  myConnection = myData->signal.connect(std::ref(mySignal), boost::signals2::at_front);
394  }
395 
396  explicit DtFeatureWrapper(const typename Inner::Ptr& f)
397  : myData(new Data(f))
398  , myConnection(myData->signal.connect(std::ref(mySignal)))
399  {
400  myData->init(myData);
401  }
402 
404  explicit DtFeatureWrapper(Inner* feature)
405  : myData(new Data(typename Inner::Ptr(feature)))
406  , myConnection(myData->signal.connect(std::ref(mySignal)))
407  {
408  myData->init(myData);
409  }
410 
411  explicit DtFeatureWrapper(const Inner& feature)
412  : myData(new Data(typename Inner::Ptr(feature.clone())))
413  , myConnection(myData->signal.connect(std::ref(mySignal)))
414  {
415  myData->init(myData);
416  }
417 
418  Inner& wrappedFeature() { return *myData->feature; }
419  const Inner& wrappedFeature() const { return *myData->feature; }
420 
423 
424  private:
425  typedef tbb::spin_mutex Mutex;
426 
427  typedef boost::signals2::signal_type<
428  void (),
429  boost::signals2::keywords::mutex_type<tbb::spin_mutex> >::type Signal;
430 
431  typedef boost::signals2::connection Connection;
432 
434  struct Data : boost::noncopyable
435  {
436  public:
437  typedef std::shared_ptr<Data> SPtr;
438  typedef std::weak_ptr<Data> WPtr;
439 
441  {
442  Mutex::scoped_lock lock(mutex);
443  if (!deleted)
444  {
445  deleted = true;
446  DetachCallback localDetacher;
447  swap(localDetacher, detacher);
448 
449  lock.release();
450 
451  try
452  {
453  if (localDetacher)
454  localDetacher();
455 
456  signal();
457  signal.disconnect_all_slots();
458  }
459  catch (...)
460  {
461  DtWarn << "Exception thrown in delete callback" << std::endl;
462  }
463  }
464  }
465 
466  explicit Data(const typename Inner::Ptr& f)
467  : feature(f)
469  {
470  }
471 
473  {
474  if (detacher)
475  detacher();
476  }
477 
478  bool init(const SPtr& This)
479  {
480  assert(!detacher);
481 
482  if (!deleted)
483  detacher = feature->addDeleteCallback(Caller(This));
484 
485  return detacher;
486  }
487 
489  struct Caller
490  {
492  explicit Caller(const SPtr& data) : datawptr(data) { }
493 
494  void operator()() const
495  {
496  SPtr data(datawptr.lock());
497  if (data)
498  data->deletedCallback();
499  }
500  };
501 
502  mutable Mutex mutex;
503  typename Inner::Ptr feature;
506  bool deleted;
507  };
508 
512  std::shared_ptr<Data> myData;
513  mutable Signal mySignal;
515  };
516 
517  DT_DLL_features std::ostream& operator<<(std::ostream&, const DtFeature::Attribute&);
518  DT_DLL_features std::ostream& operator<<(std::ostream&, const DtFeature&);
519  DT_DLL_features std::ostream& operator<<(std::ostream&, const DtFeature::Key&);
520  DT_DLL_features std::ostream& operator<<(std::ostream&, const DtFeature::Key::String&);
521 
529 }
530 
Feature::Attribute Attribute
Definition: feature.h:307
#define DT_DLL_features
stop complaining about multiple independent base classes for boost::noncopyable this should probably ...
Definition: featuresDefines.h:41
void operator()() const
Definition: feature.h:494
boost variant visitor for converting attributes with lexical_cast lexical_cast will not do anything f...
Definition: feature.h:210
Data(const typename Inner::Ptr &f)
Definition: feature.h:466
DtFeatureGeometry geometry() const
Definition: feature.h:319
Key used to lookup attributes. The DtFeature interface is a dictionary that maps Key objects to attri...
Definition: feature.h:67
Inner::DetachCallback DetachCallback
Definition: feature.h:310
bool deleted
Definition: feature.h:506
Inner::DetachCallback DetachCallback
Definition: feature.h:235
void forEachAttribute(ForEachFunction func) const
Definition: feature.h:242
boost::signals2::signal_type< void(), boost::signals2::keywords::mutex_type< tbb::spin_mutex > >::type Signal
Definition: feature.h:429
Wraps a feature object and makes sure all the callbacks are unhooked correctly In order to wrap a fea...
Definition: feature.h:300
bool isDeleted() const
Definition: feature.h:263
std::string myString
Definition: feature.h:88
DtFeatureWrapper * clone() const
Definition: feature.h:375
Feature::Attribute Attribute
Definition: feature.h:232
const Inner & myFeature
Definition: feature.h:289
std::shared_ptr< const DtFeatureWrapper > CPtr
Definition: feature.h:304
DT_DLL_terrainCS bool operator==(const DtDegMinSec &lhs, const DtDegMinSec &rhs)
#define DT_DEFINE_OBJECT_DEBUGGER_NAME(type)
Definition: objectCounter.h:31
Default on in debug, off in release.
Definition: objectCounter.h:27
Feature::Key Key
Definition: feature.h:308
DT_DLL_features std::ostream & operator<<(std::ostream &, const DtFeatureTransform &)
std::ostream output.
DtFeatureRefWrapper(const Inner &feature)
Definition: feature.h:279
void setDeleted()
Definition: feature.h:380
Feature::ForEachFunction ForEachFunction
Definition: feature.h:231
DetachCallback addDeleteCallback(const typename Inner::DeleteCallback &callback) const
Definition: feature.h:349
Inner & wrappedFeature()
Definition: feature.h:418
boost::optional< T > operator()(const From &from) const
Definition: feature.h:213
std::shared_ptr< DtFeature > Ptr
Definition: feature.h:44
DtFeatureWrapper(const Inner &feature)
Definition: feature.h:411
Mutex mutex
Definition: feature.h:502
unsigned numberOfAttributes(const typename Key::String &str) const
Definition: feature.h:329
boost::function< void()> DetachCallback
Callback used to detach the user from a feature so the users callback is not called anymore...
Definition: feature.h:179
DeletedCounter(const typename Inner::DeleteCallback &cb)
Definition: feature.h:345
bool init(const SPtr &This)
Definition: feature.h:478
std::shared_ptr< Data > SPtr
Definition: feature.h:437
DtFeature()
Definition: feature.h:47
virtual bool isDeleted() const
Check to see if feature has been deleted. Note: this is not related to C++ delete or destructors...
Definition: feature.h:199
~DtFeatureWrapper()
Definition: feature.h:312
static boost::optional< T > ConvertAttribute(const Attribute &attr)
Convert an attribute to a type using iostream.
Definition: feature.h:59
String name
Definition: feature.h:100
bool isDeleted() const
Definition: feature.h:369
Feature::ForEachFunction ForEachFunction
Definition: feature.h:306
Connection myConnection
Definition: feature.h:514
unsigned index
Definition: feature.h:101
static const char * TypeName
Definition: feature.h:42
DtFeatureGeometry geometry() const
Definition: feature.h:237
unsigned numberOfAttributes(const typename Key::String &str) const
Definition: feature.h:247
boost::function< void(const Key &, const Attribute &)> ForEachFunction
Callback used to iterating through attributes with ForEachAttribute.
Definition: feature.h:150
DtFeatureWrapper(const typename Inner::Ptr &f)
Definition: feature.h:396
const Inner & wrappedFeature() const
Definition: feature.h:419
boost::function< void()> DeleteCallback
User supplied callback called when feature is deleted.
Definition: feature.h:182
Signal signal
Definition: feature.h:505
boost::optional< Attribute > attribute(const Key &key) const
Definition: feature.h:334
DetachCallback addDeleteCallback(const typename Inner::DeleteCallback &callback) const
Definition: feature.h:257
Feature * clone() const
Definition: feature.h:268
Signal mySignal
Definition: feature.h:513
typedef long(ZCALLBACK *tell_file_func) OF((voidpf opaque
~Data()
Definition: feature.h:472
virtual void forEachAttribute(ForEachFunction f) const
Calls the provided callback on each attribute.
Definition: feature.h:156
boost::optional< T > attributeAs(const Key &k) const
Return attribute as a specific type using build in conversion methods.
Definition: feature.h:169
virtual DetachCallback addDeleteCallback(const DeleteCallback &callback) const
Add a user supplied callback to the feature to be called when the feature is deleted. If the feature is already deleted the callback may or may not be called by the implementation of this function. The callback is guaranteed to only be called once.
Definition: feature.h:192
DT_DEFINE_OBJECT_DEBUGGER_NAME_TEMPLATE2(MAKVRinTerra::DtFeatureWrapper)
std::shared_ptr< const DtFeature > CPtr
Definition: feature.h:45
boost signal for attaching to delete signal
Definition: feature.h:434
DtFeatureWrapper(const DtFeatureWrapper &from)
Copy constructor.
Definition: feature.h:387
void forEachAttribute(ForEachFunction func) const
Definition: feature.h:324
Caller(const SPtr &data)
Definition: feature.h:492
Functor for calling delete signal.
Definition: feature.h:489
const Inner::DeleteCallback callback
Definition: feature.h:344
virtual DtFeatureGeometry geometry() const
Get the geometry associated with this feature. GIS features each typically each associated with one g...
Definition: feature.h:150
Case insensitive string.
Definition: feature.h:70
void operator()() const
Definition: feature.h:346
virtual unsigned numberOfAttributes(const Key::String &) const
Number of attributes with a given key.
Definition: feature.h:159
std::shared_ptr< Data > myData
all the users of this object will attach their callbacks through this signal it will be called by the...
Definition: feature.h:512
DT_DLL_terrainCS bool operator!=(const DtDegMinSec &lhs, const DtDegMinSec &rhs)
std::weak_ptr< Data > WPtr
Definition: feature.h:438
tbb::spin_mutex Mutex
typename Inner::Ptr&amp; wrappedFeaturePtr() { return myData-&gt;feature; } const typename Inner::Ptr&amp; wrapp...
Definition: feature.h:425
Represents a GIS feature. Features consist of a DtFeatureGeometry (2.5D geometric vector data) and a ...
Definition: feature.h:36
DetachCallback detacher
Definition: feature.h:504
Definition: feature.h:228
DtFeatureWrapper(Inner *feature)
Create from instance of wrapped type.
Definition: feature.h:404
Feature::Key Key
Definition: feature.h:233
std::shared_ptr< DtFeatureWrapper > Ptr
Definition: feature.h:303
Inner::Ptr feature
Definition: feature.h:503
boost::optional< Attribute > attribute(const Key &key) const
Definition: feature.h:252
Represents a feature geometry.
Definition: featureGeometry.h:40
virtual boost::optional< Attribute > attribute(const Key &) const
Get attribute at a certain key.
Definition: feature.h:165
DtFeatureRefWrapper(const DtFeatureRefWrapper &from)
Copy constructor.
Definition: feature.h:274
boost::variant< std::string, long long, bool, double > Attribute
boost::variant type for accessing attributes.
Definition: feature.h:47
void deletedCallback()
Definition: feature.h:440
WPtr datawptr
Definition: feature.h:491
DtFeature(const DtFeature &)
Definition: feature.h:204

Document ID: Generated on Thu Oct 23 22:29:17 EDT 2025 from SVN revision 280951
Copyright © 2005-2024 MAK Technologies. All Rights Reserved (www.mak.com)