Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/netimport/NIImporter_VISUM.h
169668 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2001-2025 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 NIImporter_VISUM.h
15
/// @author Daniel Krajzewicz
16
/// @author Michael Behrisch
17
/// @date Fri, 19 Jul 2002
18
///
19
// A VISUM network importer
20
/****************************************************************************/
21
#pragma once
22
#include <config.h>
23
24
#include <string>
25
#include <map>
26
#include <vector>
27
#include <netbuild/NBCapacity2Lanes.h>
28
#include <utils/importio/LineHandler.h>
29
#include <utils/importio/LineReader.h>
30
#include <utils/importio/NamedColumnsParser.h>
31
#include "NIVisumTL.h"
32
33
34
// ===========================================================================
35
// class declaration
36
// ===========================================================================
37
class OptionsCont;
38
class NBNetBuilder;
39
class NBNodeCont;
40
class NBEdgeCont;
41
class NBNode;
42
class NBEdge;
43
44
45
// ===========================================================================
46
// class declaration
47
// ===========================================================================
48
/**
49
* @class NIImporter_VISUM
50
* @brief A VISUM network importer
51
*
52
* This class build an internal list of those VISUM-db entries which are
53
* supported, first. This list is sorted in a way that the parsed dbs can
54
* build upon each other as their related structures within the XML-input.
55
* So, nodes are loaded first, then edges, etc.
56
*
57
* Because these structures may have a different order within the VISUM-file
58
* than we need, at first the file is scanned and any occurrence of one of the
59
* searched dbs is saved. That's where the "Found $XXX at YYY" are printed.
60
* "YYY" is the character position within the file.
61
*
62
* In a second step, the dbs are parsed in the order we need. It is asked for
63
* each subsequently whether it was found and if so, the proper parse_XXX()
64
* method is called.
65
*/
66
class NIImporter_VISUM {
67
public:
68
/** @brief Loads network definition from the assigned option and stores it in the given network builder
69
*
70
* If the option "visum" is set, the file stored therein is read and
71
* the network definition stored therein is stored within the given network
72
* builder.
73
*
74
* If the option "visum" is not set, this method simply returns.
75
*
76
* @param[in] oc The options to use
77
* @param[in] nb The network builder to fill
78
*/
79
static void loadNetwork(const OptionsCont& oc, NBNetBuilder& nb);
80
81
82
protected:
83
/** @brief constructor
84
*
85
* Builds the list of typed db parsers ("TypeParser") and stores them in
86
* mySingleDataParsers in the order the according db values must be parsed.
87
*
88
* @param[in,out] nb the network builder (storage) to fill with parsed values
89
* @param[in] file The name of the file to parse
90
* @param[in] capacity2Lanes The converter from flow to lanes
91
* @param[in] useVisumPrio Information whether the VISUM type's priority shall be used
92
*/
93
NIImporter_VISUM(NBNetBuilder& nb, const std::string& file,
94
NBCapacity2Lanes capacity2Lanes, bool useVisumPrio,
95
const std::string& languageFile);
96
97
98
/// @brief destructor
99
~NIImporter_VISUM();
100
101
102
/** @brief Parses the VISUM-network file storing the parsed structures within myNetBuilder
103
*
104
* At first, it is checked whether the file can be opened. A ProcessError is thrown
105
* if not. Otherwise, the file is scanned for occurrences of db table begins. For each found
106
* db, its position within the file, and the column names are stored in the according
107
* TypeParser. After this, the sorted list of type parsers is one through and each
108
* found is used to parse the entries at the found positions using the found column names.
109
*
110
* @exception ProcessError If the file could not be opened
111
*/
112
void load();
113
114
private:
115
/** @brief Returns the value from the named column as a float
116
*
117
* @param[in] fieldName Name of the column to extract the float from
118
* @return The parsed real
119
* @exception OutOfBoundsException If the current data line has less entries than the float's position
120
* @exception NumberFormatException If the float is not numeric
121
* @exception UnknownElement If the named data field is not in the line
122
*/
123
double getNamedFloat(const std::string& fieldName);
124
125
/** @brief The same, but two different names for the field are allowed
126
*
127
* @param[in] fieldName1 Name of the first column to extract the float from
128
* @param[in] fieldName2 Name of the second column to extract the efloat from
129
* @return The parsed real
130
* @exception OutOfBoundsException If the current data line has less entries than the float's position
131
* @exception NumberFormatException If the float is not numeric
132
* @exception UnknownElement If the named data field is not in the line
133
*/
134
double getNamedFloat(const std::string& fieldName1, const std::string& fieldName2);
135
136
137
/** @brief Returns the value from the named column as a float or the default value if an error occurs
138
*
139
* @param[in] fieldName Name of the column to extract the float from
140
* @param[in] defaultValue The default to return in the case of an error
141
* @return The parsed real or the default value if an error while parsing occurred
142
*/
143
double getNamedFloat(const std::string& fieldName, double defaultValue);
144
145
/** @brief The same, but two different names for the field are allowed
146
*
147
* @param[in] fieldName1 Name of the first column to extract the float from
148
* @param[in] fieldName2 Name of the second column to extract the efloat from
149
* @param[in] defaultValue The default to return in the case of an error
150
* @return The parsed real or the default value if an error while parsing occurred
151
*/
152
double getNamedFloat(const std::string& fieldName1, const std::string& fieldName2,
153
double defaultValue);
154
155
156
/** @brief Returns the value from the named column as a normalised string
157
*
158
* "Normalised" means herein that the leading '0' (zeros) are prunned.
159
*
160
* @param[in] fieldName Name of the column to extract the string from
161
* @return The parsed, normalised string
162
* @exception OutOfBoundsException If the current data line has less entries than the string's position
163
* @exception NumberFormatException If the string is not numeric
164
* @exception UnknownElement If the named data field is not in the line
165
*/
166
std::string getNamedString(const std::string& fieldName);
167
168
/** @brief The same, but two different names for the field are allowed
169
*
170
* @param[in] fieldName1 Name of the first column to extract the string from
171
* @param[in] fieldName2 Name of the second column to extract the string from
172
* @return The parsed, normalised string
173
* @exception OutOfBoundsException If the current data line has less entries than the string's position
174
* @exception NumberFormatException If the string is not numeric
175
* @exception UnknownElement If the named data field is not in the line
176
*/
177
std::string getNamedString(const std::string& fieldName1, const std::string& fieldName2);
178
179
180
/** @brief tries to get a double which is possibly assigned to a certain modality
181
*
182
* When the double cannot be extracted using the given name, "(IV)" is
183
* appended to the begin of the name. Note that this function does not
184
* yet support public traffic.
185
*
186
* @param[in] name Name of the column to extract the real from
187
* @return The real stored under the named column, or if not found the one from name + suffix, or if not found -1
188
*/
189
double getWeightedFloat(const std::string& name, const std::string& suffix);
190
191
/// @brief as above but with two alternative names
192
double getWeightedFloat2(const std::string& name, const std::string& name2, const std::string& suffix);
193
194
/// @brief parse permissions
195
SVCPermissions getPermissions(const std::string& name, bool warn = false, SVCPermissions unknown = SVCAll);
196
197
/** @brief tries to get a bool which is possibly assigned to a certain modality
198
*
199
* When the bool cannot be extracted using the given name, "IV" is
200
* appended to the begin of the name. Note that this function does not
201
* yet support public traffic.
202
*
203
* @param[in] name Name of the column to extract the bool from
204
* @return The bool stored under the named column, or if not found the one from "(IV)"+name, or if not found false
205
*/
206
bool getWeightedBool(const std::string& name);
207
208
209
/** @brief Tries to get the node which name is stored in the given field
210
*
211
* If the field can not be parsed, an exception is thrown. Prints an error if the
212
* node could not be found, returning 0. Otherwise, if the field could be parsed
213
* and the node was found, this node is returned.
214
*
215
* @param[in] fieldName Name of the column to extract the node's name from
216
* @return An already known node with the found name
217
* @exception OutOfBoundsException If the current data line has less entries than the node id's position
218
* @exception NumberFormatException If the node id is not numeric
219
* @exception UnknownElement If the named data field is not in the line
220
*/
221
NBNode* getNamedNode(const std::string& fieldName);
222
NBNode* getNamedNodeSecure(const std::string& fieldName, NBNode* fallback = 0);
223
224
/** @brief The same, but two different names for the field are allowed
225
*
226
* @param[in] fieldName1 Name of the first column to extract the node's name from
227
* @param[in] fieldName2 Name of the second column to extract the node's name from
228
* @return An already known node with the found name
229
* @exception OutOfBoundsException If the current data line has less entries than the node id's position
230
* @exception NumberFormatException If the node id is not numeric
231
* @exception UnknownElement If the named data field is not in the line
232
*/
233
NBNode* getNamedNode(const std::string& fieldName1, const std::string& fieldName2);
234
235
236
/** @brief Tries to get the edge which name is stored in the given field
237
*
238
* If the field can not be parsed, an exception is thrown. Prints an error if the
239
* edge could not be found, returning 0. Otherwise, if the field could be parsed
240
* and the edge was found, this edge is returned.
241
*
242
* @param[in] fieldName Name of the column to extract the edge's name from
243
* @return An already known edge with the found name
244
* @exception OutOfBoundsException If the current data line has less entries than the edge id's position
245
* @exception NumberFormatException If the edge id is not numeric
246
* @exception UnknownElement If the named data field is not in the line
247
*/
248
NBEdge* getNamedEdge(const std::string& fieldName);
249
250
/** @brief The same, but two different names for the field are allowed
251
*
252
* @param[in] fieldName1 Name of the first column to extract the edge's name from
253
* @param[in] fieldName2 Name of the second column to extract the edge's name from
254
* @return An already known edge with the found name
255
* @exception OutOfBoundsException If the current data line has less entries than the edge id's position
256
* @exception NumberFormatException If the edge id is not numeric
257
* @exception UnknownElement If the named data field is not in the line
258
*/
259
NBEdge* getNamedEdge(const std::string& fieldName1, const std::string& fieldName2);
260
261
262
/** @brief Tries to get the edge which name is stored in the given field
263
* continuating the search for a subedge that ends at the given node
264
*
265
* If the field can not be parsed, an exception is thrown. Prints an error if the
266
* edge could not be found, returning 0. Otherwise, if the field could be parsed
267
* and the edge was found, this edge is returned.
268
*
269
* @param[in] fieldName Name of the column to extract the edge's name from
270
* @param[in] node The node the consecutive edge must end at in order to be returned
271
* @return The edge's continuation up to the given node, 0 if not found
272
* @exception OutOfBoundsException If the current data line has less entries than the edge id's position
273
* @exception NumberFormatException If the edge id is not numeric
274
* @exception UnknownElement If the named data field is not in the line
275
*/
276
NBEdge* getNamedEdgeContinuating(const std::string& fieldName, NBNode* node);
277
278
/** @brief The same, but two different names for the field are allowed
279
*
280
* @param[in] fieldName1 Name of the first column to extract the edge's name from
281
* @param[in] fieldName2 Name of the second column to extract the edge's name from
282
* @param[in] node The node the consecutive edge must end at in order to be returned
283
* @return The edge's continuation up to the given node, 0 if not found
284
* @exception OutOfBoundsException If the current data line has less entries than the edge id's position
285
* @exception NumberFormatException If the edge id is not numeric
286
* @exception UnknownElement If the named data field is not in the line
287
*/
288
NBEdge* getNamedEdgeContinuating(const std::string& fieldName1, const std::string& fieldName2,
289
NBNode* node);
290
291
/** @brief The same, but for an already given edge
292
*
293
* @param[in] begin The edge to get the continuation of
294
* @param[in] node The node the consecutive edge must end at in order to be returned
295
* @return The edge's continuation up to the given node, 0 if not found
296
*/
297
NBEdge* getNamedEdgeContinuating(NBEdge* begin, NBNode* node);
298
299
300
/** @brief Returns the edge that connects both nodes
301
*
302
* @param[in] FromNode Name of the node the edge shall start at
303
* @param[in] ToNode Name of the node the edge shall end at
304
* @return The edge connecting both nodes, 0 if no such edge exists
305
*/
306
NBEdge* getEdge(NBNode* FromNode, NBNode* ToNode);
307
308
309
/** @brief Returns the opposite direction of the given edge
310
*
311
* Because the opposite direction edge may be split, not the plain opposite
312
* edge, the one which name is obtained by adding/removing the leading '-', is returned,
313
* but its continuation until the named node.
314
*
315
* @param[in] edge Name of the edge to find the opposite of
316
* @param[in] node Name of the node the opposite edge's continuation must end at
317
* @return The found opposite edge's continuation, 0 if not found
318
*/
319
NBEdge* getReversedContinuating(NBEdge* edge, NBNode* node);
320
321
322
/** @brief Builds a node for the given district and returns it
323
*
324
* If the district does not exist, an error is generated and 0 returned. Otherwise
325
* a position for the new node is computed and the new node is built using a combination
326
* of the district name and the node name as id. If Inserting this node into
327
* the net builder fails, zero is returned.
328
*
329
* @param[in] id Name of the district
330
* @param[in] dest Name of the according network node
331
* @param[in] isSource Information whether this node will be used as a source
332
* @return The built node, zero if an error occurred
333
*/
334
NBNode* buildDistrictNode(const std::string& id, NBNode* dest, bool isSource);
335
336
337
/** @brief Returns whether both nodes are a valid combination of from/to-nodes
338
*
339
* They are valid if both are !=0 and differ.
340
*
341
* @param[in] from The from-node
342
* @param[in] from The to-node
343
* @return Whether the nodes may be used
344
*/
345
bool checkNodes(NBNode* from, NBNode* to);
346
347
348
private:
349
/**
350
* @brief Definition of a function for parsing a single line from a certain db
351
*
352
* This function may assume that both the LineParser is initialised
353
* with the current line.
354
*/
355
typedef void (NIImporter_VISUM::*ParsingFunction)();
356
357
/**
358
* @struct TypeParser
359
* @brief A complete call description for parsing a single db.
360
*/
361
struct TypeParser {
362
/** @brief The name of the db
363
*
364
* Initialised in the constructor */
365
std::string name;
366
367
/** @brief Pointer to the function used for parsing
368
*
369
* Initialised in the constructor */
370
ParsingFunction function;
371
372
/** @brief Position of the according db within the file
373
*
374
* Set to -1 in the constructor, and reset to the position while
375
* scanning the file if the according db was found */
376
long position;
377
378
/** @brief The column names
379
*
380
* Set while scanning the file if the according db was found */
381
std::string pattern;
382
383
};
384
385
386
387
/// @brief Parses VSYS
388
void parse_VSysTypes();
389
390
/// @brief Parses STRECKENTYP
391
void parse_Types();
392
393
/// @brief Parses KNOTEN
394
void parse_Nodes();
395
396
/// @brief Parses BEZIRK
397
void parse_Districts();
398
399
/// @brief Parses PUNKT
400
void parse_Point();
401
402
403
/// @brief Parses STRECKE/STRECKEN
404
void parse_Edges();
405
406
/// @brief Parses FLAECHENELEMENT
407
void parse_PartOfArea();
408
409
/// @brief Parses FLAECHENELEMENT
410
void parse_Kante();
411
412
413
/// @brief Parses ANBINDUNG
414
void parse_Connectors();
415
void parse_Connectors_legacy();
416
417
/// @brief Parses ABBIEGEBEZIEHUNG/ABBIEGER
418
void parse_Turns();
419
420
/// @brief Parses STRECKENPOLY
421
void parse_EdgePolys();
422
423
/// @brief Parses FAHRSTREIFEN
424
void parse_Lanes();
425
426
/// @brief Parses LSA/SIGNALANLAGE
427
void parse_TrafficLights();
428
429
/// @brief Parses KNOTENZULSA/SIGNALANLAGEZUKNOTEN
430
void parse_NodesToTrafficLights();
431
432
/// @brief Parses LSASIGNALGRUPPE/SIGNALGRUPPE
433
void parse_SignalGroups();
434
435
/// @brief Parses ABBZULSASIGNALGRUPPE/SIGNALGRUPPEZUABBIEGER
436
void parse_TurnsToSignalGroups();
437
438
/// @brief Parses ABBZULSASIGNALGRUPPE/SIGNALGRUPPEZUABBIEGER
439
void parse_AreaSubPartElement();
440
441
/// @brief Parses LSAPHASE/PHASE
442
void parse_Phases();
443
444
/// @brief Parses LSASIGNALGRUPPEZULSAPHASE
445
void parse_SignalGroupsToPhases();
446
447
/// @brief Parses FAHRSTREIFENABBIEGER
448
void parse_LanesConnections();
449
450
/// @brief Parses HALTEPUNKT (public transport stop locations)
451
void parse_stopPoints();
452
453
/** @brief Adds a parser into the sorted list of parsers to use
454
*
455
* @param[in] name db name to assign the parser to
456
* @param[in] function The function to use for parsing the named db
457
*/
458
void addParser(const std::string& name, ParsingFunction function);
459
460
private:
461
462
/// @brief whether the edge id ends with _nodeID
463
static bool isSplitEdge(NBEdge* edge, NBNode* node);
464
465
466
private:
467
/// @brief The network builder to fill with loaded values
468
NBNetBuilder& myNetBuilder;
469
470
/// @brief The name of the parsed file, for error reporting
471
std::string myFileName;
472
473
/// @brief The line reader to use to read from the file
474
LineReader myLineReader;
475
476
/** @brief the parser to parse the information from the data lines
477
*
478
* the order of columns within the visum format seems to vary, so a named parser is needed */
479
NamedColumnsParser myLineParser;
480
481
/// @brief The converter to compute the lane number of edges from their capacity
482
NBCapacity2Lanes myCapacity2Lanes;
483
484
/// @brief Definition of a storage for vsystypes
485
typedef std::map<std::string, std::string> VSysTypeNames;
486
/// @brief The used vsystypes
487
VSysTypeNames myVSysTypes;
488
489
/// @brief Definition of the list of known parsers
490
typedef std::vector<TypeParser> ParserVector;
491
/// @brief List of known parsers
492
ParserVector mySingleDataParsers;
493
494
/// @brief Definition of a map for loaded traffic lights (id->tls)
495
typedef std::map<std::string, NIVisumTL*> NIVisumTL_Map;
496
/// @brief List of visum traffic lights
497
NIVisumTL_Map myTLS;
498
499
/// @brief Already read edges
500
std::vector<std::string > myTouchedEdges;
501
502
/// @brief Information whether VISUM priority information shall be used
503
bool myUseVisumPrio;
504
505
/// @brief The name of the currently parsed item used for error reporting
506
std::string myCurrentID;
507
508
509
/// @brief A map of point ids to positions
510
std::map<long long int, Position> myPoints;
511
512
/// @brief A map of edge (not road, but "edge" in this case) ids to from/to-points
513
std::map<long long int, std::pair<long long int, long long int> > myEdges;
514
515
/// @brief A map from district shape definition name to the district
516
std::map<long long int, NBDistrict*> myShapeDistrictMap;
517
518
/// @brief A map from area parts to area ids
519
std::map<long long int, std::vector<long long int> > mySubPartsAreas;
520
521
/// @brief A temporary storage for district shapes as they are filled incrementally
522
std::map<NBDistrict*, PositionVector> myDistrictShapes;
523
524
protected:
525
/**
526
* @enum VISUM keys
527
* @brief Numbers representing VISUM keywords
528
*/
529
enum VISUM_KEY {
530
VISUM_SYS,
531
VISUM_LINKTYPE,
532
VISUM_NODE,
533
VISUM_DISTRICT,
534
VISUM_POINT,
535
VISUM_LINK,
536
VISUM_V0,
537
VISUM_TYPES,
538
VISUM_RANK,
539
VISUM_CAPACITY,
540
VISUM_XCOORD,
541
VISUM_YCOORD,
542
VISUM_FROMNODE,
543
VISUM_TONODE,
544
VISUM_TYPE,
545
VISUM_TYP,
546
VISUM_ID,
547
VISUM_CODE,
548
VISUM_DISTRICT_CONNECTION,
549
VISUM_SOURCE_DISTRICT,
550
VISUM_FROMNODENO,
551
VISUM_DIRECTION,
552
VISUM_SURFACEID,
553
VISUM_FACEID,
554
VISUM_FROMPOINTID,
555
VISUM_TOPOINTID,
556
VISUM_EDGE,
557
VISUM_VIANODENO,
558
VISUM_NUMLANES,
559
VISUM_TURN,
560
VISUM_INDEX,
561
VISUM_LINKPOLY,
562
VISUM_SURFACEITEM,
563
VISUM_FACEITEM,
564
VISUM_EDGEID,
565
VISUM_ORIGIN,
566
VISUM_DESTINATION,
567
VISUM_STOPPOINT,
568
VISUM_NAME,
569
VISUM_LINKNO,
570
VISUM_RELPOS,
571
// polyconvert keys added to avoid warnings
572
VISUM_CATID,
573
VISUM_EDGEITEM,
574
VISUM_POICATEGORY,
575
VISUM_NO // must be the last one
576
};
577
578
/// Strings for the keywords
579
static StringBijection<VISUM_KEY>::Entry KEYS_DE[];
580
581
/// @brief link directions
582
static StringBijection<VISUM_KEY> KEYS;
583
584
void loadLanguage(const std::string& file);
585
};
586
587