Ticket #161: db.patch
File db.patch, 18.2 KB (added by anton, 16 months ago) |
---|
-
src/OSMDocument.h
21 21 #ifndef OSMDOCUMENT_H 22 22 #define OSMDOCUMENT_H 23 23 24 #include "Configuration.h" 24 #include "Configuration.h" 25 #include "Export2DB.h" 25 26 26 27 namespace osm 27 28 { … … 37 38 { 38 39 public: 39 40 //! Map, which saves the parsed nodes 40 std::map<long long, Node*> m_Nodes;41 //std::map<long long, Node*> m_Nodes; 41 42 //! parsed ways 42 43 std::vector<Way*> m_Ways; 43 44 //! splitted ways 44 45 std::vector<Way*> m_SplittedWays; 45 Configuration& m_rConfig; 46 Configuration& m_rConfig; 47 Export2DB& m_db; 48 49 unsigned int m_stage; 46 50 public: 47 51 48 52 //! Constructor 49 OSMDocument( Configuration& config );53 OSMDocument( Configuration& config, Export2DB& db, unsigned int stage = 0); 50 54 //! Destructor 51 55 virtual ~OSMDocument(); 52 56 //! add node to the map -
src/Export2DB.cpp
26 26 Export2DB::Export2DB(std::string host, std::string user, std::string dbname, std::string port, std::string passwd) 27 27 :mycon(0) 28 28 { 29 29 30 30 this->conninf="host="+host+" user="+user+" dbname="+ dbname +" port="+port; 31 31 if(!passwd.empty()) 32 32 this->conninf+=" password="+passwd; 33 33 34 34 } 35 35 36 36 Export2DB::~Export2DB() … … 43 43 cout << conninf<< endl; 44 44 //mycon =PQconnectdb("user=postgres dbname=template1 hostaddr=127.0.0.1 port=5432"); 45 45 mycon =PQconnectdb(conninf.c_str()); 46 46 47 47 ConnStatusType type =PQstatus(mycon); 48 48 if(type==CONNECTION_BAD) 49 49 { … … 74 74 result = PQexec(mycon, "CREATE TABLE types (id integer, name char(200));"); 75 75 std::cout << "Types table created" << std::endl; 76 76 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; 78 78 } 79 79 80 80 void Export2DB::dropTables() … … 87 87 char tmp_id[20]; 88 88 char tmp_lon[15]; 89 89 char tmp_lat[15]; 90 90 91 91 sprintf(tmp_id,"%lld",id); 92 92 gcvt(lon,12,tmp_lon); 93 93 gcvt(lat,12,tmp_lat); 94 94 95 95 std::string query = "INSERT into nodes(id,lon,lat) values("; 96 96 query+= tmp_id; 97 97 query+=","; … … 99 99 query+=","; 100 100 query+= tmp_lat; 101 101 query+=");"; 102 102 103 103 PGresult *result = PQexec(mycon, query.c_str()); 104 PQclear(result); 104 105 } 105 106 106 107 void Export2DB::exportWay(Way* way) … … 109 110 if(!way->name.empty()) 110 111 query+=", name"; 111 112 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) + "," 114 115 + boost::lexical_cast<std::string>(way->m_NodeRefs.front()->lon) + ","+ boost::lexical_cast<std::string>(way->m_NodeRefs.front()->lat) + "," 115 116 + boost::lexical_cast<std::string>(way->m_NodeRefs.back()->lon) + ","+ boost::lexical_cast<std::string>(way->m_NodeRefs.back()->lat) + ","; 116 117 query+="GeometryFromText('" + way->geom +"', 4326)"; … … 122 123 else 123 124 { 124 125 query+=", "+ boost::lexical_cast<std::string>(way->length); 125 } 126 } 126 127 127 128 if(!way->name.empty()) 128 129 query+=",$$"+ way->name +"$$"; … … 134 135 void Export2DB::exportType(Type* type) 135 136 { 136 137 std::string query = "INSERT into types(id, name) values("; 137 138 138 139 query+=boost::lexical_cast<std::string>(type->id) + ", '" + type->name +"');"; 139 140 PGresult *result = PQexec(mycon, query.c_str()); 140 141 } … … 142 143 void Export2DB::exportClass(Type* type, Class* clss) 143 144 { 144 145 std::string query = "INSERT into classes(id, type_id, name) values("; 145 146 146 147 query+=boost::lexical_cast<std::string>(clss->id) + ", " + boost::lexical_cast<std::string>(type->id) + ", '" + clss->name +"');"; 147 148 PGresult *result = PQexec(mycon, query.c_str()); 148 149 } … … 155 156 result = PQexec(mycon,"CREATE INDEX target_idx ON ways(target);"); 156 157 result = PQexec(mycon,"CREATE INDEX geom_idx ON ways USING GIST(the_geom GIST_GEOMETRY_OPS);"); 157 158 result = PQexec(mycon,"SELECT assign_vertex_id('ways', 0.00001, 'the_geom', 'gid');"); 158 159 159 160 } 161 162 Node* 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
32 32 33 33 /** 34 34 * 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 36 36 */ 37 37 38 38 class Export2DB … … 44 44 * @param host Host address of the database 45 45 * @param user a user, who has write access to the database 46 46 * @param dbname name of the database 47 * 48 */ 47 * 48 */ 49 49 Export2DB(std::string host, std::string user, std::string dbname, std::string port, std::string password); 50 50 /** 51 51 * Destructor 52 52 * closes the connection to the database 53 */ 53 */ 54 54 ~Export2DB(); 55 55 56 56 //! connects to database 57 57 int connect(); 58 58 //! creates needed tables … … 65 65 void exportType(Type* type); 66 66 void exportClass(Type* type, Class* clss); 67 67 68 Node* findNode(long long nodeRefId); 68 69 69 /** 70 71 /** 70 72 * creates the topology 71 73 * Be careful, it takes some time. 72 * 74 * 73 75 * for example: 74 76 * complete germany: OSM file with a size of 1,1 GiB. 75 77 * Export and create topology: 76 78 * time took circa 30 hours on an Intel Xeon 2,4 GHz with 2 GiB Ram. 77 79 * But only for the streettypes "motorway", "primary" and "secondary" 78 */ 80 */ 79 81 void createTopology(); 80 82 //! Be careful! It deletes the created tables! 81 83 void dropTables(); 82 84 83 85 private: 84 86 PGconn *mycon; 85 87 std::string conninf; -
src/osm2pgrouting.cpp
17 17 * Free Software Foundation, Inc., * 18 18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 19 19 ***************************************************************************/ 20 20 21 21 #include "stdafx.h" 22 22 #include "Configuration.h" 23 23 #include "ConfigurationParserCallback.h" … … 43 43 cout << "-port <port> -- port of your database (default: 5432)" << endl; 44 44 cout << "-passwd <passwd> -- password for database access" << endl; 45 45 cout << "-clean -- drop peviously created tables" << endl; 46 46 47 47 } 48 48 49 49 int main(int argc, char* argv[]) … … 55 55 std::string port="5432"; 56 56 std::string dbname; 57 57 std::string passwd; 58 std::string stage; 58 59 bool clean = false; 59 60 if(argc >=7 && argc <=13) 60 61 { … … 62 63 while( i<argc) 63 64 { 64 65 if(strcmp(argv[i],"-file")==0) 65 { 66 { 66 67 i++; 67 68 file = argv[i]; 68 69 } 69 70 70 71 else if(strcmp(argv[i],"-conf")==0) 71 { 72 { 72 73 i++; 73 74 cFile = argv[i]; 74 75 } 75 76 76 77 else if(strcmp(argv[i],"-host")==0) 77 78 { 78 79 i++; … … 102 103 { 103 104 clean = true; 104 105 } 106 else if(strcmp(argv[i],"-stage")==0) 107 { 108 i++; 109 stage = argv[i]; 110 } 105 111 else 106 112 { 107 113 cout << "unknown paramer: " << argv[i] << endl; 108 114 _error(); 109 115 return 1; 110 116 } 111 117 112 118 i++; 113 119 } 114 120 115 121 } 116 122 else 117 123 { 118 124 _error(); 119 125 return 1; 120 126 } 121 127 122 128 if(file.empty() || cFile.empty() || dbname.empty() || user.empty()) 123 129 { 124 130 _error(); 125 131 return 1; 126 132 } 127 133 128 134 Export2DB test(host, user, dbname, port, passwd); 129 135 if(test.connect()==1) 130 136 return 1; 131 137 132 138 133 139 XMLParser parser; 134 140 135 141 cout << "Trying to load config file " << cFile.c_str() << endl; 136 142 137 143 Configuration* config = new Configuration(); … … 144 150 145 151 cout << "Trying to load data" << endl; 146 152 147 OSMDocument* document = new OSMDocument( *config );153 OSMDocument* document = new OSMDocument( *config, test, atoi(stage.c_str()) ); 148 154 OSMDocumentParserCallback callback( *document ); 149 155 150 156 cout << "Trying to parse data" << endl; 151 157 152 158 ret = parser.Parse( callback, file.c_str() ); 153 159 if( ret!=0 ) return 1; 154 160 155 161 cout << "Split ways" << endl; 156 162 157 163 document->SplitWays(); … … 159 165 { 160 166 161 167 if( clean ) 162 { 163 test.dropTables(); 168 { 169 if (atoi(stage.c_str()) < 1) { 170 test.dropTables(); 171 } 164 172 } 165 173 166 174 test.createTables(); 167 175 168 176 std::map<std::string, Type*>& types= config->m_Types; 169 177 std::map<std::string, Type*>::iterator tIt(types.begin()); 170 178 std::map<std::string, Type*>::iterator tLast(types.end()); 171 179 172 180 while(tIt!=tLast) 173 181 { 174 182 Type* type = (*tIt++).second; … … 184 192 test.exportClass(type, clss); 185 193 } 186 194 } 187 188 195 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 199 207 std::vector<Way*>& ways= document->m_SplittedWays; 200 208 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() ); 202 210 while( it_way!=last_way ) 203 211 { 204 212 Way* pWay = *it_way++; … … 206 214 } 207 215 cout << "create topology" << endl; 208 216 test.createTopology(); 209 } 210 217 } 218 211 219 //############# 212 220 213 221 /* 214 222 std::vector<Way*>& ways= document.m_Ways; 215 223 std::vector<Way*>::iterator it( ways.begin() ); … … 217 225 while( it!=last ) 218 226 { 219 227 Way* pWay = *it; 220 228 221 229 if( !pWay->name.empty() ) 222 230 { 223 231 if( pWay->m_NodeRefs.empty() ) … … 229 237 Node* n0 = pWay->m_NodeRefs.front(); 230 238 Node* n1 = pWay->m_NodeRefs.back(); 231 239 //if(n1->numsOfUse==1) 232 //cout << "way-id: " << pWay->id << " name: " << pWay->name <<endl; 240 //cout << "way-id: " << pWay->id << " name: " << pWay->name <<endl; 233 241 //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; 234 242 } 235 243 } … … 241 249 ++it; 242 250 } 243 251 */ 244 252 245 253 cout << "#########################" << endl; 246 254 247 255 cout << "size of streets: " << document->m_Ways.size() << endl; 248 256 cout << "size of splitted ways : " << document->m_SplittedWays.size() << endl; 249 257 -
src/OSMDocumentParserCallback.cpp
30 30 31 31 namespace osm 32 32 { 33 34 33 34 35 35 /** 36 36 Parser callback for OSMDocument files 37 37 */ … … 46 46 if( strcmp(name,"ref")==0 ) 47 47 { 48 48 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 53 54 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 } 56 56 } 57 57 } 58 58 } … … 86 86 } 87 87 else if( strcmp(name,"tag") == 0 ) 88 88 { 89 // <tag k="name" v="Pf änderweg"/>89 // <tag k="name" v="Pfï¿œnderweg"/> 90 90 if (atts != NULL) 91 91 { 92 92 std::string k; … … 113 113 } 114 114 else if( m_pActWay && k.compare("oneway")==0 ) 115 115 { 116 m_pActWay->oneway = true; 116 m_pActWay->oneway = true; 117 117 std::cout<<"Edge "<<m_pActWay->id<<" is oneway"<<std::endl; 118 118 119 } 120 119 } 121 120 //else if( m_pActWay && k.compare("highway")==0 ) 122 121 else if( m_pActWay && m_rDocument.m_rConfig.m_Types.count(k) ) 123 122 { … … 150 149 if( id>0 ) 151 150 { 152 151 m_pActWay = new Way( id, visibility ); 153 152 154 153 } 155 154 } 156 155 } … … 167 166 { 168 167 //#ifdef RESTRICT 169 168 //_FILTER 170 169 171 170 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) ) 172 171 { 173 172 //#endif 174 173 std::cout<<"We need a way of type "<<m_pActWay->type<<" and class "<< m_pActWay->clss<<std::endl; 175 174 176 175 m_rDocument.AddWay( m_pActWay ); 177 176 178 177 //#ifdef RESTRICT … … 183 182 delete m_pActWay; 184 183 } 185 184 //#endif 186 185 187 186 m_pActWay = 0; 188 187 } 189 188 } -
src/OSMDocument.cpp
29 29 namespace osm 30 30 { 31 31 32 OSMDocument::OSMDocument( Configuration& config ) : m_rConfig( config ) 33 { 32 OSMDocument::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; 34 35 } 35 36 36 37 OSMDocument::~OSMDocument() 37 38 { 38 ez_mapdelete( m_Nodes );39 ez_vectordelete( m_Ways ); 39 //ez_mapdelete( m_Nodes ); 40 ez_vectordelete( m_Ways ); 40 41 ez_vectordelete( m_SplittedWays ); 41 42 } 42 43 void OSMDocument::AddNode( Node* n ) 43 44 { 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 }; 45 49 } 46 50 47 51 void OSMDocument::AddWay( Way* w ) … … 49 53 m_Ways.push_back( w ); 50 54 } 51 55 52 Node* OSMDocument::FindNode( long long nodeRefId ) 56 Node* OSMDocument::FindNode( long long nodeRefId ) 53 57 const 54 58 { 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); 57 62 } 58 63 59 64 void OSMDocument::SplitWays() 60 65 { 61 66 62 67 std::vector<Way*>::const_iterator it(m_Ways.begin()); 63 68 std::vector<Way*>::const_iterator last(m_Ways.end()); 64 69 … … 68 73 while(it!=last) 69 74 { 70 75 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()); 73 78 std::vector<Node*>::const_iterator last_node( currentWay->m_NodeRefs.end()); 74 79 75 80 Node* backNode = currentWay->m_NodeRefs.back(); 76 81 77 82 78 83 79 84 while(it_node!=last_node) 80 85 { 81 86 82 87 Node* node = *it_node++; 83 88 Node* secondNode=0; 84 89 Node* lastNode=0; 85 90 86 91 Way* splitted_way = new Way( ++id, currentWay->visible ); 87 92 splitted_way->name=currentWay->name; 88 93 splitted_way->type=currentWay->type; … … 90 95 splitted_way->oneway=currentWay->oneway; 91 96 92 97 //GeometryFromText('MULTILINESTRING(('||x1||' '||y1||','||x2||' '||y2||'))',4326); 93 98 94 99 splitted_way->geom="MULTILINESTRING(("+ boost::lexical_cast<std::string>(node->lon) + " " + boost::lexical_cast<std::string>(node->lat) +","; 95 100 96 101 splitted_way->AddNodeRef(node); 97 102 98 103 bool found=false; 99 104 100 105 if(it_node!=last_node) 101 106 { 102 107 while(it_node!=last_node && !found) … … 112 117 length*=-1; 113 118 splitted_way->length+=length; 114 119 splitted_way->geom+= boost::lexical_cast<std::string>(secondNode->lon) + " " + boost::lexical_cast<std::string>(secondNode->lat) + "))"; 115 120 116 121 } 117 122 else if(backNode==(*it_node)) 118 123 { … … 131 136 } 132 137 } 133 138 } 134 139 135 140 if(splitted_way->m_NodeRefs.front()!=splitted_way->m_NodeRefs.back()) 136 141 m_SplittedWays.push_back(splitted_way); 137 142 else … … 139 144 delete splitted_way; 140 145 splitted_way=0; 141 146 } 142 147 143 148 } 144 149 145 150 } -
Makefile
9 9 MAIN = src/osm2pgrouting.cpp 10 10 11 11 all: 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 15 18 rm *.o 16 19 clean: 17 20 rm osm2pgrouting