00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef _MSC_VER
00025 #include <windows_config.h>
00026 #else
00027 #include <config.h>
00028 #endif
00029
00030 #include <string>
00031 #include <utils/common/MsgHandler.h>
00032 #include <utils/common/ToString.h>
00033 #include <utils/common/TplConvert.h>
00034 #include <utils/common/StringUtils.h>
00035 #include <utils/options/OptionsCont.h>
00036 #include <utils/geom/GeomHelper.h>
00037 #include <netbuild/NBNetBuilder.h>
00038 #include <netbuild/NBHelpers.h>
00039 #include <netbuild/NBEdge.h>
00040 #include <netbuild/NBEdgeCont.h>
00041 #include <netbuild/NBTypeCont.h>
00042 #include <netbuild/NBNode.h>
00043 #include <netbuild/NBNodeCont.h>
00044 #include "NIImporter_ArcView.h"
00045 #include <netimport/NINavTeqHelper.h>
00046 #include <utils/geom/GeoConvHelper.h>
00047 #include <utils/common/FileHelpers.h>
00048
00049 #ifdef HAVE_GDAL
00050 #include <ogrsf_frmts.h>
00051 #endif
00052
00053 #ifdef CHECK_MEMORY_LEAKS
00054 #include <foreign/nvwa/debug_new.h>
00055 #endif // CHECK_MEMORY_LEAKS
00056
00057
00058
00059
00060
00061
00062
00063
00064 void
00065 NIImporter_ArcView::loadNetwork(const OptionsCont &oc, NBNetBuilder &nb) {
00066 if (!oc.isSet("arcview")) {
00067 return;
00068 }
00069
00070
00071 std::string dbf_file = oc.getString("arcview") + ".dbf";
00072 std::string shp_file = oc.getString("arcview") + ".shp";
00073 std::string shx_file = oc.getString("arcview") + ".shx";
00074
00075 if (!FileHelpers::exists(dbf_file)) {
00076 MsgHandler::getErrorInstance()->inform("File not found: " + dbf_file);
00077 }
00078 if (!FileHelpers::exists(shp_file)) {
00079 MsgHandler::getErrorInstance()->inform("File not found: " + shp_file);
00080 }
00081 if (!FileHelpers::exists(shx_file)) {
00082 MsgHandler::getErrorInstance()->inform("File not found: " + shx_file);
00083 }
00084 if (MsgHandler::getErrorInstance()->wasInformed()) {
00085 return;
00086 }
00087
00088 NIImporter_ArcView loader(oc,
00089 nb.getNodeCont(), nb.getEdgeCont(), nb.getTypeCont(),
00090 dbf_file, shp_file, oc.getBool("speed-in-kmh"));
00091 loader.load();
00092 }
00093
00094
00095
00096
00097
00098
00099 NIImporter_ArcView::NIImporter_ArcView(const OptionsCont &oc,
00100 NBNodeCont &nc,
00101 NBEdgeCont &ec,
00102 NBTypeCont &tc,
00103 const std::string &dbf_name,
00104 const std::string &shp_name,
00105 bool speedInKMH)
00106 : myOptions(oc), mySHPName(shp_name),
00107 myNameAddition(0),
00108 myNodeCont(nc), myEdgeCont(ec), myTypeCont(tc),
00109 mySpeedInKMH(speedInKMH),
00110 myRunningNodeID(0) {}
00111
00112
00113 NIImporter_ArcView::~NIImporter_ArcView() {}
00114
00115
00116 void
00117 NIImporter_ArcView::load() {
00118 #ifdef HAVE_GDAL
00119 MsgHandler::getMessageInstance()->beginProcessMsg("Loading data from '" + mySHPName + "'...");
00120 OGRRegisterAll();
00121 OGRDataSource *poDS = OGRSFDriverRegistrar::Open(mySHPName.c_str(), FALSE);
00122 if (poDS == NULL) {
00123 MsgHandler::getErrorInstance()->inform("Could not open shape description '" + mySHPName + "'.");
00124 return;
00125 }
00126
00127
00128 OGRLayer *poLayer = poDS->GetLayer(0);
00129 poLayer->ResetReading();
00130
00131
00132 OGRSpatialReference *origTransf = poLayer->GetSpatialRef();
00133 OGRSpatialReference destTransf;
00134
00135 destTransf.SetWellKnownGeogCS("WGS84");
00136 OGRCoordinateTransformation *poCT =
00137 OGRCreateCoordinateTransformation(origTransf, &destTransf);
00138 if (poCT == NULL) {
00139 if (myOptions.isSet("arcview.guess-projection")) {
00140 OGRSpatialReference origTransf2;
00141 origTransf2.SetWellKnownGeogCS("WGS84");
00142 poCT = OGRCreateCoordinateTransformation(&origTransf2, &destTransf);
00143 }
00144 if (poCT==0) {
00145 WRITE_WARNING("Could not create geocoordinates converter; check whether proj.4 is installed.");
00146 }
00147 }
00148
00149 OGRFeature *poFeature;
00150 poLayer->ResetReading();
00151 while ((poFeature = poLayer->GetNextFeature()) != NULL) {
00152
00153 std::string id =
00154 myOptions.isSet("arcview.street-id")
00155 ? poFeature->GetFieldAsString((char*)(myOptions.getString("arcview.street-id").c_str()))
00156 : poFeature->GetFieldAsString("LINK_ID");
00157 id = StringUtils::prune(id);
00158 if (id=="") {
00159 MsgHandler::getErrorInstance()->inform("Could not obtain edge id.");
00160 return;
00161 }
00162 std::string name =
00163 myOptions.isSet("arcview.street-id")
00164 ? poFeature->GetFieldAsString((char*) myOptions.getString("arcview.street-id").c_str())
00165 : poFeature->GetFieldAsString("ST_NAME");
00166 name = StringUtils::prune(StringUtils::replace(name, "&", "&"));
00167
00168 std::string from_node =
00169 myOptions.isSet("arcview.from-id")
00170 ? poFeature->GetFieldAsString((char*)(myOptions.getString("arcview.from-id").c_str()))
00171 : poFeature->GetFieldAsString("REF_IN_ID");
00172 from_node = StringUtils::prune(from_node);
00173 std::string to_node =
00174 myOptions.isSet("arcview.to-id")
00175 ? poFeature->GetFieldAsString((char*) myOptions.getString("arcview.to-id").c_str())
00176 : poFeature->GetFieldAsString("NREF_IN_ID");
00177 to_node = StringUtils::prune(to_node);
00178 if (from_node==""||to_node=="") {
00179 from_node = toString(myRunningNodeID++);
00180 to_node = toString(myRunningNodeID++);
00181 }
00182 std::string type = poFeature->GetFieldAsString("ST_TYP_AFT");
00183 SUMOReal speed = getSpeed(*poFeature, id);
00184 unsigned int nolanes = getLaneNo(*poFeature, id, speed);
00185 int priority = getPriority(*poFeature, id);
00186 if (nolanes==0||speed==0) {
00187 if (myOptions.getBool("arcview.use-defaults-on-failure")) {
00188 nolanes = myTypeCont.getDefaultNoLanes();
00189 speed = myTypeCont.getDefaultSpeed();
00190 } else {
00191 OGRFeature::DestroyFeature(poFeature);
00192 MsgHandler::getErrorInstance()->inform("The description seems to be invalid. Please recheck usage of types.");
00193 return;
00194 }
00195 }
00196 if (mySpeedInKMH) {
00197 speed = speed / (SUMOReal) 3.6;
00198 }
00199
00200
00201
00202 OGRGeometry *poGeometry = poFeature->GetGeometryRef();
00203 OGRwkbGeometryType gtype = poGeometry->getGeometryType();
00204 assert(gtype==wkbLineString);
00205 OGRLineString *cgeom = (OGRLineString*) poGeometry;
00206 if (poCT!=0) {
00207
00208 cgeom->transform(poCT);
00209 }
00210
00211 Position2DVector shape;
00212 for (int j=0; j<cgeom->getNumPoints(); j++) {
00213 Position2D pos((SUMOReal) cgeom->getX(j), (SUMOReal) cgeom->getY(j));
00214 if (!GeoConvHelper::x2cartesian(pos)) {
00215 WRITE_WARNING("Unable to project coordinates for edge '" + id + "'.");
00216 }
00217 shape.push_back_noDoublePos(pos);
00218 }
00219
00220
00221 NBNode *from = myNodeCont.retrieve(from_node);
00222 if (from==0) {
00223 Position2D from_pos = shape[0];
00224 from = myNodeCont.retrieve(from_pos);
00225 if (from==0) {
00226 from = new NBNode(from_node, from_pos);
00227 if (!myNodeCont.insert(from)) {
00228 MsgHandler::getErrorInstance()->inform("Node '" + from_node + "' could not be added");
00229 delete from;
00230 continue;
00231 }
00232 }
00233 }
00234
00235 NBNode *to = myNodeCont.retrieve(to_node);
00236 if (to==0) {
00237 Position2D to_pos = shape[-1];
00238 to = myNodeCont.retrieve(to_pos);
00239 if (to==0) {
00240 to = new NBNode(to_node, to_pos);
00241 if (!myNodeCont.insert(to)) {
00242 MsgHandler::getErrorInstance()->inform("Node '" + to_node + "' could not be added");
00243 delete to;
00244 continue;
00245 }
00246 }
00247 }
00248
00249 if (from==to) {
00250 WRITE_WARNING("Edge '" + id + "' connects identical nodes, skipping.");
00251 continue;
00252 }
00253
00254
00255 std::string dir;
00256 int index = poFeature->GetDefnRef()->GetFieldIndex("DIR_TRAVEL");
00257 if (index>=0&&poFeature->IsFieldSet(index)) {
00258 dir = poFeature->GetFieldAsString(index);
00259 }
00260
00261 if (dir=="B"||dir=="F"||dir==""||myOptions.getBool("arcview.all-bidi")) {
00262 if (myEdgeCont.retrieve(id)==0) {
00263 NBEdge::LaneSpreadFunction spread =
00264 dir=="B"||dir=="FALSE"
00265 ? NBEdge::LANESPREAD_RIGHT
00266 : NBEdge::LANESPREAD_CENTER;
00267 NBEdge *edge = new NBEdge(id, from, to, type, speed, nolanes,
00268 priority, shape, spread);
00269 myEdgeCont.insert(edge);
00270 checkSpread(edge);
00271 }
00272 }
00273
00274 if (dir=="B"||dir=="T"||myOptions.getBool("arcview.all-bidi")) {
00275 id = "-" + id;
00276 if (myEdgeCont.retrieve(id)==0) {
00277 NBEdge::LaneSpreadFunction spread =
00278 dir=="B"||dir=="FALSE"
00279 ? NBEdge::LANESPREAD_RIGHT
00280 : NBEdge::LANESPREAD_CENTER;
00281 NBEdge *edge = new NBEdge(id, to, from, type, speed, nolanes,
00282 priority, shape.reverse(), spread);
00283 myEdgeCont.insert(edge);
00284 checkSpread(edge);
00285 }
00286 }
00287
00288 OGRFeature::DestroyFeature(poFeature);
00289 }
00290 MsgHandler::getMessageInstance()->endProcessMsg("done.");
00291 #else
00292 MsgHandler::getErrorInstance()->inform("SUMO was compiled without GDAL support.");
00293 #endif
00294 }
00295
00296 #ifdef HAVE_GDAL
00297 SUMOReal
00298 NIImporter_ArcView::getSpeed(OGRFeature &poFeature, const std::string &edgeid) {
00299 if (myOptions.isSet("arcview.type-id")) {
00300 return myTypeCont.getSpeed(poFeature.GetFieldAsString((char*)(myOptions.getString("arcview.type-id").c_str())));
00301 }
00302
00303
00304 int index = poFeature.GetDefnRef()->GetFieldIndex("speed");
00305 if (index>=0&&poFeature.IsFieldSet(index)) {
00306 return (SUMOReal) poFeature.GetFieldAsDouble(index);
00307 }
00308 index = poFeature.GetDefnRef()->GetFieldIndex("SPEED");
00309 if (index>=0&&poFeature.IsFieldSet(index)) {
00310 return (SUMOReal) poFeature.GetFieldAsDouble(index);
00311 }
00312
00313 index = poFeature.GetDefnRef()->GetFieldIndex("SPEED_CAT");
00314 if (index>=0&&poFeature.IsFieldSet(index)) {
00315 std::string def = poFeature.GetFieldAsString(index);
00316 return NINavTeqHelper::getSpeed(edgeid, def);
00317 }
00318 return -1;
00319 }
00320
00321
00322 unsigned int
00323 NIImporter_ArcView::getLaneNo(OGRFeature &poFeature, const std::string &edgeid,
00324 SUMOReal speed) {
00325 if (myOptions.isSet("arcview.type-id")) {
00326 return (unsigned int) myTypeCont.getNoLanes(poFeature.GetFieldAsString((char*)(myOptions.getString("arcview.type-id").c_str())));
00327 }
00328
00329
00330 int index = poFeature.GetDefnRef()->GetFieldIndex("nolanes");
00331 if (index>=0&&poFeature.IsFieldSet(index)) {
00332 return (unsigned int) poFeature.GetFieldAsInteger(index);
00333 }
00334 index = poFeature.GetDefnRef()->GetFieldIndex("NOLANES");
00335 if (index>=0&&poFeature.IsFieldSet(index)) {
00336 return (unsigned int) poFeature.GetFieldAsInteger(index);
00337 }
00338 index = poFeature.GetDefnRef()->GetFieldIndex("rnol");
00339 if (index>=0&&poFeature.IsFieldSet(index)) {
00340 return (unsigned int) poFeature.GetFieldAsInteger(index);
00341 }
00342 index = poFeature.GetDefnRef()->GetFieldIndex("LANE_CAT");
00343 if (index>=0&&poFeature.IsFieldSet(index)) {
00344 std::string def = poFeature.GetFieldAsString(index);
00345 return NINavTeqHelper::getLaneNumber(edgeid, def, speed);
00346 }
00347 return 0;
00348 }
00349
00350
00351 int
00352 NIImporter_ArcView::getPriority(OGRFeature &poFeature, const std::string &) {
00353 if (myOptions.isSet("arcview.type-id")) {
00354 return myTypeCont.getPriority(poFeature.GetFieldAsString((char*)(myOptions.getString("arcview.type-id").c_str())));
00355 }
00356
00357
00358 int index = poFeature.GetDefnRef()->GetFieldIndex("priority");
00359 if (index>=0&&poFeature.IsFieldSet(index)) {
00360 return poFeature.GetFieldAsInteger(index);
00361 }
00362 index = poFeature.GetDefnRef()->GetFieldIndex("PRIORITY");
00363 if (index>=0&&poFeature.IsFieldSet(index)) {
00364 return poFeature.GetFieldAsInteger(index);
00365 }
00366
00367 index = poFeature.GetDefnRef()->GetFieldIndex("FUNC_CLASS");
00368 if (index>=0&&poFeature.IsFieldSet(index)) {
00369 return poFeature.GetFieldAsInteger(index);
00370 }
00371 return 0;
00372 }
00373
00374 void
00375 NIImporter_ArcView::checkSpread(NBEdge *e) {
00376 NBEdge *ret = e->getToNode()->getConnectionTo(e->getFromNode());
00377 if (ret!=0) {
00378 e->setLaneSpreadFunction(NBEdge::LANESPREAD_RIGHT);
00379 ret->setLaneSpreadFunction(NBEdge::LANESPREAD_RIGHT);
00380 }
00381 }
00382
00383
00384 #endif
00385
00386
00387
00388
00389