[OSM-dev] Making polylines from route relations

Frederik Ramm frederik at remote.org
Wed Sep 19 13:42:49 BST 2012


Hi,

On 09/19/2012 02:28 PM, Richard Fairhurst wrote:
> Does anyone have any code to convert a route relation into a polyline?

Kind of depends how you have the data and what you want but here's a 
snippet from a program where I did that with Osmium. It's not terribly 
elegant but works ok. It is aimed at producing (ideally) a GEOS 
LineString or (when there are dangling bits) a MultiLineString.

Bye
Frederik

firstnode = -1;
lastnode = -1;

bool oneleft = true;

while(oneleft)
{
   bool donesomething = false;
   oneleft = false;

   for (unsigned int i=0; i<member_ways.size(); i++)
   {
     if (used[i]) continue;
     if ((firstnode == -1) || (member_ways[i].get_first_node_id() == 
lastnode))
     {
       for (unsigned int j=(firstnode == -1)?0:1; j< 
member_ways[i].node_count(); j++)
       {
 
coords->push_back(geos::geom::Coordinate(member_ways[i].get_lon(j), 
member_ways[i].get_lat(j)));
       }
       lastnode = member_ways[i].get_last_node_id();
       if (firstnode==-1) firstnode = member_ways[i].get_first_node_id();
       donesomething = true;
       used[i]= true;
     }
     else if (member_ways[i].get_first_node_id() == firstnode)
     {
       for (unsigned int j=1; j< member_ways[i].node_count(); j++)
       {
         coords->insert(coords->begin(), 
geos::geom::Coordinate(member_ways[i].get_lon(j), 
member_ways[i].get_lat(j)));
       }
       firstnode = member_ways[i].get_last_node_id();
       donesomething = true;
       used[i]= true;
     }
     else if (member_ways[i].get_last_node_id() == lastnode)
     {
       for (int j= member_ways[i].node_count()-2; j>=0; j--)
       {
 
coords->push_back(geos::geom::Coordinate(member_ways[i].get_lon(j), 
member_ways[i].get_lat(j)));
       }
       lastnode = member_ways[i].get_first_node_id();
       donesomething = true;
       used[i]= true;
     }
     else if (member_ways[i].get_last_node_id() == firstnode)
     {
       for (int j= member_ways[i].node_count()-2; j>=0; j--)
       {
         coords->insert(coords->begin(), 
geos::geom::Coordinate(member_ways[i].get_lon(j), 
member_ways[i].get_lat(j)));
       }
       firstnode = member_ways[i].get_first_node_id();
       donesomething = true;
       used[i]= true;
     }
     else
     {
       oneleft = true;
     }
   }

   if (!donesomething || !oneleft)
   {
     if (coords->size()>1)
     {
       geos::geom::CoordinateSequence *cs = 
Osmium::Geometry::geos_geometry_factory()->getCoordinateSequenceFactory()->create(coords);
 
linelist->push_back(Osmium::Geometry::geos_geometry_factory()->createLineString(cs));
     }
     else
     {
       delete coords;
     }
     firstnode = -1;
     lastnode = -1;
     coords = new std::vector<geos::geom::Coordinate>();
   }
}
if (linelist->size() == 0)
{
   std::cerr << "empty geometry for relation " << relation->id() << " (" 
<< member_ways.size() << " member ways)" << std::endl;
   return false;
}
geometry = 
Osmium::Geometry::geos_geometry_factory()->createMultiLineString(linelist);








-- 
Frederik Ramm  ##  eMail frederik at remote.org  ##  N49°00'09" E008°23'33"



More information about the dev mailing list