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