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