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 #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
00056
00057
00058
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
00067 std::vector<std::string> files = oc.getStringVector("osm-files");
00068
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
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
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
00088 MsgHandler::getMessageInstance()->beginProcessMsg("Parsing edges from osm-file '" + *file + "'...");
00089 XMLSubSys::runParser(edgesHandler, *file);
00090 MsgHandler::getMessageInstance()->endProcessMsg("done.");
00091 }
00092
00093 RGBColor c = RGBColor::parseColor(oc.getString("color"));
00094
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
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
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
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
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
00203 for (std::map<int, PCOSMNode*>::const_iterator i=nodes.begin(); i!=nodes.end(); ++i) {
00204 delete(*i).second;
00205 }
00206
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
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
00237
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
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
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
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
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