SUMO - Simulation of Urban MObility

PCLoaderOSM.cpp

Go to the documentation of this file.
00001 /****************************************************************************/
00007 // A reader of pois and polygons stored in OSM-format
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 <string>
00031 #include <map>
00032 #include <fstream>
00033 #include <utils/common/UtilExceptions.h>
00034 #include <utils/common/MsgHandler.h>
00035 #include <utils/common/ToString.h>
00036 #include <utils/options/OptionsCont.h>
00037 #include <utils/options/Option.h>
00038 #include <utils/common/StdDefs.h>
00039 #include <polyconvert/PCPolyContainer.h>
00040 #include "PCLoaderOSM.h"
00041 #include <utils/common/RGBColor.h>
00042 #include <utils/geom/GeomHelper.h>
00043 #include <utils/geom/Position.h>
00044 #include <utils/geom/GeoConvHelper.h>
00045 #include <utils/xml/XMLSubSys.h>
00046 #include <utils/geom/GeomConvHelper.h>
00047 #include <utils/common/FileHelpers.h>
00048 
00049 #ifdef CHECK_MEMORY_LEAKS
00050 #include <foreign/nvwa/debug_new.h>
00051 #endif // CHECK_MEMORY_LEAKS
00052 
00053 
00054 // ===========================================================================
00055 // method definitions
00056 // ===========================================================================
00057 // ---------------------------------------------------------------------------
00058 // static interface
00059 // ---------------------------------------------------------------------------
00060 void
00061 PCLoaderOSM::loadIfSet(OptionsCont& oc, PCPolyContainer& toFill,
00062                        PCTypeMap& tm) throw(ProcessError) {
00063     if (!oc.isSet("osm-files")) {
00064         return;
00065     }
00066     // parse file(s)
00067     std::vector<std::string> files = oc.getStringVector("osm-files");
00068     // load nodes, first
00069     std::map<int, PCOSMNode*> nodes;
00070     NodesHandler nodesHandler(nodes);
00071     for (std::vector<std::string>::const_iterator file=files.begin(); file!=files.end(); ++file) {
00072         // nodes
00073         if (!FileHelpers::exists(*file)) {
00074             WRITE_ERROR("Could not open osm-file '" + *file + "'.");
00075             return;
00076         }
00077         PROGRESS_BEGIN_MESSAGE("Parsing nodes from osm-file '" + *file + "'");
00078         if (!XMLSubSys::runParser(nodesHandler, *file)) {
00079             throw ProcessError();
00080         }
00081         PROGRESS_DONE_MESSAGE();
00082     }
00083     // load edges, then
00084     std::map<std::string, PCOSMEdge*> edges;
00085     EdgesHandler edgesHandler(nodes, edges);
00086     for (std::vector<std::string>::const_iterator file=files.begin(); file!=files.end(); ++file) {
00087         // edges
00088         PROGRESS_BEGIN_MESSAGE("Parsing edges from osm-file '" + *file + "'");
00089         XMLSubSys::runParser(edgesHandler, *file);
00090         PROGRESS_DONE_MESSAGE();
00091     }
00092     // build all
00093     RGBColor c = RGBColor::parseColor(oc.getString("color"));
00094     // instatiate polygons
00095     for (std::map<std::string, PCOSMEdge*>::iterator i=edges.begin(); i!=edges.end(); ++i) {
00096         PCOSMEdge* e = (*i).second;
00097         if (!e->myIsAdditional) {
00098             continue;
00099         }
00100         // compute shape
00101         PositionVector vec;
00102         for (std::vector<int>::iterator j=e->myCurrentNodes.begin(); j!=e->myCurrentNodes.end(); ++j) {
00103             PCOSMNode* n = nodes.find(*j)->second;
00104             Position pos(n->lon, n->lat);
00105             if (!GeoConvHelper::getDefaultInstance().x2cartesian(pos)) {
00106                 WRITE_WARNING("Unable to project coordinates for polygon '" + e->id + "'.");
00107             }
00108             vec.push_back_noDoublePos(pos);
00109         }
00110         // set type etc.
00111         std::string name = oc.getBool("osm.use-name")&&e->name!="" ? e->name : e->id;
00112         std::string type;
00113         RGBColor color;
00114         bool fill = vec.getBegin()==vec.getEnd();
00115         bool discard = oc.getBool("discard");
00116         int layer = oc.getInt("layer");
00117         if (tm.has(e->myType)) {
00118             const PCTypeMap::TypeDef& def = tm.get(e->myType);
00119             name = def.prefix + name;
00120             type = def.id;
00121             color = RGBColor::parseColor(def.color);
00122             fill = fill && def.allowFill;
00123             discard = def.discard;
00124             layer = def.layer;
00125         } else if (e->myType.find(".")!=std::string::npos&&tm.has(e->myType.substr(0, e->myType.find(".")))) {
00126             const PCTypeMap::TypeDef& def = tm.get(e->myType.substr(0, e->myType.find(".")));
00127             name = def.prefix + name;
00128             type = def.id;
00129             color = RGBColor::parseColor(def.color);
00130             fill = fill && def.allowFill;
00131             discard = def.discard;
00132             layer = def.layer;
00133         } else {
00134             name = oc.getString("prefix") + name;
00135             type = oc.getString("type");
00136             color = c;
00137         }
00138         if (!discard) {
00139             if (oc.getBool("osm.keep-full-type")) {
00140                 type = e->myType;
00141             }
00142             Polygon* poly = new Polygon(name, type, color, vec, fill);
00143             if (!toFill.insert(name, poly, layer)) {
00144                 WRITE_ERROR("Polygon '" + name + "' could not been added.");
00145                 delete poly;
00146             }
00147         }
00148     }
00149     // instantiate pois
00150     for (std::map<int, PCOSMNode*>::iterator i=nodes.begin(); i!=nodes.end(); ++i) {
00151         PCOSMNode* n = (*i).second;
00152         if (!n->myIsAdditional) {
00153             continue;
00154         }
00155 
00156         // patch the values
00157         bool discard = oc.getBool("discard");
00158         int layer = oc.getInt("layer");
00159         std::string name = toString(n->id);
00160         std::string type;
00161         RGBColor color;
00162         if (tm.has(n->myType)) {
00163             const PCTypeMap::TypeDef& def = tm.get(n->myType);
00164             name = def.prefix + name;
00165             type = def.id;
00166             color = RGBColor::parseColor(def.color);
00167             discard = def.discard;
00168             layer = def.layer;
00169         } else if (type.find(".")!=std::string::npos&&tm.has(type.substr(0, type.find(".")))) {
00170             const PCTypeMap::TypeDef& def = tm.get(type.substr(0, type.find(".")));
00171             name = def.prefix + name;
00172             type = def.id;
00173             color = RGBColor::parseColor(def.color);
00174             discard = def.discard;
00175             layer = def.layer;
00176         } else {
00177             name = oc.getString("prefix") + name;
00178             type = oc.getString("type");
00179             color = c;
00180         }
00181         if (!discard) {
00182             if (oc.getBool("osm.keep-full-type")) {
00183                 type = n->myType;
00184             }
00185             bool ignorePrunning = false;
00186             if (OptionsCont::getOptions().isInStringVector("prune.keep-list", name)) {
00187                 ignorePrunning = true;
00188             }
00189             Position pos(n->lon, n->lat);
00190             if (!GeoConvHelper::getDefaultInstance().x2cartesian(pos)) {
00191                 WRITE_WARNING("Unable to project coordinates for POI '" + name + "'.");
00192             }
00193             PointOfInterest* poi = new PointOfInterest(name, type, pos, color);
00194             if (!toFill.insert(name, poi, layer, ignorePrunning)) {
00195                 WRITE_ERROR("POI '" + name + "' could not been added.");
00196                 delete poi;
00197             }
00198         }
00199     }
00200 
00201 
00202     // delete nodes
00203     for (std::map<int, PCOSMNode*>::const_iterator i=nodes.begin(); i!=nodes.end(); ++i) {
00204         delete(*i).second;
00205     }
00206     // delete edges
00207     for (std::map<std::string, PCOSMEdge*>::iterator i=edges.begin(); i!=edges.end(); ++i) {
00208         delete(*i).second;
00209     }
00210 }
00211 
00212 
00213 
00214 // ---------------------------------------------------------------------------
00215 // definitions of PCLoaderOSM::NodesHandler-methods
00216 // ---------------------------------------------------------------------------
00217 PCLoaderOSM::NodesHandler::NodesHandler(std::map<int, PCOSMNode*> &toFill) throw()
00218     : SUMOSAXHandler("osm - file"), myToFill(toFill), myLastNodeID(-1) {}
00219 
00220 
00221 PCLoaderOSM::NodesHandler::~NodesHandler() throw() {}
00222 
00223 
00224 void
00225 PCLoaderOSM::NodesHandler::myStartElement(int element, const SUMOSAXAttributes& attrs) throw(ProcessError) {
00226     myParentElements.push_back(element);
00227     if (element==SUMO_TAG_NODE) {
00228         bool ok = true;
00229         int id = attrs.getIntReporting(SUMO_ATTR_ID, 0, ok);
00230         if (!ok) {
00231             return;
00232         }
00233         myLastNodeID = -1;
00234         if (myToFill.find(id)==myToFill.end()) {
00235             myLastNodeID = id;
00236             // assume we are loading multiple files...
00237             //  ... so we won't report duplicate nodes
00238             PCOSMNode* toAdd = new PCOSMNode();
00239             toAdd->id = id;
00240             toAdd->myIsAdditional = false;
00241             bool ok = true;
00242             toAdd->lon = attrs.getSUMORealReporting(SUMO_ATTR_LON, toString(id).c_str(), ok);
00243             toAdd->lat = attrs.getSUMORealReporting(SUMO_ATTR_LAT, toString(id).c_str(), ok);
00244             if (!ok) {
00245                 delete toAdd;
00246                 return;
00247             }
00248             myToFill[toAdd->id] = toAdd;
00249         }
00250     }
00251     if (element==SUMO_TAG_TAG&&myParentElements.size()>2&&myParentElements[myParentElements.size()-2]==SUMO_TAG_NODE) {
00252         bool ok = true;
00253         std::string key = attrs.getStringReporting(SUMO_ATTR_K, toString(myLastNodeID).c_str(), ok);
00254         std::string value = attrs.getOptStringReporting(SUMO_ATTR_V, toString(myLastNodeID).c_str(), ok, "");
00255         if (!ok) {
00256             return;
00257         }
00258         if (key=="waterway"||key=="aeroway"||key=="aerialway"||key=="power"||key=="man_made"||key=="building"
00259                 ||key=="leisure"||key=="amenity"||key=="shop"||key=="tourism"||key=="historic"||key=="landuse"
00260                 ||key=="natural"||key=="military"||key=="boundary"||key=="sport"||key=="polygon") {
00261             if (myLastNodeID>=0) {
00262                 myToFill[myLastNodeID]->myType = key + "." + value;
00263                 myToFill[myLastNodeID]->myIsAdditional = true;
00264             }
00265         }
00266         if (key=="name"&&myLastNodeID!=-1) {
00267             myToFill[myLastNodeID]->myType = key + "." + value;
00268         }
00269     }
00270 }
00271 
00272 
00273 void
00274 PCLoaderOSM::NodesHandler::myEndElement(int element) throw(ProcessError) {
00275     if (element==SUMO_TAG_NODE) {
00276         myLastNodeID = -1;
00277     }
00278     myParentElements.pop_back();
00279 }
00280 
00281 
00282 // ---------------------------------------------------------------------------
00283 // definitions of PCLoaderOSM::EdgesHandler-methods
00284 // ---------------------------------------------------------------------------
00285 PCLoaderOSM::EdgesHandler::EdgesHandler(
00286     const std::map<int, PCOSMNode*> &osmNodes,
00287     std::map<std::string, PCOSMEdge*> &toFill) throw()
00288     : SUMOSAXHandler("osm - file"),
00289       myOSMNodes(osmNodes), myEdgeMap(toFill) {
00290 }
00291 
00292 
00293 PCLoaderOSM::EdgesHandler::~EdgesHandler() throw() {
00294 }
00295 
00296 
00297 void
00298 PCLoaderOSM::EdgesHandler::myStartElement(int element, const SUMOSAXAttributes& attrs) throw(ProcessError) {
00299     myParentElements.push_back(element);
00300     // parse "way" elements
00301     if (element==SUMO_TAG_WAY) {
00302         bool ok = true;
00303         std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
00304         if (!ok) {
00305             return;
00306         }
00307         myCurrentEdge = new PCOSMEdge();
00308         myCurrentEdge->id = id;
00309         myCurrentEdge->myIsAdditional = false;
00310         myCurrentEdge->myIsClosed = false;
00311     }
00312     // parse "nd" (node) elements
00313     if (element==SUMO_TAG_ND) {
00314         bool ok = true;
00315         int ref = attrs.getIntReporting(SUMO_ATTR_REF, 0, ok);
00316         if (ok) {
00317             if (myOSMNodes.find(ref)==myOSMNodes.end()) {
00318                 WRITE_WARNING("The referenced geometry information (ref='" + toString(ref) + "') is not known");
00319                 return;
00320             }
00321             myCurrentEdge->myCurrentNodes.push_back(ref);
00322         }
00323     }
00324     // parse values
00325     if (element==SUMO_TAG_TAG&&myParentElements.size()>2&&myParentElements[myParentElements.size()-2]==SUMO_TAG_WAY) {
00326         bool ok = true;
00327         std::string key = attrs.getStringReporting(SUMO_ATTR_K, toString(myCurrentEdge->id).c_str(), ok);
00328         std::string value = attrs.getStringReporting(SUMO_ATTR_V, toString(myCurrentEdge->id).c_str(), ok);
00329         if (!ok) {
00330             return;
00331         }
00332         if (key=="waterway"||key=="aeroway"||key=="aerialway"||key=="power"||key=="man_made"
00333                 ||key=="building"||key=="leisure"||key=="amenity"||key=="shop"||key=="tourism"
00334                 ||key=="historic"||key=="landuse"||key=="natural"||key=="military"||key=="boundary"
00335                 ||key=="sport"||key=="polygon") {
00336             myCurrentEdge->myType = key + "." + value;
00337             myCurrentEdge->myIsAdditional = true;
00338         } else if (key=="name") {
00339             myCurrentEdge->name = value;
00340         }
00341     }
00342 }
00343 
00344 
00345 void
00346 PCLoaderOSM::EdgesHandler::myEndElement(int element) throw(ProcessError) {
00347     myParentElements.pop_back();
00348     if (element==SUMO_TAG_WAY) {
00349         if (myCurrentEdge->myIsAdditional) {
00350             myEdgeMap[myCurrentEdge->id] = myCurrentEdge;
00351         } else {
00352             delete myCurrentEdge;
00353         }
00354         myCurrentEdge = 0;
00355     }
00356 }
00357 
00358 
00359 /****************************************************************************/
00360 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines