00001
00014 #ifndef LGL_GRAPHS_HPP
00015 #define LGL_GRAPHS_HPP
00016
00017 #include <map>
00018 #include <cmath>
00019 #include <vector>
00020
00021 #include <boost/config.hpp>
00022 #include <boost/graph/adjacency_list.hpp>
00023 #include <boost/graph/iteration_macros.hpp>
00024
00025 #include <lgl/Location.hpp>
00026
00027 using namespace boost;
00028
00029 namespace jafar {
00030 namespace lgl {
00031
00036 template
00037 <
00038 typename EDGE_BUNDLE,
00039 typename VERTEX_BUNDLE,
00040 typename EDGE_WEIGHT_T
00041 >
00042 class NavGraphT {
00043
00044 public :
00045
00046
00047 typedef adjacency_list<
00048 listS,
00049 vecS,
00050 directedS,
00051 VERTEX_BUNDLE,
00052 EDGE_BUNDLE
00053 > GraphContainer;
00054
00055
00056 typedef typename graph_traits<GraphContainer>::vertex_descriptor Vertex;
00057 typedef typename graph_traits<GraphContainer>::edge_descriptor Edge;
00058 typedef std::pair<Edge, Edge> EdgePair;
00059
00060 typedef typename graph_traits<GraphContainer>::vertex_iterator vertex_iterator;
00061 typedef typename graph_traits<GraphContainer>::edge_iterator edge_iterator;
00062 typedef typename graph_traits<GraphContainer>::adjacency_iterator adjacency_iterator;
00063 typedef typename graph_traits<GraphContainer>::out_edge_iterator out_edge_iterator;
00064
00065 typedef typename graph_traits<GraphContainer>::degree_size_type degree_t;
00066
00067 typedef std::pair<adjacency_iterator, adjacency_iterator> adjacency_vertex_range_t;
00068 typedef std::pair<out_edge_iterator, out_edge_iterator> out_edge_range_t;
00069 typedef std::pair<vertex_iterator, vertex_iterator> vertex_range_t;
00070 typedef std::pair<edge_iterator, edge_iterator> edge_range_t;
00071
00072
00073 typedef std::map<int,Vertex> PosToVertex;
00074
00075 typedef typename std::map<int,Vertex>::iterator PosToVertex_iterator;
00076
00077
00078 typedef typename property_map<GraphContainer, EDGE_WEIGHT_T EDGE_BUNDLE::*>::type WeightMap;
00079
00081 GraphContainer graph;
00082
00083 PosToVertex verticesMap;
00084
00085 int xsize, ysize;
00086
00090 NavGraphT(int _xsize, int _ysize):
00091 xsize(_xsize),
00092 ysize(_ysize)
00093 {
00094 }
00095
00096 ~NavGraphT() {}
00097
00101 Vertex getVertex(const NavLocation& loc) {
00102 int posId = loc.pos_y * xsize + loc.pos_x;
00103 return verticesMap[posId];
00104 }
00105
00110 bool getVertex(const NavLocation& loc, Vertex& v, bool check=false) {
00111 if (check==true) {
00112 if (!(vertexExists(loc)))
00113 {
00114 return false;
00115 }
00116 }
00117 v = getVertex(loc);
00118 return true;
00119 }
00120
00122 NavLocation getClosestLocation(const NavLocation& _loc) {
00123 if (vertexExists(_loc))
00124 {
00125 return _loc;
00126 }
00127
00128 NavLocation foundLoc(0,0);
00129 double dist = -1.0;
00130 double dist_tmp = -1.0;
00131 double xd = 0;
00132 double yd = 0;
00133
00134 BGL_FORALL_VERTICES(v,graph, adjacency_list<>) {
00135 xd = (double)(_loc.pos_x - ((graph)[v]).pos.pos_x);
00136 yd = (double)(_loc.pos_y - (graph)[v].pos.pos_y);
00137 dist_tmp = sqrt(xd*xd + yd*yd);
00138
00139
00140 if ( (dist_tmp < dist) || (dist < 0.0))
00141 {
00142
00143 foundLoc.setPos((graph)[v].pos.pos_x, (graph)[v].pos.pos_y);
00144
00145 dist = dist_tmp;
00146 }
00147 }
00148
00149 return foundLoc;
00150 }
00151
00153 Edge getEdge(const NavLocation& loc1,const NavLocation& loc2) {
00154 return edge(getVertex(loc1),getVertex(loc2),graph).first;
00155 }
00156
00158 Edge getEdge(const NavLocation& loc1, const Vertex& vloc2) {
00159 return edge(getVertex(loc1), vloc2, graph).first;
00160 }
00161
00163 Edge getEdge(const Vertex& vloc1,const NavLocation& loc2) {
00164 return edge(vloc1,getVertex(loc2),graph).first;
00165 }
00166
00168 Edge getEdge(const Vertex& vloc1, const Vertex& vloc2) {
00169 return edge(vloc1, vloc2, graph).first;
00170 }
00171
00175 bool vertexExists(const NavLocation& loc) {
00176 int posId = loc.pos_y * xsize + loc.pos_x;
00177 PosToVertex_iterator it;
00178 it = verticesMap.find(posId);
00179 if (it==verticesMap.end())
00180 return false;
00181 else
00182 return true;
00183 }
00184
00188 Vertex addVertex(const NavLocation& loc) {
00189 int posId = loc.pos_y * xsize + loc.pos_x;
00190 if (vertexExists(posId))
00191 {
00192 return verticesMap[posId];
00193 } else {
00194 Vertex v = add_vertex(graph);
00195 verticesMap.insert(std::pair<int,Vertex>(posId,v));
00196
00197 graph[v].pos = loc;
00198 return v;
00199 }
00200 }
00201
00203 void removeGraphContent() {
00204 PosToVertex_iterator vi, next;
00205 vi = verticesMap.begin();
00206 for (next = vi; vi != verticesMap.end(); vi = next)
00207 {
00208 ++next;
00209 clear_vertex(vi->second, graph);
00210 remove_vertex(vi->second, graph);
00211 }
00212 verticesMap.clear();
00213 }
00214
00216 bool removeVertex(const NavLocation& loc) {
00217 int posId = loc.pos_y * xsize + loc.pos_x;
00218 if (!vertexExists(posId))
00219 return true;
00220 else {
00221 Vertex v = verticesMap[posId];
00222
00223
00224 clear_vertex(v,graph);
00225 remove_vertex(v,graph);
00226
00227 verticesMap.erase(posId);
00228 return true;
00229 }
00230 }
00231
00236 bool removeEdgesOnly(const NavLocation& loc) {
00237 int posId = loc.pos_y * xsize + loc.pos_x;
00238 if (!vertexExists(posId))
00239 {
00240 return false;
00241 }
00242
00243 Vertex v = verticesMap[posId];
00244
00245
00246 clear_vertex(v,graph);
00247 return true;
00248 }
00249
00254 bool removeOutEdges(const NavLocation& loc) {
00255 int posId = loc.pos_y * xsize + loc.pos_x;
00256 if (!vertexExists(posId))
00257 {
00258 return false;
00259 }
00260
00261
00262 Vertex v = verticesMap[posId];
00263 out_edge_iterator oei, edge_end;
00264 tie(oei,edge_end) = out_edges(v,graph);
00265 for (; oei != edge_end; ++oei) {
00266
00267 remove_edge(oei,graph);
00268 }
00269
00270 return true;
00271 }
00272
00277 bool removeInEdges(const NavLocation& loc) {
00278 int posId = loc.pos_y * xsize + loc.pos_x;
00279 if (!vertexExists(posId))
00280 {
00281 return false;
00282 }
00283
00284
00285 Vertex v = verticesMap[posId];
00286 adjacency_iterator ai, adj_end;
00287 tie(ai,adj_end) = adjacent_vertices(v,graph);
00288 for (; ai != adj_end; ++ai) {
00289 remove_edge(*ai,v,graph);
00290 }
00291 return true;
00292 }
00293
00294 bool addEdge(const NavLocation& loc1, const NavLocation& loc2, bool check=false) {
00295 Vertex v1,v2;
00296 if (check) {
00297 v1 = addVertex(loc1);
00298 v2 = addVertex(loc2);
00299 } else {
00300 v1 = getVertex(loc1);
00301 v2 = getVertex(loc2);
00302 }
00303
00304
00305 add_edge(v1,v2,graph);
00306
00307
00308 return true;
00309 }
00310
00311 bool addEdge(const NavLocation& loc1, const NavLocation& loc2, Edge& edge, bool check=false) {
00312 Vertex v1,v2;
00313 if (check) {
00314 v1=addVertex(loc1);
00315 v2=addVertex(loc2);
00316 } else {
00317 v1 = getVertex(loc1);
00318 v2 = getVertex(loc2);
00319 }
00320
00321
00322 edge = add_edge(v1,v2,graph).first;
00323
00324 return true;
00325 }
00326
00327 bool addEdge(const NavLocation& loc1, const NavLocation& loc2, const EDGE_BUNDLE& bundle, bool check=false) {
00328 Vertex v1,v2;
00329 if (check) {
00330 v1=addVertex(loc1);
00331 v2=addVertex(loc2);
00332 } else {
00333 v1 = getVertex(loc1);
00334 v2 = getVertex(loc2);
00335 }
00336 Edge edge = add_edge(v1,v2,graph).first;
00337
00338 setEdgeBundle(edge,bundle);
00339
00340 return true;
00341 }
00342
00346 bool addDualEdge(const NavLocation& loc1, const NavLocation& loc2)
00347 {
00348
00349
00350 Vertex v1 = addVertex(loc1);
00351 Vertex v2 = addVertex(loc2);
00352
00353 add_edge(v1,v2,graph);
00354 add_edge(v2,v1,graph);
00355
00356 return true;
00357 }
00358
00359 bool addDualEdgeFast(const NavLocation& loc1, const NavLocation& loc2)
00360 {
00361
00362 Vertex v1 = getVertex(loc1);
00363 Vertex v2 = getVertex(loc2);
00364
00365 add_edge(v1,v2,graph);
00366 add_edge(v2,v1,graph);
00367
00368 return true;
00369 }
00370
00371 bool addDualEdgeFast(const NavLocation& loc1, const NavLocation& loc2, const EDGE_BUNDLE& edge1, const EDGE_BUNDLE& edge2)
00372 {
00373
00374 Vertex v1 = getVertex(loc1);
00375 Vertex v2 = getVertex(loc2);
00376
00377 add_edge(v1,v2,graph);
00378 add_edge(v2,v1,graph);
00379
00380 return true;
00381 }
00382
00383
00384
00385 bool mesh(std::vector<NavLocation>& locs) {
00386 int nbLocs = locs.size();
00387 int i,j;
00388 for (i=0;i<nbLocs;i++) {
00389 addVertex(locs[i]);
00390 }
00391 for (i=0;i<nbLocs;i++) {
00392 for (j=i+1;j<nbLocs;j++) {
00393 addDualEdgeFast(locs[i],locs[j]);
00394 }
00395 }
00396 return true;
00397 }
00398
00399
00400
00401 bool connectInOutLocs(std::vector<NavLocation>& locs) {
00402 int nbLocs = locs.size();
00403 int i,j;
00404 for (i=0;i<nbLocs;i++) {
00405 addVertex(locs[i]);
00406 }
00407 for (i=0;i<nbLocs;i++) {
00408 for (j=i+1;j<nbLocs;j++) {
00409 if ((locs[i].pos_x!=locs[j].pos_x)&&(locs[i].pos_y!=locs[j].pos_y))
00410 addDualEdgeFast(locs[i],locs[j]);
00411 }
00412 }
00413 return true;
00414 }
00415
00416
00417 bool connect(NavLocation locToConnect, std::vector<NavLocation>& locs, bool verbose=false) {
00418
00419 int nbLocs = locs.size();
00420 for (int i=0;i<nbLocs;i++) {
00421 if (verbose)
00422 {
00423 std::cout << "# Connect " << locToConnect << " to " << locs[i] << std::endl;
00424 }
00425
00426 addDualEdge(locToConnect,locs[i]);
00427 }
00428 return true;
00429 }
00430
00435 bool removeEdge(const NavLocation& loc1, const NavLocation& loc2) {
00436 if ((!vertexExists(loc1))||(!vertexExists(loc2)))
00437 {
00438 return false;
00439 }
00440
00441 Vertex v1 = getVertex(loc1);
00442 Vertex v2 = getVertex(loc2);
00443
00444 remove_edge(v1,v2,graph);
00445 return true;
00446 }
00447
00448 bool removeDualEdge(const NavLocation& loc1, const NavLocation& loc2) {
00449
00450 if ((!vertexExists(loc1))||(!vertexExists(loc2)))
00451 {
00452 return false;
00453 }
00454
00455 Vertex v1 = getVertex(loc1);
00456 Vertex v2 = getVertex(loc2);
00457
00458 remove_edge(v1,v2,graph);
00459 remove_edge(v2,v1,graph);
00460 return true;
00461 }
00462
00466 bool setVertexBundle(const NavLocation& loc, const VERTEX_BUNDLE& bundle) {
00467
00468 Vertex v;
00469 if (!vertexExists(loc))
00470 v = addVertex(loc);
00471 else
00472 v = getVertex(loc);
00473
00474
00475 get(vertex_bundle, graph)[v]=bundle;
00476
00477 return true;
00478 }
00479
00480 bool setEdgeBundle(const Edge& e, const EDGE_BUNDLE& bundle) {
00481 get(edge_bundle, graph)[e] = bundle;
00482 return true;
00483 }
00484
00485 bool setEdgeBundle(const Vertex& v1, const Vertex& v2, const EDGE_BUNDLE& bundle) {
00486 get(edge_bundle, graph)[edge(v1,v2,graph).first]=bundle;
00487 return true;
00488 }
00489
00490 bool setEdgeBundle(const NavLocation& loc1, const NavLocation& loc2, const EDGE_BUNDLE& bundle, bool check=false) {
00491 if (check)
00492 {
00493 if ((!vertexExists(loc1)) || (!vertexExists(loc2)))
00494 {
00495 return false;
00496 }
00497 }
00498 Vertex v1 = getVertex(loc1);
00499 Vertex v2 = getVertex(loc2);
00500
00501 get(edge_bundle, graph)[edge(v1,v2,graph).first]=bundle;
00502
00503 return true;
00504 }
00505
00506 bool getVertexBundle(const NavLocation& loc, VERTEX_BUNDLE& bundle, bool check=false) {
00507 if (check)
00508 if (!vertexExists(loc))
00509 return false;
00510 Vertex v = getVertex(loc);
00511
00512
00513 bundle = get(vertex_bundle, graph)[v];
00514 return true;
00515 }
00516
00517 bool getVertexBundle(const Vertex& v, VERTEX_BUNDLE& bundle) {
00518
00519 bundle = get(vertex_bundle, graph)[v];
00520 return true;
00521 }
00522
00528 bool getEdgeBundle(const Edge& e, EDGE_BUNDLE& bundle) {
00529 bundle = get(edge_bundle, graph)[e];
00530 return true;
00531 }
00532
00533 bool getEdgeBundle(const Vertex& v1, const Vertex& v2, EDGE_BUNDLE& bundle) {
00534 bundle = get(edge_bundle, graph)[edge(v1,v2,graph).first];
00535 return true;
00536 }
00537
00538 bool getEdgeBundle(const NavLocation& loc1, const NavLocation& loc2, EDGE_BUNDLE& bundle, bool check=false) {
00539 if (check)
00540 {
00541 if ((!vertexExists(loc1)) || (!vertexExists(loc2)))
00542 {
00543 return false;
00544 }
00545 }
00546 Vertex v1 = getVertex(loc1);
00547 Vertex v2 = getVertex(loc2);
00548
00549 bundle = get(edge_bundle, graph)[edge(v1,v2,graph).first];
00550 return true;
00551 }
00552
00554 GraphContainer* getGCtn() {
00555 return (&graph);
00556 }
00557
00558 void clear() {
00559 graph.clear();
00560 verticesMap.clear();
00561 }
00562
00563
00564
00565 NavGraphT& operator=(const NavGraphT &rhs)
00566 {
00567 graph = rhs.graph;
00568 return *this;
00569 }
00570
00574 void print() {
00575
00576 vertex_iterator i, end;
00577 out_edge_iterator ei, edge_end;
00578 for(tie(i,end) = vertices(graph); i != end; ++i) {
00579 for (tie(ei,edge_end) = out_edges(*i, graph); ei != edge_end; ++ei) {
00580 std::cout << graph[*i].pos.pos_x <<":" << graph[*i].pos.pos_y;
00581 std::cout << " --> ";
00582 std::cout << graph[target(*ei, graph)].pos.pos_x <<":" << graph[target(*ei, graph)].pos.pos_y;
00583 std::cout << std::endl;
00584 }
00585
00586 }
00587 }
00588
00589 private:
00590
00591 bool vertexExists(const int& posId) {
00592 PosToVertex_iterator it;
00593 it = verticesMap.find(posId);
00594 if (it==verticesMap.end())
00595 return false;
00596 else
00597 return true;
00598 return true;
00599 }
00600
00601
00602 };
00603
00604 }
00605
00606 }
00607
00608 #endif // LGL_GRAPHS_HPP