LCOV - code coverage report
Current view: top level - src/polyconvert - PCLoaderVisum.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 1.4 % 208 3
Test Date: 2026-03-02 16:00:03 Functions: 33.3 % 3 1

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2001-2026 German Aerospace Center (DLR) and others.
       4              : // This program and the accompanying materials are made available under the
       5              : // terms of the Eclipse Public License 2.0 which is available at
       6              : // https://www.eclipse.org/legal/epl-2.0/
       7              : // This Source Code may also be made available under the following Secondary
       8              : // Licenses when the conditions for such availability set forth in the Eclipse
       9              : // Public License 2.0 are satisfied: GNU General Public License, version 2
      10              : // or later which is available at
      11              : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
      12              : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
      13              : /****************************************************************************/
      14              : /// @file    PCLoaderVisum.cpp
      15              : /// @author  Daniel Krajzewicz
      16              : /// @author  Jakob Erdmann
      17              : /// @author  Christoph Sommer
      18              : /// @author  Michael Behrisch
      19              : /// @date    Thu, 02.11.2006
      20              : ///
      21              : // A reader of pois and polygons stored in VISUM-format
      22              : /****************************************************************************/
      23              : #include <config.h>
      24              : 
      25              : #include <string>
      26              : #include <map>
      27              : #include <fstream>
      28              : #include <utils/common/StringTokenizer.h>
      29              : #include <utils/common/UtilExceptions.h>
      30              : #include <utils/common/MsgHandler.h>
      31              : #include <utils/common/StringUtils.h>
      32              : #include <utils/common/StringUtils.h>
      33              : #include <utils/common/ToString.h>
      34              : #include <utils/common/FileHelpers.h>
      35              : #include <utils/options/OptionsCont.h>
      36              : #include <utils/options/Option.h>
      37              : #include <utils/importio/LineReader.h>
      38              : #include <utils/common/StdDefs.h>
      39              : #include <polyconvert/PCPolyContainer.h>
      40              : #include "PCLoaderVisum.h"
      41              : #include <utils/common/RGBColor.h>
      42              : #include <utils/geom/GeomHelper.h>
      43              : #include <utils/geom/Boundary.h>
      44              : #include <utils/geom/Position.h>
      45              : #include <utils/geom/GeoConvHelper.h>
      46              : #include <utils/importio/NamedColumnsParser.h>
      47              : 
      48              : StringBijection<PCLoaderVisum::VISUM_KEY>::Entry PCLoaderVisum::KEYS_DE[] = {
      49              :     // duplicates NIImporter_VISUM::KEYS_DE due to lack of suitable common location
      50              :     { "VSYS", VISUM_SYS },
      51              :     { "STRECKENTYP", VISUM_LINKTYPE },
      52              :     { "KNOTEN", VISUM_NODE },
      53              :     { "BEZIRK", VISUM_DISTRICT },
      54              :     { "PUNKT", VISUM_POINT },
      55              :     { "STRECKE", VISUM_LINK },
      56              :     { "V0IV", VISUM_V0 },
      57              :     { "VSYSSET", VISUM_TYPES },
      58              :     { "RANG", VISUM_RANK },
      59              :     { "KAPIV", VISUM_CAPACITY },
      60              :     { "XKOORD", VISUM_XCOORD },
      61              :     { "YKOORD", VISUM_YCOORD },
      62              :     { "ID", VISUM_ID },
      63              :     { "CODE", VISUM_CODE },
      64              :     { "VONKNOTNR", VISUM_FROMNODE },
      65              :     { "NACHKNOTNR", VISUM_TONODE },
      66              :     { "TYPNR", VISUM_TYPE },
      67              :     { "TYP", VISUM_TYP },
      68              :     { "ANBINDUNG", VISUM_DISTRICT_CONNECTION },
      69              :     { "BEZNR", VISUM_SOURCE_DISTRICT },
      70              :     { "KNOTNR",  VISUM_FROMNODENO },
      71              :     { "RICHTUNG",  VISUM_DIRECTION },
      72              :     { "FLAECHEID",  VISUM_SURFACEID },
      73              :     { "TFLAECHEID",  VISUM_FACEID },
      74              :     { "VONPUNKTID",  VISUM_FROMPOINTID },
      75              :     { "NACHPUNKTID",  VISUM_TOPOINTID },
      76              :     { "KANTE",  VISUM_EDGE },
      77              :     { "ABBIEGER",  VISUM_TURN },
      78              :     { "UEBERKNOTNR",  VISUM_VIANODENO },
      79              :     { "ANZFAHRSTREIFEN",  VISUM_NUMLANES },
      80              :     { "INDEX",  VISUM_INDEX },
      81              :     { "STRECKENPOLY",  VISUM_LINKPOLY },
      82              :     { "FLAECHENELEMENT",  VISUM_SURFACEITEM },
      83              :     { "TEILFLAECHENELEMENT",  VISUM_FACEITEM },
      84              :     { "KANTEID",  VISUM_EDGEID },
      85              :     { "Q",  VISUM_ORIGIN },
      86              :     { "Z",  VISUM_DESTINATION },
      87              :     { "KATNR", VISUM_CATID },
      88              :     { "ZWISCHENPUNKT", VISUM_EDGEITEM },
      89              :     { "POIKATEGORIE", VISUM_POICATEGORY },
      90              :     { "NETZ", VISUM_NETWORK },
      91              :     { "DEFKOORD", VISUM_PROJECTIONDEFINITION },
      92              :     { "NR", VISUM_NO } // must be the last one
      93              : };
      94              : 
      95              : 
      96              : StringBijection<PCLoaderVisum::VISUM_KEY> PCLoaderVisum::KEYS(PCLoaderVisum::KEYS_DE, VISUM_NO);
      97              : 
      98              : 
      99              : // ===========================================================================
     100              : // method definitions
     101              : // ===========================================================================
     102              : void
     103           44 : PCLoaderVisum::loadIfSet(OptionsCont& oc, PCPolyContainer& toFill,
     104              :                          PCTypeMap& tm) {
     105           88 :     if (!oc.isSet("visum-files")) {
     106           44 :         return;
     107              :     }
     108            0 :     const std::string languageFile = oc.getString("visum.language-file");
     109            0 :     if (languageFile != "") {
     110            0 :         loadLanguage(languageFile);
     111              :     }
     112              :     // parse file(s)
     113            0 :     std::vector<std::string> files = oc.getStringVector("visum-files");
     114            0 :     for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
     115            0 :         if (!FileHelpers::isReadable(*file)) {
     116            0 :             throw ProcessError(TLF("Could not open visum-file '%'.", *file));
     117              :         }
     118            0 :         PROGRESS_BEGIN_MESSAGE("Parsing from visum-file '" + *file + "'");
     119            0 :         load(*file, oc, toFill, tm);
     120            0 :         PROGRESS_DONE_MESSAGE();
     121              :     }
     122            0 : }
     123              : 
     124              : 
     125              : 
     126              : void
     127            0 : PCLoaderVisum::load(const std::string& file, OptionsCont& oc, PCPolyContainer& toFill,
     128              :                     PCTypeMap& tm) {
     129              :     GeoConvHelper& geoConvHelper = GeoConvHelper::getProcessing();
     130              :     std::string what;
     131              :     std::map<long long int, Position> punkte;
     132              :     std::map<long long int, PositionVector> kanten;
     133              :     std::map<long long int, PositionVector> teilflaechen;
     134              :     std::map<long long int, long long int> flaechenelemente;
     135            0 :     NamedColumnsParser lineParser;
     136            0 :     LineReader lr(file);
     137            0 :     while (lr.hasMore()) {
     138            0 :         std::string line = lr.readLine();
     139              :         // reset if current is over
     140            0 :         if (line.length() == 0 || line[0] == '*' || line[0] == '$') {
     141              :             what = "";
     142              :         }
     143              :         // read items
     144            0 :         if (what == "$" + KEYS.getString(VISUM_POINT)) {
     145            0 :             lineParser.parseLine(line);
     146            0 :             long long int id = StringUtils::toLong(lineParser.get(KEYS.getString(VISUM_ID)));
     147            0 :             double x = StringUtils::toDouble(lineParser.get(KEYS.getString(VISUM_XCOORD)));
     148            0 :             double y = StringUtils::toDouble(lineParser.get(KEYS.getString(VISUM_YCOORD)));
     149              :             Position pos(x, y);
     150            0 :             if (!geoConvHelper.x2cartesian(pos)) {
     151            0 :                 WRITE_WARNINGF(TL("Unable to project coordinates for point '%'."), toString(id));
     152              :             }
     153            0 :             punkte[id] = pos;
     154              :             continue;
     155            0 :         } else if (what == "$" + KEYS.getString(VISUM_EDGE)) {
     156            0 :             lineParser.parseLine(line);
     157            0 :             long long int id = StringUtils::toLong(lineParser.get(KEYS.getString(VISUM_ID)));
     158            0 :             long long int fromID = StringUtils::toLong(lineParser.get(KEYS.getString(VISUM_FROMPOINTID)));
     159            0 :             long long int toID = StringUtils::toLong(lineParser.get(KEYS.getString(VISUM_TOPOINTID)));
     160            0 :             PositionVector vec;
     161            0 :             vec.push_back(punkte[fromID]);
     162            0 :             vec.push_back(punkte[toID]);
     163            0 :             kanten[id] = vec;
     164              :             continue;
     165            0 :         } else if (what == "$" + KEYS.getString(VISUM_EDGEITEM)) {
     166            0 :             lineParser.parseLine(line);
     167            0 :             long long int id = StringUtils::toLong(lineParser.get(KEYS.getString(VISUM_EDGEID)));
     168            0 :             int index = StringUtils::toInt(lineParser.get(KEYS.getString(VISUM_INDEX)));
     169            0 :             double x = StringUtils::toDouble(lineParser.get(KEYS.getString(VISUM_XCOORD)));
     170            0 :             double y = StringUtils::toDouble(lineParser.get(KEYS.getString(VISUM_YCOORD)));
     171              :             Position pos(x, y);
     172            0 :             if (!geoConvHelper.x2cartesian(pos)) {
     173            0 :                 WRITE_WARNINGF(TL("Unable to project coordinates for edge '%'."), toString(id));
     174              :             }
     175            0 :             kanten[id].insert(kanten[id].begin() + index, pos);
     176              :             continue;
     177            0 :         } else if (what == "$" + KEYS.getString(VISUM_FACEITEM)) {
     178            0 :             lineParser.parseLine(line);
     179            0 :             long long int id = StringUtils::toLong(lineParser.get(KEYS.getString(VISUM_FACEID)));
     180              :             //int index = StringUtils::toInt(lineParser.get("INDEX"));
     181              :             //index = 0; /// hmmmm - assume it's sorted...
     182            0 :             long long int kid = StringUtils::toLong(lineParser.get(KEYS.getString(VISUM_EDGEID)));
     183            0 :             int dir = StringUtils::toInt(lineParser.get(KEYS.getString(VISUM_DIRECTION)));
     184            0 :             if (teilflaechen.find(id) == teilflaechen.end()) {
     185            0 :                 teilflaechen[id] = PositionVector();
     186              :             }
     187            0 :             if (dir == 0) {
     188            0 :                 for (int i = 0; i < (int) kanten[kid].size(); ++i) {
     189            0 :                     teilflaechen[id].push_back_noDoublePos(kanten[kid][i]);
     190              :                 }
     191              :             } else {
     192            0 :                 for (int i = (int) kanten[kid].size() - 1; i >= 0; --i) {
     193            0 :                     teilflaechen[id].push_back_noDoublePos(kanten[kid][i]);
     194              :                 }
     195              :             }
     196              :             continue;
     197            0 :         } else if (what == "$" + KEYS.getString(VISUM_SURFACEITEM)) {
     198            0 :             lineParser.parseLine(line);
     199            0 :             long long int id = StringUtils::toLong(lineParser.get(KEYS.getString(VISUM_SURFACEID)));
     200            0 :             long long int tid = StringUtils::toLong(lineParser.get(KEYS.getString(VISUM_FACEID)));
     201            0 :             flaechenelemente[id] = tid;
     202              :             continue;
     203            0 :         }
     204              :         // set if read
     205            0 :         if (line[0] == '$') {
     206              :             what = "";
     207            0 :             if (line.find("$" + KEYS.getString(VISUM_POINT) + ":") == 0) {
     208            0 :                 what = "$" + KEYS.getString(VISUM_POINT);
     209            0 :             } else if (line.find("$" + KEYS.getString(VISUM_EDGE) + ":") == 0) {
     210            0 :                 what = "$" + KEYS.getString(VISUM_EDGE);
     211            0 :             } else if (line.find("$" + KEYS.getString(VISUM_EDGEITEM) + ":") == 0) {
     212            0 :                 what = "$" + KEYS.getString(VISUM_EDGEITEM);
     213            0 :             } else if (line.find("$" + KEYS.getString(VISUM_FACEITEM) + ":") == 0) {
     214            0 :                 what = "$" + KEYS.getString(VISUM_FACEITEM);
     215            0 :             } else if (line.find("$" + KEYS.getString(VISUM_SURFACEITEM) + ":") == 0) {
     216            0 :                 what = "$" + KEYS.getString(VISUM_SURFACEITEM);
     217              :             }
     218            0 :             if (what != "") {
     219            0 :                 lineParser.reinit(line.substr(what.length() + 1));
     220              :             }
     221              :         }
     222              :     }
     223              : 
     224              :     // do some more sane job...
     225            0 :     RGBColor c = RGBColor::parseColor(oc.getString("color"));
     226              :     std::map<std::string, std::string> typemap;
     227              :     // load the pois/polys
     228            0 :     lr.reinit();
     229              :     bool parsingCategories = false;
     230              :     bool parsingPOIs = false;
     231              :     bool parsingDistrictsDirectly = false;
     232            0 :     PositionVector vec;
     233              :     std::string polyType, lastID;
     234              :     bool first = true;
     235            0 :     while (lr.hasMore()) {
     236            0 :         std::string line = lr.readLine();
     237              :         // do not parse empty lines
     238            0 :         if (line.length() == 0) {
     239            0 :             continue;
     240              :         }
     241              :         // do not parse comment lines
     242            0 :         if (line[0] == '*') {
     243            0 :             continue;
     244              :         }
     245              : 
     246            0 :         if (line[0] == '$') {
     247              :             // reset parsing on new entry type
     248              :             parsingCategories = false;
     249              :             parsingPOIs = false;
     250              :             parsingDistrictsDirectly = false;
     251              :             polyType = "";
     252              :         }
     253              : 
     254            0 :         if (parsingCategories) {
     255              :             // parse the category
     256            0 :             StringTokenizer st(line, ";");
     257            0 :             std::string catid = st.next();
     258            0 :             std::string catname = st.next();
     259            0 :             typemap[catid] = catname;
     260            0 :         }
     261            0 :         if (parsingPOIs) {
     262              :             // parse the poi
     263              :             // $POI:Nr;CATID;CODE;NAME;Kommentar;XKoord;YKoord;
     264            0 :             lineParser.parseLine(line);
     265            0 :             long long int idL = StringUtils::toLong(lineParser.get(KEYS.getString(VISUM_NO)));
     266            0 :             std::string id = toString(idL);
     267            0 :             std::string catid = lineParser.get(KEYS.getString(VISUM_CATID));
     268              :             // process read values
     269            0 :             double x = StringUtils::toDouble(lineParser.get(KEYS.getString(VISUM_XCOORD)));
     270            0 :             double y = StringUtils::toDouble(lineParser.get(KEYS.getString(VISUM_YCOORD)));
     271              :             Position pos(x, y);
     272            0 :             if (!geoConvHelper.x2cartesian(pos)) {
     273            0 :                 WRITE_WARNINGF(TL("Unable to project coordinates for POI '%'."), id);
     274              :             }
     275            0 :             std::string type = typemap[catid];
     276              :             // patch the values
     277            0 :             bool discard = oc.getBool("discard");
     278            0 :             std::string icon = oc.getString("icon");
     279            0 :             double layer = oc.getFloat("layer");
     280            0 :             RGBColor color;
     281            0 :             if (tm.has(type)) {
     282            0 :                 const PCTypeMap::TypeDef& def = tm.get(type);
     283            0 :                 id = def.prefix + id;
     284            0 :                 type = def.id;
     285            0 :                 color = def.color;
     286            0 :                 discard = def.discard;
     287            0 :                 icon = def.icon;
     288            0 :                 layer = def.layer;
     289              :             } else {
     290            0 :                 id = oc.getString("prefix") + id;
     291            0 :                 color = c;
     292              :             }
     293            0 :             if (!discard) {
     294              :                 const std::string origId = id;
     295              :                 int index = 1;
     296            0 :                 while (toFill.getPOIs().get(id) != nullptr) {
     297            0 :                     id = origId + "#" + toString(index++);
     298              :                 }
     299            0 :                 PointOfInterest* poi = new PointOfInterest(id, type, color, pos, false, "", 0, false, 0, icon, layer);
     300            0 :                 toFill.add(poi);
     301              :             }
     302              :         }
     303              : 
     304              :         // poly
     305            0 :         if (polyType != "") {
     306            0 :             StringTokenizer st(line, ";");
     307            0 :             std::string id = st.next();
     308              :             std::string type;
     309            0 :             if (!first && lastID != id) {
     310              :                 // we have parsed a polygon completely
     311            0 :                 RGBColor color;
     312            0 :                 double layer = oc.getFloat("layer");
     313            0 :                 bool discard = oc.getBool("discard");
     314            0 :                 if (tm.has(polyType)) {
     315            0 :                     const PCTypeMap::TypeDef& def = tm.get(polyType);
     316            0 :                     id = def.prefix + id;
     317            0 :                     type = def.id;
     318            0 :                     color = def.color;
     319            0 :                     discard = def.discard;
     320            0 :                     layer = def.layer;
     321              :                 } else {
     322            0 :                     id = oc.getString("prefix") + id;
     323            0 :                     type = oc.getString("type");
     324            0 :                     color = c;
     325              :                 }
     326            0 :                 if (!discard) {
     327              :                     const std::string origId = id;
     328              :                     int index = 1;
     329            0 :                     while (toFill.getPolygons().get(id) != nullptr) {
     330            0 :                         id = origId + "#" + toString(index++);
     331              :                     }
     332            0 :                     SUMOPolygon* poly = new SUMOPolygon(id, type, color, vec, false, false, 1, layer);
     333            0 :                     toFill.add(poly);
     334              :                 }
     335              :                 vec.clear();
     336              :             }
     337              :             lastID = id;
     338              :             first = false;
     339              :             // parse current poly
     340            0 :             std::string index = st.next();
     341            0 :             std::string xpos = st.next();
     342            0 :             std::string ypos = st.next();
     343              :             Position pos2D((double) atof(xpos.c_str()), (double) atof(ypos.c_str()));
     344            0 :             if (!geoConvHelper.x2cartesian(pos2D)) {
     345            0 :                 WRITE_WARNINGF(TL("Unable to project coordinates for polygon '%'."), id);
     346              :             }
     347            0 :             vec.push_back(pos2D);
     348            0 :         }
     349              : 
     350              :         // district refering a shape
     351            0 :         if (parsingDistrictsDirectly) {
     352              :             //$BEZIRK:NR        CODE    NAME    TYPNR   XKOORD  YKOORD  FLAECHEID       BEZART  IVANTEIL_Q      IVANTEIL_Z      OEVANTEIL       METHODEANBANTEILE       ZWERT1  ZWERT2  ZWERT3  ISTINAUSWAHL    OBEZNR  NOM_COM COD_COM
     353            0 :             lineParser.parseLine(line);
     354            0 :             long long int idL = StringUtils::toLong(lineParser.get(KEYS.getString(VISUM_NO)));
     355            0 :             std::string id = toString(idL);
     356            0 :             long long int area = StringUtils::toLong(lineParser.get(KEYS.getString(VISUM_SURFACEID)));
     357            0 :             double x = StringUtils::toDouble(lineParser.get(KEYS.getString(VISUM_XCOORD)));
     358            0 :             double y = StringUtils::toDouble(lineParser.get(KEYS.getString(VISUM_YCOORD)));
     359              :             // patch the values
     360            0 :             std::string type = "district";
     361            0 :             bool discard = oc.getBool("discard");
     362            0 :             std::string icon = oc.getString("icon");
     363            0 :             double layer = oc.getFloat("layer");
     364            0 :             RGBColor color;
     365            0 :             if (tm.has(type)) {
     366            0 :                 const PCTypeMap::TypeDef& def = tm.get(type);
     367            0 :                 id = def.prefix + id;
     368            0 :                 type = def.id;
     369            0 :                 color = def.color;
     370            0 :                 discard = def.discard;
     371            0 :                 icon = def.icon;
     372            0 :                 layer = def.layer;
     373              :             } else {
     374            0 :                 id = oc.getString("prefix") + id;
     375            0 :                 type = oc.getString("type");
     376            0 :                 color = c;
     377              :             }
     378            0 :             if (!discard) {
     379            0 :                 if (teilflaechen[flaechenelemente[area]].size() > 0) {
     380              :                     const std::string origId = id;
     381              :                     int index = 1;
     382            0 :                     while (toFill.getPolygons().get(id) != nullptr) {
     383            0 :                         id = origId + "#" + toString(index++);
     384              :                     }
     385            0 :                     const auto shape = teilflaechen[flaechenelemente[area]];
     386            0 :                     SUMOPolygon* poly = new SUMOPolygon(id, type, color, shape, false, false, 1, layer);
     387            0 :                     toFill.add(poly);
     388            0 :                 } else {
     389              :                     Position pos(x, y);
     390            0 :                     if (!geoConvHelper.x2cartesian(pos)) {
     391            0 :                         WRITE_WARNINGF(TL("Unable to project coordinates for POI '%'."), id);
     392              :                     }
     393              :                     const std::string origId = id;
     394              :                     int index = 1;
     395            0 :                     while (toFill.getPOIs().get(id) != nullptr) {
     396            0 :                         id = origId + "#" + toString(index++);
     397              :                     }
     398            0 :                     PointOfInterest* poi = new PointOfInterest(id, type, color, pos, false, "", 0, false, 0, icon, layer);
     399            0 :                     toFill.add(poi);
     400              :                 }
     401              :             }
     402              :         }
     403              : 
     404              : 
     405            0 :         if (line.find("$POIKATEGORIEDEF:") == 0 || line.find("$" + KEYS.getString(VISUM_POICATEGORY) + ":") == 0) {
     406              :             // ok, got categories, begin parsing from next line
     407              :             parsingCategories = true;
     408            0 :             lineParser.reinit(line.substr(line.find(":") + 1));
     409              :         }
     410            0 :         if ((line.find("$POI:") == 0) || line.find("$POIOFCAT") != std::string::npos) {
     411              :             // ok, got pois, begin parsing from next line
     412              :             parsingPOIs = true;
     413            0 :             lineParser.reinit(line.substr(line.find(":") + 1));
     414              :         }
     415            0 :         if (line.find("$" + KEYS.getString(VISUM_DISTRICT)) == 0 && line.find(KEYS.getString(VISUM_SURFACEID)) != std::string::npos) {
     416              :             // ok, have a district header, and it seems like districts would reference shapes...
     417              :             parsingDistrictsDirectly = true;
     418            0 :             lineParser.reinit(line.substr(line.find(":") + 1));
     419              :         }
     420              : 
     421              : 
     422            0 :         if (line.find("$BEZIRKPOLY") != std::string::npos) {
     423              :             polyType = "district";
     424              :         }
     425            0 :         if (line.find("$GEBIETPOLY") != std::string::npos) {
     426              :             polyType = "area";
     427              :         }
     428              : 
     429              :     }
     430            0 : }
     431              : 
     432              : 
     433              : void
     434            0 : PCLoaderVisum::loadLanguage(const std::string& file) {
     435            0 :     std::ifstream strm(file.c_str());
     436            0 :     if (!strm.good()) {
     437            0 :         throw ProcessError(TLF("Could not load VISUM language map from '%'.", file));
     438              :     }
     439            0 :     while (strm.good()) {
     440              :         std::string keyDE;
     441              :         std::string keyNew;
     442            0 :         strm >> keyDE;
     443            0 :         strm >> keyNew;
     444              :         if (KEYS.hasString(keyDE)) {
     445            0 :             VISUM_KEY key = KEYS.get(keyDE);
     446            0 :             KEYS.remove(keyDE, key);
     447            0 :             KEYS.insert(keyNew, key);
     448              :         } else if (keyDE != "") {
     449              :             // do not warn about network-related keys (NIImporter_VISUM)
     450              :             //WRITE_WARNINGF(TL("Unknown entry '%' in VISUM language map"), keyDE);
     451              :         }
     452              :     }
     453              : 
     454            0 : }
     455              : 
     456              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1