Eclipse SUMO - Simulation of Urban MObility
ShapeContainer.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2002-2020 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
21 // Storage for geometrical objects, sorted by the layers they are in
22 /****************************************************************************/
23 #include <config.h>
24 
25 #include <fstream>
26 #include <stdlib.h>
27 #include <iostream>
28 #include <utility>
29 #include <string>
30 #include <cmath>
34 #include <utils/common/ToString.h>
35 #include <utils/common/StdDefs.h>
37 #include "PolygonDynamics.h"
38 #include "ShapeContainer.h"
39 
40 
41 // Debug defines
42 //#define DEBUG_DYNAMIC_SHAPES
43 
44 // ===========================================================================
45 // method definitions
46 // ===========================================================================
48 
50  for (auto& p : myPolygonUpdateCommands) {
51  p.second->deschedule();
52  }
54 
55  for (auto& p : myPolygonDynamics) {
56  delete p.second;
57  }
58  myPolygonDynamics.clear();
59 
60 }
61 
62 bool
63 ShapeContainer::addPolygon(const std::string& id, const std::string& type,
64  const RGBColor& color, double layer,
65  double angle, const std::string& imgFile, bool relativePath,
66  const PositionVector& shape, bool geo, bool fill, double lineWidth, bool ignorePruning) {
67  return add(new SUMOPolygon(id, type, color, shape, geo, fill, lineWidth, layer, angle, imgFile, relativePath), ignorePruning);
68 }
69 
70 
73  std::string polyID,
74  SUMOTrafficObject* trackedObject,
75  const std::vector<double>& timeSpan,
76  const std::vector<double>& alphaSpan,
77  bool looped,
78  bool rotate) {
79 
80 #ifdef DEBUG_DYNAMIC_SHAPES
81  std::cout << simtime << " ShapeContainer::addPolygonDynamics() called for polygon '" << polyID << "'" << std::endl;
82 #endif
83 
84  SUMOPolygon* p = myPolygons.get(polyID);
85  if (p == nullptr) {
86 #ifdef DEBUG_DYNAMIC_SHAPES
87  std::cout << " polygon '" << polyID << "' doesn't exist!" << std::endl;
88 #endif
89  return nullptr;
90  }
91  // remove eventually existent previously
92  removePolygonDynamics(polyID);
93 
94  // Add new dynamics
95  PolygonDynamics* pd = new PolygonDynamics(simtime, p, trackedObject, timeSpan, alphaSpan, looped, rotate);
96  myPolygonDynamics.insert(std::make_pair(polyID, pd));
97 
98  // Add tracking information
99  if (trackedObject != nullptr) {
100  auto i = myTrackingPolygons.find(pd->getTrackedObjectID());
101  if (i == myTrackingPolygons.end()) {
102  myTrackingPolygons.insert(std::make_pair(pd->getTrackedObjectID(), std::set<const SUMOPolygon*>({p})));
103  } else {
104  i->second.insert(p);
105  }
106  }
107  return pd;
108 }
109 
110 
111 bool
112 ShapeContainer::removePolygonDynamics(const std::string& polyID) {
113  SUMOPolygon* p = myPolygons.get(polyID);
114  if (p == nullptr) {
115  return false;
116  }
117  auto d = myPolygonDynamics.find(polyID);
118  if (d != myPolygonDynamics.end()) {
119 #ifdef DEBUG_DYNAMIC_SHAPES
120  std::cout << " Removing dynamics of polygon '" << polyID << "'" << std::endl;
121 #endif
122  const std::string& trackedObjID = d->second->getTrackedObjectID();
123  if (trackedObjID != "") {
124  // Remove tracking information
125  auto i = myTrackingPolygons.find(trackedObjID);
126  assert(i != myTrackingPolygons.end());
127  assert(i->second.find(p) != i->second.end());
128  i->second.erase(p);
129  // Remove highlighting information
130  clearHighlights(trackedObjID, p);
131  }
132  delete d->second;
133  myPolygonDynamics.erase(d);
134  // Clear existing polygon dynamics commands before adding new dynamics
135  cleanupPolygonDynamics(polyID);
136  return true;
137  } else {
138  return false;
139  }
140 }
141 
142 
143 bool
144 ShapeContainer::addPOI(const std::string& id, const std::string& type, const RGBColor& color, const Position& pos, bool geo,
145  const std::string& lane, double posOverLane, double posLat, double layer, double angle,
146  const std::string& imgFile, bool relativePath, double width, double height, bool ignorePruning) {
147  return add(new PointOfInterest(id, type, color, pos, geo, lane, posOverLane, posLat, layer, angle, imgFile, relativePath, width, height), ignorePruning);
148 }
149 
150 
151 bool
152 ShapeContainer::removePolygon(const std::string& id, bool /* useLock */) {
153 #ifdef DEBUG_DYNAMIC_SHAPES
154  std::cout << "ShapeContainer: Removing Polygon '" << id << "'" << std::endl;
155 #endif
157  return myPolygons.remove(id);
158 }
159 
160 
161 bool
162 ShapeContainer::removePOI(const std::string& id) {
163  return myPOIs.remove(id);
164 }
165 
166 
167 void
168 ShapeContainer::movePOI(const std::string& id, const Position& pos) {
169  PointOfInterest* p = myPOIs.get(id);
170  if (p != nullptr) {
171  static_cast<Position*>(p)->set(pos);
172  }
173 }
174 
175 
176 void
177 ShapeContainer::reshapePolygon(const std::string& id, const PositionVector& shape) {
178  SUMOPolygon* p = myPolygons.get(id);
179  if (p != nullptr) {
180  p->setShape(shape);
181  }
182 }
183 
184 
185 bool
186 ShapeContainer::add(SUMOPolygon* poly, bool /* ignorePruning */) {
187  if (!myPolygons.add(poly->getID(), poly)) {
188  delete poly;
189  return false;
190  }
191  return true;
192 }
193 
194 
195 bool
196 ShapeContainer::add(PointOfInterest* poi, bool /* ignorePruning */) {
197  if (!myPOIs.add(poi->getID(), poi)) {
198  delete poi;
199  return false;
200  }
201  return true;
202 }
203 
204 
205 void
207  auto j = myPolygonUpdateCommands.find(id);
208  if (j != myPolygonUpdateCommands.end()) {
209  j->second->deschedule();
210  myPolygonUpdateCommands.erase(j);
211  }
212 }
213 
214 
215 SUMOTime
217  SUMOTime next = pd->update(t);
218  if (next == 0) {
219  // Dynamics have expired => remove polygon
220  myPolygonUpdateCommands[pd->getPolygonID()]->deschedule();
221  // Don't aquire lock (in GUI case GUIShapeContainer::polygonDynamicsUpdate() does this)
222  removePolygon(pd->getPolygonID(), false);
223  }
224  return next;
225 }
226 
227 void
228 ShapeContainer::registerHighlight(const std::string& objectID, const int type, const std::string& polygonID) {
229  std::string toRemove = "";
230  clearHighlight(objectID, type, toRemove);
231  if (toRemove != "") {
232  removePolygon(toRemove);
233  }
234  auto i = myHighlightPolygons.find(objectID);
235  if (i == myHighlightPolygons.end()) {
236  myHighlightPolygons.insert(std::make_pair(objectID, std::map<int, std::string>({std::make_pair(type, polygonID)})));
237  } else {
238  i->second.insert(std::make_pair(type, polygonID));
239  }
240  myHighlightedObjects.insert(std::make_pair(polygonID, objectID));
241 }
242 
243 void
244 ShapeContainer::clearHighlight(const std::string& objectID, const int type, std::string& toRemove) {
245  auto i = myHighlightPolygons.find(objectID);
246  if (i != myHighlightPolygons.end()) {
247  auto j = i->second.find(type);
248  if (j != i->second.end()) {
249  toRemove = j->second;
250  myHighlightedObjects.erase(toRemove);
251  i->second.erase(j);
252  if (i->second.empty()) {
253  myHighlightPolygons.erase(i);
254  }
255  }
256  }
257 }
258 
259 void
260 ShapeContainer::clearHighlights(const std::string& objectID, SUMOPolygon* p) {
261  auto i = myHighlightPolygons.find(objectID);
262  if (i != myHighlightPolygons.end()) {
263  auto j = i->second.begin();
264  while (j != i->second.end()) {
265  if (j->second == p->getID()) {
266  i->second.erase(j);
267  break;
268  } else {
269  ++j;
270  }
271  }
272  if (i->second.empty()) {
273  myHighlightPolygons.erase(i);
274  }
275  }
276 }
277 
278 void
280  myPolygonUpdateCommands.insert(std::make_pair(polyID, cmd));
281 }
282 
283 
284 void
285 ShapeContainer::removeTrackers(std::string objectID) {
286  auto i = myTrackingPolygons.find(objectID);
287  if (i != myTrackingPolygons.end()) {
288 #ifdef DEBUG_DYNAMIC_SHAPES
289  std::cout << " Removing tracking polygons for object '" << objectID << "'" << std::endl;
290 #endif
291  while (!i->second.empty()) {
292  removePolygon((*i->second.begin())->getID());
293  }
294  myTrackingPolygons.erase(i);
295  }
296 }
297 
298 
299 /****************************************************************************/
long long int SUMOTime
Definition: SUMOTime.h:31
const std::string & getID() const
Returns the id.
Definition: Named.h:73
T get(const std::string &id) const
Retrieves an item.
bool remove(const std::string &id, const bool del=true)
Removes an item.
bool add(const std::string &id, T item)
Adds an item.
A wrapper for a Command function with parameter.
A point-of-interest.
const std::string & getPolygonID() const
const std::string & getTrackedObjectID() const
SUMOTime update(SUMOTime t)
Updates the polygon according to its timeSpan and follows the tracked object.
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:36
A list of positions.
virtual void setShape(const PositionVector &shape)
Sets the shape of the polygon.
Definition: SUMOPolygon.h:121
Representation of a vehicle, person, or container.
virtual bool removePolygonDynamics(const std::string &polyID)
Remove dynamics (animation / tracking) for the given polygon.
virtual void clearHighlight(const std::string &objectID, const int type, std::string &toRemove)
virtual bool addPolygon(const std::string &id, const std::string &type, const RGBColor &color, double layer, double angle, const std::string &imgFile, bool relativePath, const PositionVector &shape, bool geo, bool fill, double lineWidth, bool ignorePruning=false)
Builds a polygon using the given values and adds it to the container.
virtual void cleanupPolygonDynamics(const std::string &id)
Unschedules the removal and update commands of the given polygon.
virtual bool removePOI(const std::string &id)
Removes a PoI from the container.
virtual SUMOTime polygonDynamicsUpdate(SUMOTime t, PolygonDynamics *pd)
Regular update event for updating polygon dynamics.
virtual bool addPOI(const std::string &id, const std::string &type, const RGBColor &color, const Position &pos, bool geo, const std::string &lane, double posOverLane, double posLat, double layer, double angle, const std::string &imgFile, bool relativePath, double width, double height, bool ignorePruning=false)
Builds a POI using the given values and adds it to the container.
virtual void reshapePolygon(const std::string &id, const PositionVector &shape)
Assigns a shape to the named polygon.
std::map< std::string, std::map< int, std::string > > myHighlightPolygons
maps objects to a map of highlight types to highlighting polygons
std::map< std::string, PolygonDynamics * > myPolygonDynamics
stored PolygonDynamics
virtual bool removePolygon(const std::string &id, bool useLock=true)
Removes a polygon from the container.
virtual void removeTrackers(std::string objectID)
Remove all tracking polygons for the given object.
virtual void movePOI(const std::string &id, const Position &pos)
Assigns a new position to the named PoI.
std::map< const std::string, ParametrisedWrappingCommand< ShapeContainer, PolygonDynamics * > * > myPolygonUpdateCommands
Command pointers for scheduled polygon update. Maps PolyID->Command.
virtual ~ShapeContainer()
Destructor.
POIs myPOIs
stored POIs
std::map< std::string, std::string > myHighlightedObjects
inverse map to myHighlightPolygons saves the highlighted object for each polygon
std::map< const std::string, std::set< const SUMOPolygon * > > myTrackingPolygons
Information about tracked objects.
virtual PolygonDynamics * addPolygonDynamics(double simtime, std::string polyID, SUMOTrafficObject *trackedObject, const std::vector< double > &timeSpan, const std::vector< double > &alphaSpan, bool looped, bool rotate)
Adds dynamics (animation / tracking) to the given polygon.
ShapeContainer()
Constructor.
virtual void addPolygonUpdateCommand(std::string polyID, ParametrisedWrappingCommand< ShapeContainer, PolygonDynamics * > *cmd)
Register update command (for descheduling at removal)
virtual bool add(SUMOPolygon *poly, bool ignorePruning=false)
add polygon
virtual void clearHighlights(const std::string &objectID, SUMOPolygon *p)
Clears all highlight information from the maps when the object leaves the net (Highlight polygons and...
virtual void registerHighlight(const std::string &objectID, const int type, const std::string &polygonID)
register highlight of the specified type if the given id
Polygons myPolygons
stored Polygons