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