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