49#pragma warning(disable: 4435 5219 5220)
52#pragma GCC diagnostic push
53#pragma GCC diagnostic ignored "-Wpedantic"
55#include <gdal_version.h>
56#include <ogrsf_frmts.h>
58#pragma GCC diagnostic pop
74 if (!oc.
isSet(
"shapefile-prefix")) {
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";
99 shp_file, oc.
getBool(
"speed-in-kmh"));
112 const std::string& shp_name,
114 : myOptions(oc), mySHPName(shp_name),
116 myNodeCont(nc), myEdgeCont(ec), myTypeCont(tc),
117 mySpeedInKMH(speedInKMH),
130#if GDAL_VERSION_MAJOR < 2
132 OGRDataSource* poDS = OGRSFDriverRegistrar::Open(
mySHPName.c_str(), FALSE);
135 GDALDataset* poDS = (GDALDataset*)GDALOpenEx(
mySHPName.c_str(), GDAL_OF_VECTOR | GA_ReadOnly, NULL, NULL, NULL);
143 OGRLayer* poLayer = poDS->GetLayer(0);
144 poLayer->ResetReading();
147#if GDAL_VERSION_MAJOR < 3
148 OGRSpatialReference* origTransf = poLayer->GetSpatialRef();
150 const OGRSpatialReference* origTransf = poLayer->GetSpatialRef();
152 OGRSpatialReference destTransf;
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);
160 OGRCoordinateTransformation* poCT = origTransf ==
nullptr ? nullptr : OGRCreateCoordinateTransformation(origTransf, &destTransf);
161 if (poCT ==
nullptr) {
163 OGRSpatialReference origTransf2;
164 origTransf2.SetWellKnownGeogCS(
"WGS84");
165 poCT = OGRCreateCoordinateTransformation(&origTransf2, &destTransf);
170 OGRFeature* poFeature;
171 poLayer->ResetReading();
176 int featureIndex = 0;
177 bool warnNotUnique =
true;
178 bool warnMissingProjection =
true;
179 std::string idPrefix =
"";
180 std::map<std::string, int> idIndex;
181 while ((poFeature = poLayer->GetNextFeature()) != NULL) {
183 if (featureIndex == 0) {
188 std::string from_node;
190 if (!getStringEntry(poFeature,
"shapefile.street-id",
"LINK_ID",
true,
id)) {
198 getStringEntry(poFeature,
"shapefile.name",
"ST_NAME",
true, name);
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);
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);
210 if (from_node ==
"" || to_node ==
"") {
218 }
else if (poFeature->GetFieldIndex(
"ST_TYP_AFT") >= 0) {
219 type = poFeature->GetFieldAsString(
"ST_TYP_AFT");
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) {
237 WRITE_ERRORF(
TL(
"Required field '%' or '%' is missing (add fields or set option --shapefile.use-defaults-on-failure)."), lanesField, speedField);
239 OGRFeature::DestroyFeature(poFeature);
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));
256 OGRLineString* cgeom = (OGRLineString*) poGeometry;
257 if (poCT ==
nullptr && warnMissingProjection) {
259 for (
int j = 0; j < cgeom->getNumPoints(); j++) {
260 if (fabs(cgeom->getX(j)) > 180 || fabs(cgeom->getY(j)) > 90) {
264 if (2 * outOfRange > cgeom->getNumPoints()) {
265 WRITE_WARNING(
TL(
"No coordinate system found and coordinates look already projected."));
268 WRITE_WARNING(
TL(
"Could not find geo coordinate system, assuming WGS84."));
270 warnMissingProjection =
false;
272 if (poCT !=
nullptr) {
274 cgeom->transform(poCT);
278 for (
int j = 0; j < cgeom->getNumPoints(); j++) {
279 Position pos(cgeom->getX(j), cgeom->getY(j), cgeom->getZ(j));
288 if (from ==
nullptr) {
291 if (!cands.empty()) {
292 from = cands.front();
294 if (from ==
nullptr) {
295 from =
new NBNode(from_node, from_pos);
308 if (!cands.empty()) {
312 to =
new NBNode(to_node, to_pos);
328 int index = poFeature->GetDefnRef()->GetFieldIndex(
"DIR_TRAVEL");
329 if (index >= 0 && poFeature->IsFieldSet(index)) {
330 dir = poFeature->GetFieldAsString(index);
332 const std::string origID = saveOrigIDs ? 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()));
341 if (idIndex.count(
id) == 0) {
348 WRITE_WARNINGF(
TL(
"Edge '%' is not unique. Renaming subsequent edge to '%'."), idPrefix,
id);
349 warnNotUnique =
false;
354 if (dir ==
"B" || dir ==
"F" || dir ==
"" ||
myOptions.
getBool(
"shapefile.all-bidirectional")) {
360 NBEdge* edge =
new NBEdge(
id, from, to, type, speed,
NBEdge::UNSPECIFIED_FRICTION, nolanes, priority, width,
NBEdge::UNSPECIFIED_OFFSET, shape, spread, name, origID);
365 addParams(edge, poFeature, params);
367 WRITE_ERRORF(
TL(
"Could not create edge '%'. An edge with the same id already exists."),
id);
371 if ((dir ==
"B" || dir ==
"T" ||
myOptions.
getBool(
"shapefile.all-bidirectional")) && !oneway) {
377 NBEdge* edge =
new NBEdge(
"-" +
id, to, from, type, speed,
NBEdge::UNSPECIFIED_FRICTION, nolanes, priority, width,
NBEdge::UNSPECIFIED_OFFSET, shape.
reverse(), spread, name, origID);
382 addParams(edge, poFeature, params);
384 WRITE_ERRORF(
TL(
"Could not create edge '-%'. An edge with the same id already exists."),
id);
388 OGRFeature::DestroyFeature(poFeature);
391#if GDAL_VERSION_MAJOR < 2
392 OGRDataSource::DestroyDataSource(poDS);
404NIImporter_ArcView::getSpeed(OGRFeature& poFeature,
const std::string& edgeid) {
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);
412 +
"': '" + std::string(poFeature.GetFieldAsString(index)) +
"'");
423 int index = poFeature.GetDefnRef()->GetFieldIndex(
"speed");
424 if (index >= 0 && poFeature.IsFieldSet(index)) {
425 return (
double) poFeature.GetFieldAsDouble(index);
427 index = poFeature.GetDefnRef()->GetFieldIndex(
"SPEED");
428 if (index >= 0 && poFeature.IsFieldSet(index)) {
429 return (
double) poFeature.GetFieldAsDouble(index);
432 index = poFeature.GetDefnRef()->GetFieldIndex(
"SPEED_CAT");
433 if (index >= 0 && poFeature.IsFieldSet(index)) {
434 std::string def = poFeature.GetFieldAsString(index);
442NIImporter_ArcView::getLaneWidth(OGRFeature& poFeature,
const std::string& edgeid,
int laneNumber) {
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);
450 +
"' of edge '" + edgeid
451 +
"': '" + std::string(poFeature.GetFieldAsString(index)) +
"'");
453 return width / laneNumber;
466NIImporter_ArcView::getLength(OGRFeature& poFeature,
const std::string& edgeid) {
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);
474 +
"' of edge '" + edgeid
475 +
"': '" + std::string(poFeature.GetFieldAsString(index)) +
"'");
486NIImporter_ArcView::getLaneNo(OGRFeature& poFeature,
const std::string& edgeid,
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) {
495 +
"': '" + std::string(poFeature.GetFieldAsString(index)) +
"'");
506 int index = poFeature.GetDefnRef()->GetFieldIndex(
"nolanes");
507 if (index >= 0 && poFeature.IsFieldSet(index)) {
508 return (
int) poFeature.GetFieldAsInteger(index);
510 index = poFeature.GetDefnRef()->GetFieldIndex(
"NOLANES");
511 if (index >= 0 && poFeature.IsFieldSet(index)) {
512 return (
int) poFeature.GetFieldAsInteger(index);
514 index = poFeature.GetDefnRef()->GetFieldIndex(
"rnol");
515 if (index >= 0 && poFeature.IsFieldSet(index)) {
516 return (
int) poFeature.GetFieldAsInteger(index);
518 index = poFeature.GetDefnRef()->GetFieldIndex(
"LANE_CAT");
519 if (index >= 0 && poFeature.IsFieldSet(index)) {
520 std::string def = poFeature.GetFieldAsString(index);
528NIImporter_ArcView::getPriority(OGRFeature& poFeature,
const std::string& ) {
534 int index = poFeature.GetDefnRef()->GetFieldIndex(
"priority");
535 if (index >= 0 && poFeature.IsFieldSet(index)) {
536 return poFeature.GetFieldAsInteger(index);
538 index = poFeature.GetDefnRef()->GetFieldIndex(
"PRIORITY");
539 if (index >= 0 && poFeature.IsFieldSet(index)) {
540 return poFeature.GetFieldAsInteger(index);
543 index = poFeature.GetDefnRef()->GetFieldIndex(
"FUNC_CLASS");
544 if (index >= 0 && poFeature.IsFieldSet(index)) {
545 return poFeature.GetFieldAsInteger(index);
551NIImporter_ArcView::checkSpread(
NBEdge* e) {
560NIImporter_ArcView::getStringEntry(OGRFeature* poFeature,
const std::string& optionName,
const char* defaultName,
bool prune, std::string& into) {
561 std::string v(defaultName);
565 if (poFeature->GetFieldIndex(v.c_str()) < 0) {
573 into = poFeature->GetFieldAsString((
char*)v.c_str());
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());
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));
#define WRITE_WARNINGF(...)
#define WRITE_ERRORF(...)
#define WRITE_MESSAGE(msg)
#define WRITE_WARNING(msg)
#define PROGRESS_DONE_MESSAGE()
#define PROGRESS_BEGIN_MESSAGE(msg)
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)
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.
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.
void setPermissions(SVCPermissions permissions, int lane=-1)
set allowed/disallowed classes for the given lane or for all lanes if -1 is given
NBNode * getToNode() const
Returns the destination node of the edge.
static const double UNSPECIFIED_FRICTION
unspecified lane friction
const PositionVector & getGeometry() const
Returns the geometry of the edge.
const std::string & getID() const
static const double UNSPECIFIED_LOADED_LENGTH
no length override given
void setLaneSpreadFunction(LaneSpreadFunction spread)
(Re)sets how the lanes lateral offset shall be computed
NBNode * getFromNode() const
Returns the origin node of the edge.
static const double UNSPECIFIED_WIDTH
unspecified lane width
static const double UNSPECIFIED_OFFSET
unspecified lane offset
void setLoadedLength(double val)
set loaded length
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.
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.
NBEdge * getConnectionTo(NBNode *n) const
get connection to certain node
A storage for available edgeTypes of edges.
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.
~NIImporter_ArcView()
Destructor.
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)
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.
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.