SUMO - Simulation of Urban MObility
|
00001 /****************************************************************************/ 00009 // APIs for getting/setting polygon values via TraCI 00010 /****************************************************************************/ 00011 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/ 00012 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors 00013 /****************************************************************************/ 00014 // 00015 // This file is part of SUMO. 00016 // SUMO is free software: you can redistribute it and/or modify 00017 // it under the terms of the GNU General Public License as published by 00018 // the Free Software Foundation, either version 3 of the License, or 00019 // (at your option) any later version. 00020 // 00021 /****************************************************************************/ 00022 00023 00024 // =========================================================================== 00025 // included modules 00026 // =========================================================================== 00027 #ifdef _MSC_VER 00028 #include <windows_config.h> 00029 #else 00030 #include <config.h> 00031 #endif 00032 00033 #ifndef NO_TRACI 00034 00035 #include <utils/common/StdDefs.h> 00036 #include <microsim/MSNet.h> 00037 #include <utils/shapes/PointOfInterest.h> 00038 #include <utils/shapes/ShapeContainer.h> 00039 #include "TraCIConstants.h" 00040 #include "TraCIServerAPI_Polygon.h" 00041 00042 #ifdef CHECK_MEMORY_LEAKS 00043 #include <foreign/nvwa/debug_new.h> 00044 #endif // CHECK_MEMORY_LEAKS 00045 00046 00047 // =========================================================================== 00048 // used namespaces 00049 // =========================================================================== 00050 using namespace traci; 00051 00052 00053 // =========================================================================== 00054 // method definitions 00055 // =========================================================================== 00056 bool 00057 TraCIServerAPI_Polygon::processGet(TraCIServer& server, tcpip::Storage& inputStorage, 00058 tcpip::Storage& outputStorage) { 00059 std::string warning = ""; // additional description for response 00060 // variable & id 00061 int variable = inputStorage.readUnsignedByte(); 00062 std::string id = inputStorage.readString(); 00063 // check variable 00064 if (variable != ID_LIST && variable != VAR_TYPE && variable != VAR_COLOR && variable != VAR_SHAPE && variable != VAR_FILL 00065 && variable != ID_COUNT) { 00066 server.writeStatusCmd(CMD_GET_POLYGON_VARIABLE, RTYPE_ERR, "Get Polygon Variable: unsupported variable specified", outputStorage); 00067 return false; 00068 } 00069 // begin response building 00070 tcpip::Storage tempMsg; 00071 // response-code, variableID, objectID 00072 tempMsg.writeUnsignedByte(RESPONSE_GET_POLYGON_VARIABLE); 00073 tempMsg.writeUnsignedByte(variable); 00074 tempMsg.writeString(id); 00075 // process request 00076 if (variable == ID_LIST || variable == ID_COUNT) { 00077 std::vector<std::string> ids; 00078 ShapeContainer& shapeCont = MSNet::getInstance()->getShapeContainer(); 00079 for (int i = shapeCont.getMinLayer(); i <= shapeCont.getMaxLayer(); ++i) { 00080 shapeCont.getPolygonCont(i).insertIDs(ids); 00081 } 00082 if (variable == ID_LIST) { 00083 tempMsg.writeUnsignedByte(TYPE_STRINGLIST); 00084 tempMsg.writeStringList(ids); 00085 } else { 00086 tempMsg.writeUnsignedByte(TYPE_INTEGER); 00087 tempMsg.writeInt((int) ids.size()); 00088 } 00089 } else { 00090 Polygon* p = 0; 00091 ShapeContainer& shapeCont = MSNet::getInstance()->getShapeContainer(); 00092 for (int i = shapeCont.getMinLayer(); i <= shapeCont.getMaxLayer() && p == 0; ++i) { 00093 p = shapeCont.getPolygonCont(i).get(id); 00094 } 00095 if (p == 0) { 00096 server.writeStatusCmd(CMD_GET_POLYGON_VARIABLE, RTYPE_ERR, "Polygon '" + id + "' is not known", outputStorage); 00097 return false; 00098 } 00099 switch (variable) { 00100 case VAR_TYPE: 00101 tempMsg.writeUnsignedByte(TYPE_STRING); 00102 tempMsg.writeString(p->getType()); 00103 break; 00104 case VAR_COLOR: 00105 tempMsg.writeUnsignedByte(TYPE_COLOR); 00106 tempMsg.writeUnsignedByte(static_cast<int>(p->getColor().red() * 255. + .5)); 00107 tempMsg.writeUnsignedByte(static_cast<int>(p->getColor().green() * 255. + .5)); 00108 tempMsg.writeUnsignedByte(static_cast<int>(p->getColor().blue() * 255. + .5)); 00109 tempMsg.writeUnsignedByte(255); 00110 break; 00111 case VAR_SHAPE: 00112 tempMsg.writeUnsignedByte(TYPE_POLYGON); 00113 tempMsg.writeUnsignedByte(MIN2(static_cast<int>(255), static_cast<int>(p->getShape().size()))); 00114 for (unsigned int iPoint = 0; iPoint < MIN2(static_cast<size_t>(255), p->getShape().size()); ++iPoint) { 00115 tempMsg.writeDouble(p->getShape()[iPoint].x()); 00116 tempMsg.writeDouble(p->getShape()[iPoint].y()); 00117 } 00118 break; 00119 case VAR_FILL: 00120 tempMsg.writeUnsignedByte(TYPE_UBYTE); 00121 tempMsg.writeUnsignedByte(p->fill() ? 1 : 0); 00122 break; 00123 default: 00124 break; 00125 } 00126 } 00127 server.writeStatusCmd(CMD_GET_POLYGON_VARIABLE, RTYPE_OK, warning, outputStorage); 00128 server.writeResponseWithLength(outputStorage, tempMsg); 00129 return true; 00130 } 00131 00132 00133 bool 00134 TraCIServerAPI_Polygon::processSet(TraCIServer& server, tcpip::Storage& inputStorage, 00135 tcpip::Storage& outputStorage) { 00136 std::string warning = ""; // additional description for response 00137 // variable 00138 int variable = inputStorage.readUnsignedByte(); 00139 if (variable != VAR_TYPE && variable != VAR_COLOR && variable != VAR_SHAPE && variable != VAR_FILL 00140 && variable != ADD && variable != REMOVE) { 00141 server.writeStatusCmd(CMD_SET_POLYGON_VARIABLE, RTYPE_ERR, "Change Polygon State: unsupported variable specified", outputStorage); 00142 return false; 00143 } 00144 // id 00145 std::string id = inputStorage.readString(); 00146 Polygon* p = 0; 00147 int layer = 0; 00148 ShapeContainer& shapeCont = MSNet::getInstance()->getShapeContainer(); 00149 if (variable != ADD && variable != REMOVE) { 00150 for (int i = shapeCont.getMinLayer(); i <= shapeCont.getMaxLayer() && p == 0; ++i) { 00151 p = shapeCont.getPolygonCont(i).get(id); 00152 layer = i; 00153 } 00154 if (p == 0) { 00155 server.writeStatusCmd(CMD_SET_POLYGON_VARIABLE, RTYPE_ERR, "Polygon '" + id + "' is not known", outputStorage); 00156 return false; 00157 } 00158 } 00159 // process 00160 int valueDataType = inputStorage.readUnsignedByte(); 00161 switch (variable) { 00162 case VAR_TYPE: { 00163 if (valueDataType != TYPE_STRING) { 00164 server.writeStatusCmd(CMD_SET_POLYGON_VARIABLE, RTYPE_ERR, "The type must be given as a string.", outputStorage); 00165 return false; 00166 } 00167 std::string type = inputStorage.readString(); 00168 p->setType(type); 00169 } 00170 break; 00171 case VAR_COLOR: { 00172 if (valueDataType != TYPE_COLOR) { 00173 server.writeStatusCmd(CMD_SET_POLYGON_VARIABLE, RTYPE_ERR, "The color must be given using an accoring type.", outputStorage); 00174 return false; 00175 } 00176 SUMOReal r = (SUMOReal) inputStorage.readUnsignedByte() / 255.; 00177 SUMOReal g = (SUMOReal) inputStorage.readUnsignedByte() / 255.; 00178 SUMOReal b = (SUMOReal) inputStorage.readUnsignedByte() / 255.; 00179 //read SUMOReal a 00180 inputStorage.readUnsignedByte(); 00181 p->setColor(RGBColor(r, g, b)); 00182 } 00183 break; 00184 case VAR_SHAPE: { 00185 if (valueDataType != TYPE_POLYGON) { 00186 server.writeStatusCmd(CMD_SET_POLYGON_VARIABLE, RTYPE_ERR, "The shape must be given using an accoring type.", outputStorage); 00187 return false; 00188 } 00189 unsigned int noEntries = inputStorage.readUnsignedByte(); 00190 PositionVector shape; 00191 for (unsigned int i = 0; i < noEntries; ++i) { 00192 SUMOReal x = inputStorage.readDouble(); 00193 SUMOReal y = inputStorage.readDouble(); 00194 shape.push_back(Position(x, y)); 00195 } 00196 shapeCont.reshapePolygon(layer, id, shape); 00197 } 00198 break; 00199 case VAR_FILL: { 00200 if (valueDataType != TYPE_UBYTE) { 00201 server.writeStatusCmd(CMD_SET_POLYGON_VARIABLE, RTYPE_ERR, "'fill' must be defined using an unsigned byte.", outputStorage); 00202 return false; 00203 } 00204 bool fill = inputStorage.readUnsignedByte() != 0; 00205 p->setFill(fill); 00206 } 00207 break; 00208 case ADD: { 00209 if (valueDataType != TYPE_COMPOUND) { 00210 server.writeStatusCmd(CMD_SET_POLYGON_VARIABLE, RTYPE_ERR, "A compound object is needed for setting a new polygon.", outputStorage); 00211 return false; 00212 } 00213 //readt itemNo 00214 inputStorage.readInt(); 00215 // type 00216 if (inputStorage.readUnsignedByte() != TYPE_STRING) { 00217 server.writeStatusCmd(CMD_SET_POLYGON_VARIABLE, RTYPE_ERR, "The first polygon parameter must be the type encoded as a string.", outputStorage); 00218 return false; 00219 } 00220 std::string type = inputStorage.readString(); 00221 // color 00222 if (inputStorage.readUnsignedByte() != TYPE_COLOR) { 00223 server.writeStatusCmd(CMD_SET_POLYGON_VARIABLE, RTYPE_ERR, "The second polygon parameter must be the color.", outputStorage); 00224 return false; 00225 } 00226 SUMOReal r = (SUMOReal) inputStorage.readUnsignedByte() / 255.; 00227 SUMOReal g = (SUMOReal) inputStorage.readUnsignedByte() / 255.; 00228 SUMOReal b = (SUMOReal) inputStorage.readUnsignedByte() / 255.; 00229 //read SUMOReal a 00230 inputStorage.readUnsignedByte(); 00231 // fill 00232 if (inputStorage.readUnsignedByte() != TYPE_UBYTE) { 00233 server.writeStatusCmd(CMD_SET_POLYGON_VARIABLE, RTYPE_ERR, "The third polygon parameter must be 'fill' encoded as ubyte.", outputStorage); 00234 return false; 00235 } 00236 bool fill = inputStorage.readUnsignedByte() != 0; 00237 // layer 00238 if (inputStorage.readUnsignedByte() != TYPE_INTEGER) { 00239 server.writeStatusCmd(CMD_SET_POLYGON_VARIABLE, RTYPE_ERR, "The fourth polygon parameter must be the layer encoded as int.", outputStorage); 00240 return false; 00241 } 00242 layer = inputStorage.readInt(); 00243 // shape 00244 if (inputStorage.readUnsignedByte() != TYPE_POLYGON) { 00245 server.writeStatusCmd(CMD_SET_POLYGON_VARIABLE, RTYPE_ERR, "The fifth polygon parameter must be the shape.", outputStorage); 00246 return false; 00247 } 00248 unsigned int noEntries = inputStorage.readUnsignedByte(); 00249 PositionVector shape; 00250 for (unsigned int i = 0; i < noEntries; ++i) { 00251 SUMOReal x = inputStorage.readDouble(); 00252 SUMOReal y = inputStorage.readDouble(); 00253 shape.push_back(Position(x, y)); 00254 } 00255 // 00256 if (!shapeCont.addPolygon(id, layer, type, RGBColor(r, g, b), fill, shape)) { 00257 delete p; 00258 server.writeStatusCmd(CMD_SET_POLYGON_VARIABLE, RTYPE_ERR, "Could not add polygon.", outputStorage); 00259 return false; 00260 } 00261 } 00262 break; 00263 case REMOVE: { 00264 if (valueDataType != TYPE_INTEGER) { 00265 server.writeStatusCmd(CMD_SET_POI_VARIABLE, RTYPE_ERR, "The layer must be given using an int.", outputStorage); 00266 return false; 00267 } 00268 layer = inputStorage.readInt(); 00269 if (!shapeCont.removePolygon(layer, id)) { 00270 bool removed = false; 00271 for (int i = shapeCont.getMinLayer(); i <= shapeCont.getMaxLayer(); ++i) { 00272 removed |= shapeCont.removePolygon(i, id); 00273 } 00274 if (!removed) { 00275 server.writeStatusCmd(CMD_SET_POI_VARIABLE, RTYPE_ERR, "Could not remove PoI '" + id + "'", outputStorage); 00276 return false; 00277 } 00278 } 00279 } 00280 break; 00281 default: 00282 break; 00283 } 00284 server.writeStatusCmd(CMD_SET_POLYGON_VARIABLE, RTYPE_OK, warning, outputStorage); 00285 return true; 00286 } 00287 00288 #endif 00289 00290 00291 /****************************************************************************/ 00292