30#include <simgear/misc/strutils.hxx>
31#include <simgear/debug/logstream.hxx>
32#include <simgear/structure/exception.hxx>
43 const auto prefix = subs.substr(0, 1);
44 if (prefix ==
"S" || (prefix ==
"W"))
46 subs = subs.substr(1, subs.length());
47 const auto spacePos = subs.find(
" ", 0);
48 const auto degree = subs.substr(0, spacePos);
49 const auto decimal = subs.substr(spacePos, subs.length());
51 return sign * (stoi(degree) + (stof(decimal) / 60.0));
65 ParkingPushbackIndex::const_iterator it;
67 for (it = _parkingPushbacks.begin(); it != _parkingPushbacks.end(); ++it) {
68 NodeIndexMap::const_iterator j = _indexMap.find(it->second);
69 if (j == _indexMap.end()) {
71 SG_LOG(SG_NAVAID, SG_DEV_WARN,
"bad groundnet " << _groundNetwork->airport()->getId() <<
" , no node for index:" << it->first.get()->getIndex());
75 it->first->setPushBackPoint(j->second);
79 if (!_unreferencedNodes.empty()) {
84 SG_LOG(SG_NAVAID, SG_DEV_WARN,
85 "unreferenced groundnet node: " << node->getIndex());
90void FGGroundNetXMLLoader::startParking(
const XMLAttributes &atts)
94 string gateName, gateNumber;
99 int pushBackRoute = -1;
103 for (
int i = 0;
i < atts.size();
i++)
105 string attname(atts.getName(
i));
106 if (attname ==
"index") {
107 index = std::atoi(atts.getValue(
i));
108 }
else if (attname ==
"type")
109 type = atts.getValue(
i);
110 else if (attname ==
"name")
111 gateName = atts.getValue(
i);
112 else if (attname ==
"number")
113 gateNumber = atts.getValue(
i);
114 else if (attname ==
"lat")
115 lat = atts.getValue(
i);
116 else if (attname ==
"lon")
117 lon = atts.getValue(
i);
118 else if (attname ==
"heading")
119 heading = std::atof(atts.getValue(
i));
120 else if (attname ==
"radius") {
121 string radiusStr = atts.getValue(
i);
122 if (radiusStr.find(
"M") != string::npos)
123 radiusStr = radiusStr.substr(0, radiusStr.find(
"M",0));
124 radius = std::atof(radiusStr.c_str());
126 else if (attname ==
"airlineCodes")
127 airlineCodes = atts.getValue(
i);
128 else if (attname ==
"pushBackRoute") {
129 const string attrVal = atts.getValue(
i);
131 if (attrVal.empty() || (attrVal ==
"None")) {
134 pushBackRoute = simgear::strutils::readNonNegativeInt<int>(attrVal);
136 }
catch (
const sg_exception& e) {
137 SG_LOG(SG_NAVAID, SG_DEV_WARN,
138 getPath() <<
":" << getLine() <<
": " <<
139 "invalid value for 'pushBackRoute': " << e.what());
149 pos, heading, radius,
150 gateName + gateNumber,
151 type, airlineCodes));
152 if (pushBackRoute >= 0) {
153 _parkingPushbacks[parking] = pushBackRoute;
156 _indexMap[index] = parking;
157 _groundNetwork->addParking(parking);
160void FGGroundNetXMLLoader::startNode(
const XMLAttributes &atts)
164 bool onRunway =
false;
165 int holdPointType = 0;
167 for (
int i = 0;
i < atts.size() ;
i++)
169 string attname(atts.getName(
i));
170 if (attname ==
"index")
171 index = std::atoi(atts.getValue(
i));
172 else if (attname ==
"lat")
173 lat = atts.getValue(
i);
174 else if (attname ==
"lon")
175 lon = atts.getValue(
i);
176 else if (attname ==
"isOnRunway")
177 onRunway = std::atoi(atts.getValue(
i)) != 0;
178 else if (attname ==
"holdPointType") {
179 string attval = atts.getValue(
i);
180 if (attval==
"none") {
182 }
else if (attval==
"normal") {
184 }
else if (attval==
"CAT II/III") {
186 }
else if (attval==
"PushBack") {
194 if (_indexMap.find(index) != _indexMap.end()) {
195 SG_LOG(SG_NAVAID, SG_DEV_WARN,
"duplicate ground-net index:" << index);
201 _indexMap[index] = node;
202 _unreferencedNodes.insert(node);
205void FGGroundNetXMLLoader::startArc(
const XMLAttributes &atts)
207 int begin = 0, end = 0;
208 bool isPushBackRoute =
false;
210 for (
int i = 0;
i < atts.size() ;
i++)
212 string attname = atts.getName(
i);
213 if (attname ==
"begin")
214 begin = std::atoi(atts.getValue(
i));
215 else if (attname ==
"end")
216 end = std::atoi(atts.getValue(
i));
217 else if (attname ==
"isPushBackRoute")
218 isPushBackRoute = std::atoi(atts.getValue(
i)) != 0;
221 IntPair e(begin, end);
222 if (_arcSet.find(e) != _arcSet.end()) {
223 SG_LOG(SG_NAVAID, SG_DEV_WARN, _groundNetwork->airport()->ident() <<
" ground-net: skipping duplicate edge:" << begin <<
"->" << end);
228 NodeIndexMap::const_iterator it;
230 it = _indexMap.find(begin);
231 if (it == _indexMap.end()) {
232 SG_LOG(SG_NAVAID, SG_DEV_WARN,
"ground-net: bad edge:" << begin <<
"->" << end <<
", begin index unknown");
236 _unreferencedNodes.erase(it->second);
237 fromNode = it->second;
240 it = _indexMap.find(end);
241 if (it == _indexMap.end()) {
242 SG_LOG(SG_NAVAID, SG_DEV_WARN,
"ground-net: bad edge:" << begin <<
"->" << end <<
", end index unknown");
246 _unreferencedNodes.erase(it->second);
251 _groundNetwork->addSegment(fromNode, toNode);
252 if (isPushBackRoute) {
259 if (!strcmp(
"Parking",
name)) {
261 }
else if (!strcmp(
"node",
name)) {
263 }
else if (!strcmp(
"arc",
name)) {
270 int valueAsInt =
atoi(value.c_str());
271 if (!strcmp(
"version",
name)) {
272 _groundNetwork->addVersion(valueAsInt);
273 }
else if (!strcmp(
"AWOS",
name)) {
274 _groundNetwork->addAwosFreq(valueAsInt);
275 }
else if (!strcmp(
"UNICOM",
name)) {
276 _groundNetwork->addUnicomFreq(valueAsInt);
277 }
else if (!strcmp(
"CLEARANCE",
name)) {
278 _groundNetwork->addClearanceFreq(valueAsInt);
279 }
else if (!strcmp(
"GROUND",
name)) {
280 _groundNetwork->addGroundFreq(valueAsInt);
281 }
else if (!strcmp(
"TOWER",
name)) {
282 _groundNetwork->addTowerFreq(valueAsInt);
283 }
else if (!strcmp(
"APPROACH",
name)) {
284 _groundNetwork->addApproachFreq(valueAsInt);
289 string token = string(s,len);
291 if ((token.find(
" ") == string::npos && (token.find(
'\n')) == string::npos))
302 SG_LOG(SG_IO, SG_DEV_WARN,
"Warning: " << message <<
" (" << line <<
',' << column <<
')');
306 SG_LOG(SG_IO, SG_DEV_ALERT,
"Error: " << message <<
" (" << line <<
',' << column <<
')');
SGSharedPtr< FGTaxiNode > FGTaxiNodeRef
SGSharedPtr< FGParking > FGParkingRef
virtual void startElement(const char *name, const XMLAttributes &atts)
virtual void warning(const char *message, int line, int column)
virtual void data(const char *s, int len)
FGGroundNetXMLLoader(FGGroundNetwork *gn)
virtual void error(const char *message, int line, int column)
virtual void endElement(const char *name)
virtual void pi(const char *target, const char *data)
static double processPosition(const string &pos)
static int atoi(const string &str)