Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

PBF Support (Thanks to Christian for explanations)

  • Loading branch information...
commit cf46fd79b0456c8ba86154d13052d2f4c8911d3e 1 parent d38adbe
authored January 12, 2011
29  Contractor/Contractor.h
@@ -275,21 +275,17 @@ class Contractor {
275 275
     }
276 276
 
277 277
     template< class InputEdge >
278  
-    void CheckForAllOrigEdges(std::vector< InputEdge >& inputEdges)
279  
-    {
280  
-        for(unsigned int i = 0; i < inputEdges.size(); i++)
281  
-        {
  278
+    void CheckForAllOrigEdges(std::vector< InputEdge >& inputEdges) {
  279
+        for(unsigned int i = 0; i < inputEdges.size(); i++) {
282 280
             bool found = false;
283 281
             _DynamicGraph::EdgeIterator eit = _graph->BeginEdges(inputEdges[i].source());
284  
-            for(;eit<_graph->EndEdges(inputEdges[i].source()); eit++)
285  
-            {
286  
-                if(_graph->GetEdgeData(eit).distance = inputEdges[i].weight())
  282
+            for(;eit<_graph->EndEdges(inputEdges[i].source()); eit++) {
  283
+                if(_graph->GetEdgeData(eit).distance == inputEdges[i].weight())
287 284
                     found = true;
288 285
             }
289 286
             eit = _graph->BeginEdges(inputEdges[i].target());
290  
-            for(;eit<_graph->EndEdges(inputEdges[i].target()); eit++)
291  
-            {
292  
-                if(_graph->GetEdgeData(eit).distance = inputEdges[i].weight())
  287
+            for(;eit<_graph->EndEdges(inputEdges[i].target()); eit++) {
  288
+                if(_graph->GetEdgeData(eit).distance == inputEdges[i].weight())
293 289
                     found = true;
294 290
             }
295 291
             assert(found);
@@ -303,7 +299,7 @@ class Contractor {
303 299
 
304 300
         unsigned maxThreads = omp_get_max_threads();
305 301
         std::vector < _ThreadData* > threadData;
306  
-        for ( int threadNum = 0; threadNum < maxThreads; ++threadNum ) {
  302
+        for ( unsigned threadNum = 0; threadNum < maxThreads; ++threadNum ) {
307 303
             threadData.push_back( new _ThreadData( numberOfNodes ) );
308 304
         }
309 305
         cout << "Contractor is using " << maxThreads << " threads" << endl;
@@ -388,7 +384,7 @@ class Contractor {
388 384
             timeLast = _Timestamp();
389 385
 
390 386
             //insert new edges
391  
-            for ( int threadNum = 0; threadNum < maxThreads; ++threadNum ) {
  387
+            for ( unsigned threadNum = 0; threadNum < maxThreads; ++threadNum ) {
392 388
                 _ThreadData& data = *threadData[threadNum];
393 389
                 for ( int i = 0; i < ( int ) data.insertedEdges.size(); ++i ) {
394 390
                     const _ImportEdge& edge = data.insertedEdges[i];
@@ -442,14 +438,11 @@ class Contractor {
442 438
             p.printStatus(levelID);
443 439
         }
444 440
 
445  
-        for ( int threadNum = 0; threadNum < maxThreads; threadNum++ ) {
446  
-            //            _witnessList.insert( _witnessList.end(), threadData[threadNum]->witnessList.begin(), threadData[threadNum]->witnessList.end() );
  441
+        for ( unsigned threadNum = 0; threadNum < maxThreads; threadNum++ ) {
447 442
             delete threadData[threadNum];
448 443
         }
449 444
 
450  
-        //        log.PrintSummary();
451  
-        //        cout << "Total Time: " << log.GetSum().GetTotalTime()<< " s" << endl;
452  
-        cout << "checking sanity of generated data ..." << flush;
  445
+        cout << "[contractor] checking sanity of generated data ..." << flush;
453 446
         _CheckCH<_EdgeData>();
454 447
         cout << "ok" << endl;
455 448
     }
@@ -595,7 +588,7 @@ class Contractor {
595 588
             if ( node != source )
596 589
                 heap.Insert( node, inData.distance, _HeapData() );
597 590
             int maxDistance = 0;
598  
-            unsigned numTargets = 0;
  591
+            //unsigned numTargets = 0;
599 592
 
600 593
             for ( _DynamicGraph::EdgeIterator outEdge = _graph->BeginEdges( node ), endOutEdges = _graph->EndEdges( node ); outEdge != endOutEdges; ++outEdge ) {
601 594
                 const _EdgeData& outData = _graph->GetEdgeData( outEdge );
34  DataStructures/BaseParser.h
... ...
@@ -0,0 +1,34 @@
  1
+/*
  2
+    open source routing machine
  3
+    Copyright (C) Dennis Luxen, others 2010
  4
+
  5
+This program is free software; you can redistribute it and/or modify
  6
+it under the terms of the GNU AFFERO General Public License as published by
  7
+the Free Software Foundation; either version 3 of the License, or
  8
+any later version.
  9
+
  10
+This program is distributed in the hope that it will be useful,
  11
+but WITHOUT ANY WARRANTY; without even the implied warranty of
  12
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13
+GNU General Public License for more details.
  14
+
  15
+You should have received a copy of the GNU Affero General Public License
  16
+along with this program; if not, write to the Free Software
  17
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18
+or see http://www.gnu.org/licenses/agpl.txt.
  19
+ */
  20
+
  21
+#ifndef BASEPARSER_H_
  22
+#define BASEPARSER_H_
  23
+
  24
+template<typename NodeT, typename RelationT, typename WayT>
  25
+class BaseParser {
  26
+public:
  27
+    virtual ~BaseParser() {}
  28
+    virtual bool Init() = 0;
  29
+    virtual bool RegisterCallbacks(bool (*nodeCallbackPointer)(NodeT), bool (*relationCallbackPointer)(RelationT), bool (*wayCallbackPointer)(WayT)) = 0;
  30
+    virtual bool Parse() = 0;
  31
+private:
  32
+};
  33
+
  34
+#endif /* BASEPARSER_H_ */
306  DataStructures/ExtractorStructs.h
@@ -50,8 +50,6 @@ std::string names[14] = { "motorway", "motorway_link", "trunk", "trunk_link", "p
50 50
 double speeds[14] = { 110, 90, 90, 70, 70, 60, 60, 50, 55, 25, 40 , 10, 30, 5};
51 51
 
52 52
 struct _Node : NodeInfo{
53  
-    bool trafficSignal;
54  
-
55 53
     _Node(int _lat, int _lon, unsigned int _id) : NodeInfo(_lat, _lon,  _id) {}
56 54
     _Node() {}
57 55
 
@@ -77,15 +75,26 @@ struct _Coordinate {
77 75
 };
78 76
 
79 77
 struct _Way {
  78
+    _Way() {
  79
+        direction = _Way::notSure;
  80
+        maximumSpeed = -1;
  81
+        type = -1;
  82
+        useful = false;
  83
+        access = true;
  84
+    }
  85
+
80 86
     std::vector< NodeID > path;
81 87
     enum {
82 88
         notSure = 0, oneway, bidirectional, opposite
83 89
     } direction;
  90
+    unsigned id;
84 91
     unsigned nameID;
  92
+    std::string name;
85 93
     double maximumSpeed;
86  
-    bool usefull:1;
  94
+    bool useful:1;
87 95
     bool access:1;
88 96
     short type;
  97
+    HashTable<std::string, std::string> keyVals;
89 98
 };
90 99
 
91 100
 struct _Relation {
@@ -114,11 +123,11 @@ struct Settings {
114 123
         vector< double > speed;
115 124
         vector< string > names;
116 125
     } speedProfile;
117  
-//    vector<string> accessList;
118  
-    int trafficLightPenalty;
  126
+    //    vector<string> accessList;
  127
+    //    int trafficLightPenalty;
119 128
     int indexInAccessListOf( const string & key)
120 129
     {
121  
-        for(int i = 0; i< speedProfile.names.size(); i++)
  130
+        for(unsigned i = 0; i< speedProfile.names.size(); i++)
122 131
         {
123 132
             if(speedProfile.names[i] == key)
124 133
                 return i;
@@ -195,265 +204,6 @@ struct CmpNodeByID : public std::binary_function<_Node, _Node, bool>
195 204
     }
196 205
 };
197 206
 
198  
-
199  
-_Way _ReadXMLWay( xmlTextReaderPtr& inputReader, Settings& settings, string& name) {
200  
-    _Way way;
201  
-    way.direction = _Way::notSure;
202  
-    way.maximumSpeed = -1;
203  
-    way.type = -1;
204  
-    way.usefull = false;
205  
-    way.access = true;
206  
-//    cout << "new way" << endl;
207  
-    if ( xmlTextReaderIsEmptyElement( inputReader ) != 1 ) {
208  
-        const int depth = xmlTextReaderDepth( inputReader );
209  
-        while ( xmlTextReaderRead( inputReader ) == 1 ) {
210  
-            const int childType = xmlTextReaderNodeType( inputReader );
211  
-            if ( childType != 1 && childType != 15 )
212  
-                continue;
213  
-            const int childDepth = xmlTextReaderDepth( inputReader );
214  
-            xmlChar* childName = xmlTextReaderName( inputReader );
215  
-            if ( childName == NULL )
216  
-                continue;
217  
-
218  
-            if ( depth == childDepth && childType == 15 && xmlStrEqual( childName, ( const xmlChar* ) "way" ) == 1 ) {
219  
-                xmlFree( childName );
220  
-                break;
221  
-            }
222  
-            if ( childType != 1 ) {
223  
-                xmlFree( childName );
224  
-                continue;
225  
-            }
226  
-
227  
-            if ( xmlStrEqual( childName, ( const xmlChar* ) "tag" ) == 1 ) {
228  
-                xmlChar* k = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "k" );
229  
-                xmlChar* value = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "v" );
230  
-//                cout << "->k=" << k << ", v=" << value << endl;
231  
-                if ( k != NULL && value != NULL ) {
232  
-
233  
-                    if ( xmlStrEqual( k, ( const xmlChar* ) "name" ) == 1 ) {
234  
-                        name = string((char *) value);
235  
-                    } else if ( xmlStrEqual( k, ( const xmlChar* ) "ref" ) == 1 ) {
236  
-                    	if(name == "")
237  
-                    	{
238  
-                    		name = string((char *) value);
239  
-//                    		cout << ", ref: " << name << endl;
240  
-                    	}
241  
-                    }
242  
-
243  
-                    if ( xmlStrEqual( k, ( const xmlChar* ) "oneway" ) == 1 ) {
244  
-                        if ( xmlStrEqual( value, ( const xmlChar* ) "no" ) == 1 || xmlStrEqual( value, ( const xmlChar* ) "false" ) == 1 || xmlStrEqual( value, ( const xmlChar* ) "0" ) == 1 )
245  
-                            way.direction = _Way::bidirectional;
246  
-                        else if ( xmlStrEqual( value, ( const xmlChar* ) "yes" ) == 1 || xmlStrEqual( value, ( const xmlChar* ) "true" ) == 1 || xmlStrEqual( value, ( const xmlChar* ) "1" ) == 1 )
247  
-                            way.direction = _Way::oneway;
248  
-                        else if ( xmlStrEqual( value, ( const xmlChar* ) "-1" ) == 1 )
249  
-                            way.direction = _Way::opposite;
250  
-                    } else if ( xmlStrEqual( k, ( const xmlChar* ) "junction" ) == 1 ) {
251  
-                        if ( xmlStrEqual( value, ( const xmlChar* ) "roundabout" ) == 1 ) {
252  
-                            if ( way.direction == _Way::notSure ) {
253  
-                                way.direction = _Way::oneway;
254  
-                            }
255  
-                            way.usefull = true;
256  
-                            if(way.type == -1)
257  
-                                way.type = 9;
258  
-                        }
259  
-                    } else if ( xmlStrEqual( k, ( const xmlChar* ) "route" ) == 1 ) {
260  
-                        string name( (const char* ) value );
261  
-                        if (name == "ferry") {
262  
-                            for ( int i = 0; i < settings.speedProfile.names.size(); i++ ) {
263  
-                                if ( name == settings.speedProfile.names[i] ) {
264  
-                                    way.type = i;
265  
-                                    way.maximumSpeed = settings.speedProfile.speed[i];
266  
-                                    way.usefull = true;
267  
-                                    way.direction == _Way::bidirectional;
268  
-                                    break;
269  
-                                }
270  
-                            }
271  
-                        }
272  
-                    } else if ( xmlStrEqual( k, ( const xmlChar* ) "highway" ) == 1 ) {
273  
-                        string name( ( const char* ) value );
274  
-                        for ( int i = 0; i < settings.speedProfile.names.size(); i++ ) {
275  
-                            if ( name == settings.speedProfile.names[i] ) {
276  
-                                way.type = i;
277  
-                                way.usefull = true;
278  
-                                break;
279  
-                            }
280  
-                        }
281  
-                        if ( name == "motorway"  ) {
282  
-                            if ( way.direction == _Way::notSure ) {
283  
-                                way.direction = _Way::oneway;
284  
-                            }
285  
-                        } else if ( name == "motorway_link" ) {
286  
-                            if ( way.direction == _Way::notSure ) {
287  
-                                way.direction = _Way::oneway;
288  
-                            }
289  
-                        }
290  
-                    } else if ( xmlStrEqual( k, ( const xmlChar* ) "maxspeed" ) == 1 ) {
291  
-                        double maxspeed = atof(( const char* ) value );
292  
-
293  
-                        xmlChar buffer[100];
294  
-                        xmlStrPrintf( buffer, 100, ( const xmlChar* ) "%.lf", maxspeed );
295  
-                        if ( xmlStrEqual( value, buffer ) == 1 ) {
296  
-                            way.maximumSpeed = maxspeed;
297  
-                        } else {
298  
-                            xmlStrPrintf( buffer, 100, ( const xmlChar* ) "%.lf kmh", maxspeed );
299  
-                            if ( xmlStrEqual( value, buffer ) == 1 ) {
300  
-                                way.maximumSpeed = maxspeed;
301  
-                            } else {
302  
-                                xmlStrPrintf( buffer, 100, ( const xmlChar* ) "%.lfkmh", maxspeed );
303  
-                                if ( xmlStrEqual( value, buffer ) == 1 ) {
304  
-                                    way.maximumSpeed = maxspeed;
305  
-                                } else {
306  
-                                    xmlStrPrintf( buffer, 100, ( const xmlChar* ) "%.lf km/h", maxspeed );
307  
-                                    if ( xmlStrEqual( value, buffer ) == 1 ) {
308  
-                                        way.maximumSpeed = maxspeed;
309  
-                                    } else {
310  
-                                        xmlStrPrintf( buffer, 100, ( const xmlChar* ) "%.lfkm/h", maxspeed );
311  
-                                        if ( xmlStrEqual( value, buffer ) == 1 ) {
312  
-                                            way.maximumSpeed = maxspeed;
313  
-                                        } else {
314  
-                                            xmlStrPrintf( buffer, 100, ( const xmlChar* ) "%.lf mph", maxspeed );
315  
-                                            if ( xmlStrEqual( value, buffer ) == 1 ) {
316  
-                                                way.maximumSpeed = maxspeed;
317  
-                                            } else {
318  
-                                                xmlStrPrintf( buffer, 100, ( const xmlChar* ) "%.lfmph", maxspeed );
319  
-                                                if ( xmlStrEqual( value, buffer ) == 1 ) {
320  
-                                                    way.maximumSpeed = maxspeed;
321  
-                                                } else {
322  
-                                                    xmlStrPrintf( buffer, 100, ( const xmlChar* ) "%.lf mp/h", maxspeed );
323  
-                                                    if ( xmlStrEqual( value, buffer ) == 1 ) {
324  
-                                                        way.maximumSpeed = maxspeed;
325  
-                                                    } else {
326  
-                                                        xmlStrPrintf( buffer, 100, ( const xmlChar* ) "%.lfmp/h", maxspeed );
327  
-                                                        if ( xmlStrEqual( value, buffer ) == 1 ) {
328  
-                                                            way.maximumSpeed = maxspeed;
329  
-                                                        }
330  
-                                                    }
331  
-                                                }
332  
-                                            }
333  
-                                        }
334  
-                                    }
335  
-                                }
336  
-                            }
337  
-                        }
338  
-                    } else {
339  
-                        if ( xmlStrEqual( k, (const xmlChar*) "access" ))
340  
-                        {
341  
-                            if ( xmlStrEqual( value, ( const xmlChar* ) "private" ) == 1)
342  
-
343  
-                                if ( xmlStrEqual( value, ( const xmlChar* ) "private" ) == 1
344  
-                                        || xmlStrEqual( value, ( const xmlChar* ) "no" ) == 1
345  
-                                        || xmlStrEqual( value, ( const xmlChar* ) "agricultural" ) == 1
346  
-                                        || xmlStrEqual( value, ( const xmlChar* ) "forestry" ) == 1
347  
-                                        || xmlStrEqual( value, ( const xmlChar* ) "delivery" ) == 1
348  
-                                ) {
349  
-                                    way.access = false;
350  
-                                }
351  
-                                else if ( xmlStrEqual( value, ( const xmlChar* ) "yes" ) == 1
352  
-                                        || xmlStrEqual( value, ( const xmlChar* ) "designated" ) == 1
353  
-                                        || xmlStrEqual( value, ( const xmlChar* ) "official" ) == 1
354  
-                                        || xmlStrEqual( value, ( const xmlChar* ) "permissive" ) == 1
355  
-                                ) {
356  
-                                    way.access = true;
357  
-                                }
358  
-                        }
359  
-                        if ( xmlStrEqual( k, (const xmlChar*) "motorcar" ))
360  
-                        {
361  
-                            if ( xmlStrEqual( value, ( const xmlChar* ) "yes" ) == 1)
362  
-                            {
363  
-                                way.access = true;
364  
-                            } else if ( xmlStrEqual( k, (const xmlChar*) "no" )) {
365  
-                                way.access = false;
366  
-                            }
367  
-
368  
-                        }
369  
-                    }
370  
-                    if ( k != NULL )
371  
-                        xmlFree( k );
372  
-                    if ( value != NULL )
373  
-                        xmlFree( value );
374  
-                }
375  
-            } else if ( xmlStrEqual( childName, ( const xmlChar* ) "nd" ) == 1 ) {
376  
-                xmlChar* ref = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "ref" );
377  
-                if ( ref != NULL ) {
378  
-                    way.path.push_back( atoi(( const char* ) ref ) );
379  
-                    xmlFree( ref );
380  
-                }
381  
-            }
382  
-            xmlFree( childName );
383  
-        }
384  
-    }
385  
-    return way;
386  
-}
387  
-
388  
-_Node _ReadXMLNode( xmlTextReaderPtr& inputReader ) {
389  
-    _Node node;
390  
-    node.trafficSignal = false;
391  
-
392  
-    xmlChar* attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "lat" );
393  
-    if ( attribute != NULL ) {
394  
-        node.lat =  static_cast<NodeID>(100000.*atof(( const char* ) attribute ) );
395  
-        xmlFree( attribute );
396  
-    }
397  
-    attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "lon" );
398  
-    if ( attribute != NULL ) {
399  
-        node.lon =  static_cast<NodeID>(100000.*atof(( const char* ) attribute ));
400  
-        xmlFree( attribute );
401  
-    }
402  
-    attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "id" );
403  
-    if ( attribute != NULL ) {
404  
-        node.id =  atoi(( const char* ) attribute );
405  
-        xmlFree( attribute );
406  
-    }
407  
-
408  
-    if ( xmlTextReaderIsEmptyElement( inputReader ) != 1 ) {
409  
-        const int depth = xmlTextReaderDepth( inputReader );
410  
-        while ( xmlTextReaderRead( inputReader ) == 1 ) {
411  
-            const int childType = xmlTextReaderNodeType( inputReader );
412  
-            // 1 = Element, 15 = EndElement
413  
-            if ( childType != 1 && childType != 15 )
414  
-                continue;
415  
-            const int childDepth = xmlTextReaderDepth( inputReader );
416  
-            xmlChar* childName = xmlTextReaderName( inputReader );
417  
-            if ( childName == NULL )
418  
-                continue;
419  
-
420  
-            if ( depth == childDepth && childType == 15 && xmlStrEqual( childName, ( const xmlChar* ) "node" ) == 1 ) {
421  
-                xmlFree( childName );
422  
-                break;
423  
-            }
424  
-            if ( childType != 1 ) {
425  
-                xmlFree( childName );
426  
-                continue;
427  
-            }
428  
-
429  
-            if ( xmlStrEqual( childName, ( const xmlChar* ) "tag" ) == 1 ) {
430  
-                xmlChar* k = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "k" );
431  
-                xmlChar* value = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "v" );
432  
-                if ( k != NULL && value != NULL ) {
433  
-                    if ( xmlStrEqual( k, ( const xmlChar* ) "highway" ) == 1 ) {
434  
-                        if ( xmlStrEqual( value, ( const xmlChar* ) "traffic_signals" ) == 1 )
435  
-                            node.trafficSignal = true;
436  
-                    }
437  
-                }
438  
-                if ( k != NULL )
439  
-                    xmlFree( k );
440  
-                if ( value != NULL )
441  
-                    xmlFree( value );
442  
-            }
443  
-
444  
-            xmlFree( childName );
445  
-        }
446  
-    }
447  
-    return node;
448  
-}
449  
-
450  
-_Relation _ReadXMLRelation ( xmlTextReaderPtr& inputReader ) {
451  
-    _Relation relation;
452  
-    relation.type = _Relation::unknown;
453  
-
454  
-    return relation;
455  
-}
456  
-
457 207
 double ApproximateDistance( const int lat1, const int lon1, const int lat2, const int lon2 ) {
458 208
     static const double DEG_TO_RAD = 0.017453292519943295769236907684886;
459 209
     ///Earth's quatratic mean radius for WGS-84
@@ -472,15 +222,15 @@ double ApproximateDistance( const int lat1, const int lon1, const int lat2, cons
472 222
 /* Get angle of line segment (A,C)->(C,B), atan2 magic, formerly cosine theorem*/
473 223
 double GetAngleBetweenTwoEdges(const _Coordinate& A, const _Coordinate& C, const _Coordinate& B)
474 224
 {
475  
-//    double a = ApproximateDistance(A.lat, A.lon, C.lat, C.lon); //first edge segment
476  
-//    double b = ApproximateDistance(B.lat, B.lon, C.lat, C.lon); //second edge segment
477  
-//    double c = ApproximateDistance(A.lat, A.lon, B.lat, B.lon); //third edgefrom triangle
478  
-//
479  
-//    double cosAlpha = (a*a + b*b - c*c)/ (2*a*b);
480  
-//
481  
-//    double alpha = ( (acos(cosAlpha) * 180.0 / M_PI) * (cosAlpha > 0 ? -1 : 1) ) + 180;
482  
-//    return alpha;
483  
-//    V = <x2 - x1, y2 - y1>
  225
+    //    double a = ApproximateDistance(A.lat, A.lon, C.lat, C.lon); //first edge segment
  226
+    //    double b = ApproximateDistance(B.lat, B.lon, C.lat, C.lon); //second edge segment
  227
+    //    double c = ApproximateDistance(A.lat, A.lon, B.lat, B.lon); //third edgefrom triangle
  228
+    //
  229
+    //    double cosAlpha = (a*a + b*b - c*c)/ (2*a*b);
  230
+    //
  231
+    //    double alpha = ( (acos(cosAlpha) * 180.0 / M_PI) * (cosAlpha > 0 ? -1 : 1) ) + 180;
  232
+    //    return alpha;
  233
+    //    V = <x2 - x1, y2 - y1>
484 234
     int v1x = A.lon - C.lon;
485 235
     int v1y = A.lat - C.lat;
486 236
     int v2x = B.lon - C.lon;
@@ -495,10 +245,10 @@ double GetAngleBetweenTwoEdges(const _Coordinate& A, const _Coordinate& C, const
495 245
 
496 246
 string GetRandomString() {
497 247
     char s[128];
498  
-	static const char alphanum[] =
499  
-        "0123456789"
500  
-        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
501  
-        "abcdefghijklmnopqrstuvwxyz";
  248
+    static const char alphanum[] =
  249
+            "0123456789"
  250
+            "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  251
+            "abcdefghijklmnopqrstuvwxyz";
502 252
 
503 253
     for (int i = 0; i < 128; ++i) {
504 254
         s[i] = alphanum[rand() % (sizeof(alphanum) - 1)];
24  DataStructures/NNGrid.h
@@ -181,7 +181,7 @@ class NNGrid {
181 181
 			delete entries;
182 182
 		}
183 183
 
184  
-		for(int i = 0; i< indexFileStreams.size(); i++) {
  184
+		for(unsigned i = 0; i< indexFileStreams.size(); i++) {
185 185
 			delete indexFileStreams[i];
186 186
 		}
187 187
 		threadLookup.EraseAll();
@@ -207,7 +207,7 @@ class NNGrid {
207 207
 
208 208
 		std::vector<std::pair<unsigned, unsigned> > indexList;
209 209
 		getListOfIndexesForEdgeAndGridSize(start, target, indexList);
210  
-		for(int i = 0; i < indexList.size(); i++)
  210
+		for(unsigned i = 0; i < indexList.size(); i++)
211 211
 		{
212 212
 			entries->push_back(GridEdgeData(edge, indexList[i].first, indexList[i].second));
213 213
 		}
@@ -381,7 +381,7 @@ class NNGrid {
381 381
 			}
382 382
 		}
383 383
 
384  
-		for(int i = 0; i < entriesWithSameRAMIndex.size() -1; i++)
  384
+		for(unsigned i = 0; i < entriesWithSameRAMIndex.size() -1; i++)
385 385
 		{
386 386
 			assert(entriesWithSameRAMIndex[i].ramIndex== entriesWithSameRAMIndex[i+1].ramIndex);
387 387
 		}
@@ -431,7 +431,7 @@ class NNGrid {
431 431
 		}
432 432
 
433 433
 		//write contents of tmpbuffer to disk
434  
-		for(int i = 0; i < indexIntoTmpBuffer; i++)
  434
+		for(unsigned i = 0; i < indexIntoTmpBuffer; i++)
435 435
 		{
436 436
 			indexOutFile.write(&(tmpBuffer->at(i)), sizeof(char));
437 437
 			numberOfWrittenBytes += sizeof(char);
@@ -448,7 +448,7 @@ class NNGrid {
448 448
 		unsigned counter = 0;
449 449
 		unsigned max = UINT_MAX;
450 450
 
451  
-		for(int i = 0; i < vectorWithSameFileIndex.size()-1; i++)
  451
+		for(unsigned i = 0; i < vectorWithSameFileIndex.size()-1; i++)
452 452
 		{
453 453
 			assert( vectorWithSameFileIndex[i].fileIndex == vectorWithSameFileIndex[i+1].fileIndex );
454 454
 			assert( vectorWithSameFileIndex[i].ramIndex == vectorWithSameFileIndex[i+1].ramIndex );
@@ -457,44 +457,44 @@ class NNGrid {
457 457
 		for(std::vector<GridEdgeData>::const_iterator et = vectorWithSameFileIndex.begin(); et != vectorWithSameFileIndex.end(); et++)
458 458
 		{
459 459
 			char * start = (char *)&et->edge.start;
460  
-			for(int i = 0; i < sizeof(NodeID); i++)
  460
+			for(unsigned i = 0; i < sizeof(NodeID); i++)
461 461
 			{
462 462
 				tmpBuffer->at(index+counter) = start[i];
463 463
 				counter++;
464 464
 			}
465 465
 			char * target = (char *)&et->edge.target;
466  
-			for(int i = 0; i < sizeof(NodeID); i++)
  466
+			for(unsigned i = 0; i < sizeof(NodeID); i++)
467 467
 			{
468 468
 				tmpBuffer->at(index+counter) = target[i];
469 469
 				counter++;
470 470
 			}
471 471
 			char * slat = (char *) &(et->edge.startCoord.lat);
472  
-			for(int i = 0; i < sizeof(int); i++)
  472
+			for(unsigned i = 0; i < sizeof(int); i++)
473 473
 			{
474 474
 				tmpBuffer->at(index+counter) = slat[i];
475 475
 				counter++;
476 476
 			}
477 477
 			char * slon = (char *) &(et->edge.startCoord.lon);
478  
-			for(int i = 0; i < sizeof(int); i++)
  478
+			for(unsigned i = 0; i < sizeof(int); i++)
479 479
 			{
480 480
 				tmpBuffer->at(index+counter) = slon[i];
481 481
 				counter++;
482 482
 			}
483 483
 			char * tlat = (char *) &(et->edge.targetCoord.lat);
484  
-			for(int i = 0; i < sizeof(int); i++)
  484
+			for(unsigned i = 0; i < sizeof(int); i++)
485 485
 			{
486 486
 				tmpBuffer->at(index+counter) = tlat[i];
487 487
 				counter++;
488 488
 			}
489 489
 			char * tlon = (char *) &(et->edge.targetCoord.lon);
490  
-			for(int i = 0; i < sizeof(int); i++)
  490
+			for(unsigned i = 0; i < sizeof(int); i++)
491 491
 			{
492 492
 				tmpBuffer->at(index+counter) = tlon[i];
493 493
 				counter++;
494 494
 			}
495 495
 		}
496 496
 		char * umax = (char *) &max;
497  
-		for(int i = 0; i < sizeof(unsigned); i++)
  497
+		for(unsigned i = 0; i < sizeof(unsigned); i++)
498 498
 		{
499 499
 			tmpBuffer->at(index+counter) = umax[i];
500 500
 			counter++;
1  DataStructures/NodeInformationHelpDesk.h
@@ -66,6 +66,7 @@ class NodeInformationHelpDesk{
66 66
 
67 67
 	inline bool FindRoutingStarts(const _Coordinate start, const _Coordinate target, PhantomNodes * phantomNodes) {
68 68
 		readOnlyGrid->FindRoutingStarts(start, target, phantomNodes);
  69
+		return true;
69 70
 	}
70 71
 
71 72
 	inline void RegisterThread(const unsigned k, const unsigned v) {
421  DataStructures/PBFParser.h
... ...
@@ -0,0 +1,421 @@
  1
+/*
  2
+    open source routing machine
  3
+    Copyright (C) Dennis Luxen, others 2010
  4
+
  5
+This program is free software; you can redistribute it and/or modify
  6
+it under the terms of the GNU AFFERO General Public License as published by
  7
+the Free Software Foundation; either version 3 of the License, or
  8
+any later version.
  9
+
  10
+This program is distributed in the hope that it will be useful,
  11
+but WITHOUT ANY WARRANTY; without even the implied warranty of
  12
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13
+GNU General Public License for more details.
  14
+
  15
+You should have received a copy of the GNU Affero General Public License
  16
+along with this program; if not, write to the Free Software
  17
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18
+or see http://www.gnu.org/licenses/agpl.txt.
  19
+ */
  20
+
  21
+#ifndef PBFPARSER_H_
  22
+#define PBFPARSER_H_
  23
+
  24
+#include <zlib.h>
  25
+
  26
+#include "BaseParser.h"
  27
+
  28
+#include "pbf-proto/fileformat.pb.h"
  29
+#include "pbf-proto/osmformat.pb.h"
  30
+#include "../typedefs.h"
  31
+#include "HashTable.h"
  32
+#include "ExtractorStructs.h"
  33
+
  34
+
  35
+class PBFParser : public BaseParser<_Node, _Relation, _Way> {
  36
+
  37
+    enum EntityType {
  38
+        TypeNode = 1,
  39
+        TypeWay = 2,
  40
+        TypeRelation = 4,
  41
+        TypeDenseNode = 8
  42
+    } ;
  43
+
  44
+    enum Endianness {
  45
+        LittleEndian = 1,
  46
+        BigEndian = 2
  47
+    };
  48
+
  49
+    short entityTypeIndicator;
  50
+
  51
+public:
  52
+    PBFParser(const char * fileName) {
  53
+        GOOGLE_PROTOBUF_VERIFY_VERSION;
  54
+
  55
+        input.open(fileName, std::ios::in | std::ios::binary);
  56
+
  57
+        if (!input) {
  58
+            std::cerr << fileName << ": File not found." << std::endl;
  59
+        }
  60
+
  61
+        blockCount = 0;
  62
+        groupCount = 0;
  63
+    }
  64
+
  65
+    bool RegisterCallbacks(bool (*nodeCallbackPointer)(_Node), bool (*relationCallbackPointer)(_Relation), bool (*wayCallbackPointer)(_Way) ) {
  66
+        nodeCallback = *nodeCallbackPointer;
  67
+        wayCallback = *wayCallbackPointer;
  68
+        relationCallback = *relationCallbackPointer;
  69
+        return true;
  70
+    }
  71
+
  72
+    ~PBFParser() {
  73
+        if(input.is_open())
  74
+            input.close();
  75
+
  76
+        google::protobuf::ShutdownProtobufLibrary();
  77
+
  78
+        std::cout << "[info] blocks: " << blockCount << std::endl;
  79
+        std::cout << "[info] groups: " << groupCount << std::endl;
  80
+    }
  81
+
  82
+    bool Init() {
  83
+        if(!readPBFBlobHeader(input)) {
  84
+            return false;
  85
+        }
  86
+
  87
+        if(readBlob(input)) {
  88
+            char data[charBuffer.size()];
  89
+            for(unsigned i = 0; i < charBuffer.size(); i++ ){
  90
+                data[i] = charBuffer[i];
  91
+            }
  92
+            if(!PBFHeaderBlock.ParseFromArray(data, charBuffer.size() ) ) {
  93
+                std::cerr << "[error] Header not parseable!" << std::endl;
  94
+                return false;
  95
+            }
  96
+
  97
+            for(int i = 0; i < PBFHeaderBlock.required_features_size(); i++) {
  98
+                const std::string& feature = PBFHeaderBlock.required_features( i );
  99
+                bool supported = false;
  100
+                if ( feature == "OsmSchema-V0.6" )
  101
+                    supported = true;
  102
+                else if ( feature == "DenseNodes" )
  103
+                    supported = true;
  104
+
  105
+                if ( !supported ) {
  106
+                    std::cerr << "[error] required feature not supported: " << feature.data() << std::endl;
  107
+                    return false;
  108
+                }
  109
+            }
  110
+        } else {
  111
+            std::cerr << "[error] blob not loaded!" << std::endl;
  112
+        }
  113
+        return true;
  114
+    }
  115
+
  116
+    bool Parse() {
  117
+        //parse through all Blocks
  118
+        while(readNextBlock(input)) {
  119
+
  120
+            loadBlock();
  121
+            for(int i = 0; i < PBFprimitiveBlock.primitivegroup_size(); i++) {
  122
+                currentGroupID = i;
  123
+                loadGroup();
  124
+
  125
+                if(entityTypeIndicator == TypeNode)
  126
+                    parseNode();
  127
+                if(entityTypeIndicator == TypeWay)
  128
+                    parseWay();
  129
+                if(entityTypeIndicator == TypeRelation)
  130
+                    parseRelation();
  131
+                if(entityTypeIndicator == TypeDenseNode)
  132
+                    parseDenseNode();
  133
+            }
  134
+        }
  135
+        return true;
  136
+    }
  137
+
  138
+private:
  139
+
  140
+    void parseDenseNode() {
  141
+        const OSMPBF::DenseNodes& dense = PBFprimitiveBlock.primitivegroup( currentGroupID ).dense();
  142
+        int denseTagIndex = 0;
  143
+        int m_lastDenseID = 0;
  144
+        int m_lastDenseLatitude = 0;
  145
+        int m_lastDenseLongitude = 0;
  146
+
  147
+        for(int i = 0; i < dense.id_size(); i++) {
  148
+            m_lastDenseID += dense.id( i );
  149
+            m_lastDenseLatitude += dense.lat( i );
  150
+            m_lastDenseLongitude += dense.lon( i );
  151
+            _Node n;
  152
+            n.id = m_lastDenseID;
  153
+            n.lat = 100000*( ( double ) m_lastDenseLatitude * PBFprimitiveBlock.granularity() + PBFprimitiveBlock.lat_offset() ) / NANO;
  154
+            n.lon = 100000*( ( double ) m_lastDenseLongitude * PBFprimitiveBlock.granularity() + PBFprimitiveBlock.lon_offset() ) / NANO;
  155
+            while (denseTagIndex < dense.keys_vals_size()) {
  156
+                int tagValue = dense.keys_vals( denseTagIndex );
  157
+                if(tagValue == 0) {
  158
+                    denseTagIndex++;
  159
+                    break;
  160
+                }
  161
+                //int keyValue = dense.keys_vals ( denseTagIndex+1 );
  162
+                /* Key/Value Pairs are known from here on */
  163
+                //              std::cout << "[debug] node: " << n.id << std::endl;
  164
+                //              std::cout << "[debug]  key = " << PBFprimitiveBlock.stringtable().s(tagValue).data() << ", value: " << PBFprimitiveBlock.stringtable().s(keyValue).data() << std::endl;
  165
+
  166
+                denseTagIndex += 2;
  167
+            }
  168
+
  169
+            if(!(*nodeCallback)(n))
  170
+                std::cerr << "[PBFParser] dense node not parsed" << std::endl;
  171
+        }
  172
+    }
  173
+
  174
+    void parseNode() {
  175
+        _Node n;
  176
+        if(!(*nodeCallback)(n))
  177
+            std::cerr << "[PBFParser] simple node not parsed" << std::endl;
  178
+    }
  179
+
  180
+    void parseRelation() {
  181
+        const OSMPBF::PrimitiveGroup& group = PBFprimitiveBlock.primitivegroup( currentGroupID );
  182
+        for(int i = 0; i < group.relations_size(); i++ ) {
  183
+            _Relation r;
  184
+            r.type = _Relation::unknown;
  185
+            if(!(*relationCallback)(r))
  186
+                std::cerr << "[PBFParser] relation not parsed" << std::endl;
  187
+        }
  188
+    }
  189
+
  190
+    void parseWay() {
  191
+        if( PBFprimitiveBlock.primitivegroup( currentGroupID ).ways_size() > 0) {
  192
+            for(int i = 0; i < PBFprimitiveBlock.primitivegroup( currentGroupID ).ways_size(); i++) {
  193
+                const OSMPBF::Way& inputWay = PBFprimitiveBlock.primitivegroup( currentGroupID ).ways( i );
  194
+                _Way w;
  195
+                w.id = inputWay.id();
  196
+                unsigned pathNode(0);
  197
+                for(int i = 0; i < inputWay.refs_size(); i++) {
  198
+                    pathNode += inputWay.refs(i);
  199
+                    w.path.push_back(pathNode);
  200
+                }
  201
+                assert(inputWay.keys_size() == inputWay.vals_size());
  202
+                for(int i = 0; i < inputWay.keys_size(); i++) {
  203
+                    //                    std::cout << "[debug] key: " << PBFprimitiveBlock.stringtable().s(inputWay.keys(i)) << ", val: " << PBFprimitiveBlock.stringtable().s(inputWay.vals(i)) << std::endl;
  204
+                    const std::string key = PBFprimitiveBlock.stringtable().s(inputWay.keys(i));
  205
+                    const std::string val = PBFprimitiveBlock.stringtable().s(inputWay.vals(i));
  206
+                    w.keyVals.Add(key, val);
  207
+                }
  208
+                if(!(*wayCallback)(w)) {
  209
+                    std::cerr << "[PBFParser] way not parsed" << std::endl;
  210
+                }
  211
+            }
  212
+        }
  213
+    }
  214
+
  215
+    void loadGroup() {
  216
+        groupCount++;
  217
+        const OSMPBF::PrimitiveGroup& group = PBFprimitiveBlock.primitivegroup( currentGroupID );
  218
+        entityTypeIndicator = 0;
  219
+        if ( group.nodes_size() != 0 ) {
  220
+            entityTypeIndicator = TypeNode;
  221
+        }
  222
+        if ( group.ways_size() != 0 ) {
  223
+            entityTypeIndicator = TypeWay;
  224
+        }
  225
+        if ( group.relations_size() != 0 ) {
  226
+            entityTypeIndicator = TypeRelation;
  227
+        }
  228
+        if ( group.has_dense() )  {
  229
+            entityTypeIndicator =  TypeDenseNode;
  230
+            assert( group.dense().id_size() != 0 );
  231
+        }
  232
+        assert( entityTypeIndicator != 0 );
  233
+    }
  234
+
  235
+    void loadBlock() {
  236
+        blockCount++;
  237
+        currentGroupID = 0;
  238
+        currentEntityID = 0;
  239
+//        int stringCount = PBFprimitiveBlock.stringtable().s_size();
  240
+    }
  241
+
  242
+    /* Reverses Network Byte Order into something usable */
  243
+    inline unsigned swapEndian(unsigned x) {
  244
+        if(getMachineEndianness() == LittleEndian)
  245
+            return ( (x>>24) | ((x<<8) & 0x00FF0000) | ((x>>8) & 0x0000FF00) | (x<<24) );
  246
+        return x;
  247
+    }
  248
+
  249
+    bool readPBFBlobHeader(std::fstream& stream) {
  250
+        int size(0);
  251
+        stream.read((char *)&size, sizeof(int));
  252
+        size = swapEndian(size);
  253
+        if(stream.eof()) {
  254
+            return false;
  255
+        }
  256
+        if ( size > MAX_BLOB_HEADER_SIZE || size < 0 ) {
  257
+            return false;
  258
+        }
  259
+        char data[size];
  260
+        for(int i = 0; i < size; i++) {
  261
+            stream.read(&data[i], 1);
  262
+        }
  263
+
  264
+        if ( !PBFBlobHeader.ParseFromArray( data, size ) ) {
  265
+            return false;
  266
+        }
  267
+        return true;
  268
+    }
  269
+
  270
+    bool unpackZLIB(std::fstream & stream) {
  271
+        unsigned rawSize = PBFBlob.raw_size();
  272
+        char unpackedDataArray[rawSize];
  273
+        z_stream compressedDataStream;
  274
+        compressedDataStream.next_in = ( unsigned char* ) PBFBlob.zlib_data().data();
  275
+        compressedDataStream.avail_in = PBFBlob.zlib_data().size();
  276
+        compressedDataStream.next_out = ( unsigned char* ) unpackedDataArray;
  277
+        compressedDataStream.avail_out = rawSize;
  278
+        compressedDataStream.zalloc = Z_NULL;
  279
+        compressedDataStream.zfree = Z_NULL;
  280
+        compressedDataStream.opaque = Z_NULL;
  281
+        int ret = inflateInit( &compressedDataStream );
  282
+        if ( ret != Z_OK ) {
  283
+            std::cerr << "[error] failed to init zlib stream" << std::endl;
  284
+            return false;
  285
+        }
  286
+
  287
+        ret = inflate( &compressedDataStream, Z_FINISH );
  288
+        if ( ret != Z_STREAM_END ) {
  289
+            std::cerr << "[error] failed to inflate zlib stream" << std::endl;
  290
+            return false;
  291
+        }
  292
+
  293
+        ret = inflateEnd( &compressedDataStream );
  294
+        if ( ret != Z_OK ) {
  295
+            std::cerr << "[error] failed to deinit zlib stream" << std::endl;
  296
+            return false;
  297
+        }
  298
+
  299
+        charBuffer.clear(); charBuffer.resize(rawSize);
  300
+        for(unsigned i = 0; i < rawSize; i++) {
  301
+            charBuffer[i] = unpackedDataArray[i];
  302
+        }
  303
+        return true;
  304
+    }
  305
+
  306
+    bool unpackLZMA(std::fstream & stream) {
  307
+        return false;
  308
+    }
  309
+
  310
+    bool readBlob(std::fstream& stream) {
  311
+        if(stream.eof())
  312
+            return false;
  313
+
  314
+        int size = PBFBlobHeader.datasize();
  315
+        if ( size < 0 || size > MAX_BLOB_SIZE ) {
  316
+            std::cerr << "[error] invalid Blob size:" << size << std::endl;
  317
+            return false;
  318
+        }
  319
+
  320
+        char data[size];
  321
+        for(int i = 0; i < size; i++) {
  322
+            stream.read(&data[i], 1);
  323
+        }
  324
+
  325
+        if ( !PBFBlob.ParseFromArray( data, size ) ) {
  326
+            std::cerr << "[error] failed to parse blob" << std::endl;
  327
+            return false;
  328
+        }
  329
+
  330
+        if ( PBFBlob.has_raw() ) {
  331
+            const std::string& data = PBFBlob.raw();
  332
+            charBuffer.clear();
  333
+            charBuffer.resize( data.size() );
  334
+            for ( unsigned i = 0; i < data.size(); i++ ) {
  335
+                charBuffer[i] = data[i];
  336
+            }
  337
+        } else if ( PBFBlob.has_zlib_data() ) {
  338
+            if ( !unpackZLIB(stream) ) {
  339
+                std::cerr << "[error] zlib data encountered that could not be unpacked" << std::endl;
  340
+                return false;
  341
+            }
  342
+        } else if ( PBFBlob.has_lzma_data() ) {
  343
+            if ( !unpackLZMA(stream) )
  344
+                std::cerr << "[error] lzma data encountered that could not be unpacked" << std::endl;
  345
+            return false;
  346
+        } else {
  347
+            std::cerr << "[error] Blob contains no data" << std::endl;
  348
+            return false;
  349
+        }
  350
+        return true;
  351
+    }
  352
+
  353
+    bool readNextBlock(std::fstream& stream) {
  354
+        if(stream.eof()) {
  355
+            return false;
  356
+        }
  357
+
  358
+        if ( !readPBFBlobHeader(stream) )
  359
+            return false;
  360
+
  361
+        if ( PBFBlobHeader.type() != "OSMData" ) {
  362
+            std::cerr << "[error] invalid block type, found" << PBFBlobHeader.type().data() << "instead of OSMData" << std::endl;
  363
+            return false;
  364
+        }
  365
+
  366
+        if ( !readBlob(stream) )
  367
+            return false;
  368
+
  369
+        char data[charBuffer.size()];
  370
+        for(unsigned i = 0; i < charBuffer.size(); i++ ){
  371
+            data[i] = charBuffer[i];
  372
+        }
  373
+        if ( !PBFprimitiveBlock.ParseFromArray( data, charBuffer.size() ) ) {
  374
+            std::cerr << "[error] failed to parse PrimitiveBlock" << std::endl;
  375
+            return false;
  376
+        }
  377
+        return true;
  378
+    }
  379
+
  380
+    Endianness getMachineEndianness() {
  381
+        int i(1);
  382
+        char *p = (char *) &i;
  383
+        if (p[0] == 1)
  384
+            return LittleEndian;
  385
+        return BigEndian;
  386
+    }
  387
+
  388
+    static const int NANO = 1000 * 1000 * 1000;
  389
+    static const int MAX_BLOB_HEADER_SIZE = 64 * 1024;
  390
+    static const int MAX_BLOB_SIZE = 32 * 1024 * 1024;
  391
+
  392
+    OSMPBF::BlobHeader PBFBlobHeader;
  393
+    OSMPBF::Blob PBFBlob;
  394
+
  395
+    OSMPBF::HeaderBlock PBFHeaderBlock;
  396
+    OSMPBF::PrimitiveBlock PBFprimitiveBlock;
  397
+
  398
+    std::vector<char> charBuffer;
  399
+
  400
+    int currentGroupID;
  401
+    int currentEntityID;
  402
+    //    bool m_loadBlock;
  403
+    //    long long m_lastDenseID;
  404
+    //    long long m_lastDenseLatitude;
  405
+    //    long long m_lastDenseLongitude;
  406
+    //    int m_lastDenseTag;
  407
+
  408
+    /* counting the number of read blocks and groups */
  409
+    unsigned groupCount;
  410
+    unsigned blockCount;
  411
+
  412
+    /* Function pointer for nodes */
  413
+    bool (*nodeCallback)(_Node);
  414
+    bool (*wayCallback)(_Way);
  415
+    bool (*relationCallback)(_Relation);
  416
+
  417
+    /* the input stream to parse */
  418
+    std::fstream input;
  419
+};
  420
+
  421
+#endif /* PBFPARSER_H_ */
217  DataStructures/XMLParser.h
... ...
@@ -0,0 +1,217 @@
  1
+/*
  2
+    open source routing machine
  3
+    Copyright (C) Dennis Luxen, others 2010
  4
+
  5
+This program is free software; you can redistribute it and/or modify
  6
+it under the terms of the GNU AFFERO General Public License as published by
  7
+the Free Software Foundation; either version 3 of the License, or
  8
+any later version.
  9
+
  10
+This program is distributed in the hope that it will be useful,
  11
+but WITHOUT ANY WARRANTY; without even the implied warranty of
  12
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13
+GNU General Public License for more details.
  14
+
  15
+You should have received a copy of the GNU Affero General Public License
  16
+along with this program; if not, write to the Free Software
  17
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18
+or see http://www.gnu.org/licenses/agpl.txt.
  19
+ */
  20
+
  21
+#ifndef XMLPARSER_H_
  22
+#define XMLPARSER_H_
  23
+
  24
+#include <libxml/xmlreader.h>
  25
+
  26
+#include "../typedefs.h"
  27
+#include "BaseParser.h"
  28
+#include "HashTable.h"
  29
+#include "ExtractorStructs.h"
  30
+#include "InputReaderFactory.h"
  31
+
  32
+class XMLParser : public BaseParser<_Node, _Relation, _Way> {
  33
+public:
  34
+    XMLParser(const char * filename) {
  35
+        inputReader = inputReaderFactory(filename);
  36
+    }
  37
+    ~XMLParser() {}
  38
+
  39
+    bool RegisterCallbacks(bool (*nodeCallbackPointer)(_Node), bool (*relationCallbackPointer)(_Relation), bool (*wayCallbackPointer)(_Way) ) {
  40
+        nodeCallback = *nodeCallbackPointer;
  41
+        wayCallback = *wayCallbackPointer;
  42
+        relationCallback = *relationCallbackPointer;
  43
+        return true;
  44
+    }
  45
+    bool Init() {
  46
+        return (xmlTextReaderRead( inputReader ) == 1);
  47
+    }
  48
+    bool Parse() {
  49
+        while ( xmlTextReaderRead( inputReader ) == 1 ) {
  50
+            const int type = xmlTextReaderNodeType( inputReader );
  51
+
  52
+            //1 is Element
  53
+            if ( type != 1 )
  54
+                continue;
  55
+
  56
+            xmlChar* currentName = xmlTextReaderName( inputReader );
  57
+            if ( currentName == NULL )
  58
+                continue;
  59
+
  60
+            if ( xmlStrEqual( currentName, ( const xmlChar* ) "node" ) == 1 ) {
  61
+                _Node n = _ReadXMLNode(  );
  62
+                if(!(*nodeCallback)(n))
  63
+                    std::cerr << "[XMLParser] node not parsed" << std::endl;
  64
+            }
  65
+
  66
+            if ( xmlStrEqual( currentName, ( const xmlChar* ) "way" ) == 1 ) {
  67
+                string name;
  68
+                _Way way = _ReadXMLWay( );
  69
+                if(!(*wayCallback)(way)) {
  70
+                    std::cerr << "[XMLParser] way not parsed" << std::endl;
  71
+                }
  72
+            }
  73
+            if ( xmlStrEqual( currentName, ( const xmlChar* ) "relation" ) == 1 ) {
  74
+                _Relation r;
  75
+                r.type = _Relation::unknown;
  76
+                if(!(*relationCallback)(r))
  77
+                    std::cerr << "[error] relation not parsed" << std::endl;
  78
+            }
  79
+            xmlFree( currentName );
  80
+        }
  81
+        return true;
  82
+    }
  83
+
  84
+private:
  85
+    _Relation _ReadXMLRelation ( ) {
  86
+        _Relation relation;
  87
+        relation.type = _Relation::unknown;
  88
+
  89
+        return relation;
  90
+    }
  91
+
  92
+    _Way _ReadXMLWay( ) {
  93
+        _Way way;
  94
+        way.direction = _Way::notSure;
  95
+        way.maximumSpeed = -1;
  96
+        way.type = -1;
  97
+        way.useful = false;
  98
+        way.access = true;
  99
+        //    cout << "new way" << endl;
  100
+        if ( xmlTextReaderIsEmptyElement( inputReader ) != 1 ) {
  101
+            const int depth = xmlTextReaderDepth( inputReader );
  102
+            while ( xmlTextReaderRead( inputReader ) == 1 ) {
  103
+                const int childType = xmlTextReaderNodeType( inputReader );
  104
+                if ( childType != 1 && childType != 15 )
  105
+                    continue;
  106
+                const int childDepth = xmlTextReaderDepth( inputReader );
  107
+                xmlChar* childName = xmlTextReaderName( inputReader );
  108
+                if ( childName == NULL )
  109
+                    continue;
  110
+
  111
+                if ( depth == childDepth && childType == 15 && xmlStrEqual( childName, ( const xmlChar* ) "way" ) == 1 ) {
  112
+                    xmlFree( childName );
  113
+                    break;
  114
+                }
  115
+                if ( childType != 1 ) {
  116
+                    xmlFree( childName );
  117
+                    continue;
  118
+                }
  119
+
  120
+                if ( xmlStrEqual( childName, ( const xmlChar* ) "tag" ) == 1 ) {
  121
+                    xmlChar* k = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "k" );
  122
+                    xmlChar* value = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "v" );
  123
+                    //                cout << "->k=" << k << ", v=" << value << endl;
  124
+                    if ( k != NULL && value != NULL ) {
  125
+
  126
+                        way.keyVals.Add(std::string( (char *) k ), std::string( (char *) value));
  127
+                    }
  128
+                    if ( k != NULL )
  129
+                        xmlFree( k );
  130
+                    if ( value != NULL )
  131
+                        xmlFree( value );
  132
+                } else if ( xmlStrEqual( childName, ( const xmlChar* ) "nd" ) == 1 ) {
  133
+                    xmlChar* ref = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "ref" );