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
00031 #include <map>
00032 #include <string>
00033 #include <iostream>
00034 #include <cassert>
00035 #include <utils/common/ToString.h>
00036 #include <utils/common/MsgHandler.h>
00037 #include <utils/geom/GeomHelper.h>
00038 #include <utils/geom/Boundary.h>
00039 #include <netbuild/NBEdge.h>
00040 #include <netbuild/NBNode.h>
00041 #include <netbuild/NBEdgeCont.h>
00042 #include <netbuild/NBNodeCont.h>
00043 #include "NIVissimEdge.h"
00044 #include "NIVissimConnection.h"
00045 #include "NIVissimNodeDef.h"
00046 #include "NIVissimDisturbance.h"
00047 #include "NIVissimNodeParticipatingEdgeVector.h"
00048
00049 #ifdef CHECK_MEMORY_LEAKS
00050 #include <foreign/nvwa/debug_new.h>
00051 #endif // CHECK_MEMORY_LEAKS
00052
00053
00054
00055
00056 using namespace std;
00057
00058 NIVissimDisturbance::DictType NIVissimDisturbance::myDict;
00059 int NIVissimDisturbance::myRunningID = 100000000;
00060
00061 int NIVissimDisturbance::refusedProhibits = 0;
00062
00063
00064 NIVissimDisturbance::NIVissimDisturbance(int id,
00065 const std::string &name,
00066 const NIVissimExtendedEdgePoint &edge,
00067 const NIVissimExtendedEdgePoint &by,
00068 SUMOReal timegap, SUMOReal waygap,
00069 SUMOReal vmax)
00070 : myID(id), myNode(-1), myName(name), myEdge(edge), myDisturbance(by),
00071 myTimeGap(timegap), myWayGap(waygap), myVMax(vmax) {}
00072
00073
00074 NIVissimDisturbance::~NIVissimDisturbance() {}
00075
00076
00077
00078 bool
00079 NIVissimDisturbance::dictionary(int id,
00080 const std::string &name,
00081 const NIVissimExtendedEdgePoint &edge,
00082 const NIVissimExtendedEdgePoint &by,
00083 SUMOReal timegap, SUMOReal waygap, SUMOReal vmax) {
00084 int nid = myRunningID++;
00085 NIVissimDisturbance *o =
00086 new NIVissimDisturbance(nid, name, edge, by, timegap, waygap, vmax);
00087 if (!dictionary(nid, o)) {
00088 delete o;
00089 }
00090 return true;
00091 }
00092
00093
00094 bool
00095 NIVissimDisturbance::dictionary(int id, NIVissimDisturbance *o) {
00096 DictType::iterator i=myDict.find(id);
00097 if (i==myDict.end()) {
00098 myDict[id] = o;
00099 return true;
00100 }
00101 return false;
00102 }
00103
00104
00105 NIVissimDisturbance *
00106 NIVissimDisturbance::dictionary(int id) {
00107 DictType::iterator i=myDict.find(id);
00108 if (i==myDict.end()) {
00109 return 0;
00110 }
00111 return (*i).second;
00112 }
00113
00114 IntVector
00115 NIVissimDisturbance::getWithin(const AbstractPoly &poly) {
00116 IntVector ret;
00117 for (DictType::iterator i=myDict.begin(); i!=myDict.end(); i++) {
00118 if ((*i).second->crosses(poly)) {
00119 ret.push_back((*i).second->myID);
00120 }
00121 }
00122 return ret;
00123 }
00124
00125
00126 void
00127 NIVissimDisturbance::computeBounding() {
00128 assert(myBoundary==0);
00129 Boundary *bound = new Boundary();
00130 if (NIVissimAbstractEdge::dictionary(myEdge.getEdgeID())!=0) {
00131 bound->add(myEdge.getGeomPosition());
00132 }
00133 if (NIVissimAbstractEdge::dictionary(myDisturbance.getEdgeID())!=0) {
00134 bound->add(myDisturbance.getGeomPosition());
00135 }
00136 myBoundary = bound;
00137 assert(myBoundary!=0&&myBoundary->xmax()>=myBoundary->xmin());
00138 }
00139
00140
00141
00142 bool
00143 NIVissimDisturbance::addToNode(NBNode *node, NBDistrictCont &dc,
00144 NBNodeCont &nc, NBEdgeCont &ec) {
00145 myNode = 0;
00146 NIVissimConnection *pc =
00147 NIVissimConnection::dictionary(myEdge.getEdgeID());
00148 NIVissimConnection *bc =
00149 NIVissimConnection::dictionary(myDisturbance.getEdgeID());
00150 if (pc==0 && bc==0) {
00151
00152
00153
00154
00155 NIVissimEdge *e1 = NIVissimEdge::dictionary(myEdge.getEdgeID());
00156 NIVissimEdge *e2 = NIVissimEdge::dictionary(myDisturbance.getEdgeID());
00157 WRITE_WARNING("Ugly split to prohibit '" + toString<int>(e1->getID())+ "' by '" + toString<int>(e2->getID())+ "'.");
00158 Position2D pos = e1->crossesEdgeAtPoint(e2);
00159 std::string id1 = toString<int>(e1->getID()) + "x" + toString<int>(e2->getID());
00160 std::string id2 = toString<int>(e2->getID()) + "x" + toString<int>(e1->getID());
00161 NBNode *node1 = nc.retrieve(id1);
00162 NBNode *node2 = nc.retrieve(id2);
00163 NBNode *node = 0;
00164 assert(node1==0||node2==0);
00165 if (node1==0&&node2==0) {
00166 refusedProhibits++;
00167 return false;
00168
00169
00170
00171
00172
00173 } else {
00174 node = node1==0 ? node2 : node1;
00175 }
00176 ec.splitAt(dc,
00177 ec.retrievePossiblySplitted(
00178 toString<int>(e1->getID()), myEdge.getPosition()),
00179 node);
00180 ec.splitAt(dc,
00181 ec.retrievePossiblySplitted(
00182 toString<int>(e2->getID()), myDisturbance.getPosition()),
00183 node);
00184
00185
00186 NBEdge *mayDriveFrom = ec.retrieve(toString<int>(e1->getID()) + "[0]");
00187 NBEdge *mayDriveTo = ec.retrieve(toString<int>(e1->getID()) + "[1]");
00188 NBEdge *mustStopFrom = ec.retrieve(toString<int>(e2->getID()) + "[0]");
00189 NBEdge *mustStopTo = ec.retrieve(toString<int>(e2->getID()) + "[1]");
00190 if (mayDriveFrom!=0&&mayDriveTo!=0&&mustStopFrom!=0&&mustStopTo!=0) {
00191 node->addSortedLinkFoes(
00192 NBConnection(mayDriveFrom, mayDriveTo),
00193 NBConnection(mayDriveFrom, mayDriveTo));
00194 } else {
00195 refusedProhibits++;
00196 return false;
00197
00198 }
00199
00200 } else if (pc!=0 && bc==0) {
00201
00202
00203
00204
00205
00206 NBEdge *e = ec.retrievePossiblySplitted(toString<int>(myDisturbance.getEdgeID()), myDisturbance.getPosition());
00207 if (e==0) {
00208 WRITE_WARNING("Could not prohibit '"+ toString<int>(myEdge.getEdgeID()) + "' by '" + toString<int>(myDisturbance.getEdgeID())+ "'. Have not found disturbance.");
00209 refusedProhibits++;
00210 return false;
00211 }
00212 if (e->getFromNode()==e->getToNode()) {
00213 WRITE_WARNING("Could not prohibit '"+ toString<int>(myEdge.getEdgeID()) + "' by '" + toString<int>(myDisturbance.getEdgeID())+ "'. Disturbance connects same node.");
00214 refusedProhibits++;
00215
00216 return false;
00217 }
00218
00219 std::string id_pcoe = toString<int>(pc->getFromEdgeID());
00220 std::string id_pcie = toString<int>(pc->getToEdgeID());
00221 NBEdge *pcoe = ec.retrievePossiblySplitted(id_pcoe, id_pcie, true);
00222 NBEdge *pcie = ec.retrievePossiblySplitted(id_pcie, id_pcoe, false);
00223
00224
00225 if (pcoe!=0&&pcie!=0&&pcoe->getToNode()==e->getToNode()) {
00226
00227 NBNode *node = e->getToNode();
00228 const EdgeVector &connected = e->getConnectedEdges();
00229 for (EdgeVector::const_iterator i=connected.begin(); i!=connected.end(); i++) {
00230 node->addSortedLinkFoes(
00231 NBConnection(e, *i),
00232 NBConnection(pcoe, pcie));
00233 }
00234 } else {
00235 WRITE_WARNING("Would have to split edge '" + e->getID() + "' to build a prohibition");
00236 refusedProhibits++;
00237
00238 return false;
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253 }
00254 } else if (bc!=0 && pc==0) {
00255
00256
00257
00258
00259
00260 NBEdge *e = ec.retrievePossiblySplitted(
00261 toString<int>(myEdge.getEdgeID()), myEdge.getPosition());
00262 if (e==0) {
00263 WRITE_WARNING("Could not prohibit '" + toString<int>(myEdge.getEdgeID()) + "' - it was not built.");
00264 return false;
00265 }
00266 std::string nid1 = e->getID() + "[0]";
00267 std::string nid2 = e->getID() + "[1]";
00268 if (e->getFromNode()==e->getToNode()) {
00269 WRITE_WARNING("Could not prohibit '" + toString<int>(myEdge.getEdgeID()) + "' by '" + toString<int>(myDisturbance.getEdgeID())+ "'.");
00270 refusedProhibits++;
00271
00272 return false;
00273 }
00274
00275 std::string id_bcoe = toString<int>(bc->getFromEdgeID());
00276 std::string id_bcie = toString<int>(bc->getToEdgeID());
00277 NBEdge *bcoe = ec.retrievePossiblySplitted(id_bcoe, id_bcie, true);
00278 NBEdge *bcie = ec.retrievePossiblySplitted(id_bcie, id_bcoe, false);
00279
00280
00281 if (bcoe!=0&&bcie!=0&&bcoe->getToNode()==e->getToNode()) {
00282
00283 NBNode *node = e->getToNode();
00284 const EdgeVector &connected = e->getConnectedEdges();
00285 for (EdgeVector::const_iterator i=connected.begin(); i!=connected.end(); i++) {
00286 node->addSortedLinkFoes(
00287 NBConnection(bcoe, bcie),
00288 NBConnection(e, *i));
00289 }
00290 } else {
00291 WRITE_WARNING("Would have to split edge '" + e->getID() + "' to build a prohibition");
00292 refusedProhibits++;
00293 return false;
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306 }
00307 } else {
00308
00309
00310
00311 NBConnection conn1 = getConnection(node, myDisturbance.getEdgeID());
00312 NBConnection conn2 = getConnection(node, myEdge.getEdgeID());
00313 if (!conn1.check(ec)||!conn2.check(ec)) {
00314 refusedProhibits++;
00315 return false;
00316 }
00317 node->addSortedLinkFoes(conn1, conn2);
00318 }
00319 return true;
00320 }
00321
00322
00323 NBConnection
00324 NIVissimDisturbance::getConnection(NBNode *node, int aedgeid) {
00325 if (NIVissimEdge::dictionary(myEdge.getEdgeID())==0) {
00326 NIVissimConnection *c = NIVissimConnection::dictionary(aedgeid);
00327 NBEdge *from =
00328 node->getPossiblySplittedIncoming(toString<int>(c->getFromEdgeID()));
00329 NBEdge *to =
00330 node->getPossiblySplittedOutgoing(toString<int>(c->getToEdgeID()));
00331
00332
00333 return NBConnection(toString<int>(c->getFromEdgeID()), from,
00334 toString<int>(c->getToEdgeID()), to);
00335 } else {
00336 WRITE_WARNING("NIVissimDisturbance: no connection");
00337 return NBConnection(0, 0);
00338
00339 }
00340
00341 }
00342
00343 void
00344 NIVissimDisturbance::clearDict() {
00345 for (DictType::iterator i=myDict.begin(); i!=myDict.end(); i++) {
00346 delete(*i).second;
00347 }
00348 myDict.clear();
00349 }
00350
00351
00352 void
00353 NIVissimDisturbance::dict_SetDisturbances() {
00354 for (DictType::iterator i=myDict.begin(); i!=myDict.end(); i++) {
00355 NIVissimDisturbance *d = (*i).second;
00356 NIVissimAbstractEdge::dictionary(d->myEdge.getEdgeID())->addDisturbance((*i).first);
00357 NIVissimAbstractEdge::dictionary(d->myDisturbance.getEdgeID())->addDisturbance((*i).first);
00358 }
00359
00360
00361
00362
00363 }
00364
00365
00366 void
00367 NIVissimDisturbance::reportRefused() {
00368 if (refusedProhibits>0) {
00369 WRITE_WARNING("Could not build " + toString<size_t>(refusedProhibits)+ " of " + toString<size_t>(myDict.size())+ " disturbances.");
00370 }
00371 }
00372
00373
00374
00375
00376