-
Notifications
You must be signed in to change notification settings - Fork 22
Expand file tree
/
Copy pathChannelController.cc
More file actions
126 lines (107 loc) · 4.64 KB
/
ChannelController.cc
File metadata and controls
126 lines (107 loc) · 4.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see http://www.gnu.org/licenses/.
//
#ifdef WITH_OSG
#include <osg/PositionAttitudeTransform>
#include <osgEarthUtil/ObjectLocator>
#include "ChannelController.h"
using namespace osgEarth;
using namespace osgEarth::Annotation;
using namespace osgEarth::Features;
Define_Module(ChannelController);
ChannelController *ChannelController::instance = nullptr;
ChannelController::ChannelController()
{
if (instance) throw cRuntimeError("There can be only one ChannelController instance in the network");
instance = this;
}
ChannelController::~ChannelController()
{
instance = nullptr;
}
ChannelController *ChannelController::getInstance()
{
if (!instance) throw cRuntimeError("ChannelController::getInstance(): there is no ChannelController module in the network");
return instance;
}
int ChannelController::findGenericNode(IGenericNode *p)
{
for (int i = 0; i < (int) nodeList.size(); i++)
if (nodeList[i] == p) return i;
return -1;
}
void ChannelController::addGenericNode(IGenericNode *p)
{
if (findGenericNode(p) == -1) nodeList.push_back(p);
}
void ChannelController::removeGenericNode(IGenericNode *p)
{
int k = findGenericNode(p);
if (k != -1) nodeList.erase(nodeList.begin() + k);
}
void ChannelController::initialize(int stage)
{
switch (stage) {
case 0: {
playgroundLat = getSystemModule()->par("playgroundLatitude");
playgroundLon = getSystemModule()->par("playgroundLongitude");
connectionColor = par("connectionColor").stringValue();
showConnections = par("showConnections").boolValue();
break;
}
case 1: {
auto scene = OsgEarthScene::getInstance()->getScene(); // scene is initialized in stage 0 so we have to do our init in stage 1
mapNode = osgEarth::MapNode::findMapNode(scene);
connectionStyle.getOrCreate<LineSymbol>()->stroke()->color() = osgEarth::Color(connectionColor);
connectionStyle.getOrCreate<LineSymbol>()->stroke()->width() = 3.0f;
connectionStyle.getOrCreate<AltitudeSymbol>()->clamping() = AltitudeSymbol::CLAMP_ABSOLUTE;
connectionStyle.getOrCreate<AltitudeSymbol>()->technique() = AltitudeSymbol::TECHNIQUE_DRAPE;
if (showConnections) {
auto geoSRS = mapNode->getMapSRS()->getGeographicSRS();
connectionGraphNode = new FeatureNode(mapNode.get(), new Feature(new LineString(), geoSRS));
connectionGraphNode->getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
mapNode->getModelLayerGroup()->addChild(connectionGraphNode);
}
break;
}
}
}
void ChannelController::refreshDisplay() const
{
if (!showConnections) return;
auto geoSRS = mapNode->getMapSRS()->getGeographicSRS();
auto connectionGeometry = new osgEarth::Symbology::MultiGeometry();
for (int i = 0; i < (int) nodeList.size(); ++i) {
for (int j = i + 1; j < (int) nodeList.size(); ++j) {
IGenericNode *pi = nodeList[i];
IGenericNode *pj = nodeList[j];
double ix = pi->getX(), iy = pi->getY(), iz = pi->getZ();
double jx = pj->getX(), jy = pj->getY(), jz = pj->getZ();
if (pi->getTxRange() * pi->getTxRange() > (ix - jx) * (ix - jx) + (iy - jy) * (iy - jy) + (iz - jz) * (iz - jz)) {
auto ls = new LineString(2); // a single line geometry
ls->push_back(osg::Vec3d(pi->getLongitude(), pi->getLatitude(), pi->getAltitude()));
ls->push_back(osg::Vec3d(pj->getLongitude(), pj->getLatitude(), pj->getAltitude()));
connectionGeometry->add(ls);
}
}
}
auto cgraphFeature = new Feature(connectionGeometry, geoSRS, connectionStyle);
cgraphFeature->geoInterp() = GEOINTERP_GREAT_CIRCLE;
connectionGraphNode->setFeature(cgraphFeature);
}
void ChannelController::handleMessage(cMessage *msg)
{
throw cRuntimeError("This module does not process messages");
}
#endif // WITH_OSG