Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2011-2024 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 1892 : NIImporter_ITSUMO::loadNetwork(const OptionsCont& oc, NBNetBuilder& nb) {
104 : // check whether the option is set (properly)
105 3784 : if (!oc.isSet("itsumo-files")) {
106 1892 : return;
107 : }
108 : /* Parse file(s)
109 : * Each file is parsed twice: first for nodes, second for edges. */
110 0 : std::vector<std::string> files = oc.getStringVector("itsumo-files");
111 : // load nodes, first
112 0 : Handler handler(nb);
113 : handler.needsCharacterData();
114 0 : for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
115 : // nodes
116 0 : if (!FileHelpers::isReadable(*file)) {
117 0 : WRITE_ERRORF(TL("Could not open itsumo-file '%'."), *file);
118 0 : return;
119 : }
120 0 : handler.setFileName(*file);
121 0 : PROGRESS_BEGIN_MESSAGE("Parsing nodes from itsumo-file '" + *file + "'");
122 0 : if (!XMLSubSys::runParser(handler, *file)) {
123 : return;
124 : }
125 0 : PROGRESS_DONE_MESSAGE();
126 : }
127 0 : }
128 :
129 :
130 : // ---------------------------------------------------------------------------
131 : // definitions of NIImporter_ITSUMO::Handler-methods
132 : // ---------------------------------------------------------------------------
133 0 : NIImporter_ITSUMO::Handler::Handler(NBNetBuilder& toFill)
134 0 : : GenericSAXHandler(itsumoTags, ITSUMO_TAG_NOTHING, itsumoAttrs, ITSUMO_ATTR_NOTHING, "itsumo - file"), myNetBuilder(toFill) {
135 0 : }
136 :
137 :
138 0 : NIImporter_ITSUMO::Handler::~Handler() {}
139 :
140 :
141 : void
142 0 : NIImporter_ITSUMO::Handler::myStartElement(int element, const SUMOSAXAttributes& /* attrs */) {
143 0 : switch (element) {
144 0 : case ITSUMO_TAG_NODE:
145 : myParameter.clear();
146 : break;
147 0 : case ITSUMO_TAG_LANESET:
148 : myParameter.clear();
149 : break;
150 : default:
151 : break;
152 : }
153 0 : }
154 :
155 :
156 : void
157 0 : NIImporter_ITSUMO::Handler::myCharacters(int element, const std::string& chars) {
158 0 : std::string mc = StringUtils::prune(chars);
159 0 : switch (element) {
160 : // node parsing
161 : case ITSUMO_TAG_NODE_ID:
162 0 : myParameter["id"] = mc;
163 0 : break;
164 : case ITSUMO_TAG_NODE_NAME:
165 0 : myParameter["name"] = mc;
166 0 : break;
167 : case ITSUMO_TAG_X_COORD:
168 0 : myParameter["x"] = mc;
169 0 : break;
170 : case ITSUMO_TAG_Y_COORD:
171 0 : myParameter["y"] = mc;
172 0 : break;
173 : // section parsing
174 : case ITSUMO_TAG_SECTION_ID:
175 0 : myParameter["sectionID"] = mc;
176 0 : break;
177 : // laneset parsing
178 : case ITSUMO_TAG_LANESET_ID:
179 0 : myParameter["lanesetID"] = mc;
180 0 : break;
181 : case ITSUMO_TAG_LANESET_POSITION:
182 0 : myParameter["pos"] = mc;
183 0 : break;
184 : case ITSUMO_TAG_START_NODE:
185 0 : myParameter["from"] = mc;
186 0 : break;
187 : case ITSUMO_TAG_END_NODE:
188 0 : myParameter["to"] = mc;
189 0 : break;
190 : // lane parsing
191 : case ITSUMO_TAG_LANE_ID:
192 0 : myParameter["laneID"] = mc;
193 0 : break;
194 : case ITSUMO_TAG_LANE_POSITION:
195 0 : myParameter["i"] = mc;
196 0 : break;
197 : case ITSUMO_TAG_MAXIMUM_SPEED:
198 0 : myParameter["v"] = mc;
199 0 : break;
200 : default:
201 : break;
202 : }
203 0 : }
204 :
205 :
206 : void
207 0 : NIImporter_ITSUMO::Handler::myEndElement(int element) {
208 0 : switch (element) {
209 0 : case ITSUMO_TAG_SIMULATION: {
210 0 : for (std::vector<Section*>::iterator i = mySections.begin(); i != mySections.end(); ++i) {
211 0 : for (std::vector<LaneSet*>::iterator j = (*i)->laneSets.begin(); j != (*i)->laneSets.end(); ++j) {
212 0 : LaneSet* ls = (*j);
213 0 : NBEdge* edge = new NBEdge(ls->id, ls->from, ls->to, "", ls->v, NBEdge::UNSPECIFIED_FRICTION, (int)ls->lanes.size(), -1,
214 0 : NBEdge::UNSPECIFIED_WIDTH, NBEdge::UNSPECIFIED_OFFSET, LaneSpreadFunction::RIGHT);
215 0 : if (!myNetBuilder.getEdgeCont().insert(edge)) {
216 0 : delete edge;
217 0 : WRITE_ERRORF(TL("Could not add edge '%'. Probably declared twice."), ls->id);
218 : }
219 0 : delete ls;
220 : }
221 0 : delete *i;
222 : }
223 : }
224 : break;
225 : case ITSUMO_TAG_NODE: {
226 : try {
227 0 : std::string id = myParameter["id"];
228 0 : double x = StringUtils::toDouble(myParameter["x"]);
229 0 : double y = StringUtils::toDouble(myParameter["y"]);
230 : Position pos(x, y);
231 0 : if (!NBNetBuilder::transformCoordinate(pos)) {
232 0 : WRITE_ERRORF(TL("Unable to project coordinates for node '%'."), id);
233 : }
234 0 : NBNode* node = new NBNode(id, pos);
235 0 : if (!myNetBuilder.getNodeCont().insert(node)) {
236 0 : delete node;
237 0 : WRITE_ERRORF(TL("Could not add node '%'. Probably declared twice."), id);
238 : }
239 0 : } catch (NumberFormatException&) {
240 0 : WRITE_ERRORF(TL("Not numeric position information for node '%'."), myParameter["id"]);
241 0 : } catch (EmptyData&) {
242 0 : WRITE_ERRORF(TL("Missing data in node '%'."), myParameter["id"]);
243 0 : }
244 : }
245 : break;
246 0 : case ITSUMO_TAG_SECTION: {
247 0 : mySections.push_back(new Section(myParameter["sectionID"], myCurrentLaneSets));
248 : myCurrentLaneSets.clear();
249 : }
250 : break;
251 : case ITSUMO_TAG_LANESET: {
252 : try {
253 0 : std::string id = myParameter["lanesetID"];
254 0 : int i = StringUtils::toInt(myParameter["i"]);
255 0 : std::string fromID = myParameter["from"];
256 0 : std::string toID = myParameter["to"];
257 0 : NBNode* from = myNetBuilder.getNodeCont().retrieve(fromID);
258 0 : NBNode* to = myNetBuilder.getNodeCont().retrieve(toID);
259 0 : if (from == nullptr || to == nullptr) {
260 0 : WRITE_ERRORF(TL("Missing node in laneset '%'."), myParameter["lanesetID"]);
261 : } else {
262 0 : if (myLaneSets.find(id) != myLaneSets.end()) {
263 0 : WRITE_ERRORF(TL("Found laneset-id '%' twice."), id);
264 : } else {
265 : double vSum = 0;
266 0 : for (std::vector<Lane>::iterator j = myCurrentLanes.begin(); j != myCurrentLanes.end(); ++j) {
267 0 : vSum += (*j).v;
268 : }
269 0 : vSum /= (double) myCurrentLanes.size();
270 0 : LaneSet* ls = new LaneSet(id, myCurrentLanes, vSum, i, from, to);
271 0 : myLaneSets[id] = ls;
272 0 : myCurrentLaneSets.push_back(ls);
273 : myCurrentLanes.clear();
274 : }
275 : }
276 0 : } catch (NumberFormatException&) {
277 0 : WRITE_ERRORF(TL("Not numeric value in laneset '%'."), myParameter["lanesetID"]);
278 0 : } catch (EmptyData&) {
279 0 : WRITE_ERRORF(TL("Missing data in laneset '%'."), myParameter["lanesetID"]);
280 0 : }
281 : }
282 : break;
283 : case ITSUMO_TAG_LANE: {
284 : try {
285 0 : std::string id = myParameter["laneID"];
286 0 : int i = StringUtils::toInt(myParameter["i"]);
287 0 : double v = StringUtils::toDouble(myParameter["v"]);
288 0 : myCurrentLanes.push_back(Lane(id, (int) i, v));
289 0 : } catch (NumberFormatException&) {
290 0 : WRITE_ERRORF(TL("Not numeric value in lane '%'."), myParameter["laneID"]);
291 0 : } catch (EmptyData&) {
292 0 : WRITE_ERRORF(TL("Missing data in lane '%'."), myParameter["laneID"]);
293 0 : }
294 : }
295 : break;
296 : default:
297 : break;
298 : }
299 0 : }
300 :
301 :
302 : /****************************************************************************/
|