NIImporter_ArcView.cpp

Go to the documentation of this file.
00001 /****************************************************************************/
00007 // Importer for networks stored in ArcView-shape format
00008 /****************************************************************************/
00009 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00010 // Copyright 2001-2010 DLR (http://www.dlr.de/) and contributors
00011 /****************************************************************************/
00012 //
00013 //   This program is free software; you can redistribute it and/or modify
00014 //   it under the terms of the GNU General Public License as published by
00015 //   the Free Software Foundation; either version 2 of the License, or
00016 //   (at your option) any later version.
00017 //
00018 /****************************************************************************/
00019 
00020 
00021 // ===========================================================================
00022 // included modules
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 // method definitions
00060 // ===========================================================================
00061 // ---------------------------------------------------------------------------
00062 // static methods (interface in this case)
00063 // ---------------------------------------------------------------------------
00064 void
00065 NIImporter_ArcView::loadNetwork(const OptionsCont &oc, NBNetBuilder &nb) {
00066     if (!oc.isSet("arcview")) {
00067         return;
00068     }
00069     // check whether the correct set of entries is given
00070     //  and compute both file names
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     // check whether the files do exist
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     // load the arcview files
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 // loader methods
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     // begin file parsing
00128     OGRLayer  *poLayer = poDS->GetLayer(0);
00129     poLayer->ResetReading();
00130 
00131     // build coordinate transformation
00132     OGRSpatialReference *origTransf = poLayer->GetSpatialRef();
00133     OGRSpatialReference destTransf;
00134     // use wgs84 as destination
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         // read in edge attributes
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, "&", "&amp;"));
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         // read in the geometry
00202         OGRGeometry *poGeometry = poFeature->GetGeometryRef();
00203         OGRwkbGeometryType gtype = poGeometry->getGeometryType();
00204         assert(gtype==wkbLineString);
00205         OGRLineString *cgeom = (OGRLineString*) poGeometry;
00206         if (poCT!=0) {
00207             // try transform to wgs84
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         // build from-node
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         // build to-node
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         // retrieve the information whether the street is bi-directional
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         // add positive direction if wanted
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         // add negative direction if wanted
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     // try to get definitions as to be found in SUMO-XML-definitions
00303     //  idea by John Michael Calandrino
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     // try to get the NavTech-information
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     // try to get definitions as to be found in SUMO-XML-definitions
00329     //  idea by John Michael Calandrino
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 &/*edgeid*/) {
00353     if (myOptions.isSet("arcview.type-id")) {
00354         return myTypeCont.getPriority(poFeature.GetFieldAsString((char*)(myOptions.getString("arcview.type-id").c_str())));
00355     }
00356     // try to get definitions as to be found in SUMO-XML-definitions
00357     //  idea by John Michael Calandrino
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     // try to determine priority from NavTechs FUNC_CLASS attribute
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 

Generated on Wed May 5 00:06:34 2010 for Sumo - Simulation of Urban MObility by  doxygen 1.5.6