Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2017-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 POI.cpp
15 : /// @author Daniel Krajzewicz
16 : /// @author Mario Krumnow
17 : /// @author Jakob Erdmann
18 : /// @author Michael Behrisch
19 : /// @author Robert Hilbrich
20 : /// @date 30.05.2012
21 : ///
22 : // C++ TraCI client API implementation
23 : /****************************************************************************/
24 : #include <config.h>
25 :
26 : #include <utils/shapes/PointOfInterest.h>
27 : #include <utils/shapes/ShapeContainer.h>
28 : #include <utils/geom/GeomHelper.h>
29 : #include <microsim/MSNet.h>
30 : #include <libsumo/TraCIConstants.h>
31 : #include "Polygon.h"
32 : #include "POI.h"
33 : #include "Helper.h"
34 :
35 :
36 : namespace libsumo {
37 : // ===========================================================================
38 : // static member initializations
39 : // ===========================================================================
40 : SubscriptionResults POI::mySubscriptionResults;
41 : ContextSubscriptionResults POI::myContextSubscriptionResults;
42 : NamedRTree* POI::myTree(nullptr);
43 :
44 :
45 : // ===========================================================================
46 : // static member definitions
47 : // ===========================================================================
48 : std::vector<std::string>
49 318 : POI::getIDList() {
50 : std::vector<std::string> ids;
51 318 : MSNet::getInstance()->getShapeContainer().getPOIs().insertIDs(ids);
52 316 : return ids;
53 2 : }
54 :
55 :
56 : int
57 47 : POI::getIDCount() {
58 47 : return (int)getIDList().size();
59 : }
60 :
61 :
62 : std::string
63 26 : POI::getType(const std::string& poiID) {
64 26 : return getPoI(poiID)->getShapeType();
65 : }
66 :
67 :
68 : TraCIColor
69 29 : POI::getColor(const std::string& poiID) {
70 29 : return Helper::makeTraCIColor(getPoI(poiID)->getShapeColor());
71 : }
72 :
73 :
74 : TraCIPosition
75 8040 : POI::getPosition(const std::string& poiID, const bool includeZ) {
76 8040 : return Helper::makeTraCIPosition(*getPoI(poiID), includeZ);
77 : }
78 :
79 :
80 : double
81 20 : POI::getWidth(const std::string& poiID) {
82 20 : return getPoI(poiID)->getWidth();
83 : }
84 :
85 :
86 : double
87 20 : POI::getHeight(const std::string& poiID) {
88 20 : return getPoI(poiID)->getHeight();
89 : }
90 :
91 :
92 : double
93 20 : POI::getAngle(const std::string& poiID) {
94 20 : return getPoI(poiID)->getShapeNaviDegree();
95 : }
96 :
97 :
98 : std::string
99 5 : POI::getImageFile(const std::string& poiID) {
100 5 : return getPoI(poiID)->getShapeImgFile();
101 : }
102 :
103 :
104 : std::string
105 26 : POI::getParameter(const std::string& poiID, const std::string& key) {
106 52 : return getPoI(poiID)->getParameter(key, "");
107 : }
108 :
109 :
110 0 : LIBSUMO_GET_PARAMETER_WITH_KEY_IMPLEMENTATION(POI)
111 :
112 :
113 : void
114 7 : POI::setType(const std::string& poiID, const std::string& poiType) {
115 7 : getPoI(poiID)->setShapeType(poiType);
116 6 : }
117 :
118 :
119 : void
120 60 : POI::setPosition(const std::string& poiID, double x, double y) {
121 : // try to retrieve so that the correct error is generated for unknown poiIDs
122 60 : getPoI(poiID);
123 59 : MSNet::getInstance()->getShapeContainer().movePOI(poiID, Position(x, y));
124 59 : }
125 :
126 :
127 : void
128 7 : POI::setColor(const std::string& poiID, const TraCIColor& c) {
129 7 : getPoI(poiID)->setShapeColor(Helper::makeRGBColor(c));
130 6 : }
131 :
132 :
133 : void
134 5 : POI::setWidth(const std::string& poiID, double width) {
135 5 : getPoI(poiID)->setWidth(width);
136 5 : }
137 :
138 :
139 : void
140 5 : POI::setHeight(const std::string& poiID, double height) {
141 5 : getPoI(poiID)->setHeight(height);
142 5 : }
143 :
144 :
145 : void
146 5 : POI::setAngle(const std::string& poiID, double angle) {
147 5 : getPoI(poiID)->setShapeNaviDegree(angle);
148 5 : }
149 :
150 :
151 : void
152 5 : POI::setImageFile(const std::string& poiID, const std::string& imageFile) {
153 5 : getPoI(poiID)->setShapeImgFile(imageFile);
154 5 : }
155 :
156 :
157 : bool
158 108 : POI::add(const std::string& poiID, double x, double y, const TraCIColor& color, const std::string& poiType,
159 : int layer, const std::string& imgFile, double width, double height, double angle, const std::string& icon) {
160 108 : ShapeContainer& shapeCont = MSNet::getInstance()->getShapeContainer();
161 108 : bool ok = shapeCont.addPOI(poiID, poiType, Helper::makeRGBColor(color),
162 108 : Position(x, y), false, "", 0, false, 0, icon, layer,
163 : angle, imgFile, Shape::DEFAULT_RELATIVEPATH,
164 : width, height);
165 108 : if (ok && myTree != nullptr) {
166 : PointOfInterest* p = shapeCont.getPOIs().get(poiID);
167 10 : const float cmin[2] = {(float)p->x(), (float)p->y()};
168 10 : const float cmax[2] = {(float)p->x(), (float)p->y()};
169 10 : myTree->Insert(cmin, cmax, p);
170 : }
171 108 : return ok;
172 : }
173 :
174 :
175 : bool
176 12 : POI::remove(const std::string& poiID, int /* layer */) {
177 12 : ShapeContainer& shapeCont = MSNet::getInstance()->getShapeContainer();
178 : PointOfInterest* p = shapeCont.getPOIs().get(poiID);
179 11 : if (p != nullptr && myTree != nullptr) {
180 5 : const float cmin[2] = {(float)p->x(), (float)p->y()};
181 5 : const float cmax[2] = {(float)p->x(), (float)p->y()};
182 5 : myTree->Remove(cmin, cmax, p);
183 : }
184 12 : return shapeCont.removePOI(poiID);
185 : }
186 :
187 :
188 : void
189 29 : POI::highlight(const std::string& poiID, const TraCIColor& col, double size, const int alphaMax, const double duration, const int type) {
190 : // NOTE: Code is duplicated in large parts in Vehicle.cpp
191 29 : PointOfInterest* poi = getPoI(poiID);
192 :
193 : // Center of the highlight circle
194 29 : Position* center = dynamic_cast<Position*>(poi);
195 : // Size of the highlight circle
196 29 : if (size <= 0) {
197 21 : size = sqrt(poi->getHeight() * poi->getHeight() + poi->getWidth() * poi->getWidth()) * 0.7;
198 : }
199 : // Make polygon shape
200 : const unsigned int nPoints = 34;
201 29 : const PositionVector circlePV = GeomHelper::makeRing(size, size + 1., *center, nPoints);
202 29 : TraCIPositionVector circle = Helper::makeTraCIPositionVector(circlePV);
203 :
204 : #ifdef DEBUG_DYNAMIC_SHAPES
205 : std::cout << SIMTIME << " Vehicle::highlight() for vehicle '" << vehicleID << "'\n"
206 : << " circle: " << circlePV << std::endl;
207 : #endif
208 :
209 : // Find a free polygon id
210 29 : int i = 0;
211 58 : std::string polyID = poi->getID() + "_hl" + toString(i);
212 103 : while (Polygon::exists(polyID)) {
213 16 : polyID = poi->getID() + "_hl" + toString(++i);
214 : }
215 : // Line width
216 : double lw = 0.;
217 : // Layer
218 : double lyr = 0.;
219 29 : if (MSNet::getInstance()->isGUINet()) {
220 : lyr = poi->getShapeLayer();
221 13 : lyr += (type + 1) / 257.;
222 : }
223 : // Make Polygon
224 58 : Polygon::addHighlightPolygon(poiID, type, polyID, circle, col, true, "highlight", (int)lyr, lw);
225 :
226 : // Animation time line
227 : double maxAttack = 1.0; // maximal fade-in time
228 : std::vector<double> timeSpan;
229 29 : if (duration > 0.) {
230 58 : timeSpan = {0, MIN2(maxAttack, duration / 3.), 2.*duration / 3., duration};
231 : }
232 : // Alpha time line
233 : std::vector<double> alphaSpan;
234 29 : if (alphaMax > 0.) {
235 58 : alphaSpan = {0., (double) alphaMax, ((double) alphaMax) / 3., 0.};
236 : }
237 : // Attach dynamics
238 29 : Polygon::addDynamics(polyID, "", timeSpan, alphaSpan, false, false);
239 58 : }
240 :
241 :
242 : void
243 383 : POI::setParameter(const std::string& poiID, const std::string& key, const std::string& value) {
244 383 : PointOfInterest* p = getPoI(poiID);
245 383 : p->setParameter(key, value);
246 383 : }
247 :
248 :
249 :
250 8322 : LIBSUMO_SUBSCRIPTION_IMPLEMENTATION(POI, POI)
251 :
252 :
253 : PointOfInterest*
254 25142 : POI::getPoI(const std::string& id) {
255 25142 : PointOfInterest* sumoPoi = MSNet::getInstance()->getShapeContainer().getPOIs().get(id);
256 25137 : if (sumoPoi == nullptr) {
257 10 : throw TraCIException("POI '" + id + "' is not known");
258 : }
259 25137 : return sumoPoi;
260 : }
261 :
262 :
263 : NamedRTree*
264 367 : POI::getTree() {
265 367 : if (myTree == nullptr) {
266 17 : myTree = new NamedRTree();
267 17 : ShapeContainer& shapeCont = MSNet::getInstance()->getShapeContainer();
268 58 : for (const auto& i : shapeCont.getPOIs()) {
269 41 : const float cmin[2] = {(float)i.second->x(), (float)i.second->y()};
270 41 : const float cmax[2] = {(float)i.second->x(), (float)i.second->y()};
271 41 : myTree->Insert(cmin, cmax, i.second);
272 : }
273 : }
274 367 : return myTree;
275 : }
276 :
277 : void
278 40219 : POI::cleanup() {
279 40219 : delete myTree;
280 40219 : myTree = nullptr;
281 40219 : }
282 :
283 :
284 : void
285 16450 : POI::storeShape(const std::string& id, PositionVector& shape) {
286 16450 : shape.push_back(*getPoI(id));
287 16450 : }
288 :
289 :
290 : std::shared_ptr<VariableWrapper>
291 266 : POI::makeWrapper() {
292 266 : return std::make_shared<Helper::SubscriptionWrapper>(handleVariable, mySubscriptionResults, myContextSubscriptionResults);
293 : }
294 :
295 :
296 : bool
297 4320 : POI::handleVariable(const std::string& objID, const int variable, VariableWrapper* wrapper, tcpip::Storage* paramData) {
298 4320 : switch (variable) {
299 157 : case TRACI_ID_LIST:
300 157 : return wrapper->wrapStringList(objID, variable, getIDList());
301 33 : case ID_COUNT:
302 33 : return wrapper->wrapInt(objID, variable, getIDCount());
303 18 : case VAR_TYPE:
304 36 : return wrapper->wrapString(objID, variable, getType(objID));
305 21 : case VAR_COLOR:
306 21 : return wrapper->wrapColor(objID, variable, getColor(objID));
307 4026 : case VAR_POSITION:
308 4026 : return wrapper->wrapPosition(objID, variable, getPosition(objID));
309 0 : case VAR_POSITION3D:
310 0 : return wrapper->wrapPosition(objID, variable, getPosition(objID, true));
311 12 : case VAR_WIDTH:
312 12 : return wrapper->wrapDouble(objID, variable, getWidth(objID));
313 12 : case VAR_HEIGHT:
314 12 : return wrapper->wrapDouble(objID, variable, getHeight(objID));
315 12 : case VAR_ANGLE:
316 12 : return wrapper->wrapDouble(objID, variable, getAngle(objID));
317 3 : case VAR_IMAGEFILE:
318 6 : return wrapper->wrapString(objID, variable, getImageFile(objID));
319 16 : case libsumo::VAR_PARAMETER:
320 16 : paramData->readUnsignedByte();
321 32 : return wrapper->wrapString(objID, variable, getParameter(objID, paramData->readString()));
322 0 : case libsumo::VAR_PARAMETER_WITH_KEY:
323 0 : paramData->readUnsignedByte();
324 0 : return wrapper->wrapStringPair(objID, variable, getParameterWithKey(objID, paramData->readString()));
325 : default:
326 : return false;
327 : }
328 : }
329 :
330 :
331 : }
332 :
333 :
334 : /****************************************************************************/
|