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