Ticket #161: db.patch

File db.patch, 18.2 KB (added by anton, 16 months ago)
  • src/OSMDocument.h

     
    2121#ifndef OSMDOCUMENT_H 
    2222#define OSMDOCUMENT_H 
    2323 
    24 #include "Configuration.h" 
     24#include "Configuration.h" 
     25#include "Export2DB.h" 
    2526 
    2627namespace osm 
    2728{ 
     
    3738{ 
    3839public: 
    3940        //! Map, which saves the parsed nodes 
    40         std::map<long long, Node*> m_Nodes; 
     41        //std::map<long long, Node*> m_Nodes; 
    4142        //! parsed ways 
    4243        std::vector<Way*> m_Ways; 
    4344        //! splitted ways 
    4445        std::vector<Way*> m_SplittedWays; 
    45         Configuration& m_rConfig; 
     46        Configuration& m_rConfig; 
     47        Export2DB& m_db; 
     48 
     49        unsigned int m_stage; 
    4650public: 
    4751 
    4852        //! Constructor 
    49         OSMDocument( Configuration& config); 
     53        OSMDocument( Configuration& config, Export2DB& db, unsigned int stage = 0); 
    5054        //! Destructor 
    5155        virtual ~OSMDocument(); 
    5256        //! add node to the map 
  • src/Export2DB.cpp

     
    2626Export2DB::Export2DB(std::string host, std::string user, std::string dbname, std::string port, std::string passwd) 
    2727:mycon(0) 
    2828{ 
    29          
     29 
    3030this->conninf="host="+host+" user="+user+" dbname="+ dbname +" port="+port; 
    3131if(!passwd.empty()) 
    3232        this->conninf+=" password="+passwd; 
    33          
     33 
    3434} 
    3535 
    3636Export2DB::~Export2DB() 
     
    4343        cout << conninf<< endl; 
    4444        //mycon =PQconnectdb("user=postgres dbname=template1 hostaddr=127.0.0.1 port=5432"); 
    4545        mycon =PQconnectdb(conninf.c_str()); 
    46          
     46 
    4747        ConnStatusType type =PQstatus(mycon); 
    4848                if(type==CONNECTION_BAD) 
    4949                { 
     
    7474        result = PQexec(mycon, "CREATE TABLE types (id integer, name char(200));"); 
    7575        std::cout << "Types table created" << std::endl; 
    7676        result = PQexec(mycon, "CREATE TABLE classes (id integer, type_id integer, name char(200), cost double precision);"); 
    77         std::cout << "Classes table created" << std::endl;       
     77        std::cout << "Classes table created" << std::endl; 
    7878} 
    7979 
    8080void Export2DB::dropTables() 
     
    8787        char tmp_id[20]; 
    8888        char tmp_lon[15]; 
    8989        char tmp_lat[15]; 
    90          
     90 
    9191        sprintf(tmp_id,"%lld",id); 
    9292        gcvt(lon,12,tmp_lon); 
    9393        gcvt(lat,12,tmp_lat); 
    94          
     94 
    9595        std::string query = "INSERT into nodes(id,lon,lat) values("; 
    9696                                query+= tmp_id; 
    9797                                query+=","; 
     
    9999                                query+=","; 
    100100                                query+= tmp_lat; 
    101101                                query+=");"; 
    102          
     102 
    103103        PGresult *result = PQexec(mycon, query.c_str()); 
     104        PQclear(result); 
    104105} 
    105106 
    106107void Export2DB::exportWay(Way* way) 
     
    109110        if(!way->name.empty()) 
    110111                query+=", name"; 
    111112        query+=") values("; 
    112          
    113         query+=boost::lexical_cast<std::string>(way->id) + ", (SELECT id FROM classes WHERE name ='" + boost::lexical_cast<std::string>(way->clss) + "')," + boost::lexical_cast<std::string>(way->length) + ","  
     113 
     114        query+=boost::lexical_cast<std::string>(way->id) + ", (SELECT id FROM classes WHERE name ='" + boost::lexical_cast<std::string>(way->clss) + "')," + boost::lexical_cast<std::string>(way->length) + "," 
    114115                 + boost::lexical_cast<std::string>(way->m_NodeRefs.front()->lon) + ","+ boost::lexical_cast<std::string>(way->m_NodeRefs.front()->lat) + "," 
    115116                 + boost::lexical_cast<std::string>(way->m_NodeRefs.back()->lon)  + ","+ boost::lexical_cast<std::string>(way->m_NodeRefs.back()->lat) + ","; 
    116117        query+="GeometryFromText('" + way->geom +"', 4326)"; 
     
    122123        else 
    123124        { 
    124125            query+=", "+ boost::lexical_cast<std::string>(way->length); 
    125         }        
     126        } 
    126127 
    127128        if(!way->name.empty()) 
    128129                query+=",$$"+ way->name +"$$"; 
     
    134135void Export2DB::exportType(Type* type) 
    135136{ 
    136137        std::string query = "INSERT into types(id, name) values("; 
    137          
     138 
    138139        query+=boost::lexical_cast<std::string>(type->id) + ", '" + type->name +"');"; 
    139140        PGresult *result = PQexec(mycon, query.c_str()); 
    140141} 
     
    142143void Export2DB::exportClass(Type* type, Class* clss) 
    143144{ 
    144145        std::string query = "INSERT into classes(id, type_id, name) values("; 
    145          
     146 
    146147        query+=boost::lexical_cast<std::string>(clss->id) + ", " + boost::lexical_cast<std::string>(type->id) + ", '" + clss->name +"');"; 
    147148        PGresult *result = PQexec(mycon, query.c_str()); 
    148149} 
     
    155156        result = PQexec(mycon,"CREATE INDEX target_idx ON ways(target);"); 
    156157        result = PQexec(mycon,"CREATE INDEX geom_idx ON ways USING GIST(the_geom GIST_GEOMETRY_OPS);"); 
    157158        result = PQexec(mycon,"SELECT assign_vertex_id('ways', 0.00001, 'the_geom', 'gid');"); 
    158          
     159 
    159160} 
     161 
     162Node* Export2DB::findNode(long long nodeRefId) { 
     163        std::string query = "SELECT id,lon,lat FROM nodes WHERE id ='" + boost::lexical_cast<std::string>(nodeRefId) + "';"; 
     164        PGresult *result = PQexec(mycon, query.c_str()); 
     165 
     166        if (PQresultStatus(result) != PGRES_TUPLES_OK) { 
     167                std::cout << "SELECT id,lon,lat FROM nodes WHERE id ='" << boost::lexical_cast<std::string>(nodeRefId) << "'; "<< PQerrorMessage(mycon) << std::endl; 
     168            PQclear(result); 
     169            return NULL; 
     170        } 
     171 
     172        if (PQntuples(result) == 0) 
     173        { 
     174                std::cout << "SELECT id,lon,lat FROM nodes WHERE id ='" << boost::lexical_cast<std::string>(nodeRefId) << "'; gave zero rows result" << std::endl; 
     175                PQclear(result); 
     176                return NULL; 
     177        } 
     178 
     179        int id_f = PQfnumber(result, "id"); 
     180        int lon_f = PQfnumber(result, "lon"); 
     181        int lat_f = PQfnumber(result, "lat"); 
     182 
     183        char *id_ptr = PQgetvalue(result, 0, id_f); 
     184        char *lon_ptr = PQgetvalue(result, 0, lon_f); 
     185        char *lat_ptr = PQgetvalue(result, 0, lat_f); 
     186 
     187        //std::cout << "Found node: id=" << id_ptr << ", lon=" << lon_ptr << ", lat=" << lat_ptr << std::endl; 
     188 
     189        Node* node = new Node(atol(id_ptr), atof(lat_ptr), atof(lon_ptr)); 
     190 
     191        PQclear(result); 
     192 
     193        return node; 
     194} 
     195 
  • src/Export2DB.h

     
    3232 
    3333/** 
    3434 * This class connects to a postgresql database. For using this class, 
    35  * you also need to install postgis and pgrouting  
     35 * you also need to install postgis and pgrouting 
    3636 */ 
    3737 
    3838class Export2DB 
     
    4444         * @param host Host address of the database 
    4545         * @param user a user, who has write access to the database 
    4646         * @param dbname name of the database 
    47          *  
    48          */  
     47         * 
     48         */ 
    4949        Export2DB(std::string host, std::string user, std::string dbname, std::string port, std::string password); 
    5050        /** 
    5151         * Destructor 
    5252         * closes the connection to the database 
    53          */   
     53         */ 
    5454        ~Export2DB(); 
    55          
     55 
    5656        //! connects to database 
    5757        int connect(); 
    5858        //! creates needed tables 
     
    6565        void exportType(Type* type); 
    6666        void exportClass(Type* type, Class* clss); 
    6767 
     68        Node* findNode(long long nodeRefId); 
    6869 
    69         /**  
     70 
     71        /** 
    7072         * creates the topology 
    7173         * Be careful, it takes some time. 
    72          *  
     74         * 
    7375         * for example: 
    7476         * complete germany: OSM file with a size of 1,1 GiB. 
    7577         * Export and create topology: 
    7678         * time took circa 30 hours on an Intel Xeon 2,4 GHz with 2 GiB Ram. 
    7779         * But only for the streettypes "motorway", "primary" and "secondary" 
    78          */  
     80         */ 
    7981        void createTopology(); 
    8082        //! Be careful! It deletes the created tables! 
    8183        void dropTables(); 
    82          
     84 
    8385private: 
    8486PGconn *mycon; 
    8587std::string conninf; 
  • src/osm2pgrouting.cpp

     
    1717 *   Free Software Foundation, Inc.,                                       * 
    1818 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             * 
    1919 ***************************************************************************/ 
    20   
     20 
    2121#include "stdafx.h" 
    2222#include "Configuration.h" 
    2323#include "ConfigurationParserCallback.h" 
     
    4343                                cout << "-port <port> -- port of your database (default: 5432)" << endl; 
    4444                                cout << "-passwd <passwd> --  password for database access" << endl; 
    4545                                cout << "-clean -- drop peviously created tables" << endl; 
    46                                          
     46 
    4747} 
    4848 
    4949int main(int argc, char* argv[]) 
     
    5555        std::string port="5432"; 
    5656        std::string dbname; 
    5757        std::string passwd; 
     58        std::string stage; 
    5859        bool clean = false; 
    5960        if(argc >=7 && argc <=13) 
    6061        { 
     
    6263                while( i<argc) 
    6364                { 
    6465                        if(strcmp(argv[i],"-file")==0) 
    65                         {        
     66                        { 
    6667                                i++; 
    6768                                file = argv[i]; 
    6869                        } 
    6970 
    7071                        else if(strcmp(argv[i],"-conf")==0) 
    71                         {        
     72                        { 
    7273                                i++; 
    7374                                cFile = argv[i]; 
    7475                        } 
    75                                  
     76 
    7677                        else if(strcmp(argv[i],"-host")==0) 
    7778                        { 
    7879                                i++; 
     
    102103                        { 
    103104                                clean = true; 
    104105                        } 
     106                        else if(strcmp(argv[i],"-stage")==0) 
     107                        { 
     108                                i++; 
     109                                stage = argv[i]; 
     110                        } 
    105111                        else 
    106112                        { 
    107113                                cout << "unknown paramer: " << argv[i] << endl; 
    108114                                _error(); 
    109115                                return 1; 
    110116                        } 
    111                          
     117 
    112118                        i++; 
    113119                } 
    114                  
     120 
    115121        } 
    116122        else 
    117123        { 
    118124                _error(); 
    119125                return 1; 
    120126        } 
    121          
     127 
    122128        if(file.empty() || cFile.empty() || dbname.empty() || user.empty()) 
    123129        { 
    124130                _error(); 
    125131                return 1; 
    126132        } 
    127          
     133 
    128134        Export2DB test(host, user, dbname, port, passwd); 
    129135        if(test.connect()==1) 
    130136                return 1; 
    131137 
    132138 
    133139        XMLParser parser; 
    134          
     140 
    135141        cout << "Trying to load config file " << cFile.c_str() << endl; 
    136142 
    137143        Configuration* config = new Configuration(); 
     
    144150 
    145151        cout << "Trying to load data" << endl; 
    146152 
    147         OSMDocument* document = new OSMDocument( *config ); 
     153        OSMDocument* document = new OSMDocument( *config, test, atoi(stage.c_str()) ); 
    148154        OSMDocumentParserCallback callback( *document ); 
    149155 
    150156        cout << "Trying to parse data" << endl; 
    151157 
    152158        ret = parser.Parse( callback, file.c_str() ); 
    153159        if( ret!=0 ) return 1; 
    154          
     160 
    155161        cout << "Split ways" << endl; 
    156162 
    157163        document->SplitWays(); 
     
    159165        { 
    160166 
    161167                if( clean ) 
    162                 { 
    163                         test.dropTables(); 
     168                { 
     169                        if (atoi(stage.c_str()) < 1) { 
     170                                test.dropTables(); 
     171                        } 
    164172                } 
    165                  
     173 
    166174                test.createTables(); 
    167                  
     175 
    168176                std::map<std::string, Type*>& types= config->m_Types; 
    169177                std::map<std::string, Type*>::iterator tIt(types.begin()); 
    170178                std::map<std::string, Type*>::iterator tLast(types.end()); 
    171                  
     179 
    172180                while(tIt!=tLast) 
    173181                { 
    174182                        Type* type = (*tIt++).second; 
     
    184192                                test.exportClass(type, clss); 
    185193                        } 
    186194                } 
    187                  
    188195 
    189                 std::map<long long, Node*>& nodes= document->m_Nodes; 
    190                 std::map<long long, Node*>::iterator it(nodes.begin()); 
    191                 std::map<long long, Node*>::iterator last(nodes.end()); 
    192                  
    193                 while(it!=last) 
    194                 { 
    195                         Node* node = (*it++).second; 
    196                         test.exportNode(node->id,node->lon, node->lat, node->numsOfUse); 
    197                 } 
    198                  
     196 
     197                //std::map<long long, Node*>& nodes= document->m_Nodes; 
     198                //std::map<long long, Node*>::iterator it(nodes.begin()); 
     199                //std::map<long long, Node*>::iterator last(nodes.end()); 
     200 
     201                //while(it!=last) 
     202                //{ 
     203                //      Node* node = (*it++).second; 
     204                //      test.exportNode(node->id,node->lon, node->lat, node->numsOfUse); 
     205                //} 
     206 
    199207                std::vector<Way*>& ways= document->m_SplittedWays; 
    200208                std::vector<Way*>::iterator it_way( ways.begin() ); 
    201                 std::vector<Way*>::iterator last_way( ways.end() );      
     209                std::vector<Way*>::iterator last_way( ways.end() ); 
    202210                while( it_way!=last_way ) 
    203211                { 
    204212                        Way* pWay = *it_way++; 
     
    206214                } 
    207215                cout << "create topology" << endl; 
    208216                test.createTopology(); 
    209         }        
    210          
     217        } 
     218 
    211219        //############# 
    212          
     220 
    213221        /* 
    214222        std::vector<Way*>& ways= document.m_Ways; 
    215223        std::vector<Way*>::iterator it( ways.begin() ); 
     
    217225        while( it!=last ) 
    218226        { 
    219227                Way* pWay = *it; 
    220                  
     228 
    221229                if( !pWay->name.empty() ) 
    222230                { 
    223231                        if( pWay->m_NodeRefs.empty() ) 
     
    229237                                Node* n0 = pWay->m_NodeRefs.front(); 
    230238                                Node* n1 = pWay->m_NodeRefs.back(); 
    231239                                //if(n1->numsOfUse==1) 
    232                                 //cout << "way-id: " << pWay->id << " name: " << pWay->name <<endl;  
     240                                //cout << "way-id: " << pWay->id << " name: " << pWay->name <<endl; 
    233241                                //std::cout << n0->lon << " "  << n0->lat << " " << n1->lon << " " << n1->lat << " " << pWay->name.c_str() << " highway: " << pWay->highway.c_str() << " Start numberOfUse: " << n0->numsOfUse << " End numberOfUse: " << n1->numsOfUse  << " ID: " << n1->id <<  endl; 
    234242                        } 
    235243                } 
     
    241249                ++it; 
    242250        } 
    243251        */ 
    244          
     252 
    245253        cout << "#########################" << endl; 
    246          
     254 
    247255        cout << "size of streets: " << document->m_Ways.size() <<       endl; 
    248256        cout << "size of splitted ways : " << document->m_SplittedWays.size() <<        endl; 
    249257 
  • src/OSMDocumentParserCallback.cpp

     
    3030 
    3131namespace osm 
    3232{ 
    33          
    34          
     33 
     34 
    3535/** 
    3636        Parser callback for OSMDocument files 
    3737*/ 
     
    4646                        if( strcmp(name,"ref")==0 ) 
    4747                        { 
    4848                                long long nodeRefId = atol( value ); 
    49                                 m_pActWay->AddNodeRef( m_rDocument.FindNode( nodeRefId ) ); 
    50                                   Node * node = m_rDocument.FindNode( nodeRefId ); 
    51                                   if(node != 0 ){ 
    52                                     node->numsOfUse+=1; 
    53                                   }else { 
    54                                     std::cout << "Reference nd=" << nodeRefId << " has no corresponding Node Entry (Maybe Node entry after Reference?)" << std::endl; 
    55                                   } 
     49                                Node * node = m_rDocument.FindNode( nodeRefId ); 
     50                if(node != 0 ){ 
     51                        m_pActWay->AddNodeRef( node ); 
     52                        node->numsOfUse+=1; 
     53                                }else { 
     54                                        std::cout << "Reference nd=" << nodeRefId << " has no corresponding Node Entry (Maybe Node entry after Reference?)" << std::endl; 
     55                                } 
    5656                        } 
    5757                } 
    5858        } 
     
    8686        } 
    8787        else if( strcmp(name,"tag") == 0 ) 
    8888        { 
    89                 // <tag k="name" v="Pfänderweg"/> 
     89                // <tag k="name" v="Pfï¿œnderweg"/> 
    9090                if (atts != NULL) 
    9191                { 
    9292                        std::string k; 
     
    113113                                } 
    114114                                else if( m_pActWay && k.compare("oneway")==0 ) 
    115115                                { 
    116                                         m_pActWay->oneway = true;                                        
     116                                        m_pActWay->oneway = true; 
    117117                                        std::cout<<"Edge "<<m_pActWay->id<<" is oneway"<<std::endl; 
    118118 
    119                                 } 
    120                                  
     119                                } 
    121120                                //else if( m_pActWay && k.compare("highway")==0 ) 
    122121                                else if( m_pActWay && m_rDocument.m_rConfig.m_Types.count(k) ) 
    123122                                { 
     
    150149                        if( id>0 ) 
    151150                        { 
    152151                                m_pActWay = new Way( id, visibility ); 
    153                                  
     152 
    154153                        } 
    155154                } 
    156155        } 
     
    167166        { 
    168167                //#ifdef RESTRICT 
    169168                //_FILTER 
    170                  
     169 
    171170                if( m_rDocument.m_rConfig.m_Types.count(m_pActWay->type) && m_rDocument.m_rConfig.m_Types[m_pActWay->type]->m_Classes.count(m_pActWay->clss) ) 
    172171                { 
    173172                //#endif 
    174173                std::cout<<"We need a way of type "<<m_pActWay->type<<" and class "<< m_pActWay->clss<<std::endl; 
    175                  
     174 
    176175                        m_rDocument.AddWay( m_pActWay ); 
    177176 
    178177                //#ifdef RESTRICT 
     
    183182                        delete m_pActWay; 
    184183                } 
    185184                //#endif 
    186                  
     185 
    187186                m_pActWay = 0; 
    188187        } 
    189188} 
  • src/OSMDocument.cpp

     
    2929namespace osm 
    3030{ 
    3131 
    32 OSMDocument::OSMDocument( Configuration& config ) : m_rConfig( config ) 
    33 { 
     32OSMDocument::OSMDocument( Configuration& config, Export2DB& db, unsigned int stage) : m_rConfig( config ), m_db(db), m_stage(stage) 
     33{ 
     34        std::cout << "Doing from stage " << m_stage << std::endl; 
    3435} 
    3536 
    3637OSMDocument::~OSMDocument() 
    3738{ 
    38         ez_mapdelete( m_Nodes ); 
    39         ez_vectordelete( m_Ways );               
     39        //ez_mapdelete( m_Nodes ); 
     40        ez_vectordelete( m_Ways ); 
    4041        ez_vectordelete( m_SplittedWays ); 
    4142} 
    4243void OSMDocument::AddNode( Node* n ) 
    4344{ 
    44         m_Nodes[n->id] = n; 
     45        //m_Nodes[n->id] = n; 
     46        if (m_stage < 2) { 
     47                m_db.exportNode(n->id,n->lon, n->lat, n->numsOfUse); 
     48        }; 
    4549} 
    4650 
    4751void OSMDocument::AddWay( Way* w ) 
     
    4953        m_Ways.push_back( w ); 
    5054} 
    5155 
    52 Node* OSMDocument::FindNode( long long nodeRefId )  
     56Node* OSMDocument::FindNode( long long nodeRefId ) 
    5357const 
    5458{ 
    55         std::map<long long, Node*>::const_iterator  it = m_Nodes.find( nodeRefId ); 
    56         return (it!=m_Nodes.end() ) ? it->second : 0; 
     59        //std::map<long long, Node*>::const_iterator  it = m_Nodes.find( nodeRefId ); 
     60        //return (it!=m_Nodes.end() ) ? it->second : 0; 
     61        return m_db.findNode(nodeRefId); 
    5762} 
    5863 
    5964void OSMDocument::SplitWays() 
    6065{ 
    61          
     66 
    6267        std::vector<Way*>::const_iterator it(m_Ways.begin()); 
    6368        std::vector<Way*>::const_iterator last(m_Ways.end()); 
    6469 
     
    6873        while(it!=last) 
    6974        { 
    7075                Way* currentWay = *it++; 
    71                  
    72                 std::vector<Node*>::const_iterator it_node( currentWay->m_NodeRefs.begin());     
     76 
     77                std::vector<Node*>::const_iterator it_node( currentWay->m_NodeRefs.begin()); 
    7378                std::vector<Node*>::const_iterator last_node( currentWay->m_NodeRefs.end()); 
    74                  
     79 
    7580                Node* backNode = currentWay->m_NodeRefs.back(); 
    7681 
    7782 
    7883 
    7984                while(it_node!=last_node) 
    8085                { 
    81                          
     86 
    8287                        Node* node = *it_node++; 
    8388                        Node* secondNode=0; 
    8489                        Node* lastNode=0; 
    85                          
     90 
    8691                        Way* splitted_way = new Way( ++id, currentWay->visible ); 
    8792                        splitted_way->name=currentWay->name; 
    8893                        splitted_way->type=currentWay->type; 
     
    9095                        splitted_way->oneway=currentWay->oneway; 
    9196 
    9297        //GeometryFromText('MULTILINESTRING(('||x1||' '||y1||','||x2||' '||y2||'))',4326); 
    93                          
     98 
    9499                        splitted_way->geom="MULTILINESTRING(("+ boost::lexical_cast<std::string>(node->lon) + " " + boost::lexical_cast<std::string>(node->lat) +","; 
    95                          
     100 
    96101                        splitted_way->AddNodeRef(node); 
    97                          
     102 
    98103                        bool found=false; 
    99                          
     104 
    100105                        if(it_node!=last_node) 
    101106                        { 
    102107                                while(it_node!=last_node && !found) 
     
    112117                                                        length*=-1; 
    113118                                                splitted_way->length+=length; 
    114119                                                splitted_way->geom+= boost::lexical_cast<std::string>(secondNode->lon) + " " + boost::lexical_cast<std::string>(secondNode->lat) + "))"; 
    115                                                  
     120 
    116121                                        } 
    117122                                        else if(backNode==(*it_node)) 
    118123                                        { 
     
    131136                                        } 
    132137                                } 
    133138                        } 
    134                                  
     139 
    135140                        if(splitted_way->m_NodeRefs.front()!=splitted_way->m_NodeRefs.back()) 
    136141                                m_SplittedWays.push_back(splitted_way); 
    137142                        else 
     
    139144                                delete splitted_way; 
    140145                                splitted_way=0; 
    141146                        } 
    142                                  
     147 
    143148                } 
    144149 
    145150        } 
  • Makefile

     
    99MAIN = src/osm2pgrouting.cpp 
    1010 
    1111all: 
    12         $(CC) -c $(SRC) $(INC) -ggdb3 
    13         $(CC) -c $(DEPS) $(INC) -ggdb3 
    14         $(CC) -o osm2pgrouting $(MAIN) *.o $(INC) -lexpat -ggdb3 -lpq 
     12        $(CC) -c -O3 $(SRC) $(INC) 
     13        $(CC) -c -O3 $(DEPS) $(INC) 
     14        $(CC) -o osm2pgrouting $(MAIN) *.o $(INC) -lexpat -lpq 
     15#       $(CC) -c $(SRC) $(INC) -ggdb3 
     16#       $(CC) -c $(DEPS) $(INC) -ggdb3 
     17#       $(CC) -o osm2pgrouting $(MAIN) *.o $(INC) -lexpat -ggdb3 -lpq 
    1518        rm *.o 
    1619clean: 
    1720        rm osm2pgrouting