| | 47 | // visitor that terminates when we find the goal |
|---|
| | 48 | template <class Edge> |
|---|
| | 49 | class shooting_star_goal_visitor : public boost::default_shooting_star_visitor |
|---|
| | 50 | { |
|---|
| | 51 | public: |
|---|
| | 52 | shooting_star_goal_visitor(Edge goal, int max_id) : m_goal(goal){} |
|---|
| | 53 | shooting_star_goal_visitor(const shooting_star_goal_visitor &gv) : m_goal(gv.m_goal){} |
|---|
| | 54 | ~shooting_star_goal_visitor(){} |
|---|
| | 55 | |
|---|
| | 56 | template <class Graph> |
|---|
| | 57 | void examine_edge(Edge e, Graph& g) |
|---|
| | 58 | { |
|---|
| | 59 | if( g[e].id == g[m_goal].id) |
|---|
| | 60 | { |
|---|
| | 61 | throw found_goal(); |
|---|
| | 62 | } |
|---|
| | 63 | } |
|---|
| | 64 | template <class Graph> |
|---|
| | 65 | void finish_edge(Edge e, Graph& g) {} |
|---|
| | 66 | private: |
|---|
| | 67 | Edge m_goal; |
|---|
| | 68 | }; |
|---|
| | 69 | |
|---|
| | 70 | template <class Graph, class CostType> |
|---|
| | 71 | class distance_heuristic |
|---|
| | 72 | { |
|---|
| | 73 | public: |
|---|
| | 74 | typedef typename graph_traits<Graph>::edge_descriptor Edge; |
|---|
| | 75 | distance_heuristic(Graph& g, Edge goal):m_g(g), m_goal(goal){} |
|---|
| | 76 | CostType operator()(Edge e) |
|---|
| | 77 | { |
|---|
| | 78 | CostType dx = m_g[source(m_goal, m_g)].x - m_g[source(e, m_g)].x; |
|---|
| | 79 | CostType dxt = m_g[target(m_goal, m_g)].x - m_g[target(e, m_g)].x; |
|---|
| | 80 | CostType dy = m_g[source(m_goal, m_g)].y - m_g[source(e, m_g)].y; |
|---|
| | 81 | CostType dyt = m_g[target(m_goal, m_g)].y - m_g[target(e, m_g)].y; |
|---|
| | 82 | //You can choose any heuristical function from below |
|---|
| | 83 | //return ::max(dx, dy); |
|---|
| | 84 | //return ::sqrt(dx * dx + dy * dy)/2; |
|---|
| | 85 | //return 0; |
|---|
| | 86 | return (min(::fabs(dx),::fabs(dxt))+min(::fabs(dy),::fabs(dyt)))/2; |
|---|
| | 87 | } |
|---|
| | 88 | private: |
|---|
| | 89 | Graph& m_g; |
|---|
| | 90 | Edge m_goal; |
|---|
| | 91 | }; |
|---|
| | 92 | |
|---|
| | 101 | private: |
|---|
| | 102 | std::map< int, vector< std::pair<float, vector<int> > >, std::less<int> > adjacent_edges; |
|---|
| | 103 | std::map< int, int, std::less<int> > vertices; |
|---|
| | 104 | vector<int> rule; |
|---|
| | 105 | int offset; |
|---|
| | 106 | int rule_num; |
|---|
| | 107 | |
|---|
| | 108 | bool addEdge(edge_descriptor *e, OGRFeature *edge, graph_t &graph) |
|---|
| | 109 | { |
|---|
| | 110 | bool inserted; |
|---|
| | 111 | |
|---|
| | 112 | if (cost < 0) // edges are not inserted in the graph if cost is negative |
|---|
| | 113 | return; |
|---|
| | 114 | |
|---|
| | 115 | tie(*e, inserted) = add_edge(edge->GetFieldAsInteger(SOURCE_FEATURE), |
|---|
| | 116 | edge->GetFieldAsInteger(TARGET_FEATURE), graph); |
|---|
| | 117 | |
|---|
| | 118 | graph[e].cost = edge->GetFieldAsDouble(COST_FEATURE); |
|---|
| | 119 | graph[e].id = edge->GetFieldAsInteger(ID_FEATURE); |
|---|
| | 120 | |
|---|
| | 121 | graph[e].source = edge->GetFieldAsInteger(SOURCE_FEATURE); |
|---|
| | 122 | graph[e].target = edge->GetFieldAsInteger(TARGET_FEATURE); |
|---|
| | 123 | |
|---|
| | 124 | graph[e].adjacent_edges = adjacent_edges; |
|---|
| | 125 | |
|---|
| | 126 | graph[e].rank = 0; |
|---|
| | 127 | graph[e].distance = 0; |
|---|
| | 128 | |
|---|
| | 129 | OGRLineString *geom = static_cast<OGRLineString*>edge->GetGeometryRef(); |
|---|
| | 130 | |
|---|
| | 131 | vertex_descriptor s = vertex(edge->GetFieldAsInteger(SOURCE_FEATURE), graph); |
|---|
| | 132 | vertex_descriptor t = vertex(edge->GetFieldAsInteger(TARGET_FEATURE), graph); |
|---|
| | 133 | |
|---|
| | 134 | graph[s].id = edge->GetFieldAsInteger(SOURCE_FEATURE); |
|---|
| | 135 | graph[t].id = edge->GetFieldAsInteger(TARGET_FEATURE); |
|---|
| | 136 | |
|---|
| | 137 | graph[s].x=geom->getX(0); |
|---|
| | 138 | graph[s].y=geom->getY(0); |
|---|
| | 139 | graph[t].x=geom->getX(geom->getNumPoints()-1); |
|---|
| | 140 | graph[t].y=geom->getY(geom->getNumPoints()-1); |
|---|
| | 141 | } |
|---|
| | 142 | |
|---|
| | 143 | virtual void fillFeatures(OGRFeature **edges, edge_descriptor *e, graph_t &graph, int j) |
|---|
| | 144 | { |
|---|
| | 145 | |
|---|
| | 146 | //Vertex ids renumbering moved here |
|---|
| | 147 | src = edges_array[j].source; |
|---|
| | 148 | trg = edges_array[j].target; |
|---|
| | 149 | |
|---|
| | 150 | if(vertices[src]==0) |
|---|
| | 151 | { |
|---|
| | 152 | vertices[src]=j+offset; |
|---|
| | 153 | } |
|---|
| | 154 | edges_array[j].source=vertices[src]; |
|---|
| | 155 | |
|---|
| | 156 | if(vertices[trg]==0) |
|---|
| | 157 | { |
|---|
| | 158 | offset++; |
|---|
| | 159 | vertices[trg]=j+offset; |
|---|
| | 160 | } |
|---|
| | 161 | edges_array[j].target=vertices[trg]; |
|---|
| | 162 | |
|---|
| | 163 | for(z=0; z<MAX_RULE_LENGTH;++z) |
|---|
| | 164 | { |
|---|
| | 165 | if(edges_array[j].rule[z] > 0) |
|---|
| | 166 | { |
|---|
| | 167 | rule.push_back(edges_array[j].rule[z]); |
|---|
| | 168 | } |
|---|
| | 169 | } |
|---|
| | 170 | |
|---|
| | 171 | if(edges_array[j].to_cost > 0) |
|---|
| | 172 | { |
|---|
| | 173 | adjacent_edges[edges_array[j].id].push_back(std::pair<float8, vector<int> > (edges_array[j].to_cost, rule) ); |
|---|
| | 174 | rule.clear(); |
|---|
| | 175 | } |
|---|
| | 176 | |
|---|
| | 177 | if((j < count-1 && edges_array[j].id != edges_array[j+1].id)||(j==count-1)) |
|---|
| | 178 | { |
|---|
| | 179 | |
|---|
| | 180 | bool inserted = addEdge(e, edges[j], graph); |
|---|
| | 181 | |
|---|
| | 182 | graph[*e].cost = edges[j]->GetFieldAsDouble(COST_FEATURE);//set cost |
|---|
| | 183 | graph[*e].id = j;//set id |
|---|
| | 184 | |
|---|
| | 185 | |
|---|
| | 186 | if (!IsDirected() || (IsDirected() && HasReverseCost())) |
|---|
| | 187 | { |
|---|
| | 188 | |
|---|
| | 189 | if(adjacent_edges[edges_array[j].id].size() > 0) |
|---|
| | 190 | { |
|---|
| | 191 | adjacent_edges[edges_array[j].id+e_max_id].assign( adjacent_edges[edges_array[j].id].begin(), adjacent_edges[edges_array[j].id].end() ); |
|---|
| | 192 | adjacent_edges.erase(edges_array[j].id); |
|---|
| | 193 | } |
|---|
| | 194 | |
|---|
| | 195 | edge_descriptor *er; |
|---|
| | 196 | //adding an edge for opposite direction |
|---|
| | 197 | bool inserted = addEdge(er, edges[j], graph); |
|---|
| | 198 | |
|---|
| | 199 | graph[*er].id = j;//set id |
|---|
| | 200 | |
|---|
| | 201 | if (HasReverseCost()) |
|---|
| | 202 | { |
|---|
| | 203 | graph[*er].cost = edges[j]->GetFieldAsDouble(RC_FEATURE);//set reverse cost |
|---|
| | 204 | } |
|---|
| | 205 | else |
|---|
| | 206 | { |
|---|
| | 207 | graph[*er].cost = edges[j]->GetFieldAsDouble(COST_FEATURE);//set cost |
|---|
| | 208 | } |
|---|
| | 209 | |
|---|
| | 210 | } |
|---|
| | 211 | |
|---|
| | 212 | adjacent_edges.clear(); |
|---|
| | 213 | rule_num = 0; |
|---|
| | 214 | } |
|---|
| | 215 | else |
|---|
| | 216 | { |
|---|
| | 217 | rule_num++; |
|---|
| | 218 | } |
|---|
| | 219 | } |
|---|
| | 220 | |
|---|