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