[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