00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef _MSC_VER
00025 #include <windows_config.h>
00026 #else
00027 #include <config.h>
00028 #endif
00029
00030 #ifdef HAVE_VERSION_H
00031 #include <version.h>
00032 #endif
00033
00034 #include <iostream>
00035 #include <fstream>
00036 #include <string>
00037 #include <ctime>
00038 #include <netbuild/NBNetBuilder.h>
00039 #include <netgen/NGNet.h>
00040 #include <netgen/NGRandomNetBuilder.h>
00041 #include <netbuild/NBTypeCont.h>
00042 #include <utils/options/OptionsCont.h>
00043 #include <utils/options/OptionsIO.h>
00044 #include <utils/options/Option.h>
00045 #include <utils/common/MsgHandler.h>
00046 #include <utils/common/SystemFrame.h>
00047 #include <utils/common/UtilExceptions.h>
00048 #include <utils/common/RandHelper.h>
00049 #include <utils/common/ToString.h>
00050 #include <utils/geom/GeoConvHelper.h>
00051 #include <utils/xml/XMLSubSys.h>
00052 #include <utils/iodevices/OutputDevice.h>
00053
00054 #ifdef CHECK_MEMORY_LEAKS
00055 #include <foreign/nvwa/debug_new.h>
00056 #endif // CHECK_MEMORY_LEAKS
00057
00058
00059
00060
00061
00062 bool
00063 checkOptions() {
00064 OptionsCont &oc = OptionsCont::getOptions();
00065
00066 int no = 0;
00067 if (oc.getBool("spider-net")) {
00068 no++;
00069 }
00070 if (oc.getBool("grid-net")) {
00071 no++;
00072 }
00073 if (oc.getBool("random-net")) no++;
00074 if (no==0) {
00075 MsgHandler::getErrorInstance()->inform("You have to specify the type of network to generate.");
00076 return false;
00077 }
00078 if (no>1) {
00079 MsgHandler::getErrorInstance()->inform("You may specify only one type of network to generate at once.");
00080 return false;
00081 }
00082
00083 if (oc.isSet("default-junction-type")) {
00084 std::string type = oc.getString("default-junction-type");
00085 if (type!="traffic_light"&&type!="priority"&&type!="right_before_left") {
00086 MsgHandler::getErrorInstance()->inform("Only the following junction types are known: traffic_light, priority, right_before_left");
00087 return false;
00088 }
00089 }
00090
00091 if (!oc.isSet("output-file")) {
00092 MsgHandler::getErrorInstance()->inform("No output specified.");
00093 return false;
00094 }
00095
00096 return true;
00097 }
00098
00099
00101 void
00102 fillOptions() {
00103 OptionsCont &oc = OptionsCont::getOptions();
00104 oc.addCallExample("-c <CONFIGURATION>");
00105 oc.addCallExample("--grid-net [grid-network options] -o <OUTPUTFILE>");
00106 oc.addCallExample("--spider-net [spider-network opts] -o <OUTPUTFILE>");
00107 oc.addCallExample("--random-net [random-network opts] -o <OUTPUTFILE>");
00108
00109 oc.setAdditionalHelpMessage(" Either \"--grid-net\", \"--spider-net\" or \"--random-net\" must be \n supplied. In dependance to these switches other options are used.");
00110
00111
00112 SystemFrame::addConfigurationOptions(oc);
00113 oc.addOptionSubTopic("Grid Network");
00114 oc.addOptionSubTopic("Spider Network");
00115 oc.addOptionSubTopic("Random Network");
00116 oc.addOptionSubTopic("Output");
00117 oc.addOptionSubTopic("TLS Building");
00118 oc.addOptionSubTopic("Ramp Guessing");
00119 oc.addOptionSubTopic("Edge Removal");
00120 oc.addOptionSubTopic("Unregulated Nodes");
00121 oc.addOptionSubTopic("Processing");
00122 oc.addOptionSubTopic("Building Defaults");
00123 SystemFrame::addReportOptions(oc);
00124
00125
00126
00127
00128 oc.doRegister("grid-net", 'g', new Option_Bool(false));
00129 oc.addSynonyme("grid-net", "grid");
00130 oc.addDescription("grid-net", "Grid Network", "Forces NETGEN to build a grid-like network");
00131
00132 oc.doRegister("grid-number", new Option_Integer(5));
00133 oc.addSynonyme("grid-number", "number");
00134 oc.addDescription("grid-number", "Grid Network", "The number of junctions in both dirs");
00135
00136 oc.doRegister("grid-length", new Option_Float(100));
00137 oc.addSynonyme("grid-length", "length");
00138 oc.addDescription("grid-length", "Grid Network", "The length of streets in both dirs");
00139
00140 oc.doRegister("grid-x-number", new Option_Integer(5));
00141 oc.addSynonyme("grid-x-number", "x-no");
00142 oc.addDescription("grid-x-number", "Grid Network", "The number of junctions in x-dir; Overrides --grid-number");
00143
00144 oc.doRegister("grid-y-number", new Option_Integer(5));
00145 oc.addSynonyme("grid-y-number", "y-no");
00146 oc.addDescription("grid-y-number", "Grid Network", "The number of junctions in y-dir; Overrides --grid-number");
00147
00148 oc.doRegister("grid-x-length", new Option_Float(100));
00149 oc.addSynonyme("grid-x-length", "x-length");
00150 oc.addDescription("grid-x-length", "Grid Network", "The length of horizontal streets; Overrides --grid-length");
00151
00152 oc.doRegister("grid-y-length", new Option_Float(100));
00153 oc.addSynonyme("grid-y-length", "y-length");
00154 oc.addDescription("grid-y-length", "Grid Network", "The length of vertical streets; Overrides --grid-length");
00155
00156 oc.doRegister("attach-length", new Option_Float(0));
00157 oc.addDescription("attach-length", "Grid Network", "The length of streets attached at the boundary; 0 means no streets are attached");
00158
00159
00160
00161 oc.doRegister("spider-net", 's', new Option_Bool(false));
00162 oc.addSynonyme("spider-net", "spider");
00163 oc.addDescription("spider-net", "Spider Network", "Forces NETGEN to build a spider-net-like network");
00164
00165 oc.doRegister("spider-arm-number", new Option_Integer(13));
00166 oc.addSynonyme("spider-arm-number", "arms");
00167 oc.addDescription("spider-arm-number", "Spider Network", "The number of axes within the net");
00168
00169 oc.doRegister("spider-circle-number", new Option_Integer(20));
00170 oc.addSynonyme("spider-circle-number", "circles");
00171 oc.addDescription("spider-circle-number", "Spider Network", "The number of circles of the net");
00172
00173 oc.doRegister("spider-space-rad", new Option_Float(100));
00174 oc.addSynonyme("spider-space-rad", "radius");
00175 oc.addDescription("spider-space-rad", "Spider Network", "The distances between the circles");
00176
00177 oc.doRegister("spider-omit-center", new Option_Bool(false));
00178 oc.addSynonyme("spider-omit-center", "nocenter");
00179 oc.addDescription("spider-omit-center", "Spider Network", "Omit the central node of the network");
00180
00181
00182
00183 oc.doRegister("random-net", 'r', new Option_Bool(false));
00184 oc.addSynonyme("random-net", "random");
00185 oc.addDescription("random-net", "Random Network", "Forces NETGEN to build a random network");
00186
00187 oc.doRegister("rand-iterations", new Option_Integer(2000));
00188 oc.addSynonyme("rand-iterations", "iterations");
00189 oc.addDescription("rand-iterations", "Random Network", "Describes how many times an edge shall be added to the net");
00190
00191 oc.doRegister("rand-bidi-probability", new Option_Float(1));
00192 oc.addSynonyme("rand-bidi-probability", "bidi");
00193 oc.addDescription("rand-bidi-probability", "Random Network", "Defines the probability to build a reverse edge");
00194
00195 oc.doRegister("rand-max-distance", new Option_Float(250));
00196 oc.addSynonyme("rand-max-distance", "max-dist");
00197 oc.addDescription("rand-max-distance", "Random Network", "");
00198
00199 oc.doRegister("rand-min-distance", new Option_Float(100));
00200 oc.addSynonyme("rand-min-distance", "min-dist");
00201 oc.addDescription("rand-min-distance", "Random Network", "");
00202
00203 oc.doRegister("rand-min-angle", new Option_Float((SUMOReal)(45.0/180.0*PI)));
00204 oc.addSynonyme("rand-min-angle", "min-angle");
00205 oc.addDescription("rand-min-angle", "Random Network", "");
00206
00207 oc.doRegister("rand-num-tries", new Option_Integer(50));
00208 oc.addSynonyme("rand-num-tries", "num-tries");
00209 oc.addDescription("rand-num-tries", "Random Network", "");
00210
00211 oc.doRegister("rand-connectivity", new Option_Float((SUMOReal) 0.95));
00212 oc.addSynonyme("rand-connectivity", "connectivity");
00213 oc.addDescription("rand-connectivity", "Random Network", "");
00214
00215 oc.doRegister("rand-neighbor-dist1", new Option_Float(0));
00216 oc.addSynonyme("rand-neighbor-dist1", "dist1");
00217 oc.addDescription("rand-neighbor-dist1", "Random Network", "");
00218
00219 oc.doRegister("rand-neighbor-dist2", new Option_Float(0));
00220 oc.addSynonyme("rand-neighbor-dist2", "dist2");
00221 oc.addDescription("rand-neighbor-dist2", "Random Network", "");
00222
00223 oc.doRegister("rand-neighbor-dist3", new Option_Float(10));
00224 oc.addSynonyme("rand-neighbor-dist3", "dist3");
00225 oc.addDescription("rand-neighbor-dist3", "Random Network", "");
00226
00227 oc.doRegister("rand-neighbor-dist4", new Option_Float(10));
00228 oc.addSynonyme("rand-neighbor-dist4", "dist4");
00229 oc.addDescription("rand-neighbor-dist4", "Random Network", "");
00230
00231 oc.doRegister("rand-neighbor-dist5", new Option_Float(2));
00232 oc.addSynonyme("rand-neighbor-dist5", "dist5");
00233 oc.addDescription("rand-neighbor-dist5", "Random Network", "");
00234
00235 oc.doRegister("rand-neighbor-dist6", new Option_Float(1));
00236 oc.addSynonyme("rand-neighbor-dist6", "dist6");
00237 oc.addDescription("rand-neighbor-dist6", "Random Network", "");
00238
00239
00240
00241 NBNetBuilder::insertNetBuildOptions(oc);
00242
00243 oc.doRegister("default-junction-type", 'j', new Option_String());
00244 oc.addSynonyme("default-junction-type", "junctions");
00245 oc.addDescription("default-junction-type", "Building Defaults", "[traffic_light|priority|right_before_left] Determines the type of the build junctions");
00246
00247
00248
00249 RandHelper::insertRandOptions();
00250 }
00251
00252
00253 NGNet *
00254 buildNetwork(NBNetBuilder &nb) {
00255 OptionsCont &oc = OptionsCont::getOptions();
00256
00257 if (oc.getBool("spider-net")) {
00258
00259 bool hadError = false;
00260 if (oc.getInt("arms") < 3) {
00261 MsgHandler::getErrorInstance()->inform("Spider networks need at least 3 arms.");
00262 hadError = true;
00263 }
00264 if (oc.getInt("circles") < 1) {
00265 MsgHandler::getErrorInstance()->inform("Spider networks need at least one circle.");
00266 hadError = true;
00267 }
00268 if (oc.getFloat("radius") < 10) {
00269 MsgHandler::getErrorInstance()->inform("The radius of spider networks must be at least 10m.");
00270 hadError = true;
00271 }
00272 if (hadError) {
00273 throw ProcessError();
00274 }
00275
00276 NGNet *net = new NGNet(nb);
00277 net->createSpiderWeb(
00278 oc.getInt("arms"),
00279 oc.getInt("circles"),
00280 oc.getFloat("radius"),
00281 !oc.getBool("nocenter"));
00282 return net;
00283 }
00284
00285 if (oc.getBool("grid-net")) {
00286
00287 int xNo = oc.getInt("x-no");
00288 int yNo = oc.getInt("y-no");
00289 SUMOReal xLength = oc.getFloat("x-length");
00290 SUMOReal yLength = oc.getFloat("y-length");
00291 SUMOReal attachLength = oc.getFloat("attach-length");
00292 if (oc.isDefault("x-no")&&!oc.isDefault("number")) {
00293 xNo = oc.getInt("number");
00294 }
00295 if (oc.isDefault("y-no")&&!oc.isDefault("number")) {
00296 yNo = oc.getInt("number");
00297 }
00298 if (oc.isDefault("x-length")&&!oc.isDefault("length")) {
00299 xLength = oc.getFloat("length");
00300 }
00301 if (oc.isDefault("y-length")&&!oc.isDefault("length")) {
00302 yLength = oc.getFloat("length");
00303 }
00304
00305 bool hadError = false;
00306 if (xNo<2 || yNo<2) {
00307 MsgHandler::getErrorInstance()->inform("The number of nodes must be at least 2 in both directions.");
00308 hadError = true;
00309 }
00310 if (xLength<10. || yLength<10.) {
00311 MsgHandler::getErrorInstance()->inform("The distance between nodes must be at least 10m in both directions.");
00312 hadError = true;
00313 }
00314 if (attachLength != 0.0 && attachLength<10.) {
00315 MsgHandler::getErrorInstance()->inform("The length of attached streets must be at least 10m.");
00316 hadError = true;
00317 }
00318 if (hadError) {
00319 throw ProcessError();
00320 }
00321
00322 NGNet *net = new NGNet(nb);
00323 net->createChequerBoard(xNo, yNo, xLength, yLength, attachLength);
00324 return net;
00325 }
00326
00327 TNeighbourDistribution neighborDist;
00328 neighborDist.add(1, oc.getFloat("dist1"));
00329 neighborDist.add(2, oc.getFloat("dist2"));
00330 neighborDist.add(3, oc.getFloat("dist3"));
00331 neighborDist.add(4, oc.getFloat("dist4"));
00332 neighborDist.add(5, oc.getFloat("dist5"));
00333 neighborDist.add(6, oc.getFloat("dist6"));
00334 NGNet *net = new NGNet(nb);
00335 NGRandomNetBuilder randomNet(*net,
00336 oc.getFloat("min-angle"),
00337 oc.getFloat("rand-min-distance"),
00338 oc.getFloat("rand-max-distance"),
00339 oc.getFloat("connectivity"),
00340 oc.getInt("num-tries"),
00341 neighborDist);
00342 randomNet.createNet(oc.getInt("iterations"));
00343 return net;
00344 }
00345
00346
00347
00348 int
00349 main(int argc, char **argv) {
00350 OptionsCont &oc = OptionsCont::getOptions();
00351
00352 oc.setApplicationDescription("Road network generator for the microscopic road traffic simulation SUMO.");
00353 oc.setApplicationName("netgen", "SUMO netgen Version " + (std::string)VERSION_STRING);
00354 int ret = 0;
00355 try {
00356
00357 XMLSubSys::init(false);
00358 fillOptions();
00359 OptionsIO::getOptions(true, argc, argv);
00360 if (oc.processMetaOptions(argc < 2)) {
00361 SystemFrame::close();
00362 return 0;
00363 }
00364 MsgHandler::initOutputOptions();
00365 if (!checkOptions()) throw ProcessError();
00366 RandHelper::initRandGlobal();
00367 NBNetBuilder nb;
00368 nb.applyOptions(oc);
00369
00370 NGNet *net = buildNetwork(nb);
00371
00372 oc.resetWritable();
00373
00374 net->toNB();
00375 delete net;
00376
00377 WRITE_MESSAGE(" Generation done;");
00378 WRITE_MESSAGE(" " + toString<int>(nb.getNodeCont().size()) + " nodes generated.");
00379 WRITE_MESSAGE(" " + toString<int>(nb.getEdgeCont().size()) + " edges generated.");
00380 nb.buildLoaded();
00381 } catch (ProcessError &e) {
00382 if (std::string(e.what())!=std::string("Process Error") && std::string(e.what())!=std::string("")) {
00383 MsgHandler::getErrorInstance()->inform(e.what());
00384 }
00385 MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
00386 ret = 1;
00387 #ifndef _DEBUG
00388 } catch (...) {
00389 MsgHandler::getErrorInstance()->inform("Quitting (on unknown error).", false);
00390 ret = 1;
00391 #endif
00392 }
00393 OutputDevice::closeAll();
00394 SystemFrame::close();
00395 if (ret==0) {
00396 std::cout << "Success." << std::endl;
00397 }
00398 return ret;
00399 }
00400
00401
00402
00403
00404