Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2001-2024 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 : /****************************************************************************/
14 : /// @file GUIShapeContainer.cpp
15 : /// @author Daniel Krajzewicz
16 : /// @author Jakob Erdmann
17 : /// @author Michael Behrisch
18 : /// @date 08.10.2009
19 : ///
20 : // Storage for geometrical objects extended by mutexes
21 : /****************************************************************************/
22 : #include <config.h>
23 :
24 : #include "GUIShapeContainer.h"
25 : #include <utils/common/MsgHandler.h>
26 : #include <utils/shapes/PolygonDynamics.h>
27 : #include <foreign/rtree/SUMORTree.h>
28 : #include <utils/gui/globjects/GUIPolygon.h>
29 : #include <utils/gui/globjects/GUIPointOfInterest.h>
30 :
31 :
32 : // ===========================================================================
33 : // method definitions
34 : // ===========================================================================
35 7525 : GUIShapeContainer::GUIShapeContainer(SUMORTree& vis) :
36 7525 : myVis(vis),
37 7525 : myAllowReplacement(false) {
38 7525 : }
39 :
40 :
41 15024 : GUIShapeContainer::~GUIShapeContainer() {}
42 :
43 :
44 : bool
45 1059 : GUIShapeContainer::addPOI(const std::string& id, const std::string& type, const RGBColor& color, const Position& pos, bool geo,
46 : const std::string& lane, double posOverLane, bool friendlyPos, double posLat, const std::string& icon,
47 : double layer, double angle, const std::string& imgFile, bool relativePath, double width, double height,
48 : bool /* ignorePruning */) {
49 : GUIPointOfInterest* p = new GUIPointOfInterest(id, type, color, pos, geo, lane, posOverLane, friendlyPos, posLat, icon,
50 1059 : layer, angle, imgFile, relativePath, width, height);
51 1059 : FXMutexLock locker(myLock);
52 1059 : if (!myPOIs.add(id, p)) {
53 0 : if (myAllowReplacement) {
54 0 : GUIPointOfInterest* oldP = dynamic_cast<GUIPointOfInterest*>(myPOIs.get(id));
55 0 : myVis.removeAdditionalGLObject(oldP);
56 0 : myPOIs.remove(id);
57 0 : myPOIs.add(id, p);
58 0 : WRITE_WARNINGF(TL("Replacing POI '%'"), id);
59 : } else {
60 0 : delete p;
61 0 : return false;
62 : }
63 : }
64 1059 : myVis.addAdditionalGLObject(p);
65 : return true;
66 : }
67 :
68 :
69 : bool
70 109 : GUIShapeContainer::addPolygon(const std::string& id, const std::string& type,
71 : const RGBColor& color, double layer,
72 : double angle, const std::string& imgFile, bool relativePath,
73 : const PositionVector& shape, bool geo, bool fill, double lineWidth, bool /* ignorePruning */,
74 : const std::string& name) {
75 109 : GUIPolygon* p = new GUIPolygon(id, type, color, shape, geo, fill, lineWidth, layer, angle, imgFile, relativePath, name);
76 109 : FXMutexLock locker(myLock);
77 109 : if (!myPolygons.add(id, p)) {
78 0 : if (myAllowReplacement) {
79 0 : GUIPolygon* oldP = dynamic_cast<GUIPolygon*>(myPolygons.get(id));
80 0 : myVis.removeAdditionalGLObject(oldP);
81 0 : myPolygons.remove(id);
82 0 : myPolygons.add(id, p);
83 0 : WRITE_WARNINGF(TL("Replacing polygon '%'"), id);
84 : } else {
85 0 : delete p;
86 0 : return false;
87 : }
88 : }
89 218 : bool state = myInactivePolygonTypes.empty() || (std::find(myInactivePolygonTypes.begin(), myInactivePolygonTypes.end(), type) == myInactivePolygonTypes.end());
90 : p->activate(state);
91 109 : myVis.addAdditionalGLObject(p);
92 : return true;
93 : }
94 :
95 :
96 : PolygonDynamics*
97 80 : GUIShapeContainer::addPolygonDynamics(double simtime,
98 : std::string polyID,
99 : SUMOTrafficObject* trackedObject,
100 : const std::vector<double>& timeSpan,
101 : const std::vector<double>& alphaSpan,
102 : bool looped,
103 : bool rotate) {
104 80 : PolygonDynamics* pd = ShapeContainer::addPolygonDynamics(simtime, polyID, trackedObject, timeSpan, alphaSpan, looped, rotate);
105 80 : if (pd != nullptr) {
106 80 : pd->setRTree(&myVis);
107 : }
108 80 : return pd;
109 : }
110 :
111 :
112 : SUMOTime
113 2270 : GUIShapeContainer::polygonDynamicsUpdate(SUMOTime t, PolygonDynamics* pd) {
114 2270 : FXMutexLock locker(myLock);
115 2270 : GUIPolygon* p = dynamic_cast<GUIPolygon*>(pd->getPolygon());
116 : assert(p != nullptr);
117 2270 : myVis.removeAdditionalGLObject(p);
118 2270 : SUMOTime next = ShapeContainer::polygonDynamicsUpdate(t, pd);
119 2270 : if (next != 0) {
120 : // Update polygon position in RTree
121 2233 : myVis.addAdditionalGLObject(p);
122 : }
123 2270 : return next;
124 : }
125 :
126 :
127 : bool
128 69 : GUIShapeContainer::removePolygon(const std::string& id, bool useLock) {
129 69 : GUIPolygon* p = dynamic_cast<GUIPolygon*>(myPolygons.get(id));
130 69 : if (p == nullptr) {
131 : return false;
132 : }
133 : FXMutexLock* locker = nullptr;
134 69 : if (useLock) {
135 32 : locker = new FXMutexLock(myLock);
136 : }
137 69 : myVis.removeAdditionalGLObject(p);
138 69 : bool succ = ShapeContainer::removePolygon(id);
139 101 : delete locker;
140 : return succ;
141 : }
142 :
143 :
144 : bool
145 2 : GUIShapeContainer::removePOI(const std::string& id) {
146 2 : FXMutexLock locker(myLock);
147 2 : GUIPointOfInterest* p = dynamic_cast<GUIPointOfInterest*>(myPOIs.get(id));
148 2 : if (p == nullptr) {
149 : return false;
150 : }
151 2 : myVis.removeAdditionalGLObject(p);
152 2 : return myPOIs.remove(id);
153 : }
154 :
155 :
156 : void
157 54 : GUIShapeContainer::movePOI(const std::string& id, const Position& pos) {
158 54 : FXMutexLock locker(myLock);
159 54 : GUIPointOfInterest* p = dynamic_cast<GUIPointOfInterest*>(myPOIs.get(id));
160 54 : if (p != nullptr) {
161 54 : myVis.removeAdditionalGLObject(p);
162 54 : static_cast<Position*>(p)->set(pos);
163 54 : myVis.addAdditionalGLObject(p);
164 : }
165 54 : }
166 :
167 :
168 : void
169 1 : GUIShapeContainer::reshapePolygon(const std::string& id, const PositionVector& shape) {
170 1 : FXMutexLock locker(myLock);
171 1 : GUIPolygon* p = dynamic_cast<GUIPolygon*>(myPolygons.get(id));
172 1 : if (p != nullptr) {
173 1 : myVis.removeAdditionalGLObject(p);
174 1 : p->setShape(shape);
175 1 : myVis.addAdditionalGLObject(p);
176 : }
177 1 : }
178 :
179 :
180 :
181 : std::vector<GUIGlID>
182 0 : GUIShapeContainer::getPOIIds() const {
183 0 : FXMutexLock locker(myLock);
184 : std::vector<GUIGlID> ret;
185 0 : for (const auto& poi : getPOIs()) {
186 0 : ret.push_back(static_cast<GUIPointOfInterest*>(poi.second)->getGlID());
187 : }
188 0 : return ret;
189 0 : }
190 :
191 :
192 : std::vector<GUIGlID>
193 0 : GUIShapeContainer::getPolygonIDs() const {
194 0 : FXMutexLock locker(myLock);
195 : std::vector<GUIGlID> ret;
196 0 : for (const auto& poly : getPolygons()) {
197 0 : ret.push_back(static_cast<GUIPolygon*>(poly.second)->getGlID());
198 : }
199 0 : return ret;
200 0 : }
201 :
202 :
203 : void
204 0 : GUIShapeContainer::allowReplacement() {
205 0 : myAllowReplacement = true;
206 0 : }
207 :
208 :
209 : void
210 0 : GUIShapeContainer::setInactivePolygonTypes(std::set<std::string> inactivePolygonTypes) {
211 : myInactivePolygonTypes = inactivePolygonTypes;
212 0 : computeActivePolygons();
213 0 : }
214 :
215 :
216 : void
217 0 : GUIShapeContainer::addInactivePolygonTypes(std::set<std::string> inactivePolygonTypes) {
218 0 : myInactivePolygonTypes.insert(inactivePolygonTypes.begin(), inactivePolygonTypes.end());
219 0 : computeActivePolygons();
220 0 : }
221 :
222 :
223 : void
224 0 : GUIShapeContainer::removeInactivePolygonTypes(std::set<std::string> inactivePolygonTypes) {
225 0 : for (std::string type : inactivePolygonTypes) {
226 : myInactivePolygonTypes.erase(type);
227 : }
228 0 : computeActivePolygons();
229 0 : }
230 :
231 :
232 : void
233 0 : GUIShapeContainer::computeActivePolygons(void) {
234 0 : for (auto polygonWithID : myPolygons) {
235 : GUIPolygon* polygon = (GUIPolygon*)polygonWithID.second;
236 0 : bool state = std::find(myInactivePolygonTypes.begin(), myInactivePolygonTypes.end(), polygon->getShapeType()) == myInactivePolygonTypes.end();
237 : polygon->activate(state);
238 : }
239 0 : }
240 :
241 : /****************************************************************************/
|