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 2001-2010 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/Position2D.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             MsgHandler::getErrorInstance()->inform("Could not open osm-file '" + *file + "'.");
00075             return;
00076         }
00077         MsgHandler::getMessageInstance()->beginProcessMsg("Parsing nodes from osm-file '" + *file + "'...");
00078         if (!XMLSubSys::runParser(nodesHandler, *file)) {
00079             throw ProcessError();
00080         }
00081         MsgHandler::getMessageInstance()->endProcessMsg("done.");
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         MsgHandler::getMessageInstance()->beginProcessMsg("Parsing edges from osm-file '" + *file + "'...");
00089         XMLSubSys::runParser(edgesHandler, *file);
00090         MsgHandler::getMessageInstance()->endProcessMsg("done.");
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         Position2DVector vec;
00102         for (std::vector<int>::iterator j=e->myCurrentNodes.begin(); j!=e->myCurrentNodes.end(); ++j) {
00103             PCOSMNode *n = nodes.find(*j)->second;
00104             Position2D pos(n->lon, n->lat);
00105             if (!GeoConvHelper::x2cartesian(pos)) {
00106                 MsgHandler::getWarningInstance()->inform("Unable to project coordinates for polygon '" + e->id + "'.");
00107             }
00108             vec.push_back_noDoublePos(pos);
00109         }
00110         // set type etc.
00111         std::string name = e->id;
00112         std::string type;
00113         RGBColor color;
00114         bool fill = vec.getBegin()==vec.getEnd();
00115         bool discard = false;
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             Polygon2D *poly = new Polygon2D(name, type, color, vec, fill);
00143             if (!toFill.insert(name, poly, layer)) {
00144                 MsgHandler::getErrorInstance()->inform("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 = false;
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.ignore", name)) {
00187                 ignorePrunning = true;
00188             }
00189             Position2D pos(n->lon, n->lat);
00190             if (!GeoConvHelper::x2cartesian(pos)) {
00191                 MsgHandler::getWarningInstance()->inform("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                 MsgHandler::getErrorInstance()->inform("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(SumoXMLTag 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, "node", 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, "node", toString(id).c_str(), ok);
00243             toAdd->lat = attrs.getSUMORealReporting(SUMO_ATTR_LAT, "node", 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, "node", toString(myLastNodeID).c_str(), ok);
00254         std::string value = attrs.getStringReporting(SUMO_ATTR_V, "node", 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"||key=="leisure"||key=="amenity"||key=="shop"
00259                 ||key=="tourism"||key=="historic"||key=="landuse"||key=="natural"||key=="military"||key=="boundary"||key=="sport") {
00260             if (myLastNodeID>=0) {
00261                 myToFill[myLastNodeID]->myType = key + "." + value;
00262                 myToFill[myLastNodeID]->myIsAdditional = true;
00263             }
00264         }
00265     }
00266 }
00267 
00268 
00269 void
00270 PCLoaderOSM::NodesHandler::myEndElement(SumoXMLTag element) throw(ProcessError) {
00271     if (element==SUMO_TAG_NODE) {
00272         myLastNodeID = -1;
00273     }
00274     myParentElements.pop_back();
00275 }
00276 
00277 
00278 // ---------------------------------------------------------------------------
00279 // definitions of PCLoaderOSM::EdgesHandler-methods
00280 // ---------------------------------------------------------------------------
00281 PCLoaderOSM::EdgesHandler::EdgesHandler(
00282     const std::map<int, PCOSMNode*> &osmNodes,
00283     std::map<std::string, PCOSMEdge*> &toFill) throw()
00284         : SUMOSAXHandler("osm - file"),
00285         myOSMNodes(osmNodes), myEdgeMap(toFill) {
00286 }
00287 
00288 
00289 PCLoaderOSM::EdgesHandler::~EdgesHandler() throw() {
00290 }
00291 
00292 
00293 void
00294 PCLoaderOSM::EdgesHandler::myStartElement(SumoXMLTag element, const SUMOSAXAttributes &attrs) throw(ProcessError) {
00295     myParentElements.push_back(element);
00296     // parse "way" elements
00297     if (element==SUMO_TAG_WAY) {
00298         bool ok = true;
00299         std::string id = attrs.getStringReporting(SUMO_ATTR_ID, "way", 0, ok);
00300         if (!ok) {
00301             return;
00302         }
00303         myCurrentEdge = new PCOSMEdge();
00304         myCurrentEdge->id = id;
00305         myCurrentEdge->myIsAdditional = false;
00306         myCurrentEdge->myIsClosed = false;
00307     }
00308     // parse "nd" (node) elements
00309     if (element==SUMO_TAG_ND) {
00310         bool ok = true;
00311         int ref = attrs.getIntReporting(SUMO_ATTR_REF, "nd", 0, ok);
00312         if (ok) {
00313             if (myOSMNodes.find(ref)==myOSMNodes.end()) {
00314                 MsgHandler::getErrorInstance()->inform("The referenced geometry information (ref='" + toString(ref) + "') is not known");
00315                 return;
00316             }
00317             myCurrentEdge->myCurrentNodes.push_back(ref);
00318         }
00319     }
00320     // parse values
00321     if (element==SUMO_TAG_TAG&&myParentElements.size()>2&&myParentElements[myParentElements.size()-2]==SUMO_TAG_WAY) {
00322         bool ok = true;
00323         std::string key = attrs.getStringReporting(SUMO_ATTR_K, "way", toString(myCurrentEdge->id).c_str(), ok);
00324         std::string value = attrs.getStringReporting(SUMO_ATTR_V, "way", toString(myCurrentEdge->id).c_str(), ok);
00325         if (!ok) {
00326             return;
00327         }
00328         if (key=="waterway"||key=="aeroway"||key=="aerialway"||key=="power"||key=="man_made"||key=="building"||key=="leisure"||key=="amenity"||key=="shop"
00329                 ||key=="tourism"||key=="historic"||key=="landuse"||key=="natural"||key=="military"||key=="boundary"||key=="sport") {
00330             myCurrentEdge->myType = key + "." + value;
00331             myCurrentEdge->myIsAdditional = true;
00332         } else if (key=="area") {
00333             myCurrentEdge->myIsClosed = true;
00334         }
00335     }
00336 }
00337 
00338 
00339 void
00340 PCLoaderOSM::EdgesHandler::myEndElement(SumoXMLTag element) throw(ProcessError) {
00341     myParentElements.pop_back();
00342     if (element==SUMO_TAG_WAY) {
00343         if (myCurrentEdge->myIsAdditional) {
00344             myEdgeMap[myCurrentEdge->id] = myCurrentEdge;
00345         } else {
00346             delete myCurrentEdge;
00347         }
00348         myCurrentEdge = 0;
00349     }
00350 }
00351 
00352 
00353 /****************************************************************************/
00354 

Generated on Wed May 5 00:06:35 2010 for Sumo - Simulation of Urban MObility by  doxygen 1.5.6