Skip to content
Snippets Groups Projects
Commit 0808b5f2 authored by Sergi Hernandez's avatar Sergi Hernandez
Browse files

Improved the way to generate the forward and backward geometries when converting an OSM road map.

parent 4deb4763
No related branches found
No related tags found
1 merge request!2Solved a bug when creating a new geometry object: the sale factor is...
......@@ -9,6 +9,7 @@
#include <iostream>
class COSMRoadSegment
{
friend class COSMJunction;
......
......@@ -14,7 +14,7 @@ COSMRoadSegment::COSMRoadSegment(COSMWay *way)
void COSMRoadSegment::set_start_distance(double dist)
{
COSMNode *node1,*node2;
double length;
double length,start_end_distance;
if(dist>this->start_distance)
{
......@@ -25,8 +25,16 @@ void COSMRoadSegment::set_start_distance(double dist)
{
if((length-this->end_distance-dist)<MIN_ROAD_LENGTH)
{
this->end_distance=(length-MIN_ROAD_LENGTH)/2.0;
this->start_distance=(length-MIN_ROAD_LENGTH)/2.0;
if(this->end_distance==0.0)
this->start_distance=length-MIN_ROAD_LENGTH;
else
{
start_end_distance=this->end_distance+dist;
this->end_distance*=length/start_end_distance;
this->end_distance-=MIN_ROAD_LENGTH/2.0;
this->start_distance=dist*length/start_end_distance;
this->start_distance-=MIN_ROAD_LENGTH/2.0;
}
}
else
this->start_distance=dist;
......@@ -44,7 +52,7 @@ void COSMRoadSegment::set_start_distance(double dist)
void COSMRoadSegment::set_end_distance(double dist)
{
COSMNode *node1,*node2;
double length;
double length,start_end_distance;
if(dist>this->end_distance)
{
......@@ -55,8 +63,16 @@ void COSMRoadSegment::set_end_distance(double dist)
{
if((length-this->start_distance-dist)<MIN_ROAD_LENGTH)
{
this->start_distance=(length-MIN_ROAD_LENGTH)/2.0;
this->end_distance=(length-MIN_ROAD_LENGTH)/2.0;
if(this->start_distance==0.0)
this->end_distance=length-MIN_ROAD_LENGTH;
else
{
start_end_distance=dist+this->start_distance;
this->end_distance=dist*length/start_end_distance;
this->end_distance-=MIN_ROAD_LENGTH/2.0;
this->start_distance*=length/start_end_distance;
this->start_distance-=MIN_ROAD_LENGTH/2.0;
}
}
else
this->end_distance=dist;
......@@ -73,7 +89,8 @@ void COSMRoadSegment::set_end_distance(double dist)
void COSMRoadSegment::generate_fwd_geometry(CRoad *road,double resolution)
{
double heading1,heading2,x,y,angle,radius,length1,length2,dist,prev_dist,y_offset;
double heading1,heading2,x,y,angle,length1,dist,prev_dist,y_offset;
double angle2,angle3,prev_heading;
TPoint start_point,end_point;
COSMNode *node1,*node2,*node3;
......@@ -95,45 +112,54 @@ void COSMRoadSegment::generate_fwd_geometry(CRoad *road,double resolution)
start_point.heading=heading1;
start_point.curvature=0.0;
road->set_start_point(start_point);
prev_heading=heading1;
}
if((i+1)==(this->parent_way->get_num_nodes()-1))// straight line
{
end_point.x=x+(length1-this->end_distance)*cos(heading1)-y_offset*sin(heading1);
end_point.y=y+(length1-this->end_distance)*sin(heading1)+y_offset*cos(heading1);
end_point.heading=heading1;
end_point.curvature=0.0;
road->add_segment(end_point);
angle2=atan2(y_offset,length1-this->end_distance);
angle3=diff_angle(heading1,prev_heading)+angle2;
if(fabs(angle3)<1.5707)
{
end_point.x=x+(length1-this->end_distance)*cos(heading1)-y_offset*sin(heading1);
end_point.y=y+(length1-this->end_distance)*sin(heading1)+y_offset*cos(heading1);
end_point.heading=heading1;
end_point.curvature=0.0;
road->add_segment(end_point);
}
}
else
{
node3=&this->parent_way->get_node_by_index(i+2);
length2=node2->compute_distance(*node3);
heading2=node2->compute_heading(*node3);
angle=node2->compute_angle(*node1,*node3);
radius=DEFAULT_MIN_RADIUS+std::max(this->parent_way->get_num_forward_lanes(),this->parent_way->get_num_backward_lanes())*this->parent_way->get_lane_width();
dist=radius*cos(angle/2.0);
if(length1<length2)
dist=(DEFAULT_MIN_RADIUS+y_offset)/fabs(tan(angle/2.0));
if(dist>(length1-prev_dist))
{
if(dist>(length1-prev_dist))
if(i==0)
{
dist=length1-prev_dist;
radius=dist/cos(angle/2.0);
node2->get_location(x,y);
start_point.x=x-y_offset*sin(heading1);
start_point.y=y+y_offset*cos(heading1);
start_point.heading=heading2;
start_point.curvature=0.0;
road->set_start_point(start_point);
prev_dist=0.0;
prev_heading=heading2;
}
}
else
{
if((i+2)==(this->parent_way->get_num_nodes()-1))// last node
else if((i+2)==(this->parent_way->get_num_nodes()-1))
{
if(dist>(length2-this->end_distance))
dist=(length2-this->end_distance);
prev_dist=dist;
prev_heading=heading2;
}
else
{
if(dist>length2/2.0)
dist=length2/2.0;
prev_dist=dist;
prev_heading=heading1;
}
radius=dist/cos(angle/2.0);
continue;
}
else if(dist<MIN_ROAD_LENGTH/2.0)
dist=MIN_ROAD_LENGTH/2.0;
if(length1-prev_dist-dist>resolution)// straight segment
{
end_point.x=x+(length1-dist)*cos(heading1)-y_offset*sin(heading1);
......@@ -150,17 +176,19 @@ void COSMRoadSegment::generate_fwd_geometry(CRoad *road,double resolution)
end_point.curvature=0.0;
road->add_segment(end_point);
prev_dist=dist;
prev_heading=heading1;
}
}
}
void COSMRoadSegment::generate_bwd_geometry(CRoad *road,double resolution)
{
double heading1,heading2,x,y,angle,radius,length1,length2,dist,prev_dist,y_offset;
double heading1,heading2,x,y,angle,length1,dist,prev_dist,y_offset;
double angle2,angle3,prev_heading;
TPoint start_point,end_point;
COSMNode *node1,*node2,*node3;
y_offset=((double)this->parent_way->get_num_forward_lanes()-((double)this->parent_way->get_num_lanes()/2.0))*this->parent_way->get_lane_width();
y_offset=-((double)this->parent_way->get_num_forward_lanes()-((double)this->parent_way->get_num_lanes()/2.0))*this->parent_way->get_lane_width();
if(this->parent_way->get_num_nodes()<2)
throw CException(_HERE_,"Road segment does not have enough nodes to generate a geometry");
prev_dist=this->end_distance;
......@@ -178,49 +206,58 @@ void COSMRoadSegment::generate_bwd_geometry(CRoad *road,double resolution)
start_point.heading=heading1;
start_point.curvature=0.0;
road->set_start_point(start_point);
prev_heading=heading1;
}
if((i-1)==0)// straight line
{
end_point.x=x+(length1-this->start_distance)*cos(heading1)-y_offset*sin(heading1);
end_point.y=y+(length1-this->start_distance)*sin(heading1)+y_offset*cos(heading1);
end_point.heading=heading1;
end_point.curvature=0.0;
road->add_segment(end_point);
angle2=atan2(y_offset,length1-this->end_distance);
angle3=diff_angle(heading1,prev_heading)+angle2;
if(fabs(angle3)<1.5707)
{
end_point.x=x+(length1-this->start_distance)*cos(heading1)-y_offset*sin(heading1);
end_point.y=y+(length1-this->start_distance)*sin(heading1)+y_offset*cos(heading1);
end_point.heading=heading1;
end_point.curvature=0.0;
road->add_segment(end_point);
}
}
else
{
node3=&this->parent_way->get_node_by_index(i-2);
length2=node2->compute_distance(*node3);
heading2=node2->compute_heading(*node3);
angle=node2->compute_angle(*node1,*node3);
radius=DEFAULT_MIN_RADIUS+std::max(this->parent_way->get_num_forward_lanes(),this->parent_way->get_num_backward_lanes())*this->parent_way->get_lane_width();
dist=radius*cos(angle/2.0);
if(length1<length2)
dist=(DEFAULT_MIN_RADIUS+y_offset)/fabs(tan(angle/2.0));
if(dist>(length1-prev_dist))
{
if(dist>(length1-prev_dist))
if(i==(this->parent_way->get_num_nodes()-1))
{
dist=length1-prev_dist;
radius=dist/cos(angle/2.0);
node2->get_location(x,y);
start_point.x=x-y_offset*sin(heading1);
start_point.y=y+y_offset*cos(heading1);
start_point.heading=heading2;
start_point.curvature=0.0;
road->set_start_point(start_point);
prev_dist=0.0;
prev_heading=heading2;
}
}
else
{
if((i-2)==0)// last segment
else if((i-2)==0)
{
if(dist>(length2-this->start_distance))
dist=(length2-this->start_distance);
prev_dist=dist;
prev_heading=heading2;
}
else
{
if(dist>length2/2.0)
dist=length2/2.0;
prev_dist=dist;
prev_heading=heading1;
}
radius=dist/cos(angle/2.0);
continue;
}
else if(dist<MIN_ROAD_LENGTH/2.0)
dist=MIN_ROAD_LENGTH/2.0;
if(length1-prev_dist-dist>resolution)// straight segment
{
end_point.x=x+(length1-prev_dist)*cos(heading1)-y_offset*sin(heading1);
end_point.y=y+(length1-prev_dist)*sin(heading1)+y_offset*cos(heading1);
end_point.x=x+(length1-dist)*cos(heading1)-y_offset*sin(heading1);
end_point.y=y+(length1-dist)*sin(heading1)+y_offset*cos(heading1);
end_point.heading=heading1;
end_point.curvature=0.0;
road->add_segment(end_point);
......@@ -233,6 +270,7 @@ void COSMRoadSegment::generate_bwd_geometry(CRoad *road,double resolution)
end_point.curvature=0.0;
road->add_segment(end_point);
prev_dist=dist;
prev_heading=heading1;
}
}
}
......@@ -289,9 +327,9 @@ void COSMRoadSegment::convert(CRoad **left_road,CRoad **right_road,double resolu
for(unsigned int i=0;i<(*left_road)->get_num_segments();i++)
{
segment=(*left_road)->get_segment_by_index(i);
for(unsigned int j=this->get_parent_way().get_num_forward_lanes();j<this->get_parent_way().get_num_lanes();j++)
for(unsigned int j=0;j<num_lanes;j++)
{
restrictions=this->get_parent_way().get_lane_restriction(j);
restrictions=this->get_parent_way().get_lane_restriction(j+this->get_parent_way().get_num_forward_lanes());
if(restrictions&RESTRICTION_RIGHT)
{
for(unsigned int k=j+1;k<num_lanes;k++)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment