Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
NIImporter_ArcView.cpp
Go to the documentation of this file.
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/****************************************************************************/
22// Importer for networks stored in ArcView-shape format
23/****************************************************************************/
24#include <config.h>
25
26#include <string>
34#include <netbuild/NBHelpers.h>
35#include <netbuild/NBEdge.h>
36#include <netbuild/NBEdgeCont.h>
37#include <netbuild/NBTypeCont.h>
38#include <netbuild/NBNode.h>
39#include <netbuild/NBNodeCont.h>
43#include "NILoader.h"
44#include "NIImporter_ArcView.h"
45
46#ifdef HAVE_GDAL
47#ifdef _MSC_VER
48#pragma warning(push)
49#pragma warning(disable: 4435 5219 5220)
50#endif
51#if __GNUC__ > 3
52#pragma GCC diagnostic push
53#pragma GCC diagnostic ignored "-Wpedantic"
54#endif
55#include <gdal_version.h>
56#include <ogrsf_frmts.h>
57#if __GNUC__ > 3
58#pragma GCC diagnostic pop
59#endif
60#ifdef _MSC_VER
61#pragma warning(pop)
62#endif
63#endif
64
65
66// ===========================================================================
67// method definitions
68// ===========================================================================
69// ---------------------------------------------------------------------------
70// static methods (interface in this case)
71// ---------------------------------------------------------------------------
72void
74 if (!oc.isSet("shapefile-prefix")) {
75 return;
76 }
77 // check whether the correct set of entries is given
78 // and compute all file names
79 const std::string dbf_file = oc.getString("shapefile-prefix") + ".dbf";
80 const std::string shp_file = oc.getString("shapefile-prefix") + ".shp";
81 const std::string shx_file = oc.getString("shapefile-prefix") + ".shx";
82 if (!StringUtils::startsWith(shp_file, "/vsi")) {
83 // if we are not using a virtual file system, check whether the files do exist
84 if (!FileHelpers::isReadable(dbf_file)) {
85 WRITE_ERROR("File not accessible: " + dbf_file);
86 }
87 if (!FileHelpers::isReadable(shp_file)) {
88 WRITE_ERROR("File not accessible: " + shp_file);
89 }
90 if (!FileHelpers::isReadable(shx_file)) {
91 WRITE_ERROR("File not accessible: " + shx_file);
92 }
93 }
94 if (MsgHandler::getErrorInstance()->wasInformed()) {
95 return;
96 }
97 // load the arcview files
98 NIImporter_ArcView loader(oc, nb.getNodeCont(), nb.getEdgeCont(), nb.getTypeCont(),
99 shp_file, oc.getBool("speed-in-kmh"));
100 loader.load();
101}
102
103
104
105// ---------------------------------------------------------------------------
106// loader methods
107// ---------------------------------------------------------------------------
109 NBNodeCont& nc,
110 NBEdgeCont& ec,
111 NBTypeCont& tc,
112 const std::string& shp_name,
113 bool speedInKMH)
114 : myOptions(oc), mySHPName(shp_name),
115 myNameAddition(0),
116 myNodeCont(nc), myEdgeCont(ec), myTypeCont(tc),
117 mySpeedInKMH(speedInKMH),
118 myRunningEdgeID(0),
119 myRunningNodeID(0) {
120}
121
122
124
125
126void
128#ifdef HAVE_GDAL
129 PROGRESS_BEGIN_MESSAGE("Loading data from '" + mySHPName + "'");
130#if GDAL_VERSION_MAJOR < 2
131 OGRRegisterAll();
132 OGRDataSource* poDS = OGRSFDriverRegistrar::Open(mySHPName.c_str(), FALSE);
133#else
134 GDALAllRegister();
135 GDALDataset* poDS = (GDALDataset*)GDALOpenEx(mySHPName.c_str(), GDAL_OF_VECTOR | GA_ReadOnly, NULL, NULL, NULL);
136#endif
137 if (poDS == NULL) {
138 WRITE_ERRORF(TL("Could not open shape description '%'."), mySHPName);
139 return;
140 }
141
142 // begin file parsing
143 OGRLayer* poLayer = poDS->GetLayer(0);
144 poLayer->ResetReading();
145
146 // build coordinate transformation
147#if GDAL_VERSION_MAJOR < 3
148 OGRSpatialReference* origTransf = poLayer->GetSpatialRef();
149#else
150 const OGRSpatialReference* origTransf = poLayer->GetSpatialRef();
151#endif
152 OGRSpatialReference destTransf;
153 // use wgs84 as destination
154 destTransf.SetWellKnownGeogCS("WGS84");
155#if GDAL_VERSION_MAJOR > 2
156 if (myOptions.getBool("shapefile.traditional-axis-mapping") || origTransf != nullptr) {
157 destTransf.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);
158 }
159#endif
160 OGRCoordinateTransformation* poCT = origTransf == nullptr ? nullptr : OGRCreateCoordinateTransformation(origTransf, &destTransf);
161 if (poCT == nullptr) {
162 if (myOptions.getBool("shapefile.guess-projection")) {
163 OGRSpatialReference origTransf2;
164 origTransf2.SetWellKnownGeogCS("WGS84");
165 poCT = OGRCreateCoordinateTransformation(&origTransf2, &destTransf);
166 }
167 }
168
169 const bool saveOrigIDs = OptionsCont::getOptions().getBool("output.original-names");
170 OGRFeature* poFeature;
171 poLayer->ResetReading();
172
173 const double nodeJoinDist = myOptions.getFloat("shapefile.node-join-dist");
174 const std::vector<std::string> params = myOptions.getStringVector("shapefile.add-params");
175
176 int featureIndex = 0;
177 bool warnNotUnique = true;
178 bool warnMissingProjection = true;
179 std::string idPrefix = ""; // prefix for non-unique street-id values
180 std::map<std::string, int> idIndex; // running index to make street-id unique
181 while ((poFeature = poLayer->GetNextFeature()) != NULL) {
182 // read in edge attributes
183 if (featureIndex == 0) {
184 WRITE_MESSAGE("Available fields: " + toString(getFieldNames(poFeature)));
185 }
186 std::string id;
187 std::string name;
188 std::string from_node;
189 std::string to_node;
190 if (!getStringEntry(poFeature, "shapefile.street-id", "LINK_ID", true, id)) {
191 WRITE_ERRORF(TL("Needed field '%' (street-id) is missing."), id);
192 id = "";
193 }
194 if (id == "") {
196 }
197
198 getStringEntry(poFeature, "shapefile.name", "ST_NAME", true, name);
199 name = StringUtils::replace(name, "&", "&amp;");
200
201 if (!getStringEntry(poFeature, "shapefile.from-id", "REF_IN_ID", true, from_node)) {
202 WRITE_ERRORF(TL("Needed field '%' (from node id) is missing."), from_node);
203 from_node = "";
204 }
205 if (!getStringEntry(poFeature, "shapefile.to-id", "NREF_IN_ID", true, to_node)) {
206 WRITE_ERRORF(TL("Needed field '%' (to node id) is missing."), to_node);
207 to_node = "";
208 }
209
210 if (from_node == "" || to_node == "") {
211 from_node = toString(myRunningNodeID++);
212 to_node = toString(myRunningNodeID++);
213 }
214
215 std::string type;
216 if (myOptions.isSet("shapefile.type-id") && poFeature->GetFieldIndex(myOptions.getString("shapefile.type-id").c_str()) >= 0) {
217 type = poFeature->GetFieldAsString(myOptions.getString("shapefile.type-id").c_str());
218 } else if (poFeature->GetFieldIndex("ST_TYP_AFT") >= 0) {
219 type = poFeature->GetFieldAsString("ST_TYP_AFT");
220 }
221 if ((type != "" || myOptions.isSet("shapefile.type-id")) && !myTypeCont.knows(type)) {
222 WRITE_WARNINGF(TL("Unknown type '%' for edge '%'"), type, id);
223 }
224 bool oneway = myTypeCont.knows(type) ? myTypeCont.getEdgeTypeIsOneWay(type) : false;
225 double speed = getSpeed(*poFeature, id);
226 int nolanes = getLaneNo(*poFeature, id, speed);
227 int priority = getPriority(*poFeature, id);
228 double width = getLaneWidth(*poFeature, id, nolanes);
229 double length = getLength(*poFeature, id);
230 if (nolanes <= 0 || speed <= 0) {
231 if (myOptions.getBool("shapefile.use-defaults-on-failure")) {
232 nolanes = nolanes <= 0 ? myTypeCont.getEdgeTypeNumLanes(type) : nolanes;
233 speed = speed <= 0 ? myTypeCont.getEdgeTypeSpeed(type) : speed;
234 } else {
235 const std::string lanesField = myOptions.isSet("shapefile.laneNumber") ? myOptions.getString("shapefile.laneNumber") : "nolanes";
236 const std::string speedField = myOptions.isSet("shapefile.speed") ? myOptions.getString("shapefile.speed") : "speed";
237 WRITE_ERRORF(TL("Required field '%' or '%' is missing (add fields or set option --shapefile.use-defaults-on-failure)."), lanesField, speedField);
238 WRITE_ERROR("Available fields: " + toString(getFieldNames(poFeature)));
239 OGRFeature::DestroyFeature(poFeature);
240 return;
241 }
242 }
243 if (mySpeedInKMH) {
244 speed /= 3.6;
245 }
246
247
248 // read in the geometry
249 OGRGeometry* poGeometry = poFeature->GetGeometryRef();
250 OGRwkbGeometryType gtype = poGeometry->getGeometryType();
251 if (gtype != wkbLineString && gtype != wkbLineString25D) {
252 OGRFeature::DestroyFeature(poFeature);
253 WRITE_ERRORF(TL("Road geometry must be of type 'linestring' or 'linestring25D' (found '%')"), toString(gtype));
254 return;
255 }
256 OGRLineString* cgeom = (OGRLineString*) poGeometry;
257 if (poCT == nullptr && warnMissingProjection) {
258 int outOfRange = 0;
259 for (int j = 0; j < cgeom->getNumPoints(); j++) {
260 if (fabs(cgeom->getX(j)) > 180 || fabs(cgeom->getY(j)) > 90) {
261 outOfRange++;
262 }
263 }
264 if (2 * outOfRange > cgeom->getNumPoints()) {
265 WRITE_WARNING(TL("No coordinate system found and coordinates look already projected."));
266 GeoConvHelper::init("!", GeoConvHelper::getProcessing().getOffset(), GeoConvHelper::getProcessing().getOrigBoundary(), GeoConvHelper::getProcessing().getConvBoundary());
267 } else {
268 WRITE_WARNING(TL("Could not find geo coordinate system, assuming WGS84."));
269 }
270 warnMissingProjection = false;
271 }
272 if (poCT != nullptr) {
273 // try transform to wgs84
274 cgeom->transform(poCT);
275 }
276
277 PositionVector shape;
278 for (int j = 0; j < cgeom->getNumPoints(); j++) {
279 Position pos(cgeom->getX(j), cgeom->getY(j), cgeom->getZ(j));
281 WRITE_WARNINGF(TL("Unable to project coordinates for edge '%'."), id);
282 }
283 shape.push_back_noDoublePos(pos);
284 }
285
286 // build from-node
287 NBNode* from = myNodeCont.retrieve(from_node);
288 if (from == nullptr) {
289 Position from_pos = shape[0];
290 std::vector<NBNode*> cands = myNodeCont.retrieveByPos(from_pos, nodeJoinDist);
291 if (!cands.empty()) {
292 from = cands.front();
293 }
294 if (from == nullptr) {
295 from = new NBNode(from_node, from_pos);
296 if (!myNodeCont.insert(from)) {
297 WRITE_ERRORF(TL("Node '%' could not be added"), from_node);
298 delete from;
299 continue;
300 }
301 }
302 }
303 // build to-node
304 NBNode* to = myNodeCont.retrieve(to_node);
305 if (to == nullptr) {
306 Position to_pos = shape[-1];
307 std::vector<NBNode*> cands = myNodeCont.retrieveByPos(to_pos, nodeJoinDist);
308 if (!cands.empty()) {
309 to = cands.front();
310 }
311 if (to == nullptr) {
312 to = new NBNode(to_node, to_pos);
313 if (!myNodeCont.insert(to)) {
314 WRITE_ERRORF(TL("Node '%' could not be added"), to_node);
315 delete to;
316 continue;
317 }
318 }
319 }
320
321 if (from == to) {
322 WRITE_WARNINGF(TL("Edge '%' connects identical nodes, skipping."), id);
323 continue;
324 }
325
326 // retrieve the information whether the street is bi-directional
327 std::string dir;
328 int index = poFeature->GetDefnRef()->GetFieldIndex("DIR_TRAVEL");
329 if (index >= 0 && poFeature->IsFieldSet(index)) {
330 dir = poFeature->GetFieldAsString(index);
331 }
332 const std::string origID = saveOrigIDs ? id : "";
333 // check for duplicate ids
334 NBEdge* const existing = myEdgeCont.retrieve(id);
335 NBEdge* const existingReverse = myEdgeCont.retrieve("-" + id);
336 if (existing != nullptr || existingReverse != nullptr) {
337 if ((existing != nullptr && existing->getGeometry() == shape)
338 || (existingReverse != nullptr && existingReverse->getGeometry() == shape.reverse())) {
339 WRITE_ERRORF(TL("Edge '%' is not unique."), (existing != nullptr ? id : existingReverse->getID()));
340 } else {
341 if (idIndex.count(id) == 0) {
342 idIndex[id] = 0;
343 }
344 idIndex[id]++;
345 idPrefix = id;
346 id += "#" + toString(idIndex[id]);
347 if (warnNotUnique) {
348 WRITE_WARNINGF(TL("Edge '%' is not unique. Renaming subsequent edge to '%'."), idPrefix, id);
349 warnNotUnique = false;
350 }
351 }
352 }
353 // add positive direction if wanted
354 if (dir == "B" || dir == "F" || dir == "" || myOptions.getBool("shapefile.all-bidirectional")) {
355 if (myEdgeCont.retrieve(id) == 0) {
356 LaneSpreadFunction spread = dir == "B" || dir == "FALSE" ? LaneSpreadFunction::RIGHT : LaneSpreadFunction::CENTER;
357 if (spread == LaneSpreadFunction::RIGHT && OptionsCont::getOptions().getString("default.spreadtype") == toString(LaneSpreadFunction::ROADCENTER)) {
359 }
360 NBEdge* edge = new NBEdge(id, from, to, type, speed, NBEdge::UNSPECIFIED_FRICTION, nolanes, priority, width, NBEdge::UNSPECIFIED_OFFSET, shape, spread, name, origID);
362 edge->setLoadedLength(length);
363 myEdgeCont.insert(edge);
364 checkSpread(edge);
365 addParams(edge, poFeature, params);
366 } else {
367 WRITE_ERRORF(TL("Could not create edge '%'. An edge with the same id already exists."), id);
368 }
369 }
370 // add negative direction if wanted
371 if ((dir == "B" || dir == "T" || myOptions.getBool("shapefile.all-bidirectional")) && !oneway) {
372 if (myEdgeCont.retrieve("-" + id) == 0) {
373 LaneSpreadFunction spread = dir == "B" || dir == "FALSE" ? LaneSpreadFunction::RIGHT : LaneSpreadFunction::CENTER;
374 if (spread == LaneSpreadFunction::RIGHT && OptionsCont::getOptions().getString("default.spreadtype") == toString(LaneSpreadFunction::ROADCENTER)) {
376 }
377 NBEdge* edge = new NBEdge("-" + id, to, from, type, speed, NBEdge::UNSPECIFIED_FRICTION, nolanes, priority, width, NBEdge::UNSPECIFIED_OFFSET, shape.reverse(), spread, name, origID);
379 edge->setLoadedLength(length);
380 myEdgeCont.insert(edge);
381 checkSpread(edge);
382 addParams(edge, poFeature, params);
383 } else {
384 WRITE_ERRORF(TL("Could not create edge '-%'. An edge with the same id already exists."), id);
385 }
386 }
387 //
388 OGRFeature::DestroyFeature(poFeature);
389 featureIndex++;
390 }
391#if GDAL_VERSION_MAJOR < 2
392 OGRDataSource::DestroyDataSource(poDS);
393#else
394 GDALClose(poDS);
395#endif
397#else
398 WRITE_ERROR(TL("SUMO was compiled without GDAL support."));
399#endif
400}
401
402#ifdef HAVE_GDAL
403double
404NIImporter_ArcView::getSpeed(OGRFeature& poFeature, const std::string& edgeid) {
405 if (myOptions.isSet("shapefile.speed")) {
406 int index = poFeature.GetDefnRef()->GetFieldIndex(myOptions.getString("shapefile.speed").c_str());
407 if (index >= 0 && poFeature.IsFieldSet(index)) {
408 const double speed = poFeature.GetFieldAsDouble(index);
409 if (speed <= 0) {
410 WRITE_WARNING("invalid value for field: '"
411 + myOptions.getString("shapefile.speed")
412 + "': '" + std::string(poFeature.GetFieldAsString(index)) + "'");
413 } else {
414 return speed;
415 }
416 }
417 }
418 if (myOptions.isSet("shapefile.type-id")) {
419 return myTypeCont.getEdgeTypeSpeed(poFeature.GetFieldAsString((char*)(myOptions.getString("shapefile.type-id").c_str())));
420 }
421 // try to get definitions as to be found in SUMO-XML-definitions
422 // idea by John Michael Calandrino
423 int index = poFeature.GetDefnRef()->GetFieldIndex("speed");
424 if (index >= 0 && poFeature.IsFieldSet(index)) {
425 return (double) poFeature.GetFieldAsDouble(index);
426 }
427 index = poFeature.GetDefnRef()->GetFieldIndex("SPEED");
428 if (index >= 0 && poFeature.IsFieldSet(index)) {
429 return (double) poFeature.GetFieldAsDouble(index);
430 }
431 // try to get the NavTech-information
432 index = poFeature.GetDefnRef()->GetFieldIndex("SPEED_CAT");
433 if (index >= 0 && poFeature.IsFieldSet(index)) {
434 std::string def = poFeature.GetFieldAsString(index);
435 return NINavTeqHelper::getSpeed(edgeid, def);
436 }
437 return -1;
438}
439
440
441double
442NIImporter_ArcView::getLaneWidth(OGRFeature& poFeature, const std::string& edgeid, int laneNumber) {
443 if (myOptions.isSet("shapefile.width")) {
444 int index = poFeature.GetDefnRef()->GetFieldIndex(myOptions.getString("shapefile.width").c_str());
445 if (index >= 0 && poFeature.IsFieldSet(index)) {
446 const double width = poFeature.GetFieldAsDouble(index);
447 if (width <= 0) {
448 WRITE_WARNING("invalid value for field: '"
449 + myOptions.getString("shapefile.width")
450 + "' of edge '" + edgeid
451 + "': '" + std::string(poFeature.GetFieldAsString(index)) + "'");
452 } else {
453 return width / laneNumber;
454 }
455 }
456 }
457 if (myOptions.isSet("shapefile.type-id")) {
458 return myTypeCont.getEdgeTypeWidth(poFeature.GetFieldAsString((char*)(myOptions.getString("shapefile.type-id").c_str())));
459 }
461}
462
463
464
465double
466NIImporter_ArcView::getLength(OGRFeature& poFeature, const std::string& edgeid) {
467 if (myOptions.isSet("shapefile.length")) {
468 int index = poFeature.GetDefnRef()->GetFieldIndex(myOptions.getString("shapefile.length").c_str());
469 if (index >= 0 && poFeature.IsFieldSet(index)) {
470 const double length = poFeature.GetFieldAsDouble(index);
471 if (length <= 0) {
472 WRITE_WARNING("invalid value for field: '"
473 + myOptions.getString("shapefile.length")
474 + "' of edge '" + edgeid
475 + "': '" + std::string(poFeature.GetFieldAsString(index)) + "'");
476 } else {
477 return length;
478 }
479 }
480 }
482}
483
484
485int
486NIImporter_ArcView::getLaneNo(OGRFeature& poFeature, const std::string& edgeid,
487 double speed) {
488 if (myOptions.isSet("shapefile.laneNumber")) {
489 int index = poFeature.GetDefnRef()->GetFieldIndex(myOptions.getString("shapefile.laneNumber").c_str());
490 if (index >= 0 && poFeature.IsFieldSet(index)) {
491 const int laneNumber = poFeature.GetFieldAsInteger(index);
492 if (laneNumber <= 0) {
493 WRITE_WARNING("invalid value for field '"
494 + myOptions.getString("shapefile.laneNumber")
495 + "': '" + std::string(poFeature.GetFieldAsString(index)) + "'");
496 } else {
497 return laneNumber;
498 }
499 }
500 }
501 if (myOptions.isSet("shapefile.type-id")) {
502 return (int) myTypeCont.getEdgeTypeNumLanes(poFeature.GetFieldAsString((char*)(myOptions.getString("shapefile.type-id").c_str())));
503 }
504 // try to get definitions as to be found in SUMO-XML-definitions
505 // idea by John Michael Calandrino
506 int index = poFeature.GetDefnRef()->GetFieldIndex("nolanes");
507 if (index >= 0 && poFeature.IsFieldSet(index)) {
508 return (int) poFeature.GetFieldAsInteger(index);
509 }
510 index = poFeature.GetDefnRef()->GetFieldIndex("NOLANES");
511 if (index >= 0 && poFeature.IsFieldSet(index)) {
512 return (int) poFeature.GetFieldAsInteger(index);
513 }
514 index = poFeature.GetDefnRef()->GetFieldIndex("rnol");
515 if (index >= 0 && poFeature.IsFieldSet(index)) {
516 return (int) poFeature.GetFieldAsInteger(index);
517 }
518 index = poFeature.GetDefnRef()->GetFieldIndex("LANE_CAT");
519 if (index >= 0 && poFeature.IsFieldSet(index)) {
520 std::string def = poFeature.GetFieldAsString(index);
521 return NINavTeqHelper::getLaneNumber(edgeid, def, speed);
522 }
523 return 0;
524}
525
526
527int
528NIImporter_ArcView::getPriority(OGRFeature& poFeature, const std::string& /*edgeid*/) {
529 if (myOptions.isSet("shapefile.type-id")) {
530 return myTypeCont.getEdgeTypePriority(poFeature.GetFieldAsString((char*)(myOptions.getString("shapefile.type-id").c_str())));
531 }
532 // try to get definitions as to be found in SUMO-XML-definitions
533 // idea by John Michael Calandrino
534 int index = poFeature.GetDefnRef()->GetFieldIndex("priority");
535 if (index >= 0 && poFeature.IsFieldSet(index)) {
536 return poFeature.GetFieldAsInteger(index);
537 }
538 index = poFeature.GetDefnRef()->GetFieldIndex("PRIORITY");
539 if (index >= 0 && poFeature.IsFieldSet(index)) {
540 return poFeature.GetFieldAsInteger(index);
541 }
542 // try to determine priority from NavTechs FUNC_CLASS attribute
543 index = poFeature.GetDefnRef()->GetFieldIndex("FUNC_CLASS");
544 if (index >= 0 && poFeature.IsFieldSet(index)) {
545 return poFeature.GetFieldAsInteger(index);
546 }
547 return 0;
548}
549
550void
551NIImporter_ArcView::checkSpread(NBEdge* e) {
552 NBEdge* ret = e->getToNode()->getConnectionTo(e->getFromNode());
553 if (ret != 0) {
556 }
557}
558
559bool
560NIImporter_ArcView::getStringEntry(OGRFeature* poFeature, const std::string& optionName, const char* defaultName, bool prune, std::string& into) {
561 std::string v(defaultName);
562 if (myOptions.isSet(optionName)) {
563 v = myOptions.getString(optionName);
564 }
565 if (poFeature->GetFieldIndex(v.c_str()) < 0) {
566 if (myOptions.isSet(optionName)) {
567 into = v;
568 return false;
569 }
570 into = "";
571 return true;
572 }
573 into = poFeature->GetFieldAsString((char*)v.c_str());
574 if (prune) {
575 into = StringUtils::prune(into);
576 }
577 return true;
578}
579
580std::vector<std::string>
581NIImporter_ArcView::getFieldNames(OGRFeature* poFeature) const {
582 std::vector<std::string> fields;
583 for (int i = 0; i < poFeature->GetFieldCount(); i++) {
584 fields.push_back(poFeature->GetFieldDefnRef(i)->GetNameRef());
585 }
586 return fields;
587}
588
589void
590NIImporter_ArcView::addParams(NBEdge* edge, OGRFeature* poFeature, const std::vector<std::string>& params) const {
591 for (const std::string& p : params) {
592 int index = poFeature->GetDefnRef()->GetFieldIndex(p.c_str());
593 if (index >= 0 && poFeature->IsFieldSet(index)) {
594 edge->setParameter(p, poFeature->GetFieldAsString(index));
595 }
596 }
597}
598
599#endif
600
601
602/****************************************************************************/
#define WRITE_WARNINGF(...)
Definition MsgHandler.h:287
#define WRITE_ERRORF(...)
Definition MsgHandler.h:296
#define WRITE_MESSAGE(msg)
Definition MsgHandler.h:288
#define WRITE_ERROR(msg)
Definition MsgHandler.h:295
#define WRITE_WARNING(msg)
Definition MsgHandler.h:286
#define TL(string)
Definition MsgHandler.h:304
#define PROGRESS_DONE_MESSAGE()
Definition MsgHandler.h:291
#define PROGRESS_BEGIN_MESSAGE(msg)
Definition MsgHandler.h:290
LaneSpreadFunction
Numbers representing special SUMO-XML-attribute values Information how the edge's lateral offset shal...
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:49
static bool isReadable(std::string path)
Checks whether the given file is readable.
static GeoConvHelper & getProcessing()
the coordinate transformation to use for input conversion and processing
static bool init(OptionsCont &oc)
Initialises the processing and the final instance using the given options.
static MsgHandler * getErrorInstance()
Returns the instance to add errors to.
Storage for edges, including some functionality operating on multiple edges.
Definition NBEdgeCont.h:59
NBEdge * retrieve(const std::string &id, bool retrieveExtracted=false) const
Returns the edge that has the given id.
bool insert(NBEdge *edge, bool ignorePrunning=false)
Adds an edge to the dictionary.
The representation of a single edge during network building.
Definition NBEdge.h:92
void setPermissions(SVCPermissions permissions, int lane=-1)
set allowed/disallowed classes for the given lane or for all lanes if -1 is given
Definition NBEdge.cpp:4506
NBNode * getToNode() const
Returns the destination node of the edge.
Definition NBEdge.h:552
static const double UNSPECIFIED_FRICTION
unspecified lane friction
Definition NBEdge.h:355
const PositionVector & getGeometry() const
Returns the geometry of the edge.
Definition NBEdge.h:789
const std::string & getID() const
Definition NBEdge.h:1551
static const double UNSPECIFIED_LOADED_LENGTH
no length override given
Definition NBEdge.h:364
void setLaneSpreadFunction(LaneSpreadFunction spread)
(Re)sets how the lanes lateral offset shall be computed
Definition NBEdge.cpp:1015
NBNode * getFromNode() const
Returns the origin node of the edge.
Definition NBEdge.h:545
static const double UNSPECIFIED_WIDTH
unspecified lane width
Definition NBEdge.h:346
static const double UNSPECIFIED_OFFSET
unspecified lane offset
Definition NBEdge.h:349
void setLoadedLength(double val)
set loaded length
Definition NBEdge.cpp:4558
Instance responsible for building networks.
NBNodeCont & getNodeCont()
Returns a reference to the node container.
NBEdgeCont & getEdgeCont()
NBTypeCont & getTypeCont()
Returns a reference to the type container.
static bool transformCoordinate(Position &from, bool includeInBoundary=true, GeoConvHelper *from_srs=nullptr)
transforms loaded coordinates handles projections, offsets (using GeoConvHelper) and import of height...
Container for nodes during the netbuilding process.
Definition NBNodeCont.h:57
std::vector< NBNode * > retrieveByPos(const Position &position, const double offset=0.) const
Returns the node with the given coordinates.
bool insert(const std::string &id, const Position &position, NBDistrict *district=0)
Inserts a node into the map.
NBNode * retrieve(const std::string &id) const
Returns the node with the given name.
Represents a single node (junction) during network building.
Definition NBNode.h:66
NBEdge * getConnectionTo(NBNode *n) const
get connection to certain node
Definition NBNode.cpp:2810
A storage for available edgeTypes of edges.
Definition NBTypeCont.h:52
double getEdgeTypeSpeed(const std::string &edgeType) const
Returns the maximal velocity for the given edgeType [m/s].
int getEdgeTypePriority(const std::string &edgeType) const
Returns the priority for the given edgeType.
int getEdgeTypeNumLanes(const std::string &edgeType) const
Returns the number of lanes for the given edgeType.
double getEdgeTypeWidth(const std::string &edgeType) const
Returns the lane width for the given edgeType [m].
SVCPermissions getEdgeTypePermissions(const std::string &edgeType) const
Returns allowed vehicle classes for the given edgeType.
bool knows(const std::string &edgeType) const
Returns whether the named edgeType is in the container.
bool getEdgeTypeIsOneWay(const std::string &edgeType) const
Returns whether edges are one-way per default for the given edgeType.
Importer for networks stored in ArcView-shape format.
const OptionsCont & myOptions
The options to use.
void load()
Loads the shape files.
int myRunningEdgeID
A running number to assure unique ids (as fallback)
static void loadNetwork(const OptionsCont &oc, NBNetBuilder &nb)
Loads content of the optionally given ArcView Shape files.
std::string mySHPName
The name of the shape file.
NBTypeCont & myTypeCont
The container to get the types from.
NBNodeCont & myNodeCont
The container to add nodes to.
bool mySpeedInKMH
Whether the speed is given in km/h.
NBEdgeCont & myEdgeCont
The container to add edges to.
NIImporter_ArcView(const OptionsCont &oc, NBNodeCont &nc, NBEdgeCont &ec, NBTypeCont &tc, const std::string &shp_name, bool speedInKMH)
Constructor.
static int getLaneNumber(const std::string &id, const std::string &laneNoS, double speed)
Returns the lane number evaluating the given Navteq-description.
static double getSpeed(const std::string &id, const std::string &speedClassS)
Returns the speed evaluating the given Navteq-description.
A storage for options typed value containers)
Definition OptionsCont.h:89
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
const StringVector & getStringVector(const std::string &name) const
Returns the list of string-value of the named option (only for Option_StringVector)
static OptionsCont & getOptions()
Retrieves the options.
virtual void setParameter(const std::string &key, const std::string &value)
Sets a parameter.
A point in 2D or 3D with translation and scaling methods.
Definition Position.h:37
A list of positions.
void push_back_noDoublePos(const Position &p)
insert in back a non double position
PositionVector reverse() const
reverse position vector
static std::string replace(std::string str, const std::string &what, const std::string &by)
Replaces all occurrences of the second string by the third string within the first string.
static std::string prune(const std::string &str)
Removes trailing and leading whitechars.
static bool startsWith(const std::string &str, const std::string prefix)
Checks whether a given string starts with the prefix.