This is a example, how to store osm street data into a graph structure. in the future I will do a Dijkstra with this data.
#include <cstdio>
#include <utility>
#include <inttypes.h>
#include <vector>
#include <cstring>
#include <cmath>
#include <algorithm>
#define FILE_ITEMS ( 2*1024)
#define FILE_MULTI 4
#define RAM_MULTI 8
#define BBITS 5
#define BMASK ((BBITS+4)* FILE_ITEMS)
#define TORADI(angleDegrees) ((angleDegrees) * M_PI / 180.0)
#define LON_BOUND 5.85
#define LON_BOUND_DIF 3.62
#define LAT_BOUND 50.32
#define LAT_BOUND_DIF 2.2
#define DEFAULTATTR " version='1' timestamp='2019-12-20T14:59:00Z' visible='true'"
uint8_t _used;
double _lon;
double _lat;
};
bool _oneway;
};
double _lon;
double _lat;
};
uint8_t _dummy;
};
Key calcDist(
double lon1,
double lat1,
double lon2,
double lat2) {
double dist = 6378388.0 * std::acos(std::sin(
TORADI(lat1)) * std::sin(
TORADI(lat2)) + std::cos(
TORADI(lat1)) * std::cos(
TORADI(lat2)) * std::cos(
TORADI(lon2 - lon1)));
if (dist < 0) dist *=-1;
return dist;
}
if (wt.compare("motorway") == 0) return 1;
if (wt.compare("motorway_link") == 0) return 2;
if (wt.compare("trunk") == 0) return 1;
if (wt.compare("trunk_link") == 0) return 2;
if (wt.compare("primary") == 0) return 1;
if (wt.compare("primary_link") == 0) return 2;
if (wt.compare("secondary") == 0) return 1;
if (wt.compare("secondary_link") == 0) return 2;
if (wt.compare("unclassified") == 0) return 1;
if (wt.compare("tertiary") == 0) return 1;
if (wt.compare("tertiary_link") == 0) return 2;
if (wt.compare("residential") == 0) return 1;
return 0;
}
void node_callback(uint64_t osmid,
double lon,
double lat,
const Tags &) {
if (lon == 0 && lat == 0) return;
if (nodeptr == nullptr) return;
nodeptr->first._lon = lon;
nodeptr->first._lat = lat;
}
void way_callback(uint64_t osmid,
const Tags &tags,
const std::vector<uint64_t> &refs) {
if (tags.find("highway") != tags.end()) {
if (wt == 0) return;
std::vector<Key> path;
unsigned pathlength = refs.size();
bool rev = false;
bool circle = false;
if (tags.find("oneway") != tags.end()) {
std::string wt = tags.at("oneway");
if (wt.compare(
"yes") == 0) way.
_oneway =
true;
if (wt.compare(
"no") == 0) way.
_oneway =
false;
if (wt.compare("-1") == 0) {
rev = true;
}
}
if (pathlength>1) {
if (refs[0] == refs[pathlength-1]) circle = true;
}
if (circle) {
for (unsigned i=1; i < pathlength; ++i) {
if (nodeptr == nullptr) {
node.first._used = 0;
node.first._lon = 0.0;
node.first._lat = 0.0;
} else {
nodeptr->first._used++;
}
path.push_back(refs[i]);
}
path.push_back(refs[1]);
} else {
for (unsigned i=0; i < pathlength; ++i) {
if (nodeptr == nullptr) {
node.first._used = 0;
node.first._lon = 0.0;
node.first._lat = 0.0;
} else {
nodeptr->first._used++;
}
path.push_back(refs[i]);
}
}
if (rev) std::reverse(path.begin(), path.end());
}
}
void relation_callback(uint64_t ,
const Tags &,
const References & ){}
};
int main(
int argc,
char** argv) {
bool firstItem = true;
double lastLon = 0.0;
double lastLat = 0.0;
for (unsigned i=0; i < way.second.size(); ++i) {
Key ref = way.second[way.second.size()-1 - i];
if (nptr == nullptr) continue;
if (nptr->first._lon == 0 && nptr->first._lat == 0) continue;
if (nptr->first._used == 0) {
if (firstItem == false) {
dist += calcDist(nptr->first._lon, nptr->first._lat, lastLon, lastLat);
lastLon = nptr->first._lon;
lastLat = nptr->first._lat;
}
continue;
}
if (vptr == nullptr) {
vertex.first._way = wayosmid;
vertex.first._lon = nptr->first._lon;
vertex.first._lat = nptr->first._lat;
if (firstItem) {
firstItem = false;
} else {
dist +=
calcDist(vertex.first._lon, vertex.first._lat, lastLon, lastLat);
vertex.second.push_back(last);
distance.second.push_back(dist);
}
lastLon = nptr->first._lon;
lastLat = nptr->first._lat;
} else {
if (firstItem) {
firstItem = false;
} else {
dist +=
calcDist(vptr->first._lon, vptr->first._lat, lastLon, lastLat);
vptr->second.push_back(last);
dptr->second.push_back(dist);
}
lastLon = nptr->first._lon;
lastLat = nptr->first._lat;
}
dist = 0;
last = ref;
}
firstItem = true;
lastLon = 0.0;
lastLat = 0.0;
dist = 0;
if (way.first._oneway == false) {
for (unsigned i=0; i < way.second.size(); ++i) {
if (nptr == nullptr) continue;
if (nptr->first._lon == 0 && nptr->first._lat == 0) continue;
if (nptr->first._used == 0) {
if (firstItem == false) {
dist +=
calcDist(nptr->first._lon, nptr->first._lat, lastLon, lastLat);
lastLon = nptr->first._lon;
lastLat = nptr->first._lat;
}
continue;
}
if (vptr == nullptr) {
vertex.first._way = wayosmid;
vertex.first._lon = nptr->first._lon;
vertex.first._lat = nptr->first._lat;
if (firstItem) {
firstItem = false;
} else {
dist +=
calcDist(vertex.first._lon, vertex.first._lat, lastLon, lastLat);
vertex.second.push_back(last);
distance.second.push_back(dist);
}
lastLon = nptr->first._lon;
lastLat = nptr->first._lat;
} else {
if (firstItem) {
firstItem = false;
} else {
dist +=
calcDist(vptr->first._lon, vptr->first._lat, lastLon, lastLat);
vptr->second.push_back(last);
dptr->second.push_back(dist);
}
lastLon = nptr->first._lon;
lastLat = nptr->first._lat;
}
dist = 0;
last = ref;
}
}
return false;
});
uint64_t wayOsmId = 1;
FILE * pFile;
pFile = fopen ("graph.osm","w");
fprintf (pFile,
"<?xml version='1.0' encoding='UTF-8'?>\n"
"<osm version='0.6'>\n"
"<bounds minlat='%f' minlon='%f' maxlat='%f' maxlon='%f'/>\n",
);
fprintf (pFile,
"<node id='%" PRIu64
"'" DEFAULTATTR " lat='%f' lon='%f'/>\n",
id, v.first._lat, v.first._lon
);
return false;
});
for (unsigned i=0; i < v.second.size(); ++i) {
fprintf (pFile,
"<nd ref='%" PRIu64 "'/>"
"<nd ref='%" PRIu64 "'/>"
"<tag k='highway' v='secondary'/>"
"<tag k='oneway' v='yes'/>"
"<tag k='name' v=\"%" PRIu64 "\"/></way>\n",
wayOsmId,
id,
v.second[i],
dptr->second[i]
);
++wayOsmId;
}
return false;
});
fprintf (pFile, "</osm>\n");
fclose (pFile);
return 0;
}
Definition: SwappyItems.hpp:49
std::pair< TVALUE, std::vector< TKEY > > Data
Definition: SwappyItems.hpp:52
Data * get(const TKEY &key)
Definition: SwappyItems.hpp:188
bool each(Data &back, std::function< bool(TKEY, Data &)> foo)
Definition: SwappyItems.hpp:790
bool set(TKEY key, TVALUE value)
Definition: SwappyItems.hpp:123
Definition: osmpbfreader.hpp:48
std::vector< Reference > References
Definition: osmpbfreader.hpp:65
void read_osm_pbf(const std::string &filename, Visitor &visitor, bool wayOnly)
Definition: osmpbfreader.hpp:359
std::map< std::string, std::string > Tags
Definition: osmpbfreader.hpp:51
uint64_t Key
Definition: osm2graph.cpp:48
Ways_t * ways
Definition: osm2graph.cpp:84
SwappyItems< Key, Vertex, FILE_ITEMS, FILE_MULTI, RAM_MULTI, BBITS, BMASK > Vertices_t
Definition: osm2graph.cpp:88
#define LAT_BOUND
Definition: osm2graph.cpp:32
#define TORADI(angleDegrees)
Definition: osm2graph.cpp:19
#define LON_BOUND_DIF
Definition: osm2graph.cpp:31
int main(int argc, char **argv)
Definition: osm2graph.cpp:220
SwappyItems< Key, Distance, FILE_ITEMS, FILE_MULTI, RAM_MULTI, BBITS, BMASK > Distance_t
Definition: osm2graph.cpp:90
#define LON_BOUND
Definition: osm2graph.cpp:30
int relevance(const std::string &wt)
Definition: osm2graph.cpp:103
SwappyItems< Key, WayData, FILE_ITEMS, FILE_MULTI, RAM_MULTI, BBITS, BMASK > Ways_t
Definition: osm2graph.cpp:82
Nodes_t * nodes
Definition: osm2graph.cpp:85
#define DEFAULTATTR
build a map file with osmosis: ../osmosis/bin/osmosis –read-xml file=graph.osm –mw file=krefeld_mg....
Definition: osm2graph.cpp:45
Distance_t * distances
Definition: osm2graph.cpp:91
SwappyItems< Key, NodeData, FILE_ITEMS, FILE_MULTI, RAM_MULTI, BBITS, BMASK > Nodes_t
Definition: osm2graph.cpp:83
Key calcDist(double lon1, double lat1, double lon2, double lat2)
Definition: osm2graph.cpp:97
Vertices_t * verticies
Definition: osm2graph.cpp:89
#define LAT_BOUND_DIF
Definition: osm2graph.cpp:33
Definition: osm2graph.cpp:77
Definition: osm2graph.cpp:53
Definition: osm2graph.cpp:120
Definition: osm2graph.cpp:69
Definition: osm2graph.cpp:60
bool _oneway
Definition: osm2graph.cpp:61