World Ocean Simulation System (WOSS) library
woss-db-custom-data-container.h
Go to the documentation of this file.
1/* WOSS - World Ocean Simulation System -
2 *
3 * Copyright (C) 2009 Federico Guerra
4 * and regents of the SIGNET lab, University of Padova
5 *
6 * Author: Federico Guerra - federico@guerra-tlc.com
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation;
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22/*
23 * This software has been developed by Federico Guerra and SIGNET lab,
24 * University of Padova, in collaboration with the NATO Centre for
25 * Maritime Research and Experimentation (http://www.cmre.nato.int ;
26 * E-mail: pao@cmre.nato.int), whose support is gratefully acknowledged.
27 */
28
29
40#ifndef WOSS_DB_CUSTOM_DATA_CONTAINER_H
41#define WOSS_DB_CUSTOM_DATA_CONTAINER_H
42
43
44#include <map>
45#include <iostream>
46#include <time-definitions.h>
47#include <complex>
48
49namespace woss {
50
51
59 template < class T, class MidFunctor, class InFunctor, class Data, class OutComp = ::std::less<T>, class MidComp = ::std::less<double>, class InComp = ::std::less<double> >
61
62
63 protected:
64
65
69 typedef typename ::std::map< double, Data, InComp > InnerData;
70 typedef typename InnerData::iterator CDCInnerIt;
71 typedef typename InnerData::reverse_iterator CDCInnerRIt;
72 typedef typename InnerData::const_iterator CDCInnerCIt;
73 typedef typename InnerData::const_reverse_iterator CDCInnerCRIt;
74
78 typedef typename ::std::map< double, InnerData, MidComp > MediumData;
79 typedef typename MediumData::iterator CDCMediumIt;
80 typedef typename MediumData::const_iterator CDCMediumCIt;
81 typedef typename MediumData::reverse_iterator CDCMediumRIt;
82 typedef typename MediumData::const_reverse_iterator CDCMediumCRIt;
83
87 typedef ::std::map< T, MediumData, OutComp > CustomContainer;
88 typedef typename CustomContainer::iterator CDCIt;
89 typedef typename CustomContainer::reverse_iterator CDCRIt;
90 typedef typename CustomContainer::const_iterator CDCCIt;
91 typedef typename CustomContainer::const_reverse_iterator CDCCRIt;
92
93
94 public:
95
96#if __cplusplus >= 201103L // C++11 or later
97 static constexpr double DB_CDATA_ALL_MEDIUM_KEYS = -190.0;
98
99 static constexpr double DB_CDATA_ALL_INNER_KEYS = -10.0;
100#else
101 static const double DB_CDATA_ALL_MEDIUM_KEYS = -190.0;
102
103 static const double DB_CDATA_ALL_INNER_KEYS = -10.0;
104#endif // __cplusplus == 201103L
105
106 static const T DB_CDATA_ALL_OUTER_KEYS;
107
108
113
118
119
125 MediumData& operator[] ( const T& key ) { return data_map[key]; }
126
127
132 bool empty() const { return data_map.empty(); }
133
134
139 int size() const { return data_map.size(); }
140
141
152 const Data* get( const T& t = DB_CDATA_ALL_OUTER_KEYS, double b = DB_CDATA_ALL_MEDIUM_KEYS, double r = DB_CDATA_ALL_INNER_KEYS ) const;
153
160 const Data* get( const T& tx, const T& rx ) const;
161
162
174 bool insert( const Data& data, const T& t = DB_CDATA_ALL_OUTER_KEYS, double b = DB_CDATA_ALL_MEDIUM_KEYS, double r = DB_CDATA_ALL_INNER_KEYS );
175
187 void replace( const Data& data, const T& t = DB_CDATA_ALL_OUTER_KEYS, double b = DB_CDATA_ALL_MEDIUM_KEYS, double r = DB_CDATA_ALL_INNER_KEYS );
188
189
200 void erase( const T& t = DB_CDATA_ALL_OUTER_KEYS, double b = DB_CDATA_ALL_MEDIUM_KEYS, double r = DB_CDATA_ALL_INNER_KEYS );
201
202
203// void normalizeMap( const T& t );
204
205
209 void clear();
210
211
216 void setDebug( bool flag ) { debug = flag; }
217
218
223 bool usingDebug() { return debug; }
224
225
226 protected:
227
228
232 bool debug;
233
234
239
240
251 const Data* find( const T& t = DB_CDATA_ALL_OUTER_KEYS, double b = DB_CDATA_ALL_MEDIUM_KEYS, double r = DB_CDATA_ALL_INNER_KEYS ) const;
252
253
254 };
255
256
257 template < class T, class MidFunctor, class InFunctor, class Data, class OutComp, class MidComp, class InComp >
259
260
261 template < class T, class MidFunctor, class InFunctor, class Data, class OutComp, class MidComp, class InComp >
263 if ( data_map.empty() ) return NULL;
264
265 if ( debug ) ::std::cout << "CustomDataContainer::get() t = " << t << "; b = " << b << "; r = " << r << ::std::endl;
266
267 const Data* ptr = find();
268 if ( ptr != NULL ) return ptr;
269
270 CDCCIt it = data_map.find( t );
271 if ( it == data_map.end() ) return NULL;
272
273 CDCMediumCIt it2 = it->second.lower_bound( b );
274 CDCMediumCRIt rit2 = it->second.rbegin();
275
276 CDCInnerCIt it3;
277 CDCInnerCRIt rit3;
278
279 if ( it2 == it->second.end() ) {
280 if( rit2 == it->second.rend() ) return NULL;
281 it3 = rit2->second.lower_bound( r );
282 rit3 = rit2->second.rbegin();
283 if ( it3 != rit2->second.end() ) return &it3->second;
284 if ( rit3 != rit2->second.rend() ) return &rit3->second;
285 return NULL;
286 }
287 else {
288 it3 = it2->second.lower_bound( r );
289 rit3 = it2->second.rbegin();
290 if ( it3 != it2->second.end() ) return &it3->second;
291 if ( rit3 != it2->second.rend() ) return &rit3->second;
292 return NULL;
293 }
294 if ( it3 == it2->second.end() ) return NULL;
295 return &(it3->second);
296 }
297
298
299 template < class T, class MidFunctor, class InFunctor, class Data, class OutComp, class MidComp, class InComp >
301 MidFunctor mid_funct;
302 InFunctor in_funct;
303
304 double curr_b;
305 double curr_r;
306 double delta_b;
307 //double delta_r;
308 const Data* ret_val = NULL;
309
310 double curr_dist;
311 double min_dist = INFINITY;
312
313 if ( data_map.empty() == true ) {
314 if ( debug ) ::std::cout << "CustomDataContainer::get() data_map is empty " << ::std::endl;
315
316 return ret_val;
317 }
318
319 for ( CDCCIt it = data_map.begin(); it != data_map.end(); it++ ) {
320
321 if ( debug ) ::std::cout << "CustomDataContainer::get() start T = " << it->first << "; end T = " << rx << ::std::endl;
322
323 if ( it->first == DB_CDATA_ALL_OUTER_KEYS ) {
324 if ( debug ) ::std::cout << "CustomDataContainer::get() overriding start T = " << tx << "; end T = " << rx << ::std::endl;
325
326 curr_b = mid_funct(tx,rx);
327 curr_r = in_funct(tx,rx);
328 }
329 else {
330 curr_b = mid_funct(it->first,rx);
331 curr_r = in_funct(it->first,rx);
332 }
333
334 if ( debug ) ::std::cout << "CustomDataContainer::get() curr bearing = " << curr_b * 180.0 / M_PI
335 << "; curr range = " << curr_r << ::std::endl;
336
337 CDCMediumCIt itb = it->second.begin();
338 if ( itb->first == DB_CDATA_ALL_MEDIUM_KEYS ) delta_b = 0;
339 else {
340 itb = it->second.lower_bound( curr_b );
341 if ( itb == it->second.end() ) itb = (++(it->second.rbegin())).base();
342
343 delta_b = curr_b - itb->first;
344 if (delta_b < 0.0) delta_b = -delta_b;
345 if (delta_b > M_PI) delta_b = 2.0*M_PI - delta_b ;
346 }
347
348 double ort_dist = curr_r * sin(delta_b);
349 double ort_projection = ::std::sqrt( curr_r*curr_r - ort_dist*ort_dist );
350
351 if ( debug ) ::std::cout << "CustomDataContainer::get() nearest bearing = " << itb->first * 180.0 / M_PI
352 << "; diff bearing = " << delta_b * 180.0 / M_PI << "; orthog distance = " << ort_dist
353 << "; orthog range projection = " << ort_projection << ::std::endl;
354
355 CDCInnerCIt itr = itb->second.begin();
356 if ( itr->first == DB_CDATA_ALL_INNER_KEYS ) curr_dist = ort_dist;
357 else {
358 itr = itb->second.lower_bound( ort_projection );
359 if ( itr == itb->second.begin() || itr == itb->second.end() || itr->first == ort_projection ) {
360 if ( itr == itb->second.end() ) itr = (++(itb->second.rbegin())).base();
361 double adj_distance = ::std::abs( ort_projection - itr->first );
362 curr_dist = ::std::sqrt( ort_projection*ort_projection + adj_distance*adj_distance );
363 }
364 else {
365 double adj_distance = ::std::abs( ort_projection - itr->first );
366 double first_dist = ::std::sqrt( ort_projection*ort_projection + adj_distance*adj_distance );
367
368 if(debug) ::std::cout << "CustomDataContainer::get() first try, range = " << itr->first
369 << "; dist = " << first_dist << ::std::endl;
370
371 itr--;
372 adj_distance = ::std::abs( ort_projection - itr->first );
373 double before_dist = ::std::sqrt( ort_projection*ort_projection + adj_distance*adj_distance );
374
375 if (debug) ::std::cout << "CustomDataContainer::get() second try, range = " << itr->first
376 << "; dist = " << before_dist << ::std::endl;
377
378 curr_dist = ::std::min( first_dist, before_dist );
379 if ( curr_dist == first_dist ) itr++;
380 }
381 }
382 if ( debug ) ::std::cout << "CustomDataContainer::get() nearest range = " << itr->first << "; distance = " << curr_dist
383 << "; min distance = " << min_dist << ::std::endl;
384
385 if ( curr_dist < min_dist ) {
386 min_dist = curr_dist;
387 ret_val = &(itr->second);
388 if ( curr_dist == 0 ) break;
389 }
390
391 }
392
393 if ( debug && ret_val != NULL ) ::std::cout << "CustomDataContainer::get() ret value " << *ret_val << ::std::endl;
394
395 return ret_val;
396 }
397
398
399 template < class T, class MidFunctor, class InFunctor, class Data, class OutComp, class MidComp, class InComp >
401
402 if (this->debug) ::std::cout << "CustomDataContainer::find() << t = " << t << "; b = " << b << "; r = " << r << ::std::endl;
403
404 CDCCIt it = data_map.find( t );
405 if ( it == data_map.end() ) {
406
407 if ( debug ) ::std::cout << "CustomDataContainer::find() t not found" << ::std::endl;
408
409 return NULL;
410 }
411
412 if ( debug ) ::std::cout << "CustomDataContainer::find() t found" << ::std::endl;
413
414 CDCMediumCIt it2 = it->second.find( b );
415 if ( it2 == it->second.end() ) {
416
417 if ( debug ) ::std::cout << "CustomDataContainer::find() b not found" << ::std::endl;
418
419 return NULL;
420 }
421
422 if ( debug ) ::std::cout << "CustomDataContainer::find() b found" << ::std::endl;
423
424 CDCInnerCIt it3 = it2->second.find( r );
425 if ( it3 == it2->second.end() ) {
426
427 if ( debug ) ::std::cout << "CustomDataContainer::find() r not found" << ::std::endl;
428
429 return NULL;
430 }
431 if ( debug ) ::std::cout << "CustomDataContainer::find() r found, data = " << it3->second << ::std::endl;
432 return &(it3->second);
433 }
434
435
436 template < class T, class MidFunctor, class InFunctor, class Data, class OutComp, class MidComp, class InComp >
438 const Data* ptr = find( t, b, r );
439 if ( ptr != NULL ) return false;
440 data_map[t][b][r] = d;
441 return true;
442 }
443
444
445// template < class T, class MidFunctor, class InFunctor, class Data, class OutComp, class MidComp, class InComp >
446// void CustomDataContainer< T, MidFunctor, InFunctor, Data, OutComp, MidComp, InComp >::normalizeMap( const T& t ) {
447// MidFunctor mid_funct;
448// InFunctor in_funct;
449
450// double curr_b;
451// double curr_r;
452// double delta_b;
453// double delta_r;
454// const Data* ret_val = NULL;
455//
456// double curr_dist;
457// double min_dist = INFINITY;
458
459// for ( CDCCIt it = data_map.begin(); it != data_map.end(); it++ ) {
460//
461// if ( debug ) ::std::cout << "CustomDataContainer::normalizeMap() start T = " << it->first << "; end T = " << rx << ::std::endl;
462//
463// if ( it->first == DB_CDATA_ALL_OUTER_KEYS ) {
464// if ( debug ) ::std::cout << "CustomDataContainer::normalizeMap() overriding start T = " << tx << "; end T = " << rx << ::std::endl;
465//
466// curr_b = mid_funct(tx,rx);
467// curr_r = in_funct(tx,rx);
468// }
469// else {
470// curr_b = mid_funct(it->first,rx);
471// curr_r = in_funct(it->first,rx);
472// }
473//
474// if ( debug ) ::std::cout << "CustomDataContainer::normalizeMap() curr bearing = " << curr_b << "; curr range = " << curr_r << ::std::endl;
475//
476// CDCMediumCIt itb = it->second.begin();
477// if ( itb->first == DB_CDATA_ALL_MEDIUM_KEYS ) delta_b = 0;
478// else {
479// itb = it->second.lower_bound( curr_b );
480// if ( itb == it->second.end() ) itb = (++(it->second.rbegin())).base();
481//
482// delta_b = curr_b - itb->first;
483// if (delta_b < 0.0) delta_b = -delta_b;
484// if (delta_b > M_PI) delta_b = 2.0*M_PI - delta_b ;
485// }
486//
487// double ort_dist = pow( curr_r * sin(delta_b) , 2.0 );
488// double ort_projection = ::std::sqrt( curr_r*curr_r - ort_dist );
489//
490// if ( debug ) ::std::cout << "CustomDataContainer::normalizeMap() nearest bearing = " << itb->first << "; diff bearing = " << delta_b
491// << "; orthog distance = " << ort_dist << "; orthog range projection = " << ort_projection << ::std::endl;
492//
493// CDCInnerCIt itr = itb->second.begin();
494// if ( itr->first == DB_CDATA_ALL_INNER_KEYS ) curr_dist = ort_dist;
495// else {
496// itr = itb->second.lower_bound( ort_projection );
497// if ( itr == itb->second.end() ) itr = (++(itb->second.rbegin())).base();
498// double adj_distance = ::std::abs( ort_projection - itr->first );
499// curr_dist = ::std::sqrt( ort_projection*ort_projection + adj_distance*adj_distance );
500// }
501//
502// if ( debug ) ::std::cout << "CustomDataContainer::normalizeMap() nearest range = " << itr->first << "; distance = " << curr_dist
503// << "; min distance = " << min_dist << ::std::endl;
504//
505// if ( curr_dist < min_dist ) {
506// min_dist = curr_dist;
507// ret_val = &(itr->second);
508// if ( curr_dist == 0 ) break;
509// }
510//
511// }
512//
513// if ( debug ) ::std::cout << "CustomDataContainer::normalizeMap() ret value " << *ret_val << ::std::endl;
514//
515// }
516
517
518 template < class T, class MidFunctor, class InFunctor, class Data, class OutComp, class MidComp, class InComp >
520 data_map[t][b][r] = d;
521 }
522
523
524 template < class T, class MidFunctor, class InFunctor, class Data, class OutComp, class MidComp, class InComp >
526 data_map[t][b].erase(r);
527 if ( data_map[t][b].empty() ) data_map[t].erase(b);
528 if ( data_map[t].empty() ) data_map.erase(t);
529 }
530
531
532 template < class T, class MidFunctor, class InFunctor, class Data, class OutComp, class MidComp, class InComp >
536
537
543 template < class T, class MidFunctor, class InFunctor, class Data, class OutComp, class MidComp, class InComp >
544 class CustomDataContainer< T, MidFunctor, InFunctor, Data*, OutComp, MidComp, InComp > {
545
546
547 protected:
548
549
550 typedef typename ::std::map< double, Data*, InComp > InnerData;
551 typedef typename InnerData::iterator CDCInnerIt;
552 typedef typename InnerData::reverse_iterator CDCInnerRIt;
553 typedef typename InnerData::const_iterator CDCInnerCIt;
554 typedef typename InnerData::const_reverse_iterator CDCInnerCRIt;
555
556 typedef typename ::std::map< double, InnerData, MidComp > MediumData;
557 typedef typename MediumData::iterator CDCMediumIt;
558 typedef typename MediumData::const_iterator CDCMediumCIt;
559 typedef typename MediumData::reverse_iterator CDCMediumRIt;
560 typedef typename MediumData::const_reverse_iterator CDCMediumCRIt;
561
562 typedef ::std::map< T, MediumData, OutComp > CustomContainer;
563 typedef typename CustomContainer::iterator CDCIt;
564 typedef typename CustomContainer::reverse_iterator CDCRIt;
565 typedef typename CustomContainer::const_iterator CDCCIt;
566 typedef typename CustomContainer::const_reverse_iterator CDCCRIt;
567
568
569 public:
570
571#if __cplusplus >= 201103L // C++11 or later
572 static constexpr double DB_CDATA_ALL_MEDIUM_KEYS = -190.0;
573
574 static constexpr double DB_CDATA_ALL_INNER_KEYS = -10.0;
575#else
576 static const double DB_CDATA_ALL_MEDIUM_KEYS = -190.0;
577
578 static const double DB_CDATA_ALL_INNER_KEYS = -10.0;
579#endif // __cplusplus >= 201103L
580 static const T DB_CDATA_ALL_OUTER_KEYS;
581
582
583 CustomDataContainer() : debug(false), data_map() { }
584
585
586 ~CustomDataContainer() { clear(); }
587
588
589 bool empty() const { return data_map.empty(); }
590
591
592 int size() const { return data_map.size(); }
593
594
595 Data* get( const T& t = DB_CDATA_ALL_OUTER_KEYS, double b = DB_CDATA_ALL_MEDIUM_KEYS, double r = DB_CDATA_ALL_INNER_KEYS ) const;
596
597 Data* get( const T& tx, const T& rx ) const;
598
599
611 bool insert( Data* data, const T& t = DB_CDATA_ALL_OUTER_KEYS, double b = DB_CDATA_ALL_MEDIUM_KEYS, double r = DB_CDATA_ALL_INNER_KEYS );
612
613 void replace( Data* data, const T& t = DB_CDATA_ALL_OUTER_KEYS, double b = DB_CDATA_ALL_MEDIUM_KEYS, double r = DB_CDATA_ALL_INNER_KEYS );
614
615
626 void erase( const T& t = DB_CDATA_ALL_OUTER_KEYS, double b = DB_CDATA_ALL_MEDIUM_KEYS, double r = DB_CDATA_ALL_INNER_KEYS );
627
628
629// void normalizeMap( const T& t );
630
631
635 void clear();
636
637
638 void setDebug( bool flag ) { debug = flag; }
639
640 bool usingDebug() { return debug; }
641
642
643 protected:
644
645
646 bool debug;
647
648
649 CustomContainer data_map;
650
651
662 Data*& find( const T& t = DB_CDATA_ALL_OUTER_KEYS, double b = DB_CDATA_ALL_MEDIUM_KEYS, double r = DB_CDATA_ALL_INNER_KEYS ) const;
663
664
665 };
666
667
668 template < class T, class MidFunctor, class InFunctor, class Data, class OutComp, class MidComp, class InComp >
670
671
672 template < class T, class MidFunctor, class InFunctor, class Data, class OutComp, class MidComp, class InComp >
674
675 static Data* not_found = NULL;
676
677 if (debug) ::std::cout << "CustomDataContainer*::find() << t = " << t << "; b = " << b << "; r = " << r << ::std::endl;
678
679 CDCCIt it = data_map.find( t );
680 if ( it == data_map.end() ) {
681
682 if ( debug ) ::std::cout << "CustomDataContainer*::find() t not found" << ::std::endl;
683
684 return not_found;
685 }
686
687 if ( debug ) ::std::cout << "CustomDataContainer*::find() t found" << ::std::endl;
688
689 CDCMediumCIt it2 = it->second.find( b );
690 if ( it2 == it->second.end() ) {
691
692 if ( debug ) ::std::cout << "CustomDataContainer*::find() b not found" << ::std::endl;
693
694 return not_found;
695 }
696
697 if ( debug ) ::std::cout << "CustomDataContainer*::find() b found" << ::std::endl;
698
699 CDCInnerCIt it3 = it2->second.find( r );
700 if ( it3 == it2->second.end() ) {
701
702 if ( debug ) ::std::cout << "CustomDataContainer*::find() r not found" << ::std::endl;
703
704 return not_found;
705 }
706 if ( debug ) ::std::cout << "CustomDataContainer*::find() r found, data = " << *it3->second << ::std::endl;
707 return const_cast<Data*&>(it3->second);
708 }
709
710
711 template < class T, class MidFunctor, class InFunctor, class Data, class OutComp, class MidComp, class InComp >
713
714 if ( debug ) ::std::cout << "CustomDataContainer*::get() t = " << t << "; b = " << b << "; r = " << r << ::std::endl;
715
716 if ( data_map.empty() ) return NULL;
717
718 Data* ptr = find( DB_CDATA_ALL_OUTER_KEYS, DB_CDATA_ALL_MEDIUM_KEYS, DB_CDATA_ALL_INNER_KEYS );
719
720 if ( ptr != NULL ) {
721 if ( debug ) ::std::cout << "CustomDataContainer*::get() found ptr = " << ptr << "; object = " << *ptr << ::std::endl;
722
723 return new Data( *ptr );
724 }
725
726 CDCCIt it = data_map.find( t );
727 if ( it == data_map.end() ) return NULL;
728
729 CDCMediumCIt it2 = it->second.lower_bound( b );
730 CDCMediumCRIt rit2 = it->second.rbegin();
731
732 CDCInnerCIt it3;
733 CDCInnerCRIt rit3;
734
735 if ( it2 == it->second.end() ) {
736 if( rit2 == it->second.rend() ) return NULL;
737 it3 = rit2->second.lower_bound( r );
738 rit3 = rit2->second.rbegin();
739 if ( it3 != rit2->second.end() ) return new Data( *(it3->second) );
740 if ( rit3 != rit2->second.rend() ) return new Data ( *(rit3->second) );
741 return NULL;
742 }
743 else {
744 it3 = it2->second.lower_bound( r );
745 rit3 = it2->second.rbegin();
746 if ( it3 != it2->second.end() ) return new Data( *(it3->second) );
747 if ( rit3 != it2->second.rend() ) return new Data( *(rit3->second) );
748 return NULL;
749 }
750 if ( it3 == it2->second.end() ) return NULL;
751 return new Data( *(it3->second) );
752 }
753
754
755 template < class T, class MidFunctor, class InFunctor, class Data, class OutComp, class MidComp, class InComp >
757 MidFunctor mid_funct;
758 InFunctor in_funct;
759
760 double curr_b;
761 double curr_r;
762 double delta_b;
763// double delta_r;
764 const Data* ret_val = NULL;
765
766 double curr_dist;
767 double min_dist = INFINITY;
768
769 if ( data_map.empty() == true ) {
770 if ( debug ) ::std::cout << "CustomDataContainer*::get() data_map is empty " << ::std::endl;
771
772 return new Data();
773 }
774
775 for ( CDCCIt it = data_map.begin(); it != data_map.end(); it++ ) {
776
777 if ( debug ) ::std::cout << "CustomDataContainer*::get() start T = " << it->first << "; end T = " << rx << ::std::endl;
778
779 if ( it->first == DB_CDATA_ALL_OUTER_KEYS ) {
780 if ( debug ) ::std::cout << "CustomDataContainer*::get() overriding start T = " << tx << "; end T = " << rx << ::std::endl;
781
782 curr_b = mid_funct(tx,rx);
783 curr_r = in_funct(tx,rx);
784 }
785 else {
786 curr_b = mid_funct(it->first,rx);
787 curr_r = in_funct(it->first,rx);
788 }
789
790 if ( debug ) ::std::cout << "CustomDataContainer*::get() curr bearing = " << curr_b * 180.0 / M_PI
791 << "; curr range = " << curr_r << ::std::endl;
792
793 CDCMediumCIt itb = it->second.begin();
794 if ( itb->first == DB_CDATA_ALL_MEDIUM_KEYS ) delta_b = 0;
795 else {
796 itb = it->second.lower_bound( curr_b );
797 if ( itb == it->second.end() ) itb = (++(it->second.rbegin())).base();
798
799 delta_b = curr_b - itb->first;
800 if (delta_b < 0.0) delta_b = -delta_b;
801 if (delta_b > M_PI) delta_b = 2.0*M_PI - delta_b ;
802 }
803
804 double ort_dist = curr_r * sin(delta_b);
805 double ort_projection = ::std::sqrt( curr_r*curr_r - ort_dist*ort_dist );
806
807 if ( debug ) ::std::cout << "CustomDataContainer*::get() nearest bearing = " << itb->first * 180.0 / M_PI
808 << "; diff bearing = " << delta_b * 180.0 / M_PI << "; orthog distance = " << ort_dist
809 << "; orthog range projection = " << ort_projection << ::std::endl;
810
811 CDCInnerCIt itr = itb->second.begin();
812 if ( itr->first == DB_CDATA_ALL_INNER_KEYS ) curr_dist = ort_dist;
813 else {
814 itr = itb->second.lower_bound( ort_projection );
815 if ( itr == itb->second.begin() || itr == itb->second.end() || itr->first == ort_projection ) {
816 if ( itr == itb->second.end() ) itr = (++(itb->second.rbegin())).base();
817// ::std::cout << " range = " << itr->first << ::std::endl;
818 double adj_distance = ::std::abs( ort_projection - itr->first );
819 curr_dist = ::std::sqrt( ort_projection*ort_projection + adj_distance*adj_distance );
820 }
821 else {
822 double adj_distance = ::std::abs( ort_projection - itr->first );
823 double first_dist = ::std::sqrt( ort_projection*ort_projection + adj_distance*adj_distance );
824
825 if (debug) ::std::cout << "CustomDataContainer*::get() first try, range = " << itr->first
826 << "; dist = " << first_dist << ::std::endl;
827
828 itr--;
829 adj_distance = ::std::abs( ort_projection - itr->first );
830 double before_dist = ::std::sqrt( ort_projection*ort_projection + adj_distance*adj_distance );
831
832 if (debug) ::std::cout << "CustomDataContainer*::get() second try, range = " << itr->first
833 << "; dist = " << before_dist << ::std::endl;
834
835 curr_dist = ::std::min( first_dist, before_dist );
836 if ( curr_dist == first_dist ) itr++;
837 }
838 }
839
840 if ( debug ) ::std::cout << "CustomDataContainer*::get() nearest range = " << itr->first << "; distance = " << curr_dist
841 << "; min distance = " << min_dist << ::std::endl;
842
843 if ( curr_dist < min_dist ) {
844 min_dist = curr_dist;
845 ret_val = (itr->second);
846 if ( curr_dist == 0 ) break;
847 }
848
849 }
850
851 if ( debug && ( ret_val != NULL ) ) ::std::cout << "CustomDataContainer*::get() ret value " << *ret_val << ::std::endl;
852
853 if ( ret_val != NULL ) return ret_val->clone();
854 return new Data();
855 }
856
857
858 template < class T, class MidFunctor, class InFunctor, class Data, class OutComp, class MidComp, class InComp >
860
861 if (debug && d != NULL) ::std::cout << "CustomDataContainer*::insert() &d = " << d << "; d = " << *d << "; t = " << t << "; b = " << b << "; r = " << r << ::std::endl;
862
863 Data* ptr = find( t, b, r );
864
865 if ( ptr != NULL ) {
866 delete d;
867 return false;
868 }
869
870 data_map[t][b][r] = d;
871 return true;
872 }
873
874
875 template < class T, class MidFunctor, class InFunctor, class Data, class OutComp, class MidComp, class InComp >
877
878 if (debug) ::std::cout << "CustomDataContainer*::replace() d = " << *d << "; t = " << t << "; b = " << b << "; r = " << r << ::std::endl;
879
880 Data* ptr = find( t, b, r );
881
882 if ( ptr != NULL ) {
883 delete ptr;
884 ptr = d;
885 }
886 data_map[t][b][r] = d;
887 }
888
889
890 template < class T, class MidFunctor, class InFunctor, class Data, class OutComp, class MidComp, class InComp >
892 Data* ptr = find( t, b, r );
893 if ( ptr == NULL ) return;
894 if ( ptr != NULL ) delete ptr;
895 data_map[t][b].erase(r);
896 if ( data_map[t][b].empty() ) data_map[t].erase(b);
897 if ( data_map[t].empty() ) data_map.erase(t);
898 }
899
900
901 template < class T, class MidFunctor, class InFunctor, class Data, class OutComp, class MidComp, class InComp >
903 if ( data_map.empty() ) return;
904 for ( CDCIt it = data_map.begin(); it != data_map.end(); it++ ) {
905 for ( CDCMediumIt it2 = it->second.begin(); it2 != it->second.end(); it2++ ) {
906 for ( CDCInnerIt it3 = it2->second.begin(); it3 != it2->second.end(); it3++ ) {
907 if ( it3->second != NULL ) delete it3->second;
908 }
909 }
910 }
911 data_map.clear();
912 }
913
921 template < class T, class MidFunctor, class InFunctor, class Data, class OutComp = ::std::less<T>, class MidComp = ::std::less<double>, class InComp = ::std::less<double> >
923
924
925 protected:
926
930 typedef typename ::std::map< time_t, Data > TimeData;
931 typedef typename TimeData::iterator CDTCTimeIt;
932 typedef typename TimeData::reverse_iterator CDTCTimeRIt;
933 typedef typename TimeData::const_iterator CDTCTimeCIt;
934 typedef typename TimeData::const_reverse_iterator CDTCTimeCRIt;
935
939 typedef typename ::std::map< double, TimeData, InComp > InnerData;
940 typedef typename InnerData::iterator CDCInnerIt;
941 typedef typename InnerData::reverse_iterator CDCInnerRIt;
942 typedef typename InnerData::const_iterator CDCInnerCIt;
943 typedef typename InnerData::const_reverse_iterator CDCInnerCRIt;
944
948 typedef typename ::std::map< double, InnerData, MidComp > MediumData;
949 typedef typename MediumData::iterator CDCMediumIt;
950 typedef typename MediumData::const_iterator CDCMediumCIt;
951 typedef typename MediumData::reverse_iterator CDCMediumRIt;
952 typedef typename MediumData::const_reverse_iterator CDCMediumCRIt;
953
957 typedef ::std::map< T, MediumData, OutComp > CustomContainer;
958 typedef typename CustomContainer::iterator CDCIt;
959 typedef typename CustomContainer::reverse_iterator CDCRIt;
960 typedef typename CustomContainer::const_iterator CDCCIt;
961 typedef typename CustomContainer::const_reverse_iterator CDCCRIt;
962
963
964 public:
965
966
967#if __cplusplus >= 201103L // C++11 or later
968 static constexpr double DB_CDATA_ALL_MEDIUM_KEYS = -190.0;
969
970 static constexpr double DB_CDATA_ALL_INNER_KEYS = -10.0;
971#else
972 static const double DB_CDATA_ALL_MEDIUM_KEYS = -190.0;
973
974 static const double DB_CDATA_ALL_INNER_KEYS = -10.0;
975#endif // __cplusplus >= 201103L
976 static const T DB_CDATA_ALL_OUTER_KEYS;
977
978 static const Time DB_CDATA_ALL_TIME_KEYS;
979
980
985
990
991
997 MediumData& operator[] ( const T& key ) { return data_map[key]; }
998
999
1004 bool empty() const { return data_map.empty(); }
1005
1006
1011 int size() const { return data_map.size(); }
1012
1013
1026 Data get( const T& t = DB_CDATA_ALL_OUTER_KEYS, double b = DB_CDATA_ALL_MEDIUM_KEYS, double r = DB_CDATA_ALL_INNER_KEYS, const Time& time_key = DB_CDATA_ALL_TIME_KEYS ) const;
1027
1036 Data get( const T& tx, const T& rx, const Time& time_key = DB_CDATA_ALL_TIME_KEYS ) const;
1037
1038
1052 bool insert( const Data& data, const T& t = DB_CDATA_ALL_OUTER_KEYS, double b = DB_CDATA_ALL_MEDIUM_KEYS, double r = DB_CDATA_ALL_INNER_KEYS, const Time& time_key = DB_CDATA_ALL_TIME_KEYS );
1053
1067 void replace( const Data& data, const T& t = DB_CDATA_ALL_OUTER_KEYS, double b = DB_CDATA_ALL_MEDIUM_KEYS, double r = DB_CDATA_ALL_INNER_KEYS, const Time& time_key = DB_CDATA_ALL_TIME_KEYS );
1068
1081 void erase( const T& t = DB_CDATA_ALL_OUTER_KEYS, double b = DB_CDATA_ALL_MEDIUM_KEYS, double r = DB_CDATA_ALL_INNER_KEYS, const Time& time_key = DB_CDATA_ALL_TIME_KEYS);
1082
1083
1087 void clear();
1088
1089
1094 void setDebug( bool flag ) { debug = flag; }
1095
1096
1101 bool usingDebug() { return debug; }
1102
1103
1104 protected:
1105
1106
1110 bool debug;
1111
1112
1117
1118
1119 typedef typename ::std::pair< Data, bool > DataFind;
1120
1121
1134 DataFind find( const T& t = DB_CDATA_ALL_OUTER_KEYS, double b = DB_CDATA_ALL_MEDIUM_KEYS, double r = DB_CDATA_ALL_INNER_KEYS, const Time& time_key = DB_CDATA_ALL_TIME_KEYS ) const;
1135
1148 Data calculateData( const TimeData& time_data , const Time& time_key = DB_CDATA_ALL_TIME_KEYS ) const;
1149
1150
1151 };
1152
1153
1154 template < class T, class MidFunctor, class InFunctor, class Data, class OutComp, class MidComp, class InComp >
1156
1157
1158 template < class T, class MidFunctor, class InFunctor, class Data, class OutComp, class MidComp, class InComp >
1160
1161
1162 template < class T, class MidFunctor, class InFunctor, class Data, class OutComp, class MidComp, class InComp >
1163 Data CustomDataTimeContainer< T, MidFunctor, InFunctor, Data, OutComp, MidComp, InComp >::get( const T& t, double b, double r, const Time& time_key ) const {
1164 if ( data_map.empty() ) return Data();
1165
1166 if ( debug ) ::std::cout << "CustomDataTimeContainer::get() t = " << t << "; b = " << b << "; r = " << r
1167 << "; time_key = " << time_key << ::std::endl;
1168
1169 DataFind ret_val = find();
1170 if ( ret_val.second == true ) return ret_val.first;
1171
1172 CDCCIt it = data_map.find( t );
1173 if ( it == data_map.end() ) return Data();
1174
1175 CDCMediumCIt it2 = it->second.lower_bound( b );
1176 CDCMediumCRIt rit2 = it->second.rbegin();
1177
1178 CDCInnerCIt it3;
1179 CDCInnerCRIt rit3;
1180
1181 if ( it2 == it->second.end() ) {
1182 if ( rit2 == it->second.rend() ) return Data();
1183 it3 = rit2->second.lower_bound( r );
1184 rit3 = rit2->second.rbegin();
1185 if ( it3 != rit2->second.end() ) return calculateData( it3->second, time_key);
1186 if ( rit3 != rit2->second.rend() ) return calculateData( rit3->second, time_key);
1187 return Data();
1188 }
1189 else {
1190 it3 = it2->second.lower_bound( r );
1191 rit3 = it2->second.rbegin();
1192 if ( it3 != it2->second.end() ) return calculateData(it3->second, time_key);
1193 if ( rit3 != it2->second.rend() ) return calculateData(rit3->second, time_key);
1194 return Data();
1195 }
1196 if ( it3 == it2->second.end() ) return Data();
1197 return calculateData(it3->second, time_key);
1198 }
1199
1200
1201 template < class T, class MidFunctor, class InFunctor, class Data, class OutComp, class MidComp, class InComp >
1203 MidFunctor mid_funct;
1204 InFunctor in_funct;
1205
1206 double curr_b;
1207 double curr_r;
1208 double delta_b;
1209 double delta_r;
1210
1211 double curr_dist;
1212 double min_dist = INFINITY;
1213
1214 if ( data_map.empty() == true ) {
1215 if ( debug ) ::std::cout << "CustomDataTimeContainer::get() data_map is empty " << ::std::endl;
1216
1217 return Data();
1218 }
1219 const TimeData* time_data_ptr = NULL;
1220
1221 for ( CDCCIt it = data_map.begin(); it != data_map.end(); it++ ) {
1222
1223 if ( debug ) ::std::cout << "CustomDataTimeContainer::get() start T = " << it->first << "; end T = " << rx << ::std::endl;
1224
1225 if ( it->first == DB_CDATA_ALL_OUTER_KEYS ) {
1226 if ( debug ) ::std::cout << "CustomDataTimeContainer::get() overriding start T = " << tx << "; end T = " << rx << ::std::endl;
1227
1228 curr_b = mid_funct(tx,rx);
1229 curr_r = in_funct(tx,rx);
1230 }
1231 else {
1232 curr_b = mid_funct(it->first,rx);
1233 curr_r = in_funct(it->first,rx);
1234 }
1235
1236 if ( debug ) ::std::cout << "CustomDataTimeContainer::get() curr bearing = " << curr_b * 180.0 / M_PI
1237 << "; curr range = " << curr_r << ::std::endl;
1238
1239 CDCMediumCIt itb = it->second.begin();
1240 if ( itb->first == DB_CDATA_ALL_MEDIUM_KEYS ) delta_b = 0;
1241 else {
1242 itb = it->second.lower_bound( curr_b );
1243 if ( itb == it->second.end() ) itb = (++(it->second.rbegin())).base();
1244
1245 delta_b = curr_b - itb->first;
1246 if (delta_b < 0.0) delta_b = -delta_b;
1247 if (delta_b > M_PI) delta_b = 2.0*M_PI - delta_b ;
1248 }
1249
1250 double ort_dist = curr_r * sin(delta_b);
1251 double ort_projection = ::std::sqrt( curr_r*curr_r - ort_dist*ort_dist );
1252
1253 if ( debug ) ::std::cout << "CustomDataTimeContainer::get() nearest bearing = " << itb->first * 180.0 / M_PI
1254 << "; diff bearing = " << delta_b * 180.0 / M_PI << "; orthog distance = " << ort_dist
1255 << "; orthog range projection = " << ort_projection << ::std::endl;
1256
1257 CDCInnerCIt itr = itb->second.begin();
1258 if ( itr->first == DB_CDATA_ALL_INNER_KEYS ) curr_dist = ort_dist;
1259 else {
1260 itr = itb->second.lower_bound( ort_projection );
1261 if ( itr == itb->second.begin() || itr == itb->second.end() || itr->first == ort_projection ) {
1262 if ( itr == itb->second.end() ) itr = (++(itb->second.rbegin())).base();
1263 double adj_distance = ::std::abs( ort_projection - itr->first );
1264 curr_dist = ::std::sqrt( ort_projection*ort_projection + adj_distance*adj_distance );
1265 }
1266 else {
1267 double adj_distance = ::std::abs( ort_projection - itr->first );
1268 double first_dist = ::std::sqrt( ort_projection*ort_projection + adj_distance*adj_distance );
1269
1270 if (debug) ::std::cout << "CustomDataTimeContainer::get() first try, range = " << itr->first
1271 << "; dist = " << first_dist << ::std::endl;
1272
1273 itr--;
1274 adj_distance = ::std::abs( ort_projection - itr->first );
1275 double before_dist = ::std::sqrt( ort_projection*ort_projection + adj_distance*adj_distance );
1276
1277 if (debug) ::std::cout << "CustomDataTimeContainer::get() second try, range = " << itr->first
1278 << "; dist = " << before_dist << ::std::endl;
1279
1280 curr_dist = ::std::min( first_dist, before_dist );
1281 if ( curr_dist == first_dist ) itr++;
1282 }
1283 }
1284 if ( debug ) ::std::cout << "CustomDataTimeContainer::get() nearest range = " << itr->first << "; distance = " << curr_dist
1285 << "; min distance = " << min_dist << ::std::endl;
1286
1287 if ( curr_dist < min_dist ) {
1288 min_dist = curr_dist;
1289 time_data_ptr = &(itr->second);
1290 if ( curr_dist == 0 ) break;
1291 }
1292
1293 }
1294
1295 if ( time_data_ptr != NULL ) return calculateData( *time_data_ptr, time_key);
1296 return Data();
1297 }
1298
1299
1300 template < class T, class MidFunctor, class InFunctor, class Data, class OutComp, class MidComp, class InComp >
1301 typename CustomDataTimeContainer< T, MidFunctor, InFunctor, Data, OutComp, MidComp, InComp >::DataFind CustomDataTimeContainer< T, MidFunctor, InFunctor, Data, OutComp, MidComp, InComp >::find( const T& t, double b, double r, const Time& time_key ) const {
1302
1303 if (debug) ::std::cout << "CustomDataTimeContainer::find() << t = " << t << "; b = " << b << "; r = "
1304 << r << "; time_key = " << time_key << ::std::endl;
1305
1306 CDCCIt it = data_map.find( t );
1307 if ( it == data_map.end() ) {
1308
1309 if ( debug ) ::std::cout << "CustomDataTimeContainer::find() t not found" << ::std::endl;
1310
1311 return DataFind( Data(), false );
1312 }
1313
1314 if ( debug ) ::std::cout << "CustomDataTimeContainer::find() t found" << ::std::endl;
1315
1316 CDCMediumCIt it2 = it->second.find( b );
1317 if ( it2 == it->second.end() ) {
1318
1319 if ( debug ) ::std::cout << "CustomDataTimeContainer::find() b not found" << ::std::endl;
1320
1321 return DataFind( Data(), false );
1322 }
1323
1324 if ( debug ) ::std::cout << "CustomDataTimeContainer::find() b found" << ::std::endl;
1325
1326 CDCInnerCIt it3 = it2->second.find( r );
1327 if ( it3 == it2->second.end() ) {
1328
1329 if ( debug ) ::std::cout << "CustomDataTimeContainer::find() r not found" << ::std::endl;
1330
1331 return DataFind( Data(), false );
1332 }
1333 if ( debug ) ::std::cout << "CustomDataTimeContainer::find() r found" << ::std::endl;
1334
1335 CDTCTimeCIt it4 = it3->second.find( time_key );
1336 if ( it4 == it3->second.end() ) {
1337
1338 if ( debug ) ::std::cout << "CustomDataTimeContainer::find() time_key not found" << ::std::endl;
1339
1340 return DataFind( Data(), false );
1341 }
1342
1343 if ( debug ) ::std::cout << "CustomDataTimeContainer::find() time_key found, Data = " << it4->second << ::std::endl;
1344
1345 return DataFind( it4->second, true );
1346 }
1347
1348
1349 template < class T, class MidFunctor, class InFunctor, class Data, class OutComp, class MidComp, class InComp >
1350 bool CustomDataTimeContainer< T, MidFunctor, InFunctor, Data, OutComp, MidComp, InComp >::insert( const Data& d, const T& t, double b, double r, const Time& time_key ) {
1351 DataFind data = find( t, b, r, time_key );
1352 if ( data.second == true ) return false;
1353 data_map[t][b][r][time_key] = d;
1354 return true;
1355 }
1356
1357
1358 template < class T, class MidFunctor, class InFunctor, class Data, class OutComp, class MidComp, class InComp >
1359 void CustomDataTimeContainer< T, MidFunctor, InFunctor, Data, OutComp, MidComp, InComp >::replace( const Data& d, const T& t, double b, double r, const Time& time_key ) {
1360 data_map[t][b][r][time_key] = d;
1361 }
1362
1363
1364 template < class T, class MidFunctor, class InFunctor, class Data, class OutComp, class MidComp, class InComp >
1366 data_map[t][b][r].erase(time_key);
1367 if ( data_map[t][b][r].empty() ) data_map[t][b].erase(r);
1368 if ( data_map[t][b].empty() ) data_map[t].erase(b);
1369 if ( data_map[t].empty() ) data_map.erase(t);
1370 }
1371
1372
1373 template < class T, class MidFunctor, class InFunctor, class Data, class OutComp, class MidComp, class InComp >
1377
1378 template < class T, class MidFunctor, class InFunctor, class Data, class OutComp, class MidComp, class InComp >
1380 if (debug) ::std::cout << "CustomDataTimeContainer::calculateData() time_key = " << time_key << ::std::endl;
1381
1382 if ( time_data.empty() ) {
1383 if (debug) ::std::cout << "CustomDataTimeContainer::calculateData() time_data is empty." << ::std::endl;
1384
1385 return Data();
1386 }
1387
1388 if ( time_data.size() == 1 ) {
1389 if (debug) ::std::cout << "CustomDataTimeContainer::calculateData() time_data has size 1. Data created "
1390 << time_data.begin()->second << ::std::endl;
1391
1392 return time_data.begin()->second;
1393 }
1394
1395 time_t normalized_time = time_key;
1396
1397 if ( normalized_time < time_data.begin()->first ) {
1398 if (debug) ::std::cout << "CustomDataTimeContainer::calculateData() time_key has time < first key. Data created "
1399 << time_data.begin()->second << ::std::endl;
1400
1401 return time_data.begin()->second;
1402 }
1403
1404 normalized_time %= ( time_data.rbegin()->first - time_data.begin()->first );
1405 if ( normalized_time == 0 )
1406 return time_data.begin()->second;
1407
1408 normalized_time += time_data.begin();
1409 CDTCTimeIt upper_it = time_data.upper_bound(normalized_time);
1410 CDTCTimeIt lower_it = upper_it;
1411 --lower_it;
1412
1413
1414 return ( lower_it->second * ( (normalized_time - lower_it->first) / ( upper_it->first - lower_it->first ) )
1415 + upper_it->second * ( (upper_it->first - normalized_time) / ( upper_it->first - lower_it->first ) ) );
1416 }
1417
1418
1426 template < class T, class MidFunctor, class InFunctor, class Data, class OutComp, class MidComp, class InComp >
1427 class CustomDataTimeContainer< T, MidFunctor, InFunctor, Data*, OutComp, MidComp, InComp > {
1428
1429
1430 protected:
1431
1435 typedef typename ::std::map< time_t, Data* > TimeData;
1436 typedef typename TimeData::iterator CDTCTimeIt;
1437 typedef typename TimeData::reverse_iterator CDTCTimeRIt;
1438 typedef typename TimeData::const_iterator CDTCTimeCIt;
1439 typedef typename TimeData::const_reverse_iterator CDTCTimeCRIt;
1440
1444 typedef typename ::std::map< double, TimeData, InComp > InnerData;
1445 typedef typename InnerData::iterator CDCInnerIt;
1446 typedef typename InnerData::reverse_iterator CDCInnerRIt;
1447 typedef typename InnerData::const_iterator CDCInnerCIt;
1448 typedef typename InnerData::const_reverse_iterator CDCInnerCRIt;
1449
1453 typedef typename ::std::map< double, InnerData, MidComp > MediumData;
1454 typedef typename MediumData::iterator CDCMediumIt;
1455 typedef typename MediumData::const_iterator CDCMediumCIt;
1456 typedef typename MediumData::reverse_iterator CDCMediumRIt;
1457 typedef typename MediumData::const_reverse_iterator CDCMediumCRIt;
1458
1462 typedef ::std::map< T, MediumData, OutComp > CustomContainer;
1463 typedef typename CustomContainer::iterator CDCIt;
1464 typedef typename CustomContainer::reverse_iterator CDCRIt;
1465 typedef typename CustomContainer::const_iterator CDCCIt;
1466 typedef typename CustomContainer::const_reverse_iterator CDCCRIt;
1467
1468
1469 public:
1470
1471
1472#if __cplusplus >= 201103L // C++11 or later
1473 static constexpr double DB_CDATA_ALL_MEDIUM_KEYS = -190.0;
1474
1475 static constexpr double DB_CDATA_ALL_INNER_KEYS = -10.0;
1476#else
1477 static const double DB_CDATA_ALL_MEDIUM_KEYS = -190.0;
1478
1479 static const double DB_CDATA_ALL_INNER_KEYS = -10.0;
1480#endif // __cplusplus >= 201103L
1481 static const T DB_CDATA_ALL_OUTER_KEYS;
1482
1483 static const Time DB_CDATA_ALL_TIME_KEYS;
1484
1485
1489 CustomDataTimeContainer() : debug(false), data_map() { }
1490
1495
1496
1502 MediumData& operator[] ( const T& key ) { return data_map[key]; }
1503
1504
1509 bool empty() const { return data_map.empty(); }
1510
1511
1516 int size() const { return data_map.size(); }
1517
1518
1531 Data* get( const T& t = DB_CDATA_ALL_OUTER_KEYS, double b = DB_CDATA_ALL_MEDIUM_KEYS, double r = DB_CDATA_ALL_INNER_KEYS, const Time& time_key = DB_CDATA_ALL_TIME_KEYS ) const;
1532
1541 Data* get( const T& tx, const T& rx, const Time& time_key = DB_CDATA_ALL_TIME_KEYS ) const;
1542
1543
1557 bool insert( Data* data, const T& t = DB_CDATA_ALL_OUTER_KEYS, double b = DB_CDATA_ALL_MEDIUM_KEYS, double r = DB_CDATA_ALL_INNER_KEYS, const Time& time_key = DB_CDATA_ALL_TIME_KEYS );
1558
1572 void replace( Data* data, const T& t = DB_CDATA_ALL_OUTER_KEYS, double b = DB_CDATA_ALL_MEDIUM_KEYS, double r = DB_CDATA_ALL_INNER_KEYS, const Time& time_key = DB_CDATA_ALL_TIME_KEYS );
1573
1586 void erase( const T& t = DB_CDATA_ALL_OUTER_KEYS, double b = DB_CDATA_ALL_MEDIUM_KEYS, double r = DB_CDATA_ALL_INNER_KEYS, const Time& time_key = DB_CDATA_ALL_TIME_KEYS);
1587
1588
1592 void clear();
1593
1594
1599 void setDebug( bool flag ) { debug = flag; }
1600
1601
1606 bool usingDebug() { return debug; }
1607
1608
1609 protected:
1610
1611
1615 bool debug;
1616
1617
1622
1623
1624 typedef typename ::std::pair< Data*, bool > DataFind;
1625
1626
1639 DataFind find( const T& t = DB_CDATA_ALL_OUTER_KEYS, double b = DB_CDATA_ALL_MEDIUM_KEYS, double r = DB_CDATA_ALL_INNER_KEYS, const Time& time_key = DB_CDATA_ALL_TIME_KEYS ) const;
1640
1653 Data* calculateData( const TimeData& time_data , const Time& time_key = DB_CDATA_ALL_TIME_KEYS ) const;
1654
1655
1656 };
1657
1658
1659 template < class T, class MidFunctor, class InFunctor, class Data, class OutComp, class MidComp, class InComp >
1661
1662
1663 template < class T, class MidFunctor, class InFunctor, class Data, class OutComp, class MidComp, class InComp >
1665
1666
1667 template < class T, class MidFunctor, class InFunctor, class Data, class OutComp, class MidComp, class InComp >
1668 Data* CustomDataTimeContainer< T, MidFunctor, InFunctor, Data*, OutComp, MidComp, InComp >::get( const T& t, double b, double r, const Time& time_key ) const {
1669 if ( data_map.empty() ) return new Data();
1670
1671 if ( debug ) ::std::cout << "CustomDataTimeContainer*::get() t = " << t << "; b = " << b << "; r = " << r
1672 << "; time_key = " << time_key << ::std::endl;
1673
1674 DataFind ret_val = find();
1675 if ( ret_val.second == true ) return ret_val.first->clone();
1676
1677 CDCCIt it = data_map.find( t );
1678 if ( it == data_map.end() ) return new Data();
1679
1680 CDCMediumCIt it2 = it->second.lower_bound( b );
1681 CDCMediumCRIt rit2 = it->second.rbegin();
1682
1683 CDCInnerCIt it3;
1684 CDCInnerCRIt rit3;
1685
1686 if ( it2 == it->second.end() ) {
1687 if ( rit2 == it->second.rend() ) return new Data();
1688 it3 = rit2->second.lower_bound( r );
1689 rit3 = rit2->second.rbegin();
1690 if ( it3 != rit2->second.end() ) return calculateData(it3->second, time_key);
1691 if ( rit3 != rit2->second.rend() ) return calculateData(rit3->second, time_key);
1692 return new Data();
1693 }
1694 else {
1695 it3 = it2->second.lower_bound( r );
1696 rit3 = it2->second.rbegin();
1697 if ( it3 != it2->second.end() ) return calculateData(it3->second, time_key);
1698 if ( rit3 != it2->second.rend() ) return calculateData(rit3->second, time_key);
1699 return new Data();
1700 }
1701 if ( it3 == it2->second.end() ) return new Data();
1702 return calculateData(it3->second, time_key);
1703 }
1704
1705
1706 template < class T, class MidFunctor, class InFunctor, class Data, class OutComp, class MidComp, class InComp >
1708 MidFunctor mid_funct;
1709 InFunctor in_funct;
1710
1711 double curr_b;
1712 double curr_r;
1713 double delta_b;
1714// double delta_r;
1715
1716 double curr_dist;
1717 double min_dist = INFINITY;
1718
1719 if ( data_map.empty() == true ) {
1720 if ( debug ) ::std::cout << "CustomDataTimeContainer::get() data_map is empty " << ::std::endl;
1721
1722 return new Data();
1723 }
1724 const TimeData* time_data_ptr = NULL;
1725
1726 for ( CDCCIt it = data_map.begin(); it != data_map.end(); it++ ) {
1727
1728 if ( debug ) ::std::cout << "CustomDataTimeContainer::get() start T = " << it->first << "; end T = " << rx << ::std::endl;
1729
1730 if ( it->first == DB_CDATA_ALL_OUTER_KEYS ) {
1731 if ( debug ) ::std::cout << "CustomDataTimeContainer::get() overriding start T = " << tx << "; end T = " << rx << ::std::endl;
1732
1733 curr_b = mid_funct(tx,rx);
1734 curr_r = in_funct(tx,rx);
1735 }
1736 else {
1737 curr_b = mid_funct(it->first,rx);
1738 curr_r = in_funct(it->first,rx);
1739 }
1740
1741 if ( debug ) ::std::cout << "CustomDataTimeContainer::get() curr bearing = " << curr_b * 180.0 / M_PI
1742 << "; curr range = " << curr_r << ::std::endl;
1743
1744 CDCMediumCIt itb = it->second.begin();
1745 if ( itb->first == DB_CDATA_ALL_MEDIUM_KEYS ) delta_b = 0;
1746 else {
1747 itb = it->second.lower_bound( curr_b );
1748 if ( itb == it->second.end() ) itb = (++(it->second.rbegin())).base();
1749
1750 delta_b = curr_b - itb->first;
1751 if (delta_b < 0.0) delta_b = -delta_b;
1752 if (delta_b > M_PI) delta_b = 2.0*M_PI - delta_b ;
1753 }
1754
1755 double ort_dist = curr_r * sin(delta_b);
1756 double ort_projection = ::std::sqrt( curr_r*curr_r - ort_dist*ort_dist );
1757
1758 if ( debug ) ::std::cout << "CustomDataTimeContainer::get() nearest bearing = " << itb->first * 180.0 / M_PI
1759 << "; diff bearing = " << delta_b * 180.0 / M_PI << "; orthog distance = " << ort_dist
1760 << "; orthog range projection = " << ort_projection << ::std::endl;
1761
1762 CDCInnerCIt itr = itb->second.begin();
1763 if ( itr->first == DB_CDATA_ALL_INNER_KEYS ) curr_dist = ort_dist;
1764 else {
1765 itr = itb->second.lower_bound( ort_projection );
1766 if ( itr == itb->second.begin() || itr == itb->second.end() || itr->first == ort_projection ) {
1767 if ( itr == itb->second.end() ) itr = (++(itb->second.rbegin())).base();
1768 double adj_distance = ::std::abs( ort_projection - itr->first );
1769 curr_dist = ::std::sqrt( ort_projection*ort_projection + adj_distance*adj_distance );
1770 }
1771 else {
1772 double adj_distance = ::std::abs( ort_projection - itr->first );
1773 double first_dist = ::std::sqrt( ort_projection*ort_projection + adj_distance*adj_distance );
1774
1775 if (debug) ::std::cout << "CustomDataTimeContainer::get() first try, range = " << itr->first
1776 << "; dist = " << first_dist << ::std::endl;
1777
1778 itr--;
1779 adj_distance = ::std::abs( ort_projection - itr->first );
1780 double before_dist = ::std::sqrt( ort_projection*ort_projection + adj_distance*adj_distance );
1781
1782 if (debug) ::std::cout << "CustomDataTimeContainer::get() second try, range = " << itr->first
1783 << "; dist = " << before_dist << ::std::endl;
1784
1785 curr_dist = ::std::min( first_dist, before_dist );
1786 if ( curr_dist == first_dist ) itr++;
1787 }
1788 }
1789 if ( debug ) ::std::cout << "CustomDataTimeContainer::get() nearest range = " << itr->first << "; distance = " << curr_dist
1790 << "; min distance = " << min_dist << ::std::endl;
1791
1792 if ( curr_dist < min_dist ) {
1793 min_dist = curr_dist;
1794 time_data_ptr = &(itr->second);
1795 if ( curr_dist == 0 ) break;
1796 }
1797
1798 }
1799
1800 if ( time_data_ptr != NULL ) return calculateData( *time_data_ptr, time_key);
1801 return new Data();
1802 }
1803
1804
1805 template < class T, class MidFunctor, class InFunctor, class Data, class OutComp, class MidComp, class InComp >
1806 typename CustomDataTimeContainer< T, MidFunctor, InFunctor, Data*, OutComp, MidComp, InComp >::DataFind CustomDataTimeContainer< T, MidFunctor, InFunctor, Data*, OutComp, MidComp, InComp >::find( const T& t, double b, double r, const Time& time_key ) const {
1807
1808 if (debug) ::std::cout << "CustomDataTimeContainer*::find() << t = " << t << "; b = " << b << "; r = "
1809 << r << "; time_key = " << time_key << ::std::endl;
1810
1811 CDCCIt it = data_map.find( t );
1812 if ( it == data_map.end() ) {
1813
1814 if ( debug ) ::std::cout << "CustomDataTimeContainer*::find() t not found" << ::std::endl;
1815
1816 return DataFind( NULL, false );
1817 }
1818
1819 if ( debug ) ::std::cout << "CustomDataTimeContainer*::find() t found" << ::std::endl;
1820
1821 CDCMediumCIt it2 = it->second.find( b );
1822 if ( it2 == it->second.end() ) {
1823
1824 if ( debug ) ::std::cout << "CustomDataTimeContainer*::find() b not found" << ::std::endl;
1825
1826 return DataFind( NULL, false );
1827 }
1828
1829 if ( debug ) ::std::cout << "CustomDataTimeContainer*::find() b found" << ::std::endl;
1830
1831 CDCInnerCIt it3 = it2->second.find( r );
1832 if ( it3 == it2->second.end() ) {
1833
1834 if ( debug ) ::std::cout << "CustomDataTimeContainer::find() r not found" << ::std::endl;
1835
1836 return DataFind( NULL, false );
1837 }
1838 if ( debug ) ::std::cout << "CustomDataTimeContainer*::find() r found" << ::std::endl;
1839
1840 CDTCTimeCIt it4 = it3->second.find( time_key );
1841 if ( it4 == it3->second.end() ) {
1842
1843 if ( debug ) ::std::cout << "CustomDataTimeContainer*::find() time_key not found" << ::std::endl;
1844
1845 return DataFind( NULL, false );
1846 }
1847
1848 if ( debug ) ::std::cout << "CustomDataTimeContainer*::find() time_key found, Data = " << it4->second << ::std::endl;
1849
1850 return DataFind( it4->second, true );
1851 }
1852
1853
1854 template < class T, class MidFunctor, class InFunctor, class Data, class OutComp, class MidComp, class InComp >
1855 bool CustomDataTimeContainer< T, MidFunctor, InFunctor, Data*, OutComp, MidComp, InComp >::insert( Data* d, const T& t, double b, double r, const Time& time_key ) {
1856 DataFind data = find( t, b, r, time_key );
1857 if ( data.second == true ) return false;
1858 data_map[t][b][r][time_key] = d;
1859 return true;
1860 }
1861
1862
1863 template < class T, class MidFunctor, class InFunctor, class Data, class OutComp, class MidComp, class InComp >
1864 void CustomDataTimeContainer< T, MidFunctor, InFunctor, Data*, OutComp, MidComp, InComp >::replace( Data* d, const T& t, double b, double r, const Time& time_key ) {
1865
1866 if (debug) ::std::cout << "CustomDataTimeContainer*::replace() d = " << *d << "; t = " << t << "; b = " << b << "; r = " << r << "; time_key " << time_key << ::std::endl;
1867
1868 DataFind ptr = find( t, b, r, time_key );
1869
1870 if ( ptr.first != NULL ) {
1871 delete ptr;
1872 ptr = d;
1873 }
1874
1875 data_map[t][b][r][time_key] = d;
1876 }
1877
1878
1879 template < class T, class MidFunctor, class InFunctor, class Data, class OutComp, class MidComp, class InComp >
1881 DataFind ptr = find( t, b, r, time_key );
1882 if ( ptr.first == NULL ) return;
1883 if ( ptr.first != NULL ) delete ptr.first;
1884
1885 data_map[t][b][r].erase(time_key);
1886 if ( data_map[t][b][r].empty() ) data_map[t][b].erase(r);
1887 if ( data_map[t][b].empty() ) data_map[t].erase(b);
1888 if ( data_map[t].empty() ) data_map.erase(t);
1889 }
1890
1891
1892 template < class T, class MidFunctor, class InFunctor, class Data, class OutComp, class MidComp, class InComp >
1894 if ( data_map.empty() ) return;
1895 for ( CDCIt it = data_map.begin(); it != data_map.end(); it++ ) {
1896 for ( CDCMediumIt it2 = it->second.begin(); it2 != it->second.end(); it2++ ) {
1897 for ( CDCInnerIt it3 = it2->second.begin(); it3 != it2->second.end(); it3++ ) {
1898 for ( CDTCTimeCIt it4 = it3->second.begin(); it4 != it3->second.end(); it4++) {
1899 if ( it4->second != NULL ) delete it4->second;
1900 }
1901 }
1902 }
1903 }
1904 data_map.clear();
1905 }
1906
1907
1908 template < class T, class MidFunctor, class InFunctor, class Data, class OutComp, class MidComp, class InComp >
1910 if (debug) ::std::cout << "CustomDataTimeContainer*::calculateData() time_key = "
1911 << time_key << "; time_key in time_t = " << (time_t)time_key
1912 << "; time_data size = " << time_data.size()
1913 << "; time data min value = " << time_data.begin()->first
1914 << "; time_data max value = " << time_data.rbegin()->first << ::std::endl;
1915
1916 if ( time_data.empty() ) {
1917 if (debug) ::std::cout << "CustomDataTimeContainer*::calculateData() time_data is empty." << ::std::endl;
1918
1919 return new Data();
1920 }
1921
1922 if ( time_data.size() == 1 ) {
1923 if (debug) ::std::cout << "CustomDataTimeContainer*::calculateData() time_data has size 1. Data cloned from "
1924 << time_data.begin()->second << "; ret value " << *(time_data.begin()->second) << ::std::endl;
1925
1926 return (time_data.begin()->second)->clone();
1927 }
1928
1929 CDTCTimeCIt fit = time_data.find(time_key);
1930 if ( fit != time_data.end() ) {
1931 if (debug) ::std::cout << "CustomDataTimeContainer*::calculateData() time key found, ret value "
1932 << *(fit->second) << ::std::endl;
1933
1934 return fit->second->clone();
1935 }
1936
1937 time_t normalized_time = time_key;
1938
1939 CDTCTimeCIt upper_it;
1940 CDTCTimeCIt lower_it;
1941 double alpha, beta;
1942
1943 if ( (normalized_time > time_data.rbegin()->first) || (normalized_time < time_data.begin()->first) ) {
1944 normalized_time %= time_data.rbegin()->first - time_data.begin()->first;
1945
1946 if (debug) ::std::cout << "CustomDataTimeContainer*::calculateData() time out of bound, normalized on time = "
1947 << (time_data.rbegin()->first - time_data.begin()->first) << "; normalized_time = "
1948 << normalized_time << "; final time = " << (time_data.begin()->first + normalized_time )
1949 << ::std::endl;
1950
1951 normalized_time += time_data.begin()->first;
1952 }
1953
1954 upper_it = time_data.upper_bound(normalized_time);
1955
1956 if ( upper_it == time_data.begin() ) {
1957 if (debug) ::std::cout << "CustomDataTimeContainer*::calculateData() normalized_time = " << normalized_time
1958 << "; upper_it time is first in time data = " << upper_it->first
1959 << "; ret value = " << *(upper_it->second) << ::std::endl;
1960
1961 return (upper_it->second)->clone();
1962 }
1963 lower_it = upper_it;
1964 --lower_it;
1965
1966 alpha = ( ::std::abs((double)(upper_it->first - normalized_time)) / ::std::abs((double)( upper_it->first - lower_it->first )) );
1967 beta = ( ::std::abs((double)(normalized_time - lower_it->first)) / ::std::abs((double)( upper_it->first - lower_it->first )) );
1968
1969 if (debug) ::std::cout << "CustomDataTimeContainer*::calculateData() normalized_time = " << normalized_time
1970 << "; lower_it time = " << lower_it->first
1971 << "; upper_it time = " << upper_it->first
1972 << "; alpha = " << alpha << "; beta " << beta << ::std::endl;
1973
1974 Data* ret_val = (lower_it->second)->clone();
1975
1976 *ret_val = (*ret_val) * alpha + (*(upper_it->second)) * beta;
1977
1978 if (debug) ::std::cout << "CustomDataTimeContainer*::calculateData() return value = "
1979 << *ret_val << ::std::endl;
1980
1981 return ret_val;
1982 }
1983
1984
1985}
1986
1987
1988#endif /* WOSS_DB_CUSTOM_DATA_CONTAINER_H */
1989
Class for managing custom db data.
Definition woss-db-custom-data-container.h:60
MediumData & operator[](const T &key)
Definition woss-db-custom-data-container.h:125
const Data * find(const T &t=DB_CDATA_ALL_OUTER_KEYS, double b=DB_CDATA_ALL_MEDIUM_KEYS, double r=DB_CDATA_ALL_INNER_KEYS) const
Definition woss-db-custom-data-container.h:400
int size() const
Definition woss-db-custom-data-container.h:139
CustomDataContainer()
Definition woss-db-custom-data-container.h:112
bool usingDebug()
Definition woss-db-custom-data-container.h:223
::std::map< double, InnerData, MidComp > MediumData
Definition woss-db-custom-data-container.h:78
bool insert(const Data &data, const T &t=DB_CDATA_ALL_OUTER_KEYS, double b=DB_CDATA_ALL_MEDIUM_KEYS, double r=DB_CDATA_ALL_INNER_KEYS)
Definition woss-db-custom-data-container.h:437
const Data * get(const T &tx, const T &rx) const
Definition woss-db-custom-data-container.h:300
::std::map< double, Data, InComp > InnerData
Definition woss-db-custom-data-container.h:69
void replace(const Data &data, const T &t=DB_CDATA_ALL_OUTER_KEYS, double b=DB_CDATA_ALL_MEDIUM_KEYS, double r=DB_CDATA_ALL_INNER_KEYS)
Definition woss-db-custom-data-container.h:519
bool debug
Definition woss-db-custom-data-container.h:232
::std::map< T, MediumData, OutComp > CustomContainer
Definition woss-db-custom-data-container.h:87
bool empty() const
Definition woss-db-custom-data-container.h:132
~CustomDataContainer()
Definition woss-db-custom-data-container.h:117
void setDebug(bool flag)
Definition woss-db-custom-data-container.h:216
void clear()
Definition woss-db-custom-data-container.h:533
CustomContainer data_map
Definition woss-db-custom-data-container.h:238
void erase(const T &t=DB_CDATA_ALL_OUTER_KEYS, double b=DB_CDATA_ALL_MEDIUM_KEYS, double r=DB_CDATA_ALL_INNER_KEYS)
Definition woss-db-custom-data-container.h:525
const Data * get(const T &t=DB_CDATA_ALL_OUTER_KEYS, double b=DB_CDATA_ALL_MEDIUM_KEYS, double r=DB_CDATA_ALL_INNER_KEYS) const
Definition woss-db-custom-data-container.h:262
::std::map< double, InnerData, MidComp > MediumData
Definition woss-db-custom-data-container.h:1453
void setDebug(bool flag)
Definition woss-db-custom-data-container.h:1599
CustomContainer data_map
Definition woss-db-custom-data-container.h:1621
::std::map< double, TimeData, InComp > InnerData
Definition woss-db-custom-data-container.h:1444
::std::map< time_t, Data * > TimeData
Definition woss-db-custom-data-container.h:1435
::std::map< T, MediumData, OutComp > CustomContainer
Definition woss-db-custom-data-container.h:1462
Class for managing custom db data.
Definition woss-db-custom-data-container.h:922
bool insert(const Data &data, const T &t=DB_CDATA_ALL_OUTER_KEYS, double b=DB_CDATA_ALL_MEDIUM_KEYS, double r=DB_CDATA_ALL_INNER_KEYS, const Time &time_key=DB_CDATA_ALL_TIME_KEYS)
Definition woss-db-custom-data-container.h:1350
bool empty() const
Definition woss-db-custom-data-container.h:1004
DataFind find(const T &t=DB_CDATA_ALL_OUTER_KEYS, double b=DB_CDATA_ALL_MEDIUM_KEYS, double r=DB_CDATA_ALL_INNER_KEYS, const Time &time_key=DB_CDATA_ALL_TIME_KEYS) const
Definition woss-db-custom-data-container.h:1301
::std::map< time_t, Data > TimeData
Definition woss-db-custom-data-container.h:930
Data get(const T &t=DB_CDATA_ALL_OUTER_KEYS, double b=DB_CDATA_ALL_MEDIUM_KEYS, double r=DB_CDATA_ALL_INNER_KEYS, const Time &time_key=DB_CDATA_ALL_TIME_KEYS) const
Definition woss-db-custom-data-container.h:1163
void erase(const T &t=DB_CDATA_ALL_OUTER_KEYS, double b=DB_CDATA_ALL_MEDIUM_KEYS, double r=DB_CDATA_ALL_INNER_KEYS, const Time &time_key=DB_CDATA_ALL_TIME_KEYS)
Definition woss-db-custom-data-container.h:1365
Data get(const T &tx, const T &rx, const Time &time_key=DB_CDATA_ALL_TIME_KEYS) const
Definition woss-db-custom-data-container.h:1202
MediumData & operator[](const T &key)
Definition woss-db-custom-data-container.h:997
void replace(const Data &data, const T &t=DB_CDATA_ALL_OUTER_KEYS, double b=DB_CDATA_ALL_MEDIUM_KEYS, double r=DB_CDATA_ALL_INNER_KEYS, const Time &time_key=DB_CDATA_ALL_TIME_KEYS)
Definition woss-db-custom-data-container.h:1359
::std::map< double, InnerData, MidComp > MediumData
Definition woss-db-custom-data-container.h:948
::std::map< T, MediumData, OutComp > CustomContainer
Definition woss-db-custom-data-container.h:957
bool usingDebug()
Definition woss-db-custom-data-container.h:1101
bool debug
Definition woss-db-custom-data-container.h:1110
CustomContainer data_map
Definition woss-db-custom-data-container.h:1116
int size() const
Definition woss-db-custom-data-container.h:1011
CustomDataTimeContainer()
Definition woss-db-custom-data-container.h:984
void clear()
Definition woss-db-custom-data-container.h:1374
~CustomDataTimeContainer()
Definition woss-db-custom-data-container.h:989
void setDebug(bool flag)
Definition woss-db-custom-data-container.h:1094
::std::map< double, TimeData, InComp > InnerData
Definition woss-db-custom-data-container.h:939
Data calculateData(const TimeData &time_data, const Time &time_key=DB_CDATA_ALL_TIME_KEYS) const
Definition woss-db-custom-data-container.h:1379
a class for time date manipulation
Definition time-definitions.h:95
Definitions and library for woss::Time, woss::SimTime, woss::TimeReference and woss::TimeReferenceTcl...