SUMO - Simulation of Urban MObility
RODFDetector.cpp
Go to the documentation of this file.
1 /****************************************************************************/
13 // Class representing a detector within the DFROUTER
14 /****************************************************************************/
15 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
16 // Copyright (C) 2006-2015 DLR (http://www.dlr.de/) and contributors
17 /****************************************************************************/
18 //
19 // This file is part of SUMO.
20 // SUMO is free software: you can redistribute it and/or modify
21 // it under the terms of the GNU General Public License as published by
22 // the Free Software Foundation, either version 3 of the License, or
23 // (at your option) any later version.
24 //
25 /****************************************************************************/
26 
27 
28 // ===========================================================================
29 // included modules
30 // ===========================================================================
31 #ifdef _MSC_VER
32 #include <windows_config.h>
33 #else
34 #include <config.h>
35 #endif
36 
37 #include <cassert>
38 #include "RODFDetector.h"
42 #include <utils/common/ToString.h>
43 #include <router/ROEdge.h>
44 #include "RODFEdge.h"
45 #include "RODFRouteDesc.h"
46 #include "RODFRouteCont.h"
47 #include "RODFDetectorFlow.h"
49 #include <utils/common/StdDefs.h>
51 #include <utils/geom/GeomHelper.h>
52 #include "RODFNet.h"
56 
57 #ifdef CHECK_MEMORY_LEAKS
58 #include <foreign/nvwa/debug_new.h>
59 #endif // CHECK_MEMORY_LEAKS
60 
61 
62 // ===========================================================================
63 // method definitions
64 // ===========================================================================
65 RODFDetector::RODFDetector(const std::string& id, const std::string& laneID,
66  SUMOReal pos, const RODFDetectorType type)
67  : Named(id), myLaneID(laneID), myPosition(pos), myType(type), myRoutes(0) {}
68 
69 
70 RODFDetector::RODFDetector(const std::string& id, const RODFDetector& f)
72  myType(f.myType), myRoutes(0) {
73  if (f.myRoutes != 0) {
74  myRoutes = new RODFRouteCont(*(f.myRoutes));
75  }
76 }
77 
78 
80  delete myRoutes;
81 }
82 
83 
84 void
86  myType = type;
87 }
88 
89 
92  SUMOReal distance = rd.edges2Pass[0]->getFromJunction()->getPosition().distanceTo(rd.edges2Pass.back()->getToJunction()->getPosition());
93  SUMOReal length = 0;
94  for (ROEdgeVector::const_iterator i = rd.edges2Pass.begin(); i != rd.edges2Pass.end(); ++i) {
95  length += (*i)->getLength();
96  }
97  return (distance / length);
98 }
99 
100 
101 void
103  const RODFDetectorFlows& flows,
104  SUMOTime startTime, SUMOTime endTime, SUMOTime stepOffset) {
105  if (myRoutes == 0) {
106  return;
107  }
108  // compute edges to determine split probabilities
109  const std::vector<RODFRouteDesc>& routes = myRoutes->get();
110  std::vector<RODFEdge*> nextDetEdges;
111  std::set<ROEdge*> preSplitEdges;
112  for (std::vector<RODFRouteDesc>::const_iterator i = routes.begin(); i != routes.end(); ++i) {
113  const RODFRouteDesc& rd = *i;
114  bool hadSplit = false;
115  for (ROEdgeVector::const_iterator j = rd.edges2Pass.begin(); j != rd.edges2Pass.end(); ++j) {
116  if (hadSplit && net->hasDetector(*j)) {
117  if (find(nextDetEdges.begin(), nextDetEdges.end(), *j) == nextDetEdges.end()) {
118  nextDetEdges.push_back(static_cast<RODFEdge*>(*j));
119  }
120  myRoute2Edge[rd.routename] = static_cast<RODFEdge*>(*j);
121  break;
122  }
123  if (!hadSplit) {
124  preSplitEdges.insert(*j);
125  }
126  if ((*j)->getNumSuccessors() > 1) {
127  hadSplit = true;
128  }
129  }
130  }
131  std::map<ROEdge*, SUMOReal> inFlows;
132  if (OptionsCont::getOptions().getBool("respect-concurrent-inflows")) {
133  for (std::vector<RODFEdge*>::const_iterator i = nextDetEdges.begin(); i != nextDetEdges.end(); ++i) {
134  std::set<ROEdge*> seen(preSplitEdges);
135  ROEdgeVector pending;
136  pending.push_back(*i);
137  seen.insert(*i);
138  while (!pending.empty()) {
139  ROEdge* e = pending.back();
140  pending.pop_back();
141  for (ROEdgeVector::const_iterator it = e->getPredecessors().begin(); it != e->getPredecessors().end(); it++) {
142  ROEdge* e2 = *it;
143  if (e2->getNumSuccessors() == 1 && seen.count(e2) == 0) {
144  if (net->hasDetector(e2)) {
145  inFlows[*i] += detectors.getAggFlowFor(e2, 0, 0, flows);
146  } else {
147  pending.push_back(e2);
148  }
149  seen.insert(e2);
150  }
151  }
152  }
153  }
154  }
155  // compute the probabilities to use a certain direction
156  int index = 0;
157  for (SUMOTime time = startTime; time < endTime; time += stepOffset, ++index) {
158  mySplitProbabilities.push_back(std::map<RODFEdge*, SUMOReal>());
159  SUMOReal overallProb = 0;
160  // retrieve the probabilities
161  for (std::vector<RODFEdge*>::const_iterator i = nextDetEdges.begin(); i != nextDetEdges.end(); ++i) {
162  SUMOReal flow = detectors.getAggFlowFor(*i, time, 60, flows) - inFlows[*i];
163  overallProb += flow;
164  mySplitProbabilities[index][*i] = flow;
165  }
166  // norm probabilities
167  if (overallProb > 0) {
168  for (std::vector<RODFEdge*>::const_iterator i = nextDetEdges.begin(); i != nextDetEdges.end(); ++i) {
169  mySplitProbabilities[index][*i] = mySplitProbabilities[index][*i] / overallProb;
170  }
171  }
172  }
173 }
174 
175 
176 void
178  SUMOTime startTime, SUMOTime endTime, SUMOTime stepOffset,
179  const RODFNet& net,
180  std::map<size_t, RandomDistributor<size_t>* >& into) const {
181  if (myRoutes == 0) {
183  WRITE_ERROR("Missing routes for detector '" + myID + "'.");
184  }
185  return;
186  }
187  std::vector<RODFRouteDesc>& descs = myRoutes->get();
188  // iterate through time (in output interval steps)
189  for (SUMOTime time = startTime; time < endTime; time += stepOffset) {
190  into[time] = new RandomDistributor<size_t>();
191  std::map<ROEdge*, SUMOReal> flowMap;
192  // iterate through the routes
193  size_t index = 0;
194  for (std::vector<RODFRouteDesc>::iterator ri = descs.begin(); ri != descs.end(); ++ri, index++) {
195  SUMOReal prob = 1.;
196  for (ROEdgeVector::iterator j = (*ri).edges2Pass.begin(); j != (*ri).edges2Pass.end() && prob > 0;) {
197  if (!net.hasDetector(*j)) {
198  ++j;
199  continue;
200  }
201  const RODFDetector& det = detectors.getAnyDetectorForEdge(static_cast<RODFEdge*>(*j));
202  const std::vector<std::map<RODFEdge*, SUMOReal> >& probs = det.getSplitProbabilities();
203  if (probs.size() == 0) {
204  prob = 0;
205  ++j;
206  continue;
207  }
208  const std::map<RODFEdge*, SUMOReal>& tprobs = probs[(time - startTime) / stepOffset];
209  RODFEdge* splitEdge = 0;
210  for (std::map<RODFEdge*, SUMOReal>::const_iterator k = tprobs.begin(); k != tprobs.end(); ++k) {
211  if (find(j, (*ri).edges2Pass.end(), (*k).first) != (*ri).edges2Pass.end()) {
212  prob *= (*k).second;
213  splitEdge = (*k).first;
214  break;
215  }
216  }
217  if (splitEdge != 0) {
218  j = find(j, (*ri).edges2Pass.end(), splitEdge);
219  } else {
220  ++j;
221  }
222  }
223  into[time]->add(prob, index);
224  (*ri).overallProb = prob;
225  }
226  }
227 }
228 
229 
230 const std::vector<RODFRouteDesc>&
232  return myRoutes->get();
233 }
234 
235 
236 void
238  myPriorDetectors.insert(det);
239 }
240 
241 
242 void
244  myFollowingDetectors.insert(det);
245 }
246 
247 
248 const std::set<const RODFDetector*>&
250  return myPriorDetectors;
251 }
252 
253 
254 const std::set<const RODFDetector*>&
256  return myFollowingDetectors;
257 }
258 
259 
260 
261 void
263  delete myRoutes;
264  myRoutes = routes;
265 }
266 
267 
268 void
270  if (myRoutes == 0) {
271  myRoutes = new RODFRouteCont();
272  }
273  myRoutes->addRouteDesc(nrd);
274 }
275 
276 
277 bool
279  return myRoutes != 0 && myRoutes->get().size() != 0;
280 }
281 
282 
283 bool
284 RODFDetector::writeEmitterDefinition(const std::string& file,
285  const std::map<size_t, RandomDistributor<size_t>* >& dists,
286  const RODFDetectorFlows& flows,
287  SUMOTime startTime, SUMOTime endTime,
288  SUMOTime stepOffset,
289  bool includeUnusedRoutes,
290  SUMOReal scale,
291  bool insertionsOnly,
292  SUMOReal defaultSpeed) const {
295  if (getType() != SOURCE_DETECTOR) {
296  out.writeXMLHeader("calibrator");
297  }
298  // routes
299  if (myRoutes != 0 && myRoutes->get().size() != 0) {
300  const std::vector<RODFRouteDesc>& routes = myRoutes->get();
302  bool isEmptyDist = true;
303  for (std::vector<RODFRouteDesc>::const_iterator i = routes.begin(); i != routes.end(); ++i) {
304  if ((*i).overallProb > 0) {
305  isEmptyDist = false;
306  }
307  }
308  for (std::vector<RODFRouteDesc>::const_iterator i = routes.begin(); i != routes.end(); ++i) {
309  if ((*i).overallProb > 0 || includeUnusedRoutes) {
310  out.openTag(SUMO_TAG_ROUTE).writeAttr(SUMO_ATTR_REFID, (*i).routename).writeAttr(SUMO_ATTR_PROB, (*i).overallProb).closeTag();
311  }
312  if (isEmptyDist) {
314  }
315  }
316  out.closeTag(); // routeDistribution
317  } else {
318  WRITE_ERROR("Detector '" + getID() + "' has no routes!?");
319  return false;
320  }
321  // insertions
322  if (insertionsOnly || flows.knows(myID)) {
323  // get the flows for this detector
324  const std::vector<FlowDef>& mflows = flows.getFlowDefs(myID);
325  // go through the simulation seconds
326  unsigned int index = 0;
327  for (SUMOTime time = startTime; time < endTime; time += stepOffset, index++) {
328  // get own (departure flow)
329  assert(index < mflows.size());
330  const FlowDef& srcFD = mflows[index]; // !!! check stepOffset
331  // get flows at end
332  RandomDistributor<size_t>* destDist = dists.find(time) != dists.end() ? dists.find(time)->second : 0;
333  // go through the cars
334  size_t carNo = (size_t)((srcFD.qPKW + srcFD.qLKW) * scale);
335  for (size_t car = 0; car < carNo; ++car) {
336  // get the vehicle parameter
337  SUMOReal v = -1;
338  std::string vtype;
339  int destIndex = destDist != 0 && destDist->getOverallProb() > 0 ? (int) destDist->get() : -1;
340  if (srcFD.isLKW >= 1) {
341  srcFD.isLKW = srcFD.isLKW - (SUMOReal) 1.;
342  v = srcFD.vLKW;
343  vtype = "LKW";
344  } else {
345  v = srcFD.vPKW;
346  vtype = "PKW";
347  }
348  // compute insertion speed
349  if (v <= 0 || v > 250) {
350  v = defaultSpeed;
351  } else {
352  v = (SUMOReal)(v / 3.6);
353  }
354  // compute the departure time
355  SUMOTime ctime = (SUMOTime)(time + ((SUMOReal) stepOffset * (SUMOReal) car / (SUMOReal) carNo));
356 
357  // write
359  if (getType() == SOURCE_DETECTOR) {
360  out.writeAttr(SUMO_ATTR_ID, "emitter_" + myID + "_" + toString(ctime));
361  } else {
362  out.writeAttr(SUMO_ATTR_ID, "calibrator_" + myID + "_" + toString(ctime));
363  }
364  if (oc.getBool("vtype")) {
365  out.writeAttr(SUMO_ATTR_TYPE, vtype);
366  }
368  if (oc.isSet("departlane")) {
369  out.writeNonEmptyAttr(SUMO_ATTR_DEPARTLANE, oc.getString("departlane"));
370  } else {
371  out.writeAttr(SUMO_ATTR_DEPARTLANE, TplConvert::_2int(myLaneID.substr(myLaneID.rfind("_") + 1).c_str()));
372  }
373  if (oc.isSet("departpos")) {
374  std::string posDesc = oc.getString("departpos");
375  if (posDesc.substr(0, 8) == "detector") {
376  SUMOReal position = myPosition;
377  if (posDesc.length() > 8) {
378  if (posDesc[8] == '+') {
379  position += TplConvert::_2SUMOReal(posDesc.substr(9).c_str());
380  } else if (posDesc[8] == '-') {
381  position -= TplConvert::_2SUMOReal(posDesc.substr(9).c_str());
382  } else {
383  throw NumberFormatException();
384  }
385  }
386  out.writeAttr(SUMO_ATTR_DEPARTPOS, position);
387  } else {
389  }
390  } else {
392  }
393  if (oc.isSet("departspeed")) {
394  out.writeNonEmptyAttr(SUMO_ATTR_DEPARTSPEED, oc.getString("departspeed"));
395  } else {
396  if (v > defaultSpeed) {
397  out.writeAttr(SUMO_ATTR_DEPARTSPEED, "max");
398  } else {
400  }
401  }
402  if (oc.isSet("arrivallane")) {
403  out.writeNonEmptyAttr(SUMO_ATTR_ARRIVALLANE, oc.getString("arrivallane"));
404  }
405  if (oc.isSet("arrivalpos")) {
406  out.writeNonEmptyAttr(SUMO_ATTR_ARRIVALPOS, oc.getString("arrivalpos"));
407  }
408  if (oc.isSet("arrivalspeed")) {
409  out.writeNonEmptyAttr(SUMO_ATTR_ARRIVALSPEED, oc.getString("arrivalspeed"));
410  }
411  if (destIndex >= 0) {
412  out.writeAttr(SUMO_ATTR_ROUTE, myRoutes->get()[destIndex].routename);
413  } else {
415  }
416  out.closeTag();
417  srcFD.isLKW += srcFD.fLKW;
418  }
419  }
420  }
421  if (getType() != SOURCE_DETECTOR) {
422  out.close();
423  }
424  return true;
425 }
426 
427 
428 bool
429 RODFDetector::writeRoutes(std::vector<std::string>& saved,
430  OutputDevice& out) {
431  if (myRoutes != 0) {
432  return myRoutes->save(saved, "", out);
433  }
434  return false;
435 }
436 
437 
438 void
440  const RODFDetectorFlows& flows,
441  SUMOTime startTime, SUMOTime endTime,
442  SUMOTime stepOffset, SUMOReal defaultSpeed) {
444  out.writeXMLHeader("vss");
445  const std::vector<FlowDef>& mflows = flows.getFlowDefs(myID);
446  unsigned int index = 0;
447  for (SUMOTime t = startTime; t < endTime; t += stepOffset, index++) {
448  assert(index < mflows.size());
449  const FlowDef& srcFD = mflows[index];
450  SUMOReal speed = MAX2(srcFD.vLKW, srcFD.vPKW);
451  if (speed <= 0 || speed > 250) {
452  speed = defaultSpeed;
453  } else {
454  speed = (SUMOReal)(speed / 3.6);
455  }
457  }
458  out.close();
459 }
460 
461 
462 
463 
464 
465 
466 
467 
468 
469 
471 
472 
474  for (std::vector<RODFDetector*>::iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
475  delete *i;
476  }
477 }
478 
479 
480 bool
482  if (myDetectorMap.find(dfd->getID()) != myDetectorMap.end()) {
483  return false;
484  }
485  myDetectorMap[dfd->getID()] = dfd;
486  myDetectors.push_back(dfd);
487  std::string edgeid = dfd->getLaneID().substr(0, dfd->getLaneID().rfind('_'));
488  if (myDetectorEdgeMap.find(edgeid) == myDetectorEdgeMap.end()) {
489  myDetectorEdgeMap[edgeid] = std::vector<RODFDetector*>();
490  }
491  myDetectorEdgeMap[edgeid].push_back(dfd);
492  return true; // !!!
493 }
494 
495 
496 bool
498  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
499  if ((*i)->getType() == TYPE_NOT_DEFINED) {
500  return false;
501  }
502  }
503  return true;
504 }
505 
506 
507 bool
509  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
510  if ((*i)->hasRoutes()) {
511  return true;
512  }
513  }
514  return false;
515 }
516 
517 
518 const std::vector< RODFDetector*>&
520  return myDetectors;
521 }
522 
523 
524 void
525 RODFDetectorCon::save(const std::string& file) const {
527  out.writeXMLHeader("detectors");
528  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
529  out.openTag(SUMO_TAG_DETECTOR_DEFINITION).writeAttr(SUMO_ATTR_ID, StringUtils::escapeXML((*i)->getID())).writeAttr(SUMO_ATTR_LANE, (*i)->getLaneID()).writeAttr(SUMO_ATTR_POSITION, (*i)->getPos());
530  switch ((*i)->getType()) {
531  case BETWEEN_DETECTOR:
532  out.writeAttr(SUMO_ATTR_TYPE, "between");
533  break;
534  case SOURCE_DETECTOR:
535  out.writeAttr(SUMO_ATTR_TYPE, "source");
536  break;
537  case SINK_DETECTOR:
538  out.writeAttr(SUMO_ATTR_TYPE, "sink");
539  break;
540  case DISCARDED_DETECTOR:
541  out.writeAttr(SUMO_ATTR_TYPE, "discarded");
542  break;
543  default:
544  throw 1;
545  }
546  out.closeTag();
547  }
548  out.close();
549 }
550 
551 
552 void
553 RODFDetectorCon::saveAsPOIs(const std::string& file) const {
555  out.writeXMLHeader("pois");
556  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
558  switch ((*i)->getType()) {
559  case BETWEEN_DETECTOR:
560  out.writeAttr(SUMO_ATTR_TYPE, "between_detector_position").writeAttr(SUMO_ATTR_COLOR, RGBColor::BLUE);
561  break;
562  case SOURCE_DETECTOR:
563  out.writeAttr(SUMO_ATTR_TYPE, "source_detector_position").writeAttr(SUMO_ATTR_COLOR, RGBColor::GREEN);
564  break;
565  case SINK_DETECTOR:
566  out.writeAttr(SUMO_ATTR_TYPE, "sink_detector_position").writeAttr(SUMO_ATTR_COLOR, RGBColor::RED);
567  break;
568  case DISCARDED_DETECTOR:
569  out.writeAttr(SUMO_ATTR_TYPE, "discarded_detector_position").writeAttr(SUMO_ATTR_COLOR, RGBColor(51, 51, 51, 255));
570  break;
571  default:
572  throw 1;
573  }
574  out.writeAttr(SUMO_ATTR_LANE, (*i)->getLaneID()).writeAttr(SUMO_ATTR_POSITION, (*i)->getPos()).closeTag();
575  }
576  out.close();
577 }
578 
579 
580 void
581 RODFDetectorCon::saveRoutes(const std::string& file) const {
583  out.writeXMLHeader("routes");
584  std::vector<std::string> saved;
585  // write for source detectors
586  bool lastWasSaved = true;
587  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
588  if ((*i)->getType() != SOURCE_DETECTOR) {
589  // do not build routes for other than sources
590  continue;
591  }
592  if (lastWasSaved) {
593  out << "\n";
594  }
595  lastWasSaved = (*i)->writeRoutes(saved, out);
596  }
597  out << "\n";
598  out.close();
599 }
600 
601 
602 const RODFDetector&
603 RODFDetectorCon::getDetector(const std::string& id) const {
604  return *(myDetectorMap.find(id)->second);
605 }
606 
607 
609 RODFDetectorCon::getModifiableDetector(const std::string& id) const {
610  return *(myDetectorMap.find(id)->second);
611 }
612 
613 
614 bool
615 RODFDetectorCon::knows(const std::string& id) const {
616  return myDetectorMap.find(id) != myDetectorMap.end();
617 }
618 
619 
620 void
621 RODFDetectorCon::writeEmitters(const std::string& file,
622  const RODFDetectorFlows& flows,
623  SUMOTime startTime, SUMOTime endTime,
624  SUMOTime stepOffset, const RODFNet& net,
625  bool writeCalibrators,
626  bool includeUnusedRoutes,
627  SUMOReal scale,
628  bool insertionsOnly) {
629  // compute turn probabilities at detector
630  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
631  (*i)->computeSplitProbabilities(&net, *this, flows, startTime, endTime, stepOffset);
632  }
633  //
635  out.writeXMLHeader("additional", "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo.dlr.de/xsd/additional_file.xsd\"");
636  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
637  RODFDetector* det = *i;
638  // get file name for values (emitter/calibrator definition)
639  std::string escapedID = StringUtils::escapeXML(det->getID());
640  std::string defFileName;
641  if (det->getType() == SOURCE_DETECTOR) {
642  defFileName = file;
643  } else if (writeCalibrators && det->getType() == BETWEEN_DETECTOR) {
644  defFileName = FileHelpers::getFilePath(file) + "calibrator_" + escapedID + ".def.xml";
645  } else {
646  defFileName = FileHelpers::getFilePath(file) + "other_" + escapedID + ".def.xml";
647  continue;
648  }
649  // try to write the definition
650  SUMOReal defaultSpeed = net.getEdge(det->getEdgeID())->getSpeed();
651  // ... compute routes' distribution over time
652  std::map<size_t, RandomDistributor<size_t>* > dists;
653  if (!insertionsOnly && flows.knows(det->getID())) {
654  det->buildDestinationDistribution(*this, startTime, endTime, stepOffset, net, dists);
655  }
656  // ... write the definition
657  if (!det->writeEmitterDefinition(defFileName, dists, flows, startTime, endTime, stepOffset, includeUnusedRoutes, scale, insertionsOnly, defaultSpeed)) {
658  // skip if something failed... (!!!)
659  continue;
660  }
661  // ... clear temporary values
662  clearDists(dists);
663  // write the declaration into the file
664  if (writeCalibrators && det->getType() == BETWEEN_DETECTOR) {
665  out.openTag(SUMO_TAG_CALIBRATOR).writeAttr(SUMO_ATTR_ID, "calibrator_" + escapedID).writeAttr(SUMO_ATTR_POSITION, det->getPos());
666  out.writeAttr(SUMO_ATTR_LANE, det->getLaneID()).writeAttr(SUMO_ATTR_FRIENDLY_POS, true).writeAttr(SUMO_ATTR_FILE, defFileName).closeTag();
667  }
668  }
669  out.close();
670 }
671 
672 
673 void
674 RODFDetectorCon::writeEmitterPOIs(const std::string& file,
675  const RODFDetectorFlows& flows) {
677  out.writeXMLHeader("additional", "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo.dlr.de/xsd/additional_file.xsd\"");
678  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
679  RODFDetector* det = *i;
680  SUMOReal flow = flows.getFlowSumSecure(det->getID());
681  const unsigned char col = static_cast<unsigned char>(128 * flow / flows.getMaxDetectorFlow() + 128);
682  out.openTag(SUMO_TAG_POI).writeAttr(SUMO_ATTR_ID, StringUtils::escapeXML((*i)->getID()) + ":" + toString(flow));
683  switch ((*i)->getType()) {
684  case BETWEEN_DETECTOR:
685  out.writeAttr(SUMO_ATTR_TYPE, "between_detector_position").writeAttr(SUMO_ATTR_COLOR, RGBColor(0, 0, col, 255));
686  break;
687  case SOURCE_DETECTOR:
688  out.writeAttr(SUMO_ATTR_TYPE, "source_detector_position").writeAttr(SUMO_ATTR_COLOR, RGBColor(0, col, 0, 255));
689  break;
690  case SINK_DETECTOR:
691  out.writeAttr(SUMO_ATTR_TYPE, "sink_detector_position").writeAttr(SUMO_ATTR_COLOR, RGBColor(col, 0, 0, 255));
692  break;
693  case DISCARDED_DETECTOR:
694  out.writeAttr(SUMO_ATTR_TYPE, "discarded_detector_position").writeAttr(SUMO_ATTR_COLOR, RGBColor(51, 51, 51, 255));
695  break;
696  default:
697  throw 1;
698  }
699  out.writeAttr(SUMO_ATTR_LANE, (*i)->getLaneID()).writeAttr(SUMO_ATTR_POSITION, (*i)->getPos()).closeTag();
700  }
701  out.close();
702 }
703 
704 
705 int
707  const RODFDetectorFlows&) const {
708  UNUSED_PARAMETER(period);
709  UNUSED_PARAMETER(time);
710  if (edge == 0) {
711  return 0;
712  }
713 // SUMOReal stepOffset = 60; // !!!
714 // SUMOReal startTime = 0; // !!!
715 // cout << edge->getID() << endl;
716  assert(myDetectorEdgeMap.find(edge->getID()) != myDetectorEdgeMap.end());
717  const std::vector<FlowDef>& flows = static_cast<const RODFEdge*>(edge)->getFlows();
718  SUMOReal agg = 0;
719  for (std::vector<FlowDef>::const_iterator i = flows.begin(); i != flows.end(); ++i) {
720  const FlowDef& srcFD = *i;
721  if (srcFD.qLKW >= 0) {
722  agg += srcFD.qLKW;
723  }
724  if (srcFD.qPKW >= 0) {
725  agg += srcFD.qPKW;
726  }
727  }
728  return (int) agg;
729  /* !!! make this time variable
730  if (flows.size()!=0) {
731  SUMOReal agg = 0;
732  size_t beginIndex = (int)((time/stepOffset) - startTime); // !!! falsch!!!
733  for (SUMOTime t=0; t<period&&beginIndex<flows.size(); t+=(SUMOTime) stepOffset) {
734  const FlowDef &srcFD = flows[beginIndex++];
735  if (srcFD.qLKW>=0) {
736  agg += srcFD.qLKW;
737  }
738  if (srcFD.qPKW>=0) {
739  agg += srcFD.qPKW;
740  }
741  }
742  return (int) agg;
743  }
744  */
745 // return -1;
746 }
747 
748 
749 void
751  const std::string& file,
752  const RODFDetectorFlows& flows,
753  SUMOTime startTime, SUMOTime endTime,
754  SUMOTime stepOffset) {
756  out.writeXMLHeader("additional", "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo.dlr.de/xsd/additional_file.xsd\"");
757  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
758  RODFDetector* det = *i;
759  // write the declaration into the file
760  if (det->getType() == SINK_DETECTOR && flows.knows(det->getID())) {
761  std::string filename = FileHelpers::getFilePath(file) + "vss_" + det->getID() + ".def.xml";
763  SUMOReal defaultSpeed = net != 0 ? net->getEdge(det->getEdgeID())->getSpeed() : (SUMOReal) 200.;
764  det->writeSingleSpeedTrigger(filename, flows, startTime, endTime, stepOffset, defaultSpeed);
765  }
766  }
767  out.close();
768 }
769 
770 
771 void
774  out.writeXMLHeader("additional", "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo.dlr.de/xsd/additional_file.xsd\"");
775  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
776  RODFDetector* det = *i;
777  // write the declaration into the file
778  if (det->getType() == SINK_DETECTOR) {
780  out.writeAttr(SUMO_ATTR_POSITION, SUMOReal(0)).writeAttr(SUMO_ATTR_FILE, "endrerouter_" + det->getID() + ".def.xml").closeTag();
781  }
782  }
783  out.close();
784 }
785 
786 
787 void
789  bool includeSources,
790  bool singleFile, bool friendly) {
792  out.writeXMLHeader("additional");
793  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
794  RODFDetector* det = *i;
795  // write the declaration into the file
796  if (det->getType() != SOURCE_DETECTOR || includeSources) {
797  SUMOReal pos = det->getPos();
798  if (det->getType() == SOURCE_DETECTOR) {
799  pos += 1;
800  }
803  if (friendly) {
805  }
806  if (!singleFile) {
807  out.writeAttr(SUMO_ATTR_FILE, "validation_det_" + StringUtils::escapeXML(det->getID()) + ".xml");
808  } else {
809  out.writeAttr(SUMO_ATTR_FILE, "validation_dets.xml");
810  }
811  out.closeTag();
812  }
813  }
814  out.close();
815 }
816 
817 
818 void
819 RODFDetectorCon::removeDetector(const std::string& id) {
820  //
821  std::map<std::string, RODFDetector*>::iterator ri1 = myDetectorMap.find(id);
822  RODFDetector* oldDet = (*ri1).second;
823  myDetectorMap.erase(ri1);
824  //
825  std::vector<RODFDetector*>::iterator ri2 =
826  find(myDetectors.begin(), myDetectors.end(), oldDet);
827  myDetectors.erase(ri2);
828  //
829  bool found = false;
830  for (std::map<std::string, std::vector<RODFDetector*> >::iterator rr3 = myDetectorEdgeMap.begin(); !found && rr3 != myDetectorEdgeMap.end(); ++rr3) {
831  std::vector<RODFDetector*>& dets = (*rr3).second;
832  for (std::vector<RODFDetector*>::iterator ri3 = dets.begin(); !found && ri3 != dets.end();) {
833  if (*ri3 == oldDet) {
834  found = true;
835  ri3 = dets.erase(ri3);
836  } else {
837  ++ri3;
838  }
839  }
840  }
841  delete oldDet;
842 }
843 
844 
845 void
847  // routes must be built (we have ensured this in main)
848  // detector followers/prior must be build (we have ensured this in main)
849  //
850  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
851  RODFDetector* det = *i;
852  const std::set<const RODFDetector*>& prior = det->getPriorDetectors();
853  const std::set<const RODFDetector*>& follower = det->getFollowerDetectors();
854  size_t noFollowerWithRoutes = 0;
855  size_t noPriorWithRoutes = 0;
856  // count occurences of detectors with/without routes
857  std::set<const RODFDetector*>::const_iterator j;
858  for (j = prior.begin(); j != prior.end(); ++j) {
859  if (flows.knows((*j)->getID())) {
860  ++noPriorWithRoutes;
861  }
862  }
863  for (j = follower.begin(); j != follower.end(); ++j) {
864  if (flows.knows((*j)->getID())) {
865  ++noFollowerWithRoutes;
866  }
867  }
868 
869  // do not process detectors which have no routes
870  if (!flows.knows(det->getID())) {
871  continue;
872  }
873 
874  // plain case: all of the prior detectors have routes
875  if (noPriorWithRoutes == prior.size()) {
876  // the number of vehicles is the sum of all vehicles on prior
877  continue;
878  }
879 
880  // plain case: all of the follower detectors have routes
881  if (noFollowerWithRoutes == follower.size()) {
882  // the number of vehicles is the sum of all vehicles on follower
883  continue;
884  }
885 
886  }
887 }
888 
889 
890 const RODFDetector&
892  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
893  if ((*i)->getEdgeID() == edge->getID()) {
894  return **i;
895  }
896  }
897  throw 1;
898 }
899 
900 
901 void
902 RODFDetectorCon::clearDists(std::map<size_t, RandomDistributor<size_t>* >& dists) const {
903  for (std::map<size_t, RandomDistributor<size_t>* >::iterator i = dists.begin(); i != dists.end(); ++i) {
904  delete(*i).second;
905  }
906 }
907 
908 
909 void
910 RODFDetectorCon::mesoJoin(const std::string& nid,
911  const std::vector<std::string>& oldids) {
912  // build the new detector
913  const RODFDetector& first = getDetector(*(oldids.begin()));
914  RODFDetector* newDet = new RODFDetector(nid, first);
915  addDetector(newDet);
916  // delete previous
917  for (std::vector<std::string>::const_iterator i = oldids.begin(); i != oldids.end(); ++i) {
918  removeDetector(*i);
919  }
920 }
921 
922 
923 /****************************************************************************/
RODFDetector & getModifiableDetector(const std::string &id) const
bool knows(const std::string &id) const
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:257
static const RGBColor BLUE
Definition: RGBColor.h:191
void close()
Closes the device and removes it from the dictionary.
long long int SUMOTime
Definition: SUMOTime.h:43
void addRoute(RODFRouteDesc &nrd)
void removeDetector(const std::string &id)
SUMOReal getFlowSumSecure(const std::string &id) const
unsigned int getNumSuccessors() const
Returns the number of edges this edge is connected to.
Definition: ROEdge.cpp:220
RODFDetectorType
Numerical representation of different detector types.
Definition: RODFDetector.h:65
Represents a generic random distribution.
static SUMOReal _2SUMOReal(const E *const data)
Definition: TplConvert.h:242
bool addDetector(RODFDetector *dfd)
void addRoutes(RODFRouteCont *routes)
A source detector.
Definition: RODFDetector.h:76
ROEdge * getEdge(const std::string &name) const
Retrieves an edge from the network.
Definition: RONet.h:158
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
RODFDetector(const std::string &id, const std::string &laneID, SUMOReal pos, const RODFDetectorType type)
Constructor.
static std::string escapeXML(const std::string &orig)
Replaces the standard escapes by their XML entities.
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:61
void buildDestinationDistribution(const RODFDetectorCon &detectors, SUMOTime startTime, SUMOTime endTime, SUMOTime stepOffset, const RODFNet &net, std::map< size_t, RandomDistributor< size_t > * > &into) const
const std::vector< RODFRouteDesc > & getRouteVector() const
ROEdgeVector edges2Pass
The edges the route is made of.
Definition: RODFRouteDesc.h:56
T MAX2(T a, T b)
Definition: StdDefs.h:79
SUMOReal getMaxDetectorFlow() const
void addPriorDetector(const RODFDetector *det)
const std::vector< RODFDetector * > & getDetectors() const
void saveRoutes(const std::string &file) const
void writeSpeedTrigger(const RODFNet *const net, const std::string &file, const RODFDetectorFlows &flows, SUMOTime startTime, SUMOTime endTime, SUMOTime stepOffset)
const std::set< const RODFDetector * > & getFollowerDetectors() const
bool writeEmitterDefinition(const std::string &file, const std::map< size_t, RandomDistributor< size_t > * > &dists, const RODFDetectorFlows &flows, SUMOTime startTime, SUMOTime endTime, SUMOTime stepOffset, bool includeUnusedRoutes, SUMOReal scale, bool insertionsOnly, SUMOReal defaultSpeed) const
std::string getEdgeID() const
Returns the id of the edge this detector is placed on.
Definition: RODFDetector.h:133
std::vector< RODFRouteDesc > & get()
Returns the container of stored routes.
SUMOReal computeDistanceFactor(const RODFRouteDesc &rd) const
A container for flows.
A container for RODFDetectors.
Definition: RODFDetector.h:227
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:39
bool hasDetector(ROEdge *edge) const
Definition: RODFNet.cpp:660
void computeSplitProbabilities(const RODFNet *net, const RODFDetectorCon &detectors, const RODFDetectorFlows &flows, SUMOTime startTime, SUMOTime endTime, SUMOTime stepOffset)
RODFRouteCont * myRoutes
Definition: RODFDetector.h:207
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:69
const RODFDetector & getAnyDetectorForEdge(const RODFEdge *const edge) const
bool writeXMLHeader(const std::string &rootElement, const std::string &attrs="", const std::string &comment="")
Writes an XML header with optional configuration.
void writeEmitters(const std::string &file, const RODFDetectorFlows &flows, SUMOTime startTime, SUMOTime endTime, SUMOTime stepOffset, const RODFNet &net, bool writeCalibrators, bool includeUnusedRoutes, SUMOReal scale, bool insertionsOnly)
RODFDetectorType getType() const
Returns the type of the detector.
Definition: RODFDetector.h:150
A not yet defined detector.
Definition: RODFDetector.h:67
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
const std::string & getID() const
Returns the id.
Definition: Named.h:65
SUMOReal myPosition
Definition: RODFDetector.h:205
bool writeRoutes(std::vector< std::string > &saved, OutputDevice &out)
static const RGBColor GREEN
Definition: RGBColor.h:190
void save(const std::string &file) const
the edges of a route
An in-between detector.
Definition: RODFDetector.h:73
OutputDevice & writeNonEmptyAttr(const SumoXMLAttr attr, const std::string &val)
writes a string attribute only if it is not the empty string and not the string "default" ...
Definition: OutputDevice.h:290
std::vector< ROEdge * > ROEdgeVector
Definition: RODFRouteDesc.h:43
int getAggFlowFor(const ROEdge *edge, SUMOTime time, SUMOTime period, const RODFDetectorFlows &flows) const
T get(MTRand *which=0) const
Draw a sample of the distribution.
A detector which had to be discarded (!!!)
Definition: RODFDetector.h:70
const ROEdgeVector & getPredecessors() const
Returns the edge at the given position from the list of incoming edges.
Definition: ROEdge.h:313
A DFROUTER-network.
Definition: RODFNet.h:51
void writeValidationDetectors(const std::string &file, bool includeSources, bool singleFile, bool friendly)
~RODFDetector()
Destructor.
std::string myLaneID
Definition: RODFDetector.h:204
bool knows(const std::string &det_id) const
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:53
void writeSingleSpeedTrigger(const std::string &file, const RODFDetectorFlows &flows, SUMOTime startTime, SUMOTime endTime, SUMOTime stepOffset, SUMOReal defaultSpeed)
Definition of the traffic during a certain time containing the flows and speeds.
void saveAsPOIs(const std::string &file) const
A route within the DFROUTER.
Definition: RODFRouteDesc.h:54
A basic edge for routing applications.
Definition: ROEdge.h:73
std::vector< std::map< RODFEdge *, SUMOReal > > mySplitProbabilities
Definition: RODFDetector.h:209
Base class for objects which have an id.
Definition: Named.h:45
const std::set< const RODFDetector * > & getPriorDetectors() const
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:205
SUMOReal getOverallProb() const
Return the sum of the probabilites assigned to the members.
static int _2int(const E *const data)
Definition: TplConvert.h:114
std::string myID
The name of the object.
Definition: Named.h:133
static const RGBColor RED
Definition: RGBColor.h:189
RODFDetectorType myType
Definition: RODFDetector.h:206
std::map< std::string, RODFEdge * > myRoute2Edge
Definition: RODFDetector.h:210
static OutputDevice & getDevice(const std::string &name)
Returns the described OutputDevice.
const RODFDetector & getDetector(const std::string &id) const
void guessEmptyFlows(RODFDetectorFlows &flows)
Class representing a detector within the DFROUTER.
Definition: RODFDetector.h:88
A storage for options typed value containers)
Definition: OptionsCont.h:108
A container for DFROUTER-routes.
Definition: RODFRouteCont.h:63
SUMOReal qPKW
SUMOReal getPos() const
Returns the position at which the detector lies.
Definition: RODFDetector.h:141
std::string routename
The name of the route.
Definition: RODFRouteDesc.h:58
void writeEmitterPOIs(const std::string &file, const RODFDetectorFlows &flows)
void setType(RODFDetectorType type)
std::set< const RODFDetector * > myPriorDetectors
Definition: RODFDetector.h:208
A variable speed sign.
const std::vector< FlowDef > & getFlowDefs(const std::string &id) const
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:71
bool closeTag()
Closes the most recently opened tag.
#define SUMOReal
Definition: config.h:214
const std::vector< std::map< RODFEdge *, SUMOReal > > & getSplitProbabilities() const
Definition: RODFDetector.h:194
static std::string getFilePath(const std::string &path)
Removes the file information from the given path.
Definition: FileHelpers.cpp:76
std::set< const RODFDetector * > myFollowingDetectors
Definition: RODFDetector.h:208
void writeEndRerouterDetectors(const std::string &file)
void mesoJoin(const std::string &nid, const std::vector< std::string > &oldids)
void addRouteDesc(RODFRouteDesc &desc)
Adds a route to the container.
void clearDists(std::map< size_t, RandomDistributor< size_t > * > &dists) const
Clears the given distributions map, deleting the timed distributions.
SUMOReal qLKW
bool detectorsHaveRoutes() const
A color information.
void addFollowingDetector(const RODFDetector *det)
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
bool save(std::vector< std::string > &saved, const std::string &prependix, OutputDevice &out)
Saves routes.
bool hasRoutes() const
bool detectorsHaveCompleteTypes() const
const std::string & getLaneID() const
Returns the id of the lane this detector is placed on.
Definition: RODFDetector.h:125
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.