00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef _MSC_VER
00025 #include <windows_config.h>
00026 #else
00027 #include <config.h>
00028 #endif
00029
00030 #include <string>
00031 #include <iostream>
00032 #include <xercesc/sax/HandlerBase.hpp>
00033 #include <xercesc/sax/AttributeList.hpp>
00034 #include <xercesc/sax/SAXParseException.hpp>
00035 #include <xercesc/sax/SAXException.hpp>
00036 #include "NIXMLConnectionsHandler.h"
00037 #include <netbuild/NBEdge.h>
00038 #include <netbuild/NBEdgeCont.h>
00039 #include <netbuild/NBNode.h>
00040 #include <utils/common/StringTokenizer.h>
00041 #include <utils/xml/SUMOSAXHandler.h>
00042 #include <utils/xml/SUMOXMLDefinitions.h>
00043 #include <utils/common/ToString.h>
00044 #include <utils/common/TplConvert.h>
00045 #include <utils/common/TplConvertSec.h>
00046 #include <utils/common/UtilExceptions.h>
00047 #include <utils/common/MsgHandler.h>
00048
00049 #ifdef CHECK_MEMORY_LEAKS
00050 #include <foreign/nvwa/debug_new.h>
00051 #endif // CHECK_MEMORY_LEAKS
00052
00053
00054
00055
00056
00057 NIXMLConnectionsHandler::NIXMLConnectionsHandler(NBEdgeCont &ec) throw()
00058 : SUMOSAXHandler("xml-connection-description"), myEdgeCont(ec),
00059 myHaveReportedAboutFunctionDeprecation(false) {}
00060
00061
00062 NIXMLConnectionsHandler::~NIXMLConnectionsHandler() throw() {}
00063
00064
00065 void
00066 NIXMLConnectionsHandler::myStartElement(SumoXMLTag element,
00067 const SUMOSAXAttributes &attrs) throw(ProcessError) {
00068 if (element==SUMO_TAG_RESET) {
00069 bool ok = true;
00070 std::string from = attrs.getStringReporting(SUMO_ATTR_FROM, "reset", 0, ok);
00071 std::string to = attrs.getStringReporting(SUMO_ATTR_TO, "reset", 0, ok);
00072 if (!ok) {
00073 return;
00074 }
00075 NBEdge *fromEdge = myEdgeCont.retrieve(from);
00076 NBEdge *toEdge = myEdgeCont.retrieve(to);
00077 if (fromEdge==0) {
00078 MsgHandler::getErrorInstance()->inform("The connection-source edge '" + from + "' to reset is not known.");
00079 return;
00080 }
00081 if (toEdge==0) {
00082 MsgHandler::getErrorInstance()->inform("The connection-destination edge '" + to + "' to reset is not known.");
00083 return;
00084 }
00085 fromEdge->removeFromConnections(toEdge);
00086 }
00087
00088 if (element==SUMO_TAG_CONNECTION) {
00089 bool ok = true;
00090 std::string from = attrs.getOptStringReporting(SUMO_ATTR_FROM, "connection", 0, ok, "");
00091 std::string to = attrs.getOptStringReporting(SUMO_ATTR_TO, "connection", 0, ok, "");
00092 std::string laneConn = attrs.getOptStringReporting(SUMO_ATTR_LANE, "connection", 0, ok, "");
00093 if (!ok) {
00094 return;
00095 }
00096 if (from.length()==0) {
00097 MsgHandler::getErrorInstance()->inform("A from-edge is not specified within one of the connections");
00098 return;
00099 }
00100
00101 NBEdge *fromEdge = myEdgeCont.retrieve(from);
00102 NBEdge *toEdge = to.length()!=0 ? myEdgeCont.retrieve(to) : 0;
00103
00104 if (fromEdge==0) {
00105 MsgHandler::getErrorInstance()->inform("The connection-source edge '" + from + "' is not known.");
00106 return;
00107 }
00108 if (toEdge==0 && to.length()!=0) {
00109 MsgHandler::getErrorInstance()->inform("The connection-destination edge '" + to + "' is not known.");
00110 return;
00111 }
00112
00113 if (!myHaveReportedAboutFunctionDeprecation&&attrs.hasAttribute(SUMO_ATTR_TYPE)) {
00114 MsgHandler::getWarningInstance()->inform("While parsing connections: 'type' is deprecated.\n All occurences are ignored.");
00115 myHaveReportedAboutFunctionDeprecation = true;
00116 }
00117 if (laneConn=="") {
00118 fromEdge->addEdge2EdgeConnection(toEdge);
00119 } else {
00120 parseLaneBound(attrs, fromEdge, toEdge);
00121 }
00122 }
00123 if (element==SUMO_TAG_PROHIBITION) {
00124 bool ok = true;
00125 std::string prohibitor = attrs.getOptStringReporting(SUMO_ATTR_PROHIBITOR, "prohibition", 0, ok, "");
00126 std::string prohibited = attrs.getOptStringReporting(SUMO_ATTR_PROHIBITED, "prohibition", 0, ok, "");
00127 if (!ok) {
00128 return;
00129 }
00130 NBConnection prohibitorC = parseConnection("prohibitor", prohibitor);
00131 NBConnection prohibitedC = parseConnection("prohibited", prohibited);
00132 if (prohibitorC.getFrom()==0||prohibitedC.getFrom()==0) {
00133
00134 return;
00135 }
00136 NBNode *n = prohibitorC.getFrom()->getToNode();
00137 n->addSortedLinkFoes(prohibitorC, prohibitedC);
00138 }
00139 }
00140
00141
00142 NBConnection
00143 NIXMLConnectionsHandler::parseConnection(const std::string &defRole,
00144 const std::string &def) throw() {
00145
00146 size_t div = def.find("->");
00147 if (div==std::string::npos) {
00148 MsgHandler::getErrorInstance()->inform("Missing connection divider in " + defRole + " '" + def + "'");
00149 return NBConnection(0, 0);
00150 }
00151 std::string fromDef = def.substr(0, div);
00152 std::string toDef = def.substr(div+2);
00153
00154
00155
00156 if (fromDef.find('_')!=std::string::npos) {
00157 fromDef = fromDef.substr(0, fromDef.find('_'));
00158 }
00159 if (toDef.find('_')!=std::string::npos) {
00160 toDef = toDef.substr(0, toDef.find('_'));
00161 }
00162
00163 NBEdge *fromE = myEdgeCont.retrieve(fromDef);
00164 NBEdge *toE = myEdgeCont.retrieve(toDef);
00165
00166 if (fromE==0) {
00167 MsgHandler::getErrorInstance()->inform("Could not find edge '" + fromDef + "' in " + defRole + " '" + def + "'");
00168 return NBConnection(0, 0);
00169 }
00170 if (toE==0) {
00171 MsgHandler::getErrorInstance()->inform("Could not find edge '" + toDef + "' in " + defRole + " '" + def + "'");
00172 return NBConnection(0, 0);
00173 }
00174 return NBConnection(fromE, toE);
00175 }
00176
00177
00178 void
00179 NIXMLConnectionsHandler::parseLaneBound(const SUMOSAXAttributes &attrs,
00180 NBEdge *from,
00181 NBEdge *to) throw() {
00182 if (to==0) {
00183
00184 return;
00185 }
00186 bool ok = true;
00187 std::string laneConn = attrs.getOptStringReporting(SUMO_ATTR_LANE, "connection", 0, ok, "");
00188
00189 StringTokenizer st(laneConn, ':');
00190 if (st.size()!=2) {
00191 MsgHandler::getErrorInstance()->inform("Invalid lane to lane connection from '" +
00192 from->getID() + "' to '" + to->getID() + "'.");
00193 return;
00194 }
00195 bool mayDefinitelyPass = attrs.getOptBoolReporting(SUMO_ATTR_PASS, "connection", 0, ok, false);
00196 if (!ok) {
00197 return;
00198 }
00199
00200 int fromLane;
00201 int toLane;
00202 try {
00203 fromLane = TplConvertSec<char>::_2intSec(st.next().c_str(), -1);
00204 toLane = TplConvertSec<char>::_2intSec(st.next().c_str(), -1);
00205 if (fromLane<0 || fromLane>=from->getNoLanes() || toLane<0 || toLane>=to->getNoLanes()) {
00206 MsgHandler::getErrorInstance()->inform("False lane index in connection from '" + from->getID() + "' to '" + to->getID() + "'.");
00207 return;
00208 }
00209 if (from->hasConnectionTo(to, toLane)) {
00210 WRITE_WARNING("Target lane '" + to->getID() + "_" + toString(toLane) + "' is already connected from '" + from->getID() + "'.");
00211 }
00212 if (!from->addLane2LaneConnection(fromLane, to, toLane, NBEdge::L2L_USER, true, mayDefinitelyPass)) {
00213 NBEdge *nFrom = from;
00214 bool toNext = true;
00215 do {
00216 if (nFrom->getToNode()->getOutgoingEdges().size()!=1) {
00217 toNext = false;
00218 break;
00219 }
00220 NBEdge *t = nFrom->getToNode()->getOutgoingEdges()[0];
00221 if (t->getID().substr(0, t->getID().find('/'))!=nFrom->getID().substr(0, nFrom->getID().find('/'))) {
00222 toNext = false;
00223 break;
00224 }
00225 if (toNext) {
00226 nFrom = t;
00227 }
00228 } while (toNext);
00229 if (nFrom==0||!nFrom->addLane2LaneConnection(fromLane, to, toLane, NBEdge::L2L_USER, false, mayDefinitelyPass)) {
00230 WRITE_WARNING("Could not set loaded connection from '" + from->getID() + "_" + toString<int>(fromLane) + "' to '" + to->getID() + "_" + toString<int>(toLane) + "'.");
00231 } else {
00232 from = nFrom;
00233 }
00234 }
00235 } catch (NumberFormatException &) {
00236 MsgHandler::getErrorInstance()->inform("At least one of the defined lanes was not numeric");
00237 }
00238
00239 bool keepUncontrolled = attrs.getOptBoolReporting(SUMO_ATTR_UNCONTROLLED, 0, 0, ok, false);
00240 if (keepUncontrolled) {
00241 from->disableConnection4TLS(fromLane, to, toLane);
00242 }
00243 }
00244
00245
00246
00247
00248