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.sourceforge.net/
15 // Copyright (C) 2001-2012 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 "RODFDetector.h"
40 #include <utils/common/ToString.h>
41 #include <router/ROEdge.h>
42 #include "RODFEdge.h"
43 #include "RODFRouteDesc.h"
44 #include "RODFRouteCont.h"
45 #include "RODFDetectorFlow.h"
47 #include <utils/common/StdDefs.h>
48 #include <utils/geom/GeomHelper.h>
49 #include "RODFNet.h"
52 
53 #ifdef CHECK_MEMORY_LEAKS
54 #include <foreign/nvwa/debug_new.h>
55 #endif // CHECK_MEMORY_LEAKS
56 
57 
58 // ===========================================================================
59 // method definitions
60 // ===========================================================================
61 RODFDetector::RODFDetector(const std::string& id, const std::string& laneID,
62  SUMOReal pos, const RODFDetectorType type)
63  : myID(id), myLaneID(laneID), myPosition(pos), myType(type), myRoutes(0) {}
64 
65 
66 RODFDetector::RODFDetector(const std::string& id, const RODFDetector& f)
67  : myID(id), myLaneID(f.myLaneID), myPosition(f.myPosition),
68  myType(f.myType), myRoutes(0) {
69  if (f.myRoutes != 0) {
70  myRoutes = new RODFRouteCont(*(f.myRoutes));
71  }
72 }
73 
74 
76  delete myRoutes;
77 }
78 
79 
80 void
82  myType = type;
83 }
84 
85 
88  SUMOReal distance = rd.edges2Pass[0]->getFromNode()->getPosition().distanceTo(rd.edges2Pass.back()->getToNode()->getPosition());
89  SUMOReal length = 0;
90  for (std::vector<ROEdge*>::const_iterator i = rd.edges2Pass.begin(); i != rd.edges2Pass.end(); ++i) {
91  length += (*i)->getLength();
92  }
93  return (distance / length);
94 }
95 
96 
97 void
99  const RODFDetectorFlows& flows,
100  SUMOTime startTime, SUMOTime endTime, SUMOTime stepOffset) {
101  if (myRoutes == 0) {
102  return;
103  }
104  // compute edges to determine split probabilities
105  const std::vector<RODFRouteDesc> &routes = myRoutes->get();
106  std::vector<RODFEdge*> nextDetEdges;
107  for (std::vector<RODFRouteDesc>::const_iterator i = routes.begin(); i != routes.end(); ++i) {
108  const RODFRouteDesc& rd = *i;
109  bool hadSplit = false;
110  bool hadDetectorAfterSplit = false;
111  for (std::vector<ROEdge*>::const_iterator j = rd.edges2Pass.begin(); !hadDetectorAfterSplit && j != rd.edges2Pass.end(); ++j) {
112  if (hadSplit && !hadDetectorAfterSplit && net->hasDetector(*j)) {
113  hadDetectorAfterSplit = true;
114  if (find(nextDetEdges.begin(), nextDetEdges.end(), *j) == nextDetEdges.end()) {
115  nextDetEdges.push_back(static_cast<RODFEdge*>(*j));
116  }
117  myRoute2Edge[rd.routename] = static_cast<RODFEdge*>(*j);
118  }
119  if ((*j)->getNoFollowing() > 1) {
120  hadSplit = true;
121  }
122  }
123  }
124  // compute the probabilities to use a certain direction
125  int index = 0;
126  for (SUMOTime time = startTime; time < endTime; time += stepOffset, ++index) {
127  mySplitProbabilities.push_back(std::map<RODFEdge*, SUMOReal>());
128  SUMOReal overallProb = 0;
129  // retrieve the probabilities
130  for (std::vector<RODFEdge*>::const_iterator i = nextDetEdges.begin(); i != nextDetEdges.end(); ++i) {
131  SUMOReal flow = detectors.getAggFlowFor(*i, time, 60, flows);
132  overallProb += flow;
133  mySplitProbabilities[index][*i] = flow;
134  }
135  // norm probabilities
136  if (overallProb > 0) {
137  for (std::vector<RODFEdge*>::const_iterator i = nextDetEdges.begin(); i != nextDetEdges.end(); ++i) {
138  mySplitProbabilities[index][*i] = mySplitProbabilities[index][*i] / overallProb;
139  }
140  }
141  }
142 }
143 
144 
145 void
147  const RODFDetectorFlows& flows,
148  SUMOTime startTime,
149  SUMOTime endTime,
150  SUMOTime stepOffset,
151  const RODFNet& net,
152  std::map<size_t, RandomDistributor<size_t>* > &into,
153  int maxFollower) const {
154  UNUSED_PARAMETER(maxFollower);
155  if (myRoutes == 0) {
157  WRITE_ERROR("Missing routes for detector '" + myID + "'.");
158  }
159  return;
160  }
161  std::vector<RODFRouteDesc> &descs = myRoutes->get();
162 // const std::vector<FlowDef> &mflows = flows.getFlowDefs(myID);
163  // iterate through time (in output interval steps)
164  for (SUMOTime time = startTime; time < endTime; time += stepOffset) {
165  into[time] = new RandomDistributor<size_t>();
166  std::map<ROEdge*, SUMOReal> flowMap;
167  // iterate through the routes
168  size_t index = 0;
169  for (std::vector<RODFRouteDesc>::iterator ri = descs.begin(); ri != descs.end(); ++ri, index++) {
170  SUMOReal prob = 1.;
171  for (std::vector<ROEdge*>::iterator j = (*ri).edges2Pass.begin(); j != (*ri).edges2Pass.end() && prob > 0; ++j) {
172  if (!net.hasDetector(*j)) {
173  continue;
174  }
175  const RODFDetector& det = detectors.getAnyDetectorForEdge(static_cast<RODFEdge*>(*j));
176  const std::vector<std::map<RODFEdge*, SUMOReal> > &probs = det.getSplitProbabilities();
177  if (probs.size() == 0) {
178  prob = 0;
179  continue;
180  }
181  const std::map<RODFEdge*, SUMOReal> &tprobs = probs[(time - startTime) / stepOffset];
182  for (std::map<RODFEdge*, SUMOReal>::const_iterator k = tprobs.begin(); k != tprobs.end(); ++k) {
183  if (find(j, (*ri).edges2Pass.end(), (*k).first) != (*ri).edges2Pass.end()) {
184  prob *= (*k).second;
185  }
186  }
187  }
188  into[time]->add(prob, index);
189  (*ri).overallProb = prob;
190  }
191  }
192 }
193 
194 
195 const std::vector<RODFRouteDesc> &
197  return myRoutes->get();
198 }
199 
200 
201 void
203  myPriorDetectors.push_back(det);
204 }
205 
206 
207 void
209  myFollowingDetectors.push_back(det);
210 }
211 
212 
213 const std::vector<RODFDetector*> &
215  return myPriorDetectors;
216 }
217 
218 
219 const std::vector<RODFDetector*> &
221  return myFollowingDetectors;
222 }
223 
224 
225 
226 void
228  delete myRoutes;
229  myRoutes = routes;
230 }
231 
232 
233 void
235  if (myRoutes == 0) {
236  myRoutes = new RODFRouteCont();
237  }
238  myRoutes->addRouteDesc(nrd);
239 }
240 
241 
242 bool
244  return myRoutes != 0 && myRoutes->get().size() != 0;
245 }
246 
247 
248 bool
249 RODFDetector::writeEmitterDefinition(const std::string& file,
250  const std::map<size_t, RandomDistributor<size_t>* > &dists,
251  const RODFDetectorFlows& flows,
252  SUMOTime startTime, SUMOTime endTime,
253  SUMOTime stepOffset,
254  bool includeUnusedRoutes,
255  SUMOReal scale,
256  bool insertionsOnly,
257  SUMOReal defaultSpeed) const {
259  if (getType() != SOURCE_DETECTOR) {
260  out.writeXMLHeader("calibrator");
261  }
262  // routes
263  if (myRoutes != 0 && myRoutes->get().size() != 0) {
264  const std::vector<RODFRouteDesc> &routes = myRoutes->get();
265  out.openTag("routeDistribution") << " id=\"" << myID << "\">\n";
266  bool isEmptyDist = true;
267  for (std::vector<RODFRouteDesc>::const_iterator i = routes.begin(); i != routes.end(); ++i) {
268  if ((*i).overallProb > 0) {
269  isEmptyDist = false;
270  }
271  }
272  for (std::vector<RODFRouteDesc>::const_iterator i = routes.begin(); i != routes.end(); ++i) {
273  if ((*i).overallProb > 0 || includeUnusedRoutes) {
274  out.openTag("route") << " refId=\"" << (*i).routename << "\" probability=\"" << (*i).overallProb << "\"";
275  out.closeTag(true);
276  }
277  if (isEmptyDist) {
278  out.openTag("route") << " refId=\"" << (*i).routename << "\" probability=\"1\"";
279  out.closeTag(true);
280  }
281  }
282  out.closeTag();
283  } else {
284  WRITE_ERROR("Detector '" + getID() + "' has no routes!?");
285  return false;
286  }
287  // emissions
288  if (insertionsOnly || flows.knows(myID)) {
289  // get the flows for this detector
290 
291  const std::vector<FlowDef> &mflows = flows.getFlowDefs(myID);
292  // go through the simulation seconds
293  int index = 0;
294  for (SUMOTime time = startTime; time < endTime; time += stepOffset, index++) {
295  // get own (departure flow)
296  assert(index < mflows.size());
297  const FlowDef& srcFD = mflows[index]; // !!! check stepOffset
298  // get flows at end
299  RandomDistributor<size_t> *destDist = dists.find(time) != dists.end() ? dists.find(time)->second : 0;
300  // go through the cars
301  size_t carNo = (size_t)((srcFD.qPKW + srcFD.qLKW) * scale);
302  for (size_t car = 0; car < carNo; ++car) {
303  // get the vehicle parameter
304  std::string type = "test";
305  SUMOReal v = -1;
306  int destIndex = destDist != 0 && destDist->getOverallProb() > 0 ? (int) destDist->get() : -1;
307  if (srcFD.isLKW >= 1) {
308  srcFD.isLKW = srcFD.isLKW - (SUMOReal) 1.;
310  v = srcFD.vLKW;
311  } else {
313  v = srcFD.vPKW;
314  }
315  // compute emission speed
316  if (v < 0 || v > 250) {
317  v = defaultSpeed;
318  } else {
319  v = (SUMOReal)(v / 3.6);
320  }
321  // compute the departure time
322  SUMOTime ctime = (SUMOTime)(time + ((SUMOReal) stepOffset * (SUMOReal) car / (SUMOReal) carNo));
323 
324  // write
325  out.openTag("vehicle") << " id=\"";
326  if (getType() == SOURCE_DETECTOR) {
327  out << "emitter_" << myID;
328  } else {
329  out << "calibrator_" << myID;
330  }
331  out << "_" << ctime << "\"" // !!! running
332  << " depart=\"" << time2string(ctime) << "\""
333  << " departSpeed=\"";
334  if (v > defaultSpeed) {
335  out << "max";
336  } else {
337  out << v;
338  }
339  out << "\" departPos=\"" << myPosition << "\""
340  << " departLane=\"" << myLaneID.substr(myLaneID.rfind("_") + 1) << "\" route=\"";
341  if (destIndex >= 0) {
342  out << myRoutes->get()[destIndex].routename << "\"";
343  } else {
344  out << myID << "\"";
345  }
346  out.closeTag(true);
347  srcFD.isLKW += srcFD.fLKW;
348  }
349  }
350  }
351  if (getType() != SOURCE_DETECTOR) {
352  out.close();
353  }
354  return true;
355 }
356 
357 
358 bool
359 RODFDetector::writeRoutes(std::vector<std::string> &saved,
360  OutputDevice& out) {
361  if (myRoutes != 0) {
362  return myRoutes->save(saved, "", out);
363  }
364  return false;
365 }
366 
367 
368 void
370  const RODFDetectorFlows& flows,
371  SUMOTime startTime, SUMOTime endTime,
372  SUMOTime stepOffset, SUMOReal defaultSpeed) {
374  out.writeXMLHeader("vss");
375  const std::vector<FlowDef> &mflows = flows.getFlowDefs(myID);
376  int index = 0;
377  for (SUMOTime t = startTime; t < endTime; t += stepOffset, index++) {
378  assert(index < mflows.size());
379  const FlowDef& srcFD = mflows[index];
380  SUMOReal speed = MAX2(srcFD.vLKW, srcFD.vPKW);
381  if (speed <= 0 || speed > 250) {
382  speed = defaultSpeed;
383  } else {
384  speed = (SUMOReal)(speed / 3.6);
385  }
386  out << " <step time=\"" << t << "\" speed=\"" << speed << "\"/>\n";
387  }
388  out.close();
389 }
390 
391 
392 
393 
394 
395 
396 
397 
398 
399 
401 
402 
404  for (std::vector<RODFDetector*>::iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
405  delete *i;
406  }
407 }
408 
409 
410 bool
412  if (myDetectorMap.find(dfd->getID()) != myDetectorMap.end()) {
413  return false;
414  }
415  myDetectorMap[dfd->getID()] = dfd;
416  myDetectors.push_back(dfd);
417  std::string edgeid = dfd->getLaneID().substr(0, dfd->getLaneID().rfind('_'));
418  if (myDetectorEdgeMap.find(edgeid) == myDetectorEdgeMap.end()) {
419  myDetectorEdgeMap[edgeid] = std::vector<RODFDetector*>();
420  }
421  myDetectorEdgeMap[edgeid].push_back(dfd);
422  return true; // !!!
423 }
424 
425 
426 bool
428  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
429  if ((*i)->getType() == TYPE_NOT_DEFINED) {
430  return false;
431  }
432  }
433  return true;
434 }
435 
436 
437 bool
439  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
440  if ((*i)->hasRoutes()) {
441  return true;
442  }
443  }
444  return false;
445 }
446 
447 
448 const std::vector< RODFDetector*> &
450  return myDetectors;
451 }
452 
453 
454 void
455 RODFDetectorCon::save(const std::string& file) const {
457  out.writeXMLHeader("detectors");
458  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
459  out << " <" << toString(SUMO_TAG_DETECTOR_DEFINITION) << " id=\"" << StringUtils::escapeXML((*i)->getID())
460  << "\" lane=\"" << (*i)->getLaneID()
461  << "\" pos=\"" << (*i)->getPos();
462  switch ((*i)->getType()) {
463  case BETWEEN_DETECTOR:
464  out << "\" type=\"between\"";
465  break;
466  case SOURCE_DETECTOR:
467  out << "\" type=\"source\"";
468  break;
469  case SINK_DETECTOR:
470  out << "\" type=\"sink\"";
471  break;
472  case DISCARDED_DETECTOR:
473  out << "\" type=\"discarded\"";
474  break;
475  default:
476  throw 1;
477  }
478  out << "/>\n";
479  }
480  out.close();
481 }
482 
483 
484 void
485 RODFDetectorCon::saveAsPOIs(const std::string& file) const {
487  out.writeXMLHeader("pois");
488  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
489  out << " <poi id=\"" << StringUtils::escapeXML((*i)->getID());
490  switch ((*i)->getType()) {
491  case BETWEEN_DETECTOR:
492  out << "\" type=\"between_detector_position\" color=\"0,0,1\"";
493  break;
494  case SOURCE_DETECTOR:
495  out << "\" type=\"source_detector_position\" color=\"0,1,0\"";
496  break;
497  case SINK_DETECTOR:
498  out << "\" type=\"sink_detector_position\" color=\"1,0,0\"";
499  break;
500  case DISCARDED_DETECTOR:
501  out << "\" type=\"discarded_detector_position\" color=\".2,.2,.2\"";
502  break;
503  default:
504  throw 1;
505  }
506  out << " lane=\"" << (*i)->getLaneID() << "\" pos=\""
507  << (*i)->getPos() << "\"/>\n";
508  }
509  out.close();
510 }
511 
512 
513 void
514 RODFDetectorCon::saveRoutes(const std::string& file) const {
516  out.writeXMLHeader("routes");
517  std::vector<std::string> saved;
518  // write for source detectors
519  bool lastWasSaved = true;
520  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
521  if ((*i)->getType() != SOURCE_DETECTOR) {
522  // do not build routes for other than sources
523  continue;
524  }
525  if (lastWasSaved) {
526  out << "\n";
527  }
528  lastWasSaved = (*i)->writeRoutes(saved, out);
529  }
530  out << "\n";
531  out.close();
532 }
533 
534 
535 const RODFDetector&
536 RODFDetectorCon::getDetector(const std::string& id) const {
537  return *(myDetectorMap.find(id)->second);
538 }
539 
540 
541 bool
542 RODFDetectorCon::knows(const std::string& id) const {
543  return myDetectorMap.find(id) != myDetectorMap.end();
544 }
545 
546 
547 void
548 RODFDetectorCon::writeEmitters(const std::string& file,
549  const RODFDetectorFlows& flows,
550  SUMOTime startTime, SUMOTime endTime,
551  SUMOTime stepOffset, const RODFNet& net,
552  bool writeCalibrators,
553  bool includeUnusedRoutes,
554  SUMOReal scale,
555  int maxFollower,
556  bool insertionsOnly) {
557  // compute turn probabilities at detector
558  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
559  (*i)->computeSplitProbabilities(&net, *this, flows, startTime, endTime, stepOffset);
560  }
561  //
563  out.writeXMLHeader("additional");
564  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
565  RODFDetector* det = *i;
566  // get file name for values (emitter/calibrator definition)
567  std::string escapedID = StringUtils::escapeXML(det->getID());
568  std::string defFileName;
569  if (det->getType() == SOURCE_DETECTOR) {
570  defFileName = file;
571  } else if (writeCalibrators && det->getType() == BETWEEN_DETECTOR) {
572  defFileName = FileHelpers::getFilePath(file) + "calibrator_" + escapedID + ".def.xml";
573  } else {
574  defFileName = FileHelpers::getFilePath(file) + "other_" + escapedID + ".def.xml";
575  continue;
576  }
577  // try to write the definition
578  SUMOReal defaultSpeed = net.getEdge(det->getEdgeID())->getSpeed();
579  // ... compute routes' distribution over time
580  std::map<size_t, RandomDistributor<size_t>* > dists;
581  if (!insertionsOnly && flows.knows(det->getID())) {
582  det->buildDestinationDistribution(*this, flows, startTime, endTime, stepOffset, net, dists, maxFollower);
583  }
584  // ... write the definition
585  if (!det->writeEmitterDefinition(defFileName, dists, flows, startTime, endTime, stepOffset, includeUnusedRoutes, scale, insertionsOnly, defaultSpeed)) {
586  // skip if something failed... (!!!)
587  continue;
588  }
589  // ... clear temporary values
590  clearDists(dists);
591  // write the declaration into the file
592  if (writeCalibrators && det->getType() == BETWEEN_DETECTOR) {
593  out << " <calibrator id=\"calibrator_" << escapedID
594  << "\" pos=\"" << det->getPos() << "\" "
595  << "lane=\"" << det->getLaneID() << "\" "
596  << "friendlyPos=\"x\" " // !!!
597  << "file=\"" << defFileName << "\"/>\n";
598  }
599  }
600  out.close();
601 }
602 
603 
604 void
605 RODFDetectorCon::writeEmitterPOIs(const std::string& file,
606  const RODFDetectorFlows& flows) {
608  out.writeXMLHeader("additional");
609  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
610  RODFDetector* det = *i;
611  SUMOReal flow = flows.getFlowSumSecure(det->getID());
612  SUMOReal col = flow / flows.getMaxDetectorFlow();
613  col = (SUMOReal)(col / 2. + .5);
614  SUMOReal r, g, b;
615  r = g = b = 0;
616  out << " <poi id=\"" << StringUtils::escapeXML((*i)->getID()) << ":" << flow;
617  switch ((*i)->getType()) {
618  case BETWEEN_DETECTOR:
619  out << "\" type=\"between_detector_position\" color=\"0,0," << col << "\"";
620  break;
621  case SOURCE_DETECTOR:
622  out << "\" type=\"source_detector_position\" color=\"0," << col << ",0\"";
623  break;
624  case SINK_DETECTOR:
625  out << "\" type=\"sink_detector_position\" color=\"" << col << ",0,0\"";
626  break;
627  case DISCARDED_DETECTOR:
628  out << "\" type=\"discarded_detector_position\" color=\".2,.2,.2\"";
629  break;
630  default:
631  throw 1;
632  }
633  out << " lane=\"" << (*i)->getLaneID() << "\" pos=\"" << (*i)->getPos() << "\"/>\n";
634  }
635  out.close();
636 }
637 
638 
639 int
641  const RODFDetectorFlows&) const {
642  UNUSED_PARAMETER(period);
643  UNUSED_PARAMETER(time);
644  if (edge == 0) {
645  return 0;
646  }
647 // SUMOReal stepOffset = 60; // !!!
648 // SUMOReal startTime = 0; // !!!
649 // cout << edge->getID() << endl;
650  assert(myDetectorEdgeMap.find(edge->getID()) != myDetectorEdgeMap.end());
651  const std::vector<FlowDef> &flows = static_cast<const RODFEdge*>(edge)->getFlows();
652  SUMOReal agg = 0;
653  for (std::vector<FlowDef>::const_iterator i = flows.begin(); i != flows.end(); ++i) {
654  const FlowDef& srcFD = *i;
655  if (srcFD.qLKW >= 0) {
656  agg += srcFD.qLKW;
657  }
658  if (srcFD.qPKW >= 0) {
659  agg += srcFD.qPKW;
660  }
661  }
662  return (int) agg;
663  /* !!! make this time variable
664  if (flows.size()!=0) {
665  SUMOReal agg = 0;
666  size_t beginIndex = (int)((time/stepOffset) - startTime); // !!! falsch!!!
667  for (SUMOTime t=0; t<period&&beginIndex<flows.size(); t+=(SUMOTime) stepOffset) {
668  const FlowDef &srcFD = flows[beginIndex++];
669  if (srcFD.qLKW>=0) {
670  agg += srcFD.qLKW;
671  }
672  if (srcFD.qPKW>=0) {
673  agg += srcFD.qPKW;
674  }
675  }
676  return (int) agg;
677  }
678  */
679 // return -1;
680 }
681 
682 
683 void
685  const std::string& file,
686  const RODFDetectorFlows& flows,
687  SUMOTime startTime, SUMOTime endTime,
688  SUMOTime stepOffset) {
690  out.writeXMLHeader("additional");
691  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
692  RODFDetector* det = *i;
693  // write the declaration into the file
694  if (det->getType() == SINK_DETECTOR && flows.knows(det->getID())) {
695  std::string filename = FileHelpers::getFilePath(file) + "vss_" + det->getID() + ".def.xml";
696  out << " <variableSpeedSign id=\"vss_" << StringUtils::escapeXML(det->getID()) << '\"'
697  << " lanes=\"" << det->getLaneID() << '\"'
698  << " file=\"" << filename << "\"/>\n";
699  SUMOReal defaultSpeed = net != 0 ? net->getEdge(det->getEdgeID())->getSpeed() : (SUMOReal) 200.;
700  det->writeSingleSpeedTrigger(filename, flows, startTime, endTime, stepOffset, defaultSpeed);
701  }
702  }
703  out.close();
704 }
705 
706 
707 void
710  out.writeXMLHeader("additional");
711  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
712  RODFDetector* det = *i;
713  // write the declaration into the file
714  if (det->getType() == SINK_DETECTOR) {
715  out << " <rerouter id=\"endrerouter_" << StringUtils::escapeXML(det->getID())
716  << "\" edges=\"" <<
717  det->getLaneID() << "\" attr=\"reroute\" pos=\"0\" file=\"endrerouter_"
718  << det->getID() << ".def.xml\"/>\n";
719  }
720  }
721  out.close();
722 }
723 
724 
725 void
727  bool includeSources,
728  bool singleFile, bool friendly) {
730  out.writeXMLHeader("additional");
731  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
732  RODFDetector* det = *i;
733  // write the declaration into the file
734  if (det->getType() != SOURCE_DETECTOR || includeSources) {
735  SUMOReal pos = det->getPos();
736  if (det->getType() == SOURCE_DETECTOR) {
737  pos += 1;
738  }
739  out << " <detector id=\"validation_" << StringUtils::escapeXML(det->getID()) << "\" "
740  << "lane=\"" << det->getLaneID() << "\" "
741  << "pos=\"" << pos << "\" "
742  << "freq=\"60\" ";
743  if (friendly) {
744  out << "friendlyPos=\"x\" ";
745  }
746  if (!singleFile) {
747  out << "file=\"validation_det_" << StringUtils::escapeXML(det->getID()) << ".xml\"/>\n";
748  } else {
749  out << "file=\"validation_dets.xml\"/>\n";
750  }
751  }
752  }
753  out.close();
754 }
755 
756 
757 void
758 RODFDetectorCon::removeDetector(const std::string& id) {
759  //
760  std::map<std::string, RODFDetector*>::iterator ri1 = myDetectorMap.find(id);
761  RODFDetector* oldDet = (*ri1).second;
762  myDetectorMap.erase(ri1);
763  //
764  std::vector<RODFDetector*>::iterator ri2 =
765  find(myDetectors.begin(), myDetectors.end(), oldDet);
766  myDetectors.erase(ri2);
767  //
768  bool found = false;
769  for (std::map<std::string, std::vector<RODFDetector*> >::iterator rr3 = myDetectorEdgeMap.begin(); !found && rr3 != myDetectorEdgeMap.end(); ++rr3) {
770  std::vector<RODFDetector*> &dets = (*rr3).second;
771  for (std::vector<RODFDetector*>::iterator ri3 = dets.begin(); !found && ri3 != dets.end();) {
772  if (*ri3 == oldDet) {
773  found = true;
774  ri3 = dets.erase(ri3);
775  } else {
776  ++ri3;
777  }
778  }
779  }
780  delete oldDet;
781 }
782 
783 
784 void
786  // routes must be built (we have ensured this in main)
787  // detector followers/prior must be build (we have ensured this in main)
788  //
789  bool changed = true;
790  while (changed) {
791  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
792  RODFDetector* det = *i;
793  const std::vector<RODFDetector*> &prior = det->getPriorDetectors();
794  const std::vector<RODFDetector*> &follower = det->getFollowerDetectors();
795  size_t noFollowerWithRoutes = 0;
796  size_t noPriorWithRoutes = 0;
797  // count occurences of detectors with/without routes
798  std::vector<RODFDetector*>::const_iterator j;
799  for (j = prior.begin(); j != prior.end(); ++j) {
800  if (flows.knows((*j)->getID())) {
801  ++noPriorWithRoutes;
802  }
803  }
804  assert(noPriorWithRoutes <= prior.size());
805  for (j = follower.begin(); j != follower.end(); ++j) {
806  if (flows.knows((*j)->getID())) {
807  ++noFollowerWithRoutes;
808  }
809  }
810  assert(noFollowerWithRoutes <= follower.size());
811 
812  // do not process detectors which have no routes
813  if (!flows.knows(det->getID())) {
814  continue;
815  }
816 
817  // plain case: some of the following detectors have no routes
818  if (noFollowerWithRoutes == follower.size()) {
819  // the number of vehicles is the sum of all vehicles on prior
820  continue;
821  }
822 
823  }
824  }
825 }
826 
827 
828 const RODFDetector&
830  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
831  if ((*i)->getEdgeID() == edge->getID()) {
832  return **i;
833  }
834  }
835  throw 1;
836 }
837 
838 
839 void
840 RODFDetectorCon::clearDists(std::map<size_t, RandomDistributor<size_t>* > &dists) const {
841  for (std::map<size_t, RandomDistributor<size_t>* >::iterator i = dists.begin(); i != dists.end(); ++i) {
842  delete(*i).second;
843  }
844 }
845 
846 
847 void
848 RODFDetectorCon::mesoJoin(const std::string& nid,
849  const std::vector<std::string> &oldids) {
850  // build the new detector
851  const RODFDetector& first = getDetector(*(oldids.begin()));
852  RODFDetector* newDet = new RODFDetector(nid, first);
853  addDetector(newDet);
854  // delete previous
855  for (std::vector<std::string>::const_iterator i = oldids.begin(); i != oldids.end(); ++i) {
856  removeDetector(*i);
857  }
858 }
859 
860 
861 /****************************************************************************/