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/StringTokenizer.h>
00034 #include <utils/common/UtilExceptions.h>
00035 #include <utils/common/MsgHandler.h>
00036 #include <utils/common/StringUtils.h>
00037 #include <utils/common/TplConvert.h>
00038 #include <utils/common/ToString.h>
00039 #include <utils/common/FileHelpers.h>
00040 #include <utils/options/OptionsCont.h>
00041 #include <utils/options/Option.h>
00042 #include <utils/importio/LineReader.h>
00043 #include <utils/common/StdDefs.h>
00044 #include <polyconvert/PCPolyContainer.h>
00045 #include "PCLoaderVisum.h"
00046 #include <utils/common/RGBColor.h>
00047 #include <utils/geom/GeomHelper.h>
00048 #include <utils/geom/Boundary.h>
00049 #include <utils/geom/Position2D.h>
00050 #include <utils/geom/GeoConvHelper.h>
00051 #include <utils/importio/NamedColumnsParser.h>
00052
00053 #ifdef CHECK_MEMORY_LEAKS
00054 #include <foreign/nvwa/debug_new.h>
00055 #endif // CHECK_MEMORY_LEAKS
00056
00057
00058
00059
00060
00061 void
00062 PCLoaderVisum::loadIfSet(OptionsCont &oc, PCPolyContainer &toFill,
00063 PCTypeMap &tm) throw(ProcessError) {
00064 if (!oc.isSet("visum-files")) {
00065 return;
00066 }
00067
00068 std::vector<std::string> files = oc.getStringVector("visum-files");
00069 for (std::vector<std::string>::const_iterator file=files.begin(); file!=files.end(); ++file) {
00070 if (!FileHelpers::exists(*file)) {
00071 throw ProcessError("Could not open visum-file '" + *file + "'.");
00072 }
00073 MsgHandler::getMessageInstance()->beginProcessMsg("Parsing from visum-file '" + *file + "'...");
00074 load(*file, oc, toFill, tm);
00075 MsgHandler::getMessageInstance()->endProcessMsg("done.");
00076 }
00077 }
00078
00079
00080
00081 void
00082 PCLoaderVisum::load(const std::string &file, OptionsCont &oc, PCPolyContainer &toFill,
00083 PCTypeMap &tm) throw(ProcessError) {
00084 std::string what;
00085 std::map<long, Position2D> punkte;
00086 std::map<long, Position2DVector> kanten;
00087 std::map<long, Position2DVector> teilflaechen;
00088 std::map<long, long> flaechenelemente;
00089 NamedColumnsParser lineParser;
00090 LineReader lr(file);
00091 while (lr.hasMore()) {
00092 std::string line = lr.readLine();
00093
00094 if (line.length()==0||line[0]=='*'||line[0]=='$') {
00095 what = "";
00096 }
00097
00098 if (what=="$PUNKT") {
00099 lineParser.parseLine(line);
00100 long id = TplConvert<char>::_2long(lineParser.get("ID").c_str());
00101 SUMOReal x = TplConvert<char>::_2SUMOReal(lineParser.get("XKOORD").c_str());
00102 SUMOReal y = TplConvert<char>::_2SUMOReal(lineParser.get("YKOORD").c_str());
00103 Position2D pos(x, y);
00104 if (!GeoConvHelper::x2cartesian(pos)) {
00105 MsgHandler::getWarningInstance()->inform("Unable to project coordinates for point '" + toString(id) + "'.");
00106 }
00107 punkte[id] = pos;
00108 continue;
00109 } else if (what=="$KANTE") {
00110 lineParser.parseLine(line);
00111 long id = TplConvert<char>::_2long(lineParser.get("ID").c_str());
00112 long fromID = TplConvert<char>::_2long(lineParser.get("VONPUNKTID").c_str());
00113 long toID = TplConvert<char>::_2long(lineParser.get("NACHPUNKTID").c_str());
00114 Position2DVector vec;
00115 vec.push_back(punkte[fromID]);
00116 vec.push_back(punkte[toID]);
00117 kanten[id] = vec;
00118 continue;
00119 } else if (what=="$ZWISCHENPUNKT") {
00120 lineParser.parseLine(line);
00121 long id = TplConvert<char>::_2long(lineParser.get("KANTEID").c_str());
00122 int index = TplConvert<char>::_2int(lineParser.get("INDEX").c_str());
00123 SUMOReal x = TplConvert<char>::_2SUMOReal(lineParser.get("XKOORD").c_str());
00124 SUMOReal y = TplConvert<char>::_2SUMOReal(lineParser.get("YKOORD").c_str());
00125 Position2D pos(x, y);
00126 if (!GeoConvHelper::x2cartesian(pos)) {
00127 MsgHandler::getWarningInstance()->inform("Unable to project coordinates for edge '" + toString(id) + "'.");
00128 }
00129 kanten[id].insertAt(index, pos);
00130 continue;
00131 } else if (what=="$TEILFLAECHENELEMENT") {
00132 lineParser.parseLine(line);
00133 long id = TplConvert<char>::_2long(lineParser.get("TFLAECHEID").c_str());
00134 int index = TplConvert<char>::_2int(lineParser.get("INDEX").c_str());
00135 index = 0;
00136 long kid = TplConvert<char>::_2long(lineParser.get("KANTEID").c_str());
00137 int dir = TplConvert<char>::_2int(lineParser.get("RICHTUNG").c_str());
00138 if (teilflaechen.find(id)==teilflaechen.end()) {
00139 teilflaechen[id] = Position2DVector();
00140 }
00141 if (dir==0) {
00142 for (int i=0; i<(int) kanten[kid].size(); ++i) {
00143 teilflaechen[id].push_back_noDoublePos(kanten[kid][i]);
00144 }
00145 } else {
00146 for (int i=(int) kanten[kid].size()-1; i>=0; --i) {
00147 teilflaechen[id].push_back_noDoublePos(kanten[kid][i]);
00148 }
00149 }
00150 continue;
00151 } else if (what=="$FLAECHENELEMENT") {
00152 lineParser.parseLine(line);
00153 long id = TplConvert<char>::_2long(lineParser.get("FLAECHEID").c_str());
00154 long tid = TplConvert<char>::_2long(lineParser.get("TFLAECHEID").c_str());
00155 int enklave = TplConvert<char>::_2int(lineParser.get("ENKLAVE").c_str());
00156 enklave = 0;
00157 flaechenelemente[id] = tid;
00158 continue;
00159 }
00160
00161 if (line[0]=='$') {
00162 what = "";
00163 if (line.find("$PUNKT")==0) {
00164 what = "$PUNKT";
00165 } else if (line.find("$KANTE")==0) {
00166 what = "$KANTE";
00167 } else if (line.find("$ZWISCHENPUNKT")==0) {
00168 what = "$ZWISCHENPUNKT";
00169 } else if (line.find("$TEILFLAECHENELEMENT")==0) {
00170 what = "$TEILFLAECHENELEMENT";
00171 } else if (line.find("$FLAECHENELEMENT")==0) {
00172 what = "$FLAECHENELEMENT";
00173 }
00174 if (what!="") {
00175 lineParser.reinit(line.substr(what.length()+1));
00176 }
00177 }
00178 }
00179
00180
00181 RGBColor c = RGBColor::parseColor(oc.getString("color"));
00182 std::map<std::string, std::string> typemap;
00183
00184 lr.reinit();
00185 bool parsingCategories = false;
00186 bool parsingPOIs = false;
00187 bool parsingDistrictsDirectly = false;
00188 Position2DVector vec;
00189 std::string polyType, lastID;
00190 bool first = true;
00191 while (lr.hasMore()) {
00192 std::string line = lr.readLine();
00193
00194 if (line.length()==0) {
00195 continue;
00196 }
00197
00198 if (line[0]=='*') {
00199 continue;
00200 }
00201
00202 if (line[0]=='$') {
00203
00204 parsingCategories = false;
00205 parsingPOIs = false;
00206 parsingDistrictsDirectly = false;
00207 polyType = "";
00208 }
00209
00210 if (parsingCategories) {
00211
00212 StringTokenizer st(line, ";");
00213 std::string catid = st.next();
00214 std::string catname = st.next();
00215 typemap[catid] = catname;
00216 }
00217 if (parsingPOIs) {
00218
00219
00220 StringTokenizer st(line, ";");
00221 std::string num = st.next();
00222 std::string catid = st.next();
00223 std::string code = st.next();
00224 std::string name = st.next();
00225 std::string comment = st.next();
00226 std::string xpos = st.next();
00227 std::string ypos = st.next();
00228
00229 SUMOReal x = TplConvert<char>::_2SUMOReal(xpos.c_str());
00230 SUMOReal y = TplConvert<char>::_2SUMOReal(ypos.c_str());
00231 Position2D pos(x, y);
00232 if (!GeoConvHelper::x2cartesian(pos)) {
00233 MsgHandler::getWarningInstance()->inform("Unable to project coordinates for POI '" + num + "'.");
00234 }
00235 std::string type = typemap[catid];
00236
00237 name = num;
00238
00239 bool discard = false;
00240 int layer = oc.getInt("layer");
00241 RGBColor color;
00242 if (tm.has(type)) {
00243 const PCTypeMap::TypeDef &def = tm.get(type);
00244 name = def.prefix + name;
00245 type = def.id;
00246 color = RGBColor::parseColor(def.color);
00247 discard = def.discard;
00248 layer = def.layer;
00249 } else {
00250 name = oc.getString("prefix") + name;
00251 type = oc.getString("type");
00252 color = c;
00253 }
00254 if (!discard) {
00255 PointOfInterest *poi = new PointOfInterest(name, type, pos, color);
00256 if (!toFill.insert(name, poi, layer)) {
00257 MsgHandler::getErrorInstance()->inform("POI '" + name + "' could not been added.");
00258 delete poi;
00259 }
00260 }
00261 }
00262
00263
00264 if (polyType!="") {
00265 StringTokenizer st(line, ";");
00266 std::string id = st.next();
00267 std::string type;
00268 if (!first&&lastID!=id) {
00269
00270 RGBColor color;
00271 int layer = oc.getInt("layer");
00272 bool discard = false;
00273 if (tm.has(polyType)) {
00274 const PCTypeMap::TypeDef &def = tm.get(polyType);
00275 id = def.prefix + id;
00276 type = def.id;
00277 color = RGBColor::parseColor(def.color);
00278 discard = def.discard;
00279 layer = def.layer;
00280 } else {
00281 id = oc.getString("prefix") + id;
00282 type = oc.getString("type");
00283 color = c;
00284 }
00285 if (!discard) {
00286 Polygon2D *poly = new Polygon2D(id, type, color, vec, false);
00287 if (!toFill.insert(id, poly, 1)) {
00288 MsgHandler::getErrorInstance()->inform("Polygon '" + id + "' could not been added.");
00289 delete poly;
00290 }
00291 }
00292 vec.clear();
00293 }
00294 lastID = id;
00295 first = false;
00296
00297 std::string index = st.next();
00298 std::string xpos = st.next();
00299 std::string ypos = st.next();
00300 Position2D pos2D((SUMOReal) atof(xpos.c_str()), (SUMOReal) atof(ypos.c_str()));
00301 if (!GeoConvHelper::x2cartesian(pos2D)) {
00302 MsgHandler::getWarningInstance()->inform("Unable to project coordinates for polygon '" + id + "'.");
00303 }
00304 vec.push_back(pos2D);
00305 }
00306
00307
00308 if (parsingDistrictsDirectly) {
00309
00310 StringTokenizer st(line, ";");
00311 std::string num = st.next();
00312 std::string code = st.next();
00313 std::string name = st.next();
00314 st.next();
00315 std::string xpos = st.next();
00316 std::string ypos = st.next();
00317 long id = TplConvert<char>::_2long(st.next().c_str());
00318
00319 std::string type = "district";
00320 name = num;
00321 bool discard = false;
00322 int layer = oc.getInt("layer");
00323 RGBColor color;
00324 if (tm.has(type)) {
00325 const PCTypeMap::TypeDef &def = tm.get(type);
00326 name = def.prefix + name;
00327 type = def.id;
00328 color = RGBColor::parseColor(def.color);
00329 discard = def.discard;
00330 layer = def.layer;
00331 } else {
00332 name = oc.getString("prefix") + name;
00333 type = oc.getString("type");
00334 color = c;
00335 }
00336 if (!discard) {
00337 if (teilflaechen[flaechenelemente[id]].size()>0) {
00338 Polygon2D *poly = new Polygon2D(name, type, color, teilflaechen[flaechenelemente[id]], false);
00339 if (!toFill.insert(name, poly, layer)) {
00340 MsgHandler::getErrorInstance()->inform("Polygon '" + name + "' could not been added.");
00341 delete poly;
00342 }
00343 } else {
00344 SUMOReal x = TplConvert<char>::_2SUMOReal(xpos.c_str());
00345 SUMOReal y = TplConvert<char>::_2SUMOReal(ypos.c_str());
00346 Position2D pos(x, y);
00347 if (!GeoConvHelper::x2cartesian(pos)) {
00348 MsgHandler::getWarningInstance()->inform("Unable to project coordinates for POI '" + name + "'.");
00349 }
00350 PointOfInterest *poi = new PointOfInterest(name, type, pos, color);
00351 if (!toFill.insert(name, poi, layer)) {
00352 MsgHandler::getErrorInstance()->inform("POI '" + name + "' could not been added.");
00353 delete poi;
00354 }
00355 }
00356 }
00357 }
00358
00359
00360 if (line.find("$POIKATEGORIEDEF:")==0||line.find("$POIKATEGORIE:")==0) {
00361
00362 parsingCategories = true;
00363 }
00364 if (line.find("$POI:")==0) {
00365
00366 parsingPOIs = true;
00367 }
00368 if (line.find("$BEZIRK")==0 && line.find("FLAECHEID")!=std::string::npos) {
00369
00370 parsingDistrictsDirectly = true;
00371 }
00372
00373
00374 if (line.find("$BEZIRKPOLY")!=std::string::npos) {
00375 polyType = "district";
00376 }
00377 if (line.find("$GEBIETPOLY")!=std::string::npos) {
00378 polyType = "area";
00379 }
00380
00381 }
00382 }
00383
00384
00385
00386
00387