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 <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/Position2D.h>
00037 #include <utils/geom/GeomHelper.h>
00038 #include <utils/geom/Position2DVector.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
00060
00061 NIVissimDistrictConnection::DictType NIVissimDistrictConnection::myDict;
00062 std::map<int, IntVector> NIVissimDistrictConnection::myDistrictsConnections;
00063
00064
00065
00066
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
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
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
00165 const IntVector &connections = (*k).second;
00166
00167 std::string dsid = toString<int>((*k).first);
00168 NBDistrict *district = new NBDistrict(dsid);
00169 dc.insert(district);
00170
00171 Position2DVector 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 Position2D distCenter = pos.getPolygonCenter();
00177 if (connections.size()==1) {
00178 distCenter.add(10, 10);
00179 }
00180 district->setCenter(distCenter);
00181
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 ) {
00196
00197
00198
00199
00200 for (std::map<int, IntVector>::iterator k=myDistrictsConnections.begin(); k!=myDistrictsConnections.end(); k++) {
00201
00202 const IntVector &connections = (*k).second;
00203
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
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 MsgHandler::getWarningInstance()->inform("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
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()/(SUMOReal) 3.6, 3, -1,
00243 NBEdge::LANESPREAD_RIGHT);
00244 if (!ec.insert(source)) {
00245 throw 1;
00246 }
00247 SUMOReal percNormed =
00248 c->myPercentages[(*k).first];
00249 if (!district->addSource(source, percNormed)) {
00250 throw 1;
00251 }
00252 }
00253
00254
00255 if (e->getToNode()==parkingPlace) {
00256 id = "VissimToParkingplace" + toString<int>((*k).first) + "-" + toString<int>(c->myID);
00257 NBEdge *destination =
00258 new NBEdge(id, parkingPlace, districtNode,
00259 "Connection", (SUMOReal) 100/(SUMOReal) 3.6, 2, -1,
00260 NBEdge::LANESPREAD_RIGHT);
00261 if (!ec.insert(destination)) {
00262 throw 1;
00263 }
00264 SUMOReal percNormed2 =
00265 c->myPercentages[(*k).first];
00266 if (!district->addSink(destination, percNormed2)) {
00267 throw 1;
00268 }
00269 }
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283 }
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336 }
00337 }
00338
00339
00340
00341 Position2D
00342 NIVissimDistrictConnection::geomPosition() const {
00343 NIVissimAbstractEdge *e = NIVissimEdge::dictionary(myEdgeID);
00344 return e->getGeomPosition(myPosition);
00345 }
00346
00347
00348 NIVissimDistrictConnection *
00349 NIVissimDistrictConnection::dict_findForEdge(int edgeid) {
00350 for (DictType::iterator i=myDict.begin(); i!=myDict.end(); i++) {
00351 if ((*i).second->myEdgeID==edgeid) {
00352 return (*i).second;
00353 }
00354 }
00355 return 0;
00356 }
00357
00358
00359 void
00360 NIVissimDistrictConnection::clearDict() {
00361 for (DictType::iterator i=myDict.begin(); i!=myDict.end(); i++) {
00362 delete(*i).second;
00363 }
00364 myDict.clear();
00365 }
00366
00367
00368 SUMOReal
00369 NIVissimDistrictConnection::getMeanSpeed() const {
00370
00371 if (myAssignedVehicles.size()==0) {
00372 MsgHandler::getWarningInstance()->inform("No streams assigned at district'" + toString(myID) + "'.\n Using default speed 200km/h");
00373 return (SUMOReal) 200/(SUMOReal) 3.6;
00374 }
00375 SUMOReal speed = 0;
00376 std::vector<std::pair<int, int> >::const_iterator i;
00377 for (i=myAssignedVehicles.begin(); i!=myAssignedVehicles.end(); i++) {
00378 speed += getRealSpeed((*i).second);
00379 }
00380 return speed / (SUMOReal) myAssignedVehicles.size();
00381 }
00382
00383
00384 SUMOReal
00385 NIVissimDistrictConnection::getRealSpeed(int distNo) const {
00386 std::string id = toString<int>(distNo);
00387 Distribution *dist = NBDistribution::dictionary("speed", id);
00388 if (dist==0) {
00389 WRITE_WARNING("The referenced speed distribution '" + id + "' is not known.");
00390 WRITE_WARNING(". Using default.");
00391 return OptionsCont::getOptions().getFloat("vissim.default-speed");
00392 }
00393 assert(dist!=0);
00394 SUMOReal speed = dist->getMax();
00395 if (speed<0||speed>1000) {
00396 WRITE_WARNING(" False speed at district '" + id);
00397 WRITE_WARNING(". Using default.");
00398 speed = OptionsCont::getOptions().getFloat("vissim.default-speed");
00399 }
00400 return speed;
00401 }
00402
00403
00404
00405
00406