49 #pragma GCC diagnostic push
50 #pragma GCC diagnostic ignored "-Wpedantic"
52 #include <ogrsf_frmts.h>
54 #pragma GCC diagnostic pop
67 if (!oc.
isSet(
"shapefile-prefix")) {
72 std::string dbf_file = oc.
getString(
"shapefile-prefix") +
".dbf";
73 std::string shp_file = oc.
getString(
"shapefile-prefix") +
".shp";
74 std::string shx_file = oc.
getString(
"shapefile-prefix") +
".shx";
91 dbf_file, shp_file, oc.
getBool(
"speed-in-kmh"));
104 const std::string& dbf_name,
105 const std::string& shp_name,
107 : myOptions(oc), mySHPName(shp_name),
109 myNodeCont(nc), myEdgeCont(ec), myTypeCont(tc),
110 mySpeedInKMH(speedInKMH),
124 #if GDAL_VERSION_MAJOR < 2
126 OGRDataSource* poDS = OGRSFDriverRegistrar::Open(
mySHPName.c_str(), FALSE);
129 GDALDataset* poDS = (GDALDataset*)GDALOpenEx(
mySHPName.c_str(), GDAL_OF_VECTOR | GA_ReadOnly, NULL, NULL, NULL);
137 OGRLayer* poLayer = poDS->GetLayer(0);
138 poLayer->ResetReading();
141 OGRSpatialReference* origTransf = poLayer->GetSpatialRef();
142 OGRSpatialReference destTransf;
144 destTransf.SetWellKnownGeogCS(
"WGS84");
145 OGRCoordinateTransformation* poCT = OGRCreateCoordinateTransformation(origTransf, &destTransf);
148 OGRSpatialReference origTransf2;
149 origTransf2.SetWellKnownGeogCS(
"WGS84");
150 poCT = OGRCreateCoordinateTransformation(&origTransf2, &destTransf);
153 WRITE_WARNING(
"Could not create geocoordinates converter; check whether proj.4 is installed.");
158 OGRFeature* poFeature;
159 poLayer->ResetReading();
164 int featureIndex = 0;
165 bool warnNotUnique =
true;
166 std::string idPrefix =
"";
167 std::map<std::string, int> idIndex;
168 while ((poFeature = poLayer->GetNextFeature()) != NULL) {
170 if (featureIndex == 0) {
175 std::string from_node;
177 if (!getStringEntry(poFeature,
"shapefile.street-id",
"LINK_ID",
true,
id)) {
178 WRITE_ERROR(
"Needed field '" +
id +
"' (street-id) is missing.");
185 getStringEntry(poFeature,
"shapefile.name",
"ST_NAME",
true, name);
188 if (!getStringEntry(poFeature,
"shapefile.from-id",
"REF_IN_ID",
true, from_node)) {
189 WRITE_ERROR(
"Needed field '" + from_node +
"' (from node id) is missing.");
192 if (!getStringEntry(poFeature,
"shapefile.to-id",
"NREF_IN_ID",
true, to_node)) {
193 WRITE_ERROR(
"Needed field '" + to_node +
"' (to node id) is missing.");
197 if (from_node ==
"" || to_node ==
"") {
205 }
else if (poFeature->GetFieldIndex(
"ST_TYP_AFT") >= 0) {
206 type = poFeature->GetFieldAsString(
"ST_TYP_AFT");
209 WRITE_WARNING(
"Unknown type '" + type +
"' for edge '" +
id +
"'");
213 double speed = getSpeed(*poFeature,
id);
214 int nolanes = getLaneNo(*poFeature,
id, speed);
215 int priority = getPriority(*poFeature,
id);
216 if (nolanes <= 0 || speed <= 0) {
223 WRITE_ERROR(
"Required field '" + lanesField +
"' or '" + speedField +
"' is missing (add fields or set option --shapefile.use-defaults-on-failure).");
225 OGRFeature::DestroyFeature(poFeature);
230 speed = speed / (double) 3.6;
235 OGRGeometry* poGeometry = poFeature->GetGeometryRef();
236 OGRwkbGeometryType gtype = poGeometry->getGeometryType();
237 if (gtype != wkbLineString && gtype != wkbLineString25D) {
238 OGRFeature::DestroyFeature(poFeature);
239 WRITE_ERROR(
"Road geometry must be of type 'linestring' or 'linestring25D' (found '" +
toString(gtype) +
"')");
242 OGRLineString* cgeom = (OGRLineString*) poGeometry;
245 cgeom->transform(poCT);
249 for (
int j = 0; j < cgeom->getNumPoints(); j++) {
250 Position pos((
double) cgeom->getX(j), (
double) cgeom->getY(j), (
double) cgeom->getZ(j));
252 WRITE_WARNING(
"Unable to project coordinates for edge '" +
id +
"'.");
263 from =
new NBNode(from_node, from_pos);
265 WRITE_ERROR(
"Node '" + from_node +
"' could not be added");
277 to =
new NBNode(to_node, to_pos);
279 WRITE_ERROR(
"Node '" + to_node +
"' could not be added");
287 WRITE_WARNING(
"Edge '" +
id +
"' connects identical nodes, skipping.");
293 int index = poFeature->GetDefnRef()->GetFieldIndex(
"DIR_TRAVEL");
294 if (index >= 0 && poFeature->IsFieldSet(index)) {
295 dir = poFeature->GetFieldAsString(index);
297 const std::string origID = saveOrigIDs ? id :
"";
301 if (existing !=
nullptr || existingReverse !=
nullptr) {
302 std::string duplicateID = existing !=
nullptr ? id : existingReverse->
getID();
303 if ((existing != 0 && existing->
getGeometry() == shape)
305 WRITE_ERROR(
"Edge '" + duplicateID +
" is not unique");
307 if (idIndex.count(
id) == 0) {
314 WRITE_WARNING(
"street-id '" + idPrefix +
"' is not unique. Renaming subsequent edge to '" +
id +
"'");
315 warnNotUnique =
false;
320 if (dir ==
"B" || dir ==
"F" || dir ==
"" ||
myOptions.
getBool(
"shapefile.all-bidirectional")) {
323 NBEdge* edge =
new NBEdge(
id, from, to, type, speed, nolanes, priority, width,
NBEdge::UNSPECIFIED_OFFSET, shape, name, origID, spread);
327 addParams(edge, poFeature, params);
329 WRITE_ERROR(
"Could not create edge '" +
id +
"'. An edge with the same id already exists");
333 if ((dir ==
"B" || dir ==
"T" ||
myOptions.
getBool(
"shapefile.all-bidirectional")) && !oneway) {
336 NBEdge* edge =
new NBEdge(
"-" +
id, to, from, type, speed, nolanes, priority, width,
NBEdge::UNSPECIFIED_OFFSET, shape.
reverse(), name, origID, spread);
340 addParams(edge, poFeature, params);
342 WRITE_ERROR(
"Could not create edge '-" +
id +
"'. An edge with the same id already exists");
346 OGRFeature::DestroyFeature(poFeature);
349 #if GDAL_VERSION_MAJOR < 2
350 OGRDataSource::DestroyDataSource(poDS);
356 WRITE_ERROR(
"SUMO was compiled without GDAL support.");
362 NIImporter_ArcView::getSpeed(OGRFeature& poFeature,
const std::string& edgeid) {
364 int index = poFeature.GetDefnRef()->GetFieldIndex(
myOptions.
getString(
"shapefile.speed").c_str());
365 if (index >= 0 && poFeature.IsFieldSet(index)) {
366 const double speed = poFeature.GetFieldAsDouble(index);
370 +
"': '" + std::string(poFeature.GetFieldAsString(index)) +
"'");
381 int index = poFeature.GetDefnRef()->GetFieldIndex(
"speed");
382 if (index >= 0 && poFeature.IsFieldSet(index)) {
383 return (
double) poFeature.GetFieldAsDouble(index);
385 index = poFeature.GetDefnRef()->GetFieldIndex(
"SPEED");
386 if (index >= 0 && poFeature.IsFieldSet(index)) {
387 return (
double) poFeature.GetFieldAsDouble(index);
390 index = poFeature.GetDefnRef()->GetFieldIndex(
"SPEED_CAT");
391 if (index >= 0 && poFeature.IsFieldSet(index)) {
392 std::string def = poFeature.GetFieldAsString(index);
400 NIImporter_ArcView::getLaneNo(OGRFeature& poFeature,
const std::string& edgeid,
403 int index = poFeature.GetDefnRef()->GetFieldIndex(
myOptions.
getString(
"shapefile.laneNumber").c_str());
404 if (index >= 0 && poFeature.IsFieldSet(index)) {
405 const int laneNumber = poFeature.GetFieldAsInteger(index);
406 if (laneNumber <= 0) {
409 +
"': '" + std::string(poFeature.GetFieldAsString(index)) +
"'");
420 int index = poFeature.GetDefnRef()->GetFieldIndex(
"nolanes");
421 if (index >= 0 && poFeature.IsFieldSet(index)) {
422 return (
int) poFeature.GetFieldAsInteger(index);
424 index = poFeature.GetDefnRef()->GetFieldIndex(
"NOLANES");
425 if (index >= 0 && poFeature.IsFieldSet(index)) {
426 return (
int) poFeature.GetFieldAsInteger(index);
428 index = poFeature.GetDefnRef()->GetFieldIndex(
"rnol");
429 if (index >= 0 && poFeature.IsFieldSet(index)) {
430 return (
int) poFeature.GetFieldAsInteger(index);
432 index = poFeature.GetDefnRef()->GetFieldIndex(
"LANE_CAT");
433 if (index >= 0 && poFeature.IsFieldSet(index)) {
434 std::string def = poFeature.GetFieldAsString(index);
442 NIImporter_ArcView::getPriority(OGRFeature& poFeature,
const std::string& ) {
448 int index = poFeature.GetDefnRef()->GetFieldIndex(
"priority");
449 if (index >= 0 && poFeature.IsFieldSet(index)) {
450 return poFeature.GetFieldAsInteger(index);
452 index = poFeature.GetDefnRef()->GetFieldIndex(
"PRIORITY");
453 if (index >= 0 && poFeature.IsFieldSet(index)) {
454 return poFeature.GetFieldAsInteger(index);
457 index = poFeature.GetDefnRef()->GetFieldIndex(
"FUNC_CLASS");
458 if (index >= 0 && poFeature.IsFieldSet(index)) {
459 return poFeature.GetFieldAsInteger(index);
465 NIImporter_ArcView::checkSpread(
NBEdge* e) {
474 NIImporter_ArcView::getStringEntry(OGRFeature* poFeature,
const std::string& optionName,
const char* defaultName,
bool prune, std::string& into) {
475 std::string v(defaultName);
479 if (poFeature->GetFieldIndex(v.c_str()) < 0) {
487 into = poFeature->GetFieldAsString((
char*)v.c_str());
494 std::vector<std::string>
495 NIImporter_ArcView::getFieldNames(OGRFeature* poFeature)
const {
496 std::vector<std::string> fields;
497 for (
int i = 0; i < poFeature->GetFieldCount(); i++) {
498 fields.push_back(poFeature->GetFieldDefnRef(i)->GetNameRef());
504 NIImporter_ArcView::addParams(
NBEdge* edge, OGRFeature* poFeature,
const std::vector<std::string>& params)
const {
505 for (
const std::string& p : params) {
506 int index = poFeature->GetDefnRef()->GetFieldIndex(p.c_str());
507 if (index >= 0 && poFeature->IsFieldSet(index)) {
508 edge->
setParameter(p, poFeature->GetFieldAsString(index));