1 #include "network/network.hpp"
2 #include "util/debug.hpp"
3 #include "util/util.hpp"
4 #include "algorithm/geom_algorithm.hpp"
6 #include <ogrsf_frmts.h>
12 #include <boost/geometry/index/rtree.hpp>
13 #include <boost/function_output_iterator.hpp>
32 Network::Network(
const std::string &filename,
33 const std::string &id_name,
34 const std::string &source_name,
35 const std::string &target_name)
37 SPDLOG_INFO(
"Read network from file {}",filename);
39 GDALDataset *poDS = (GDALDataset*) GDALOpenEx(
40 filename.c_str(), GDAL_OF_VECTOR, NULL, NULL, NULL );
42 SPDLOG_CRITICAL(
"Open dataset failed.");
45 OGRLayer *ogrlayer = poDS->GetLayer(0);
46 int NUM_FEATURES = ogrlayer->GetFeatureCount();
49 OGRFeatureDefn *ogrFDefn = ogrlayer->GetLayerDefn();
50 OGRFeature *ogrFeature;
53 int id_idx=ogrFDefn->GetFieldIndex(id_name.c_str());
54 int source_idx=ogrFDefn->GetFieldIndex(source_name.c_str());
55 int target_idx=ogrFDefn->GetFieldIndex(target_name.c_str());
56 if (source_idx<0||target_idx<0||id_idx<0) {
57 SPDLOG_CRITICAL(
"Id, source or target column not found");
59 std::exit(EXIT_FAILURE);
62 if (wkbFlatten(ogrFDefn->GetGeomType()) != wkbLineString)
64 SPDLOG_CRITICAL(
"Geometry type of network is {}, should be linestring",
65 OGRGeometryTypeToName(ogrFDefn->GetGeomType()));
67 std::exit(EXIT_FAILURE);
69 SPDLOG_DEBUG(
"Geometry type of network is {}",
70 OGRGeometryTypeToName(ogrFDefn->GetGeomType()));
72 OGRSpatialReference *ogrsr = ogrFDefn->GetGeomFieldDefn(0)->GetSpatialRef();
73 if (ogrsr !=
nullptr) {
74 srid = ogrsr->GetEPSGGeogCS();
78 SPDLOG_WARN(
"SRID is not found, set to 4326 by default");
80 SPDLOG_DEBUG(
"SRID is {}",srid);
84 SPDLOG_WARN(
"SRID is not found, set to 4326 by default");
88 while( (ogrFeature = ogrlayer->GetNextFeature()) != NULL){
89 EdgeID id = ogrFeature->GetFieldAsInteger(id_idx);
90 NodeID source = ogrFeature->GetFieldAsInteger(source_idx);
91 NodeID target = ogrFeature->GetFieldAsInteger(target_idx);
92 OGRGeometry *rawgeometry = ogrFeature->GetGeometryRef();
94 if (rawgeometry->getGeometryType()==wkbLineString) {
96 }
else if (rawgeometry->getGeometryType()==wkbMultiLineString) {
97 SPDLOG_TRACE(
"Feature id {} s {} t {} is multilinestring",
99 SPDLOG_TRACE(
"Read only the first linestring");
102 SPDLOG_CRITICAL(
"Unknown geometry type for feature id {} s {} t {}",
106 if (node_map.find(source)==node_map.end()) {
107 s_idx = node_id_vec.size();
108 node_id_vec.push_back(source);
109 node_map.insert({source,s_idx});
110 vertex_points.push_back(geom.
get_point(0));
112 s_idx = node_map[source];
114 if (node_map.find(target)==node_map.end()) {
115 t_idx = node_id_vec.size();
116 node_id_vec.push_back(target);
117 node_map.insert({target,t_idx});
119 vertex_points.push_back(geom.
get_point(npoints-1));
121 t_idx = node_map[target];
123 edges.push_back({index,id,s_idx,t_idx,geom.
get_length(),geom});
124 edge_map.insert({id,index});
126 OGRFeature::DestroyFeature(ogrFeature);
129 num_vertices = node_id_vec.size();
130 SPDLOG_INFO(
"Number of edges {} nodes {}",edges.size(),num_vertices);
131 SPDLOG_INFO(
"Field index: id {} source {} target {}",
132 id_idx,source_idx,target_idx);
134 SPDLOG_INFO(
"Read network done.");
137 int Network::get_node_count()
const {
138 return node_id_vec.size();
141 int Network::get_edge_count()
const {
146 const std::vector<Edge> &Network::get_edges()
const
154 return index<edges.size() ? edges[index].id:-1;
158 return edge_map.at(
id);
162 return index<num_vertices ? node_id_vec[index] : -1;
166 return node_map.at(
id);
170 return vertex_points[index];
174 void Network::build_rtree_index() {
176 SPDLOG_DEBUG(
"Create boost rtree");
178 for (std::size_t i = 0; i < edges.size(); ++i) {
180 Edge *edge = &edges[i];
184 rtree.insert(std::make_pair(b,edge));
186 SPDLOG_DEBUG(
"Create boost rtree done");
190 double radius)
const {
191 return search_tr_cs_knn(trajectory.
geom,k,radius);
199 unsigned int current_candidate_index = num_vertices;
200 for (
int i=0; i<NumberPoints; ++i) {
203 double px = geom.
get_x(i);
204 double py = geom.
get_y(i);
208 std::vector<Item> temp;
211 rtree.query(boost::geometry::index::intersects(b),
212 std::back_inserter(temp));
213 int Nitems = temp.size();
214 for (
unsigned int j=0; j<Nitems; ++j) {
217 Edge *edge = temp[j].second;
220 double closest_x,closest_y;
222 &dist,&offset,&closest_x,&closest_y);
229 Point(closest_x,closest_y)};
241 std::partial_sort_copy(
242 pcs.begin(),pcs.end(),
243 tr_cs[i].begin(),tr_cs[i].end(),
246 for (
int m=0; m<tr_cs[i].size(); ++m) {
247 tr_cs[i][m].index = current_candidate_index+m;
249 current_candidate_index+=tr_cs[i].size();
255 const LineString &Network::get_edge_geom(
int edge_id)
const {
256 return edges[get_edge_index(edge_id)].geom;
264 if (complete_path.empty())
return line;
266 int NCsegs = complete_path.size();
271 const LineString &firstseg = get_edge_geom(complete_path[0]);
275 firstseg,&dist,&lastoffset);
278 append_segs_to_line(&line,firstlineseg,0);
280 const LineString &firstseg = get_edge_geom(complete_path[0]);
281 const LineString &lastseg = get_edge_geom(complete_path[NCsegs-1]);
288 lastseg,&dist,&lastoffset);
291 append_segs_to_line(&line,firstlineseg,0);
293 for(
int i=1; i<NCsegs-1; ++i) {
294 const LineString &middleseg = get_edge_geom(complete_path[i]);
295 append_segs_to_line(&line,middleseg,1);
298 append_segs_to_line(&line,lastlineseg,1);
303 const std::vector<Point> &Network::get_vertex_points()
const {
304 return vertex_points;
308 return vertex_points[u];
311 LineString Network::route2geometry(
const std::vector<EdgeID> &path)
const
314 if (path.empty())
return line;
316 int NCsegs = path.size();
317 for(
int i=0; i<NCsegs; ++i) {
321 append_segs_to_line(&line,seg,0);
323 append_segs_to_line(&line,seg,1);
330 LineString Network::route2geometry(
const std::vector<EdgeIndex> &path)
const
333 if (path.empty())
return line;
335 int NCsegs = path.size();
336 for(
int i=0; i<NCsegs; ++i)
340 append_segs_to_line(&line,seg,0);
342 append_segs_to_line(&line,seg,1);
349 void Network::append_segs_to_line(
LineString *line,
353 for(
int i=0; i<Npoints; ++i) {