SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TraCIServerAPI_Polygon.cpp
Go to the documentation of this file.
1 /****************************************************************************/
9 // APIs for getting/setting polygon values via TraCI
10 /****************************************************************************/
11 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
12 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
13 /****************************************************************************/
14 //
15 // This file is part of SUMO.
16 // SUMO is free software: you can redistribute it and/or modify
17 // it under the terms of the GNU General Public License as published by
18 // the Free Software Foundation, either version 3 of the License, or
19 // (at your option) any later version.
20 //
21 /****************************************************************************/
22 
23 
24 // ===========================================================================
25 // included modules
26 // ===========================================================================
27 #ifdef _MSC_VER
28 #include <windows_config.h>
29 #else
30 #include <config.h>
31 #endif
32 
33 #ifndef NO_TRACI
34 
35 #include <utils/common/StdDefs.h>
36 #include <microsim/MSNet.h>
37 #include <utils/shapes/Polygon.h>
39 #include "TraCIConstants.h"
40 #include "TraCIServerAPI_Polygon.h"
41 
42 #ifdef CHECK_MEMORY_LEAKS
43 #include <foreign/nvwa/debug_new.h>
44 #endif // CHECK_MEMORY_LEAKS
45 
46 
47 // ===========================================================================
48 // used namespaces
49 // ===========================================================================
50 using namespace traci;
51 
52 
53 // ===========================================================================
54 // method definitions
55 // ===========================================================================
56 bool
58  tcpip::Storage& outputStorage) {
59  // variable & id
60  int variable = inputStorage.readUnsignedByte();
61  std::string id = inputStorage.readString();
62  // check variable
63  if (variable != ID_LIST && variable != VAR_TYPE && variable != VAR_COLOR && variable != VAR_SHAPE && variable != VAR_FILL
64  && variable != ID_COUNT) {
65  server.writeStatusCmd(CMD_GET_POLYGON_VARIABLE, RTYPE_ERR, "Get Polygon Variable: unsupported variable specified", outputStorage);
66  return false;
67  }
68  // begin response building
69  tcpip::Storage tempMsg;
70  // response-code, variableID, objectID
72  tempMsg.writeUnsignedByte(variable);
73  tempMsg.writeString(id);
74  // process request
75  if (variable == ID_LIST || variable == ID_COUNT) {
76  std::vector<std::string> ids;
78  shapeCont.getPolygons().insertIDs(ids);
79  if (variable == ID_LIST) {
81  tempMsg.writeStringList(ids);
82  } else {
84  tempMsg.writeInt((int) ids.size());
85  }
86  } else {
87  int layer;
88  Polygon* p = getPolygon(id, layer);
89  if (p == 0) {
90  server.writeStatusCmd(CMD_GET_POLYGON_VARIABLE, RTYPE_ERR, "Polygon '" + id + "' is not known", outputStorage);
91  return false;
92  }
93  switch (variable) {
94  case VAR_TYPE:
96  tempMsg.writeString(p->getType());
97  break;
98  case VAR_COLOR:
100  tempMsg.writeUnsignedByte(static_cast<int>(p->getColor().red() * 255. + .5));
101  tempMsg.writeUnsignedByte(static_cast<int>(p->getColor().green() * 255. + .5));
102  tempMsg.writeUnsignedByte(static_cast<int>(p->getColor().blue() * 255. + .5));
103  tempMsg.writeUnsignedByte(255);
104  break;
105  case VAR_SHAPE:
107  tempMsg.writeUnsignedByte(MIN2(static_cast<int>(255), static_cast<int>(p->getShape().size())));
108  for (unsigned int iPoint = 0; iPoint < MIN2(static_cast<size_t>(255), p->getShape().size()); ++iPoint) {
109  tempMsg.writeDouble(p->getShape()[iPoint].x());
110  tempMsg.writeDouble(p->getShape()[iPoint].y());
111  }
112  break;
113  case VAR_FILL:
114  tempMsg.writeUnsignedByte(TYPE_UBYTE);
115  tempMsg.writeUnsignedByte(p->getFill() ? 1 : 0);
116  break;
117  default:
118  break;
119  }
120  }
121  server.writeStatusCmd(CMD_GET_POLYGON_VARIABLE, RTYPE_OK, "", outputStorage);
122  server.writeResponseWithLength(outputStorage, tempMsg);
123  return true;
124 }
125 
126 
127 bool
129  tcpip::Storage& outputStorage) {
130  std::string warning = ""; // additional description for response
131  // variable
132  int variable = inputStorage.readUnsignedByte();
133  if (variable != VAR_TYPE && variable != VAR_COLOR && variable != VAR_SHAPE && variable != VAR_FILL
134  && variable != ADD && variable != REMOVE) {
135  server.writeStatusCmd(CMD_SET_POLYGON_VARIABLE, RTYPE_ERR, "Change Polygon State: unsupported variable specified", outputStorage);
136  return false;
137  }
138  // id
139  std::string id = inputStorage.readString();
140  Polygon* p = 0;
141  int layer = 0;
143  if (variable != ADD && variable != REMOVE) {
144  p = getPolygon(id, layer);
145  if (p == 0) {
146  server.writeStatusCmd(CMD_SET_POLYGON_VARIABLE, RTYPE_ERR, "Polygon '" + id + "' is not known", outputStorage);
147  return false;
148  }
149  }
150  // process
151  int valueDataType = inputStorage.readUnsignedByte();
152  switch (variable) {
153  case VAR_TYPE: {
154  if (valueDataType != TYPE_STRING) {
155  server.writeStatusCmd(CMD_SET_POLYGON_VARIABLE, RTYPE_ERR, "The type must be given as a string.", outputStorage);
156  return false;
157  }
158  std::string type = inputStorage.readString();
159  p->setType(type);
160  }
161  break;
162  case VAR_COLOR: {
163  if (valueDataType != TYPE_COLOR) {
164  server.writeStatusCmd(CMD_SET_POLYGON_VARIABLE, RTYPE_ERR, "The color must be given using an accoring type.", outputStorage);
165  return false;
166  }
167  SUMOReal r = (SUMOReal) inputStorage.readUnsignedByte() / 255.;
168  SUMOReal g = (SUMOReal) inputStorage.readUnsignedByte() / 255.;
169  SUMOReal b = (SUMOReal) inputStorage.readUnsignedByte() / 255.;
170  //read SUMOReal a
171  inputStorage.readUnsignedByte();
172  p->setColor(RGBColor(r, g, b));
173  }
174  break;
175  case VAR_SHAPE: {
176  if (valueDataType != TYPE_POLYGON) {
177  server.writeStatusCmd(CMD_SET_POLYGON_VARIABLE, RTYPE_ERR, "The shape must be given using an accoring type.", outputStorage);
178  return false;
179  }
180  unsigned int noEntries = inputStorage.readUnsignedByte();
181  PositionVector shape;
182  for (unsigned int i = 0; i < noEntries; ++i) {
183  SUMOReal x = inputStorage.readDouble();
184  SUMOReal y = inputStorage.readDouble();
185  shape.push_back(Position(x, y));
186  }
187  shapeCont.reshapePolygon(id, shape);
188  }
189  break;
190  case VAR_FILL: {
191  if (valueDataType != TYPE_UBYTE) {
192  server.writeStatusCmd(CMD_SET_POLYGON_VARIABLE, RTYPE_ERR, "'fill' must be defined using an unsigned byte.", outputStorage);
193  return false;
194  }
195  bool fill = inputStorage.readUnsignedByte() != 0;
196  p->setFill(fill);
197  }
198  break;
199  case ADD: {
200  if (valueDataType != TYPE_COMPOUND) {
201  server.writeStatusCmd(CMD_SET_POLYGON_VARIABLE, RTYPE_ERR, "A compound object is needed for setting a new polygon.", outputStorage);
202  return false;
203  }
204  //readt itemNo
205  inputStorage.readInt();
206  // type
207  if (inputStorage.readUnsignedByte() != TYPE_STRING) {
208  server.writeStatusCmd(CMD_SET_POLYGON_VARIABLE, RTYPE_ERR, "The first polygon parameter must be the type encoded as a string.", outputStorage);
209  return false;
210  }
211  std::string type = inputStorage.readString();
212  // color
213  if (inputStorage.readUnsignedByte() != TYPE_COLOR) {
214  server.writeStatusCmd(CMD_SET_POLYGON_VARIABLE, RTYPE_ERR, "The second polygon parameter must be the color.", outputStorage);
215  return false;
216  }
217  SUMOReal r = (SUMOReal) inputStorage.readUnsignedByte() / 255.;
218  SUMOReal g = (SUMOReal) inputStorage.readUnsignedByte() / 255.;
219  SUMOReal b = (SUMOReal) inputStorage.readUnsignedByte() / 255.;
220  //read SUMOReal a
221  inputStorage.readUnsignedByte();
222  // fill
223  if (inputStorage.readUnsignedByte() != TYPE_UBYTE) {
224  server.writeStatusCmd(CMD_SET_POLYGON_VARIABLE, RTYPE_ERR, "The third polygon parameter must be 'fill' encoded as ubyte.", outputStorage);
225  return false;
226  }
227  bool fill = inputStorage.readUnsignedByte() != 0;
228  // layer
229  if (inputStorage.readUnsignedByte() != TYPE_INTEGER) {
230  server.writeStatusCmd(CMD_SET_POLYGON_VARIABLE, RTYPE_ERR, "The fourth polygon parameter must be the layer encoded as int.", outputStorage);
231  return false;
232  }
233  layer = inputStorage.readInt();
234  // shape
235  if (inputStorage.readUnsignedByte() != TYPE_POLYGON) {
236  server.writeStatusCmd(CMD_SET_POLYGON_VARIABLE, RTYPE_ERR, "The fifth polygon parameter must be the shape.", outputStorage);
237  return false;
238  }
239  unsigned int noEntries = inputStorage.readUnsignedByte();
240  PositionVector shape;
241  for (unsigned int i = 0; i < noEntries; ++i) {
242  SUMOReal x = inputStorage.readDouble();
243  SUMOReal y = inputStorage.readDouble();
244  shape.push_back(Position(x, y));
245  }
246  //
247  if (!shapeCont.addPolygon(id, type, RGBColor(r, g, b), (SUMOReal)layer,
249  delete p;
250  server.writeStatusCmd(CMD_SET_POLYGON_VARIABLE, RTYPE_ERR, "Could not add polygon.", outputStorage);
251  return false;
252  }
253  }
254  break;
255  case REMOVE: {
256  if (valueDataType != TYPE_INTEGER) {
257  server.writeStatusCmd(CMD_SET_POLYGON_VARIABLE, RTYPE_ERR, "The layer must be given using an int.", outputStorage);
258  return false;
259  }
260  layer = inputStorage.readInt();
261  if (!shapeCont.removePolygon(id)) {
262  server.writeStatusCmd(CMD_SET_POLYGON_VARIABLE, RTYPE_ERR, "Could not remove polygon '" + id + "'", outputStorage);
263  return false;
264  }
265  }
266  break;
267  default:
268  break;
269  }
270  server.writeStatusCmd(CMD_SET_POLYGON_VARIABLE, RTYPE_OK, warning, outputStorage);
271  return true;
272 }
273 
274 
275 bool
276 TraCIServerAPI_Polygon::getShape(const std::string& id, PositionVector& shape) {
277  int layer;
278  Polygon* poly = getPolygon(id, layer);
279  if (poly == 0) {
280  return false;
281  }
282  shape.push_back(poly->getShape());
283  return true;
284 }
285 
286 
287 Polygon*
288 TraCIServerAPI_Polygon::getPolygon(const std::string& id, int& layer) {
290  return shapeCont.getPolygons().get(id);
291 }
292 
293 
294 TraCIRTree*
296  TraCIRTree* t = new TraCIRTree();
298  const std::map<std::string, Polygon*>& polygons = shapeCont.getPolygons().getMyMap();
299  for (std::map<std::string, Polygon*>::const_iterator i = polygons.begin(); i != polygons.end(); ++i) {
300  Boundary b = (*i).second->getShape().getBoxBoundary();
301  t->addObject((*i).second, b);
302  }
303  return t;
304 }
305 
306 
307 #endif
308 
309 
310 /****************************************************************************/
311