Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/netimport/NIImporter_ITSUMO.cpp
169666 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2011-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_ITSUMO.cpp
15
/// @author Daniel Krajzewicz
16
/// @author Jakob Erdmann
17
/// @author Michael Behrisch
18
/// @date 2011-09-16
19
///
20
// Importer for networks stored in ITSUMO format
21
/****************************************************************************/
22
#include <config.h>
23
#include <set>
24
#include <functional>
25
#include <sstream>
26
#include <utils/xml/SUMOSAXHandler.h>
27
#include <utils/common/MsgHandler.h>
28
#include <netbuild/NBEdge.h>
29
#include <netbuild/NBEdgeCont.h>
30
#include <netbuild/NBNode.h>
31
#include <netbuild/NBNodeCont.h>
32
#include <netbuild/NBNetBuilder.h>
33
#include <utils/geom/GeoConvHelper.h>
34
#include <utils/options/OptionsCont.h>
35
#include <utils/common/StringUtils.h>
36
#include <utils/common/FileHelpers.h>
37
#include <utils/common/StringTokenizer.h>
38
#include <utils/common/StringUtils.h>
39
#include <utils/xml/XMLSubSys.h>
40
#include "NILoader.h"
41
#include "NIImporter_ITSUMO.h"
42
43
44
45
// ===========================================================================
46
// static variables
47
// ===========================================================================
48
SequentialStringBijection::Entry NIImporter_ITSUMO::itsumoTags[] = {
49
{ "simulation", NIImporter_ITSUMO::ITSUMO_TAG_SIMULATION },
50
{ "network_id", NIImporter_ITSUMO::ITSUMO_TAG_NETWORK_ID },
51
{ "network_name", NIImporter_ITSUMO::ITSUMO_TAG_NETWORK_NAME },
52
{ "nodes", NIImporter_ITSUMO::ITSUMO_TAG_NODES },
53
{ "node", NIImporter_ITSUMO::ITSUMO_TAG_NODE },
54
{ "node_id", NIImporter_ITSUMO::ITSUMO_TAG_NODE_ID },
55
{ "node_name", NIImporter_ITSUMO::ITSUMO_TAG_NODE_NAME },
56
{ "x_coord", NIImporter_ITSUMO::ITSUMO_TAG_X_COORD },
57
{ "y_coord", NIImporter_ITSUMO::ITSUMO_TAG_Y_COORD },
58
{ "sources", NIImporter_ITSUMO::ITSUMO_TAG_SOURCES },
59
{ "sinks", NIImporter_ITSUMO::ITSUMO_TAG_SINKS },
60
{ "traffic_lights", NIImporter_ITSUMO::ITSUMO_TAG_TRAFFIC_LIGHTS },
61
{ "streets", NIImporter_ITSUMO::ITSUMO_TAG_STREETS },
62
{ "street", NIImporter_ITSUMO::ITSUMO_TAG_STREET },
63
{ "street_id", NIImporter_ITSUMO::ITSUMO_TAG_STREET_ID },
64
{ "street_name", NIImporter_ITSUMO::ITSUMO_TAG_STREET_NAME },
65
{ "sections", NIImporter_ITSUMO::ITSUMO_TAG_SECTIONS },
66
{ "section", NIImporter_ITSUMO::ITSUMO_TAG_SECTION },
67
{ "section_id", NIImporter_ITSUMO::ITSUMO_TAG_SECTION_ID },
68
{ "section_name", NIImporter_ITSUMO::ITSUMO_TAG_SECTION_NAME },
69
{ "is_preferencial", NIImporter_ITSUMO::ITSUMO_TAG_IS_PREFERENCIAL },
70
{ "delimiting_node", NIImporter_ITSUMO::ITSUMO_TAG_DELIMITING_NODE },
71
{ "lanesets", NIImporter_ITSUMO::ITSUMO_TAG_LANESETS },
72
{ "laneset", NIImporter_ITSUMO::ITSUMO_TAG_LANESET },
73
{ "laneset_id", NIImporter_ITSUMO::ITSUMO_TAG_LANESET_ID },
74
{ "laneset_position", NIImporter_ITSUMO::ITSUMO_TAG_LANESET_POSITION },
75
{ "start_node", NIImporter_ITSUMO::ITSUMO_TAG_START_NODE },
76
{ "end_node", NIImporter_ITSUMO::ITSUMO_TAG_END_NODE },
77
{ "turning_probabilities", NIImporter_ITSUMO::ITSUMO_TAG_TURNING_PROBABILITIES },
78
{ "direction", NIImporter_ITSUMO::ITSUMO_TAG_DIRECTION },
79
{ "destination_laneset", NIImporter_ITSUMO::ITSUMO_TAG_DESTINATION_LANESET },
80
{ "probability", NIImporter_ITSUMO::ITSUMO_TAG_PROBABILITY },
81
{ "lanes", NIImporter_ITSUMO::ITSUMO_TAG_LANES },
82
{ "lane", NIImporter_ITSUMO::ITSUMO_TAG_LANE },
83
{ "lane_id", NIImporter_ITSUMO::ITSUMO_TAG_LANE_ID },
84
{ "lane_position", NIImporter_ITSUMO::ITSUMO_TAG_LANE_POSITION },
85
{ "maximum_speed", NIImporter_ITSUMO::ITSUMO_TAG_MAXIMUM_SPEED },
86
{ "deceleration_prob", NIImporter_ITSUMO::ITSUMO_TAG_DECELERATION_PROB },
87
{ "", NIImporter_ITSUMO::ITSUMO_TAG_NOTHING }
88
};
89
90
91
SequentialStringBijection::Entry NIImporter_ITSUMO::itsumoAttrs[] = {
92
{ "", NIImporter_ITSUMO::ITSUMO_ATTR_NOTHING }
93
};
94
95
96
// ===========================================================================
97
// method definitions
98
// ===========================================================================
99
// ---------------------------------------------------------------------------
100
// static methods
101
// ---------------------------------------------------------------------------
102
void
103
NIImporter_ITSUMO::loadNetwork(const OptionsCont& oc, NBNetBuilder& nb) {
104
// check whether the option is set (properly)
105
if (!oc.isSet("itsumo-files")) {
106
return;
107
}
108
/* Parse file(s)
109
* Each file is parsed twice: first for nodes, second for edges. */
110
std::vector<std::string> files = oc.getStringVector("itsumo-files");
111
// load nodes, first
112
Handler handler(nb);
113
handler.needsCharacterData();
114
for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
115
// nodes
116
if (!FileHelpers::isReadable(*file)) {
117
WRITE_ERRORF(TL("Could not open itsumo-file '%'."), *file);
118
return;
119
}
120
handler.setFileName(*file);
121
PROGRESS_BEGIN_MESSAGE("Parsing nodes from itsumo-file '" + *file + "'");
122
if (!XMLSubSys::runParser(handler, *file)) {
123
return;
124
}
125
PROGRESS_DONE_MESSAGE();
126
}
127
}
128
129
130
// ---------------------------------------------------------------------------
131
// definitions of NIImporter_ITSUMO::Handler-methods
132
// ---------------------------------------------------------------------------
133
NIImporter_ITSUMO::Handler::Handler(NBNetBuilder& toFill)
134
: GenericSAXHandler(itsumoTags, ITSUMO_TAG_NOTHING, itsumoAttrs, ITSUMO_ATTR_NOTHING, "itsumo - file"), myNetBuilder(toFill) {
135
}
136
137
138
NIImporter_ITSUMO::Handler::~Handler() {}
139
140
141
void
142
NIImporter_ITSUMO::Handler::myStartElement(int element, const SUMOSAXAttributes& /* attrs */) {
143
switch (element) {
144
case ITSUMO_TAG_NODE:
145
myParameter.clear();
146
break;
147
case ITSUMO_TAG_LANESET:
148
myParameter.clear();
149
break;
150
default:
151
break;
152
}
153
}
154
155
156
void
157
NIImporter_ITSUMO::Handler::myCharacters(int element, const std::string& chars) {
158
std::string mc = StringUtils::prune(chars);
159
switch (element) {
160
// node parsing
161
case ITSUMO_TAG_NODE_ID:
162
myParameter["id"] = mc;
163
break;
164
case ITSUMO_TAG_NODE_NAME:
165
myParameter["name"] = mc;
166
break;
167
case ITSUMO_TAG_X_COORD:
168
myParameter["x"] = mc;
169
break;
170
case ITSUMO_TAG_Y_COORD:
171
myParameter["y"] = mc;
172
break;
173
// section parsing
174
case ITSUMO_TAG_SECTION_ID:
175
myParameter["sectionID"] = mc;
176
break;
177
// laneset parsing
178
case ITSUMO_TAG_LANESET_ID:
179
myParameter["lanesetID"] = mc;
180
break;
181
case ITSUMO_TAG_LANESET_POSITION:
182
myParameter["pos"] = mc;
183
break;
184
case ITSUMO_TAG_START_NODE:
185
myParameter["from"] = mc;
186
break;
187
case ITSUMO_TAG_END_NODE:
188
myParameter["to"] = mc;
189
break;
190
// lane parsing
191
case ITSUMO_TAG_LANE_ID:
192
myParameter["laneID"] = mc;
193
break;
194
case ITSUMO_TAG_LANE_POSITION:
195
myParameter["i"] = mc;
196
break;
197
case ITSUMO_TAG_MAXIMUM_SPEED:
198
myParameter["v"] = mc;
199
break;
200
default:
201
break;
202
}
203
}
204
205
206
void
207
NIImporter_ITSUMO::Handler::myEndElement(int element) {
208
switch (element) {
209
case ITSUMO_TAG_SIMULATION: {
210
for (std::vector<Section*>::iterator i = mySections.begin(); i != mySections.end(); ++i) {
211
for (std::vector<LaneSet*>::iterator j = (*i)->laneSets.begin(); j != (*i)->laneSets.end(); ++j) {
212
LaneSet* ls = (*j);
213
NBEdge* edge = new NBEdge(ls->id, ls->from, ls->to, "", ls->v, NBEdge::UNSPECIFIED_FRICTION, (int)ls->lanes.size(), -1,
214
NBEdge::UNSPECIFIED_WIDTH, NBEdge::UNSPECIFIED_OFFSET, LaneSpreadFunction::RIGHT);
215
if (!myNetBuilder.getEdgeCont().insert(edge)) {
216
delete edge;
217
WRITE_ERRORF(TL("Could not add edge '%'. Probably declared twice."), ls->id);
218
}
219
delete ls;
220
}
221
delete *i;
222
}
223
}
224
break;
225
case ITSUMO_TAG_NODE: {
226
try {
227
std::string id = myParameter["id"];
228
double x = StringUtils::toDouble(myParameter["x"]);
229
double y = StringUtils::toDouble(myParameter["y"]);
230
Position pos(x, y);
231
if (!NBNetBuilder::transformCoordinate(pos)) {
232
WRITE_ERRORF(TL("Unable to project coordinates for node '%'."), id);
233
}
234
NBNode* node = new NBNode(id, pos);
235
if (!myNetBuilder.getNodeCont().insert(node)) {
236
delete node;
237
WRITE_ERRORF(TL("Could not add node '%'. Probably declared twice."), id);
238
}
239
} catch (NumberFormatException&) {
240
WRITE_ERRORF(TL("Not numeric position information for node '%'."), myParameter["id"]);
241
} catch (EmptyData&) {
242
WRITE_ERRORF(TL("Missing data in node '%'."), myParameter["id"]);
243
}
244
}
245
break;
246
case ITSUMO_TAG_SECTION: {
247
mySections.push_back(new Section(myParameter["sectionID"], myCurrentLaneSets));
248
myCurrentLaneSets.clear();
249
}
250
break;
251
case ITSUMO_TAG_LANESET: {
252
try {
253
std::string id = myParameter["lanesetID"];
254
int i = StringUtils::toInt(myParameter["i"]);
255
std::string fromID = myParameter["from"];
256
std::string toID = myParameter["to"];
257
NBNode* from = myNetBuilder.getNodeCont().retrieve(fromID);
258
NBNode* to = myNetBuilder.getNodeCont().retrieve(toID);
259
if (from == nullptr || to == nullptr) {
260
WRITE_ERRORF(TL("Missing node in laneset '%'."), myParameter["lanesetID"]);
261
} else {
262
if (myLaneSets.find(id) != myLaneSets.end()) {
263
WRITE_ERRORF(TL("Found laneset-id '%' twice."), id);
264
} else {
265
double vSum = 0;
266
for (std::vector<Lane>::iterator j = myCurrentLanes.begin(); j != myCurrentLanes.end(); ++j) {
267
vSum += (*j).v;
268
}
269
vSum /= (double) myCurrentLanes.size();
270
LaneSet* ls = new LaneSet(id, myCurrentLanes, vSum, i, from, to);
271
myLaneSets[id] = ls;
272
myCurrentLaneSets.push_back(ls);
273
myCurrentLanes.clear();
274
}
275
}
276
} catch (NumberFormatException&) {
277
WRITE_ERRORF(TL("Not numeric value in laneset '%'."), myParameter["lanesetID"]);
278
} catch (EmptyData&) {
279
WRITE_ERRORF(TL("Missing data in laneset '%'."), myParameter["lanesetID"]);
280
}
281
}
282
break;
283
case ITSUMO_TAG_LANE: {
284
try {
285
std::string id = myParameter["laneID"];
286
int i = StringUtils::toInt(myParameter["i"]);
287
double v = StringUtils::toDouble(myParameter["v"]);
288
myCurrentLanes.push_back(Lane(id, (int) i, v));
289
} catch (NumberFormatException&) {
290
WRITE_ERRORF(TL("Not numeric value in lane '%'."), myParameter["laneID"]);
291
} catch (EmptyData&) {
292
WRITE_ERRORF(TL("Missing data in lane '%'."), myParameter["laneID"]);
293
}
294
}
295
break;
296
default:
297
break;
298
}
299
}
300
301
302
/****************************************************************************/
303
304