SUMO - Simulation of Urban MObility
|
00001 /****************************************************************************/ 00009 // ------------------- 00010 /****************************************************************************/ 00011 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/ 00012 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors 00013 /****************************************************************************/ 00014 // 00015 // This file is part of SUMO. 00016 // SUMO is free software: you can redistribute it and/or modify 00017 // it under the terms of the GNU General Public License as published by 00018 // the Free Software Foundation, either version 3 of the License, or 00019 // (at your option) any later version. 00020 // 00021 /****************************************************************************/ 00022 00023 00024 // =========================================================================== 00025 // included modules 00026 // =========================================================================== 00027 #ifdef _MSC_VER 00028 #include <windows_config.h> 00029 #else 00030 #include <config.h> 00031 #endif 00032 00033 #include <map> 00034 #include <string> 00035 #include <algorithm> 00036 #include <cassert> 00037 #include <utils/common/VectorHelper.h> 00038 #include <utils/common/ToString.h> 00039 #include <utils/geom/Position.h> 00040 #include <utils/geom/GeomHelper.h> 00041 #include <utils/geom/PositionVector.h> 00042 #include <utils/options/OptionsCont.h> 00043 #include "NIVissimAbstractEdge.h" 00044 #include "NIVissimEdge.h" 00045 #include <netbuild/NBEdge.h> 00046 #include <netbuild/NBEdgeCont.h> 00047 #include <netbuild/NBNode.h> 00048 #include <netbuild/NBNodeCont.h> 00049 #include <netbuild/NBDistrict.h> 00050 #include <netbuild/NBDistrictCont.h> 00051 #include "NIVissimDistrictConnection.h" 00052 #include <utils/distribution/Distribution.h> 00053 #include <netbuild/NBDistribution.h> 00054 #include <utils/common/MsgHandler.h> 00055 00056 #ifdef CHECK_MEMORY_LEAKS 00057 #include <foreign/nvwa/debug_new.h> 00058 #endif // CHECK_MEMORY_LEAKS 00059 00060 00061 // =========================================================================== 00062 // static member definitions 00063 // =========================================================================== 00064 NIVissimDistrictConnection::DictType NIVissimDistrictConnection::myDict; 00065 std::map<int, std::vector<int> > NIVissimDistrictConnection::myDistrictsConnections; 00066 00067 00068 // =========================================================================== 00069 // method definitions 00070 // =========================================================================== 00071 NIVissimDistrictConnection::NIVissimDistrictConnection(int id, 00072 const std::string& name, 00073 const std::vector<int>& districts, const std::vector<SUMOReal>& percentages, 00074 int edgeid, SUMOReal position, 00075 const std::vector<std::pair<int, int> > &assignedVehicles) 00076 : myID(id), myName(name), myDistricts(districts), 00077 myEdgeID(edgeid), myPosition(position), 00078 myAssignedVehicles(assignedVehicles) { 00079 std::vector<int>::iterator i = myDistricts.begin(); 00080 std::vector<SUMOReal>::const_iterator j = percentages.begin(); 00081 while (i != myDistricts.end()) { 00082 myPercentages[*i] = *j; 00083 i++; 00084 j++; 00085 } 00086 } 00087 00088 00089 NIVissimDistrictConnection::~NIVissimDistrictConnection() {} 00090 00091 00092 00093 bool 00094 NIVissimDistrictConnection::dictionary(int id, const std::string& name, 00095 const std::vector<int>& districts, const std::vector<SUMOReal>& percentages, 00096 int edgeid, SUMOReal position, 00097 const std::vector<std::pair<int, int> > &assignedVehicles) { 00098 NIVissimDistrictConnection* o = 00099 new NIVissimDistrictConnection(id, name, districts, percentages, 00100 edgeid, position, assignedVehicles); 00101 if (!dictionary(id, o)) { 00102 delete o; 00103 return false; 00104 } 00105 return true; 00106 } 00107 00108 00109 bool 00110 NIVissimDistrictConnection::dictionary(int id, NIVissimDistrictConnection* o) { 00111 DictType::iterator i = myDict.find(id); 00112 if (i == myDict.end()) { 00113 myDict[id] = o; 00114 return true; 00115 } 00116 return false; 00117 } 00118 00119 00120 NIVissimDistrictConnection* 00121 NIVissimDistrictConnection::dictionary(int id) { 00122 DictType::iterator i = myDict.find(id); 00123 if (i == myDict.end()) { 00124 return 0; 00125 } 00126 return (*i).second; 00127 } 00128 00129 void 00130 NIVissimDistrictConnection::dict_BuildDistrictConnections() { 00131 // pre-assign connections to districts 00132 for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) { 00133 NIVissimDistrictConnection* c = (*i).second; 00134 const std::vector<int>& districts = c->myDistricts; 00135 for (std::vector<int>::const_iterator j = districts.begin(); j != districts.end(); j++) { 00136 // assign connection to district 00137 myDistrictsConnections[*j].push_back((*i).first); 00138 } 00139 } 00140 } 00141 00142 00143 void 00144 NIVissimDistrictConnection::dict_CheckEdgeEnds() { 00145 for (std::map<int, std::vector<int> >::iterator k = myDistrictsConnections.begin(); k != myDistrictsConnections.end(); k++) { 00146 const std::vector<int>& connections = (*k).second; 00147 for (std::vector<int>::const_iterator j = connections.begin(); j != connections.end(); j++) { 00148 NIVissimDistrictConnection* c = dictionary(*j); 00149 c->checkEdgeEnd(); 00150 } 00151 } 00152 } 00153 00154 00155 void 00156 NIVissimDistrictConnection::checkEdgeEnd() { 00157 NIVissimEdge* edge = NIVissimEdge::dictionary(myEdgeID); 00158 assert(edge != 0); 00159 edge->checkDistrictConnectionExistanceAt(myPosition); 00160 } 00161 00162 00163 void 00164 NIVissimDistrictConnection::dict_BuildDistrictNodes(NBDistrictCont& dc, 00165 NBNodeCont& nc) { 00166 for (std::map<int, std::vector<int> >::iterator k = myDistrictsConnections.begin(); k != myDistrictsConnections.end(); k++) { 00167 // get the connections 00168 const std::vector<int>& connections = (*k).second; 00169 // retrieve the current district 00170 std::string dsid = toString<int>((*k).first); 00171 NBDistrict* district = new NBDistrict(dsid); 00172 dc.insert(district); 00173 // compute the middle of the district 00174 PositionVector pos; 00175 for (std::vector<int>::const_iterator j = connections.begin(); j != connections.end(); j++) { 00176 NIVissimDistrictConnection* c = dictionary(*j); 00177 pos.push_back(c->geomPosition()); 00178 } 00179 Position distCenter = pos.getPolygonCenter(); 00180 if (connections.size() == 1) { // !!! ok, ok, maybe not the best way just to add an offset 00181 distCenter.add(10, 10); 00182 } 00183 district->setCenter(distCenter); 00184 // build the node 00185 std::string id = "District" + district->getID(); 00186 NBNode* districtNode = 00187 new NBNode(id, district->getPosition(), district); 00188 if (!nc.insert(districtNode)) { 00189 throw 1; 00190 } 00191 } 00192 } 00193 00194 void 00195 NIVissimDistrictConnection::dict_BuildDistricts(NBDistrictCont& dc, 00196 NBEdgeCont& ec, 00197 NBNodeCont& nc/*, 00198 NBDistribution &distc*/) { 00199 // add the sources and sinks 00200 // their normalised probability is computed within NBDistrict 00201 // to avoid SUMOReal code writing and more securty within the converter 00202 // go through the district table 00203 for (std::map<int, std::vector<int> >::iterator k = myDistrictsConnections.begin(); k != myDistrictsConnections.end(); k++) { 00204 // get the connections 00205 const std::vector<int>& connections = (*k).second; 00206 // retrieve the current district 00207 NBDistrict* district = 00208 dc.retrieve(toString<int>((*k).first)); 00209 NBNode* districtNode = nc.retrieve("District" + district->getID()); 00210 assert(district != 0 && districtNode != 0); 00211 00212 for (std::vector<int>::const_iterator l = connections.begin(); l != connections.end(); l++) { 00213 NIVissimDistrictConnection* c = dictionary(*l); 00214 // get the edge to connect the parking place to 00215 NBEdge* e = ec.retrieve(toString<int>(c->myEdgeID)); 00216 if (e == 0) { 00217 e = ec.retrievePossiblySplitted(toString<int>(c->myEdgeID), c->myPosition); 00218 } 00219 if (e == 0) { 00220 WRITE_WARNING("Could not build district '" + toString<int>((*k).first) + "' - edge '" + toString<int>(c->myEdgeID) + "' is missing."); 00221 continue; 00222 } 00223 std::string id = "ParkingPlace" + toString<int>(*l); 00224 NBNode* parkingPlace = nc.retrieve(id); 00225 if (parkingPlace == 0) { 00226 SUMOReal pos = c->getPosition(); 00227 if (pos < e->getLength() - pos) { 00228 parkingPlace = e->getFromNode(); 00229 parkingPlace->invalidateIncomingConnections(); 00230 } else { 00231 parkingPlace = e->getToNode(); 00232 parkingPlace->invalidateOutgoingConnections(); 00233 } 00234 } 00235 assert( 00236 e->getToNode() == parkingPlace 00237 || 00238 e->getFromNode() == parkingPlace); 00239 00240 // build the connection to the source 00241 if (e->getFromNode() == parkingPlace) { 00242 id = "VissimFromParkingplace" + toString<int>((*k).first) + "-" + toString<int>(c->myID); 00243 NBEdge* source = 00244 new NBEdge(id, districtNode, parkingPlace, 00245 "Connection", c->getMeanSpeed(/*distc*/) / (SUMOReal) 3.6, 3, -1, -1, LANESPREAD_RIGHT); 00246 if (!ec.insert(source)) { // !!! in den Konstruktor 00247 throw 1; // !!! 00248 } 00249 SUMOReal percNormed = 00250 c->myPercentages[(*k).first]; 00251 if (!district->addSource(source, percNormed)) { 00252 throw 1; 00253 } 00254 } 00255 00256 // build the connection to the destination 00257 if (e->getToNode() == parkingPlace) { 00258 id = "VissimToParkingplace" + toString<int>((*k).first) + "-" + toString<int>(c->myID); 00259 NBEdge* destination = 00260 new NBEdge(id, parkingPlace, districtNode, 00261 "Connection", (SUMOReal) 100 / (SUMOReal) 3.6, 2, -1, -1, LANESPREAD_RIGHT); 00262 if (!ec.insert(destination)) { // !!! (in den Konstruktor) 00263 throw 1; // !!! 00264 } 00265 SUMOReal percNormed2 = 00266 c->myPercentages[(*k).first]; 00267 if (!district->addSink(destination, percNormed2)) { 00268 throw 1; // !!! 00269 } 00270 } 00271 00272 /* 00273 if(e->getToNode()==districtNode) { 00274 SUMOReal percNormed = 00275 c->myPercentages[(*k).first]; 00276 district->addSink(e, percNormed); 00277 } 00278 if(e->getFromNode()==districtNode) { 00279 SUMOReal percNormed = 00280 c->myPercentages[(*k).first]; 00281 district->addSource(e, percNormed); 00282 } 00283 */ 00284 } 00285 00286 /* 00287 // add them as sources and sinks to the current district 00288 for(std::vector<int>::const_iterator l=connections.begin(); l!=connections.end(); l++) { 00289 // get the current connections 00290 NIVissimDistrictConnection *c = dictionary(*l); 00291 // get the edge to connect the parking place to 00292 NBEdge *e = NBEdgeCont::retrieve(toString<int>(c->myEdgeID)); 00293 Position edgepos = c->geomPosition(); 00294 NBNode *edgeend = e->tryGetNodeAtPosition(c->myPosition, 00295 e->getLength()/4.0); 00296 if(edgeend==0) { 00297 // Edge splitting omitted on build district connections by now 00298 assert(false); 00299 } 00300 00301 // build the district-node if not yet existing 00302 std::string id = "VissimParkingplace" + district->getID(); 00303 NBNode *districtNode = nc.retrieve(id); 00304 assert(districtNode!=0); 00305 00306 if(e->getToNode()==edgeend) { 00307 // build the connection to the source 00308 id = std::string("VissimFromParkingplace") 00309 + toString<int>((*k).first) + "-" 00310 + toString<int>(c->myID); 00311 NBEdge *source = 00312 new NBEdge(id, id, districtNode, edgeend, 00313 "Connection", 100/3.6, 2, 100, 0, 00314 NBEdge::EDGEFUNCTION_SOURCE); 00315 NBEdgeCont::insert(source); // !!! (in den Konstruktor) 00316 SUMOReal percNormed = 00317 c->myPercentages[(*k).first]; 00318 district->addSource(source, percNormed); 00319 } else { 00320 // build the connection to the destination 00321 id = std::string("VissimToParkingplace") 00322 + toString<int>((*k).first) + "-" 00323 + toString<int>(c->myID); 00324 NBEdge *destination = 00325 new NBEdge(id, id, edgeend, districtNode, 00326 "Connection", 100/3.6, 2, 100, 0, 00327 NBEdge::EDGEFUNCTION_SINK); 00328 NBEdgeCont::insert(destination); // !!! (in den Konstruktor) 00329 00330 // add both the source and the sink to the district 00331 SUMOReal percNormed = 00332 c->myPercentages[(*k).first]; 00333 district->addSink(destination, percNormed); 00334 } 00335 } 00336 */ 00337 } 00338 } 00339 00340 00341 00342 Position 00343 NIVissimDistrictConnection::geomPosition() const { 00344 NIVissimAbstractEdge* e = NIVissimEdge::dictionary(myEdgeID); 00345 return e->getGeomPosition(myPosition); 00346 } 00347 00348 00349 NIVissimDistrictConnection* 00350 NIVissimDistrictConnection::dict_findForEdge(int edgeid) { 00351 for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) { 00352 if ((*i).second->myEdgeID == edgeid) { 00353 return (*i).second; 00354 } 00355 } 00356 return 0; 00357 } 00358 00359 00360 void 00361 NIVissimDistrictConnection::clearDict() { 00362 for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) { 00363 delete(*i).second; 00364 } 00365 myDict.clear(); 00366 } 00367 00368 00369 SUMOReal 00370 NIVissimDistrictConnection::getMeanSpeed(/*NBDistribution &dc*/) const { 00371 //assert(myAssignedVehicles.size()!=0); 00372 if (myAssignedVehicles.size() == 0) { 00373 WRITE_WARNING("No streams assigned at district'" + toString(myID) + "'.\n Using default speed 200km/h"); 00374 return (SUMOReal) 200 / (SUMOReal) 3.6; 00375 } 00376 SUMOReal speed = 0; 00377 std::vector<std::pair<int, int> >::const_iterator i; 00378 for (i = myAssignedVehicles.begin(); i != myAssignedVehicles.end(); i++) { 00379 speed += getRealSpeed(/*dc, */(*i).second); 00380 } 00381 return speed / (SUMOReal) myAssignedVehicles.size(); 00382 } 00383 00384 00385 SUMOReal 00386 NIVissimDistrictConnection::getRealSpeed(/*NBDistribution &dc, */int distNo) const { 00387 std::string id = toString<int>(distNo); 00388 Distribution* dist = NBDistribution::dictionary("speed", id); 00389 if (dist == 0) { 00390 WRITE_WARNING("The referenced speed distribution '" + id + "' is not known."); 00391 WRITE_WARNING(". Using default."); 00392 return OptionsCont::getOptions().getFloat("vissim.default-speed"); 00393 } 00394 assert(dist != 0); 00395 SUMOReal speed = dist->getMax(); 00396 if (speed < 0 || speed > 1000) { 00397 WRITE_WARNING(" False speed at district '" + id); 00398 WRITE_WARNING(". Using default."); 00399 speed = OptionsCont::getOptions().getFloat("vissim.default-speed"); 00400 } 00401 return speed; 00402 } 00403 00404 00405 00406 /****************************************************************************/ 00407