SUMO - Simulation of Urban MObility
polyconvert_main.cpp
Go to the documentation of this file.
00001 /****************************************************************************/
00010 // Main for POLYCONVERT
00011 /****************************************************************************/
00012 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00013 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
00014 /****************************************************************************/
00015 //
00016 //   This file is part of SUMO.
00017 //   SUMO is free software: you can redistribute it and/or modify
00018 //   it under the terms of the GNU General Public License as published by
00019 //   the Free Software Foundation, either version 3 of the License, or
00020 //   (at your option) any later version.
00021 //
00022 /****************************************************************************/
00023 
00024 
00025 // ===========================================================================
00026 // included modules
00027 // ===========================================================================
00028 #ifdef _MSC_VER
00029 #include <windows_config.h>
00030 #else
00031 #include <config.h>
00032 #endif
00033 
00034 #ifdef HAVE_VERSION_H
00035 #include <version.h>
00036 #endif
00037 
00038 #include <iostream>
00039 #include <string>
00040 #include <utils/options/OptionsIO.h>
00041 #include <utils/options/OptionsCont.h>
00042 #include <utils/common/UtilExceptions.h>
00043 #include <utils/common/StringTokenizer.h>
00044 #include <utils/common/SystemFrame.h>
00045 #include <utils/common/MsgHandler.h>
00046 #include <utils/common/TplConvert.h>
00047 #include <utils/common/ToString.h>
00048 #include <utils/iodevices/OutputDevice.h>
00049 #include <utils/importio/LineReader.h>
00050 #include <utils/geom/GeomConvHelper.h>
00051 #include <utils/geom/Boundary.h>
00052 #include <polyconvert/PCLoaderVisum.h>
00053 #include <polyconvert/PCLoaderDlrNavteq.h>
00054 #include <polyconvert/PCLoaderXML.h>
00055 #include <polyconvert/PCLoaderOSM.h>
00056 #include <polyconvert/PCLoaderArcView.h>
00057 #include <polyconvert/PCTypeMap.h>
00058 #include <polyconvert/PCTypeDefHandler.h>
00059 #include <polyconvert/PCNetProjectionLoader.h>
00060 #include <utils/xml/XMLSubSys.h>
00061 #include <utils/geom/GeoConvHelper.h>
00062 
00063 #ifdef CHECK_MEMORY_LEAKS
00064 #include <foreign/nvwa/debug_new.h>
00065 #endif // CHECK_MEMORY_LEAKS
00066 
00067 
00068 // ===========================================================================
00069 // method definitions
00070 // ===========================================================================
00071 void
00072 fillOptions() {
00073     OptionsCont& oc = OptionsCont::getOptions();
00074     oc.addCallExample("-c <CONFIGURATION>", "run with configuration options set in file");
00075 
00076     // insert options sub-topics
00077     SystemFrame::addConfigurationOptions(oc); // fill this subtopic, too
00078     oc.addOptionSubTopic("Input");
00079     oc.addOptionSubTopic("Output");
00080     GeoConvHelper::addProjectionOptions(oc);
00081     oc.addOptionSubTopic("Pruning");
00082     oc.addOptionSubTopic("Processing");
00083     oc.addOptionSubTopic("Building Defaults");
00084     SystemFrame::addReportOptions(oc); // fill this subtopic, too
00085 
00086 
00087     // register options
00088     // add i/o options
00089     // original network
00090     oc.doRegister("net-file", 'n', new Option_FileName());
00091     oc.addSynonyme("net-file", "net");
00092     oc.addDescription("net-file", "Input", "Loads SUMO-network FILE as reference to offset and projection");
00093 
00094     // dlrnavteq import
00095     oc.doRegister("dlr-navteq-poly-files", new Option_FileName());
00096     oc.addDescription("dlr-navteq-poly-files", "Input", "Reads polygons from FILE assuming they're coded in DLR-Navteq (Elmar)-format");
00097     oc.doRegister("dlr-navteq-poi-files", new Option_FileName());
00098     oc.addDescription("dlr-navteq-poi-files", "Input", "Reads pois from FILE+ assuming they're coded in DLR-Navteq (Elmar)-format");
00099 
00100     // visum import
00101     oc.doRegister("visum-files", new Option_FileName());
00102     oc.addSynonyme("visum-files", "visum");
00103     oc.addDescription("visum-files", "Input", "Reads polygons from FILE assuming it's a Visum-net");
00104 
00105     // xml import
00106     oc.doRegister("xml-files", new Option_FileName());
00107     oc.addSynonyme("xml-files", "xml");
00108     oc.addDescription("xml-files", "Input", "Reads pois and shapes from FILE assuming they're coded in XML");
00109 
00110     // osm import
00111     oc.doRegister("osm-files", new Option_FileName());
00112     oc.addSynonyme("osm-files", "osm");
00113     oc.addDescription("osm-files", "Input", "Reads pois from FILE+ assuming they're coded in OSM");
00114     oc.doRegister("osm.keep-full-type", new Option_Bool(false));
00115     oc.addDescription("osm.keep-full-type", "Input", "The type will be made of the key-value - pair.");
00116     oc.doRegister("osm.use-name", new Option_Bool(false));
00117     oc.addDescription("osm.use-name", "Input", "The id will be set from the given 'name' attribute.");
00118 
00119     // arcview import
00120     oc.doRegister("shapefile-prefixes", new Option_FileName());
00121     oc.addSynonyme("shapefile-prefixes", "shapefile-prefix");
00122     oc.addSynonyme("shapefile-prefixes", "shapefile");
00123     oc.addSynonyme("shapefile-prefixes", "shape-files", true);
00124     oc.addDescription("shapefile-prefixes", "Input", "Reads shapes from shapefiles FILE+");
00125 
00126     oc.doRegister("shapefile.guess-projection", new Option_Bool(false));
00127     oc.addSynonyme("shapefile.guess-projection", "arcview.guess-projection", true);
00128     oc.addDescription("shapefile.guess-projection", "Input", "Guesses the shapefile's projection");
00129 
00130     oc.doRegister("shapefile.id-column", new Option_FileName());
00131     oc.addSynonyme("shapefile.id-column", "shapefile.id-name", true);
00132     oc.addSynonyme("shapefile.id-column", "shape-files.id-name", true);
00133     oc.addDescription("shapefile.id-column", "Input", "Defines in which column the id can be found");
00134 
00135     // typemap reading
00136     oc.doRegister("type-file", new Option_FileName());
00137     oc.addSynonyme("type-file", "typemap", true);
00138     oc.addDescription("type-file", "Input", "Reads types from FILE");
00139 
00140 
00141     // output
00142     oc.doRegister("output-file", 'o', new Option_FileName("polygons.xml"));
00143     oc.addSynonyme("output-file", "output");
00144     oc.addDescription("output-file", "Output", "Write generated polygons/pois to FILE");
00145 
00146 
00147     // prunning options
00148     oc.doRegister("prune.in-net", new Option_Bool(false));
00149     oc.addSynonyme("prune.in-net", "prune.on-net", true);
00150     oc.addDescription("prune.in-net", "Pruning", "Enables pruning on net boundaries");
00151 
00152     oc.doRegister("prune.in-net.offsets", new Option_String("0,0,0,0"));
00153     oc.addSynonyme("prune.in-net.offsets", "prune.on-net.offsets", true);
00154     oc.addDescription("prune.in-net.offsets", "Pruning", "Uses STR as offset definition added to the net boundaries");
00155 
00156     oc.doRegister("prune.boundary", new Option_String());
00157     oc.addDescription("prune.boundary", "Pruning", "Uses STR as pruning boundary");
00158 
00159     oc.doRegister("prune.keep-list", new Option_String());
00160     oc.addSynonyme("prune.keep-list", "prune.keep");
00161     oc.addSynonyme("prune.keep-list", "prune.ignore", true);
00162     oc.addDescription("prune.keep-list", "Pruning", "Items in STR will be kept though out of boundary");
00163 
00164     oc.doRegister("prune.explicit", new Option_String(""));
00165     oc.addSynonyme("prune.explicit", "remove");
00166     oc.addDescription("prune.explicit", "Pruning", "Items with names in STR will be removed");
00167 
00168 
00169     oc.doRegister("offset.x", new Option_Float(0));
00170     oc.addSynonyme("offset.x", "x-offset-to-apply", true);
00171     oc.addDescription("offset.x", "Processing", "Adds FLOAT to net x-positions");
00172 
00173     oc.doRegister("offset.y", new Option_Float(0));
00174     oc.addSynonyme("offset.y", "y-offset-to-apply", true);
00175     oc.addDescription("offset.y", "Processing", "Adds FLOAT to net y-positions");
00176 
00177 
00178     // building defaults options
00179     oc.doRegister("color", new Option_String("0.2,0.5,1."));
00180     oc.addDescription("color", "Building Defaults", "Sets STR as default color");
00181 
00182     oc.doRegister("prefix", new Option_String(""));
00183     oc.addDescription("prefix", "Building Defaults", "Sets STR as default prefix");
00184 
00185     oc.doRegister("type", new Option_String("unknown"));
00186     oc.addDescription("type", "Building Defaults", "Sets STR as default type");
00187 
00188     oc.doRegister("layer", new Option_Integer(-1));
00189     oc.addDescription("layer", "Building Defaults", "Sets INT as default layer");
00190 
00191     oc.doRegister("discard", new Option_Bool(false));
00192     oc.addDescription("discard", "Building Defaults", "Sets default action to discard");
00193 }
00194 
00195 
00196 int
00197 main(int argc, char** argv) {
00198     OptionsCont& oc = OptionsCont::getOptions();
00199     oc.setApplicationDescription("Importer of polygons and POIs for the road traffic simulation SUMO.");
00200     oc.setApplicationName("polyconvert", "SUMO polyconvert Version " + (std::string)VERSION_STRING);
00201     int ret = 0;
00202     try {
00203         // initialise subsystems
00204         XMLSubSys::init(false);
00205         fillOptions();
00206         OptionsIO::getOptions(true, argc, argv);
00207         if (oc.processMetaOptions(argc < 2)) {
00208             OutputDevice::closeAll();
00209             SystemFrame::close();
00210             return 0;
00211         }
00212         MsgHandler::initOutputOptions();
00213         // build the projection
00214         Boundary origNetBoundary, pruningBoundary;
00215         Position netOffset;
00216         std::string proj;
00217         PCNetProjectionLoader::loadIfSet(oc, netOffset, origNetBoundary, pruningBoundary, proj);
00218         if (proj != "") {
00219             if (oc.isDefault("proj")) {
00220                 oc.set("proj", proj);
00221             }
00222             if (oc.isDefault("offset.x")) {
00223                 oc.set("offset.x", toString(netOffset.x()));
00224             }
00225             if (oc.isDefault("offset.y")) {
00226                 oc.set("offset.y", toString(netOffset.y()));
00227             }
00228         }
00229 #ifdef HAVE_PROJ
00230         unsigned numProjections = oc.getBool("simple-projection") + oc.getBool("proj.utm") + oc.getBool("proj.dhdn") + (oc.getString("proj").length() > 1);
00231         if ((oc.isSet("osm-files") || oc.isSet("dlr-navteq-poly-files") || oc.isSet("dlr-navteq-poi-files")) && numProjections == 0) {
00232             oc.set("proj.utm", "true");
00233         }
00234         if ((oc.isSet("dlr-navteq-poly-files") || oc.isSet("dlr-navteq-poi-files")) && oc.isDefault("proj.scale")) {
00235             oc.set("proj.scale", std::string("5"));
00236         }
00237 #endif
00238         if (!GeoConvHelper::init(oc)) {
00239             throw ProcessError("Could not build projection!");
00240         }
00241 
00242         // check whether the input shall be pruned
00243         bool prune = false;
00244         if (oc.getBool("prune.in-net")) {
00245             if (!oc.isSet("net")) {
00246                 throw ProcessError("In order to prune the input on the net, you have to supply a network.");
00247             }
00248             bool ok = true;
00249             // !!! no proper error handling
00250             Boundary offsets = GeomConvHelper::parseBoundaryReporting(oc.getString("prune.in-net.offsets"), "--prune.on-net.offsets", 0, ok);
00251             pruningBoundary = Boundary(
00252                                   pruningBoundary.xmin() + offsets.xmin(),
00253                                   pruningBoundary.ymin() + offsets.ymin(),
00254                                   pruningBoundary.xmax() + offsets.xmax(),
00255                                   pruningBoundary.ymax() + offsets.ymax());
00256             prune = true;
00257         }
00258         if (oc.isSet("prune.boundary")) {
00259             bool ok = true;
00260             // !!! no proper error handling
00261             pruningBoundary = GeomConvHelper::parseBoundaryReporting(oc.getString("prune.boundary"), "--prune.boundary", 0, ok);
00262             prune = true;
00263         }
00264 
00265         PCPolyContainer toFill(prune, pruningBoundary, oc.getStringVector("remove"));
00266 
00267         // read in the type defaults
00268         PCTypeMap tm;
00269         if (oc.isSet("type-file")) {
00270             PCTypeDefHandler handler(oc, tm);
00271             if (!XMLSubSys::runParser(handler, oc.getString("type-file"))) {
00272                 // something failed
00273                 throw ProcessError();
00274             }
00275         }
00276 
00277         // read in the data
00278         PCLoaderXML::loadIfSet(oc, toFill, tm); // SUMO-XML
00279         PCLoaderOSM::loadIfSet(oc, toFill, tm); // OSM-XML
00280         PCLoaderDlrNavteq::loadIfSet(oc, toFill, tm); // Elmar-files
00281         PCLoaderVisum::loadIfSet(oc, toFill, tm); // VISUM
00282         PCLoaderArcView::loadIfSet(oc, toFill, tm); // shape-files
00283         // check whether any errors occured
00284         if (!MsgHandler::getErrorInstance()->wasInformed()) {
00285             // no? ok, save
00286             toFill.save(oc.getString("output-file"));
00287         } else {
00288             throw ProcessError();
00289         }
00290     } catch (ProcessError& e) {
00291         if (std::string(e.what()) != std::string("Process Error") && std::string(e.what()) != std::string("")) {
00292             WRITE_ERROR(e.what());
00293         }
00294         MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
00295         ret = 1;
00296 #ifndef _DEBUG
00297     } catch (...) {
00298         MsgHandler::getErrorInstance()->inform("Quitting (on unknown error).", false);
00299         ret = 1;
00300 #endif
00301     }
00302     OutputDevice::closeAll();
00303     SystemFrame::close();
00304     // report about ending
00305     if (ret == 0) {
00306         std::cout << "Success." << std::endl;
00307     }
00308     return ret;
00309 }
00310 
00311 
00312 
00313 /****************************************************************************/
00314 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines