| | 232 | |
| | 233 | TrackSegment* computeAveragedSpeedTrackSegment(TrackSegment* ts) |
| | 234 | { |
| | 235 | if (!ts) return 0; |
| | 236 | |
| | 237 | osg::ref_ptr<osg::EllipsoidModel> em = new osg::EllipsoidModel; |
| | 238 | const TrackSegment::TrackPoints& orig_points = ts->getTrackPoints(); |
| | 239 | |
| | 240 | if (orig_points.size()>2) |
| | 241 | { |
| | 242 | // only do smoothing if we have more than two points. |
| | 243 | osg::ref_ptr<TrackSegment> new_ts = new TrackSegment; |
| | 244 | |
| | 245 | |
| | 246 | // compute overall distance |
| | 247 | double total_distance = 0; |
| | 248 | for(unsigned int i=1; i<orig_points.size()-1; ++i) |
| | 249 | { |
| | 250 | osg::Vec3d point_a, point_b; |
| | 251 | em->convertLatLongHeightToXYZ(osg::DegreesToRadians(orig_points[i].latitude), osg::DegreesToRadians(orig_points[i].longitude), orig_points[i].elevation, |
| | 252 | point_a.x(), point_a.y(), point_a.z()); |
| | 253 | em->convertLatLongHeightToXYZ(osg::DegreesToRadians(orig_points[i+1].latitude), osg::DegreesToRadians(orig_points[i+1].longitude), orig_points[i+1].elevation, |
| | 254 | point_b.x(), point_b.y(), point_b.z()); |
| | 255 | total_distance += (point_b-point_a).length(); |
| | 256 | } |
| | 257 | |
| | 258 | double total_time = orig_points[orig_points.size()-1].time - orig_points[0].time; |
| | 259 | double average_speed = total_distance/total_time; |
| | 260 | |
| | 261 | OSG_NOTICE<<"total_time = "<<total_time<<std::endl; |
| | 262 | OSG_NOTICE<<"total_distance = "<<total_distance<<std::endl; |
| | 263 | OSG_NOTICE<<"average_speed = "<<average_speed<<std::endl; |
| | 264 | |
| | 265 | TrackSegment::TrackPoints& new_points = new_ts->getTrackPoints(); |
| | 266 | new_points.resize(orig_points.size()); |
| | 267 | new_points[0] = orig_points[0]; |
| | 268 | |
| | 269 | double accumulated_distance = 0.0; |
| | 270 | for(unsigned int i=0; i<orig_points.size()-1; ++i) |
| | 271 | { |
| | 272 | osg::Vec3d point_a, point_b; |
| | 273 | em->convertLatLongHeightToXYZ(osg::DegreesToRadians(orig_points[i].latitude), osg::DegreesToRadians(orig_points[i].longitude), orig_points[i].elevation, |
| | 274 | point_a.x(), point_a.y(), point_a.z()); |
| | 275 | em->convertLatLongHeightToXYZ(osg::DegreesToRadians(orig_points[i+1].latitude), osg::DegreesToRadians(orig_points[i+1].longitude), orig_points[i+1].elevation, |
| | 276 | point_b.x(), point_b.y(), point_b.z()); |
| | 277 | |
| | 278 | accumulated_distance += (point_b-point_a).length(); |
| | 279 | |
| | 280 | new_points[i+1] = orig_points[i+1]; |
| | 281 | new_points[i+1].time = accumulated_distance / average_speed; |
| | 282 | } |
| | 283 | return new_ts.release(); |
| | 284 | } |
| | 285 | else |
| | 286 | { |
| | 287 | // we have two or less points and can't do smoothing, so will just return original TrackSegment |
| | 288 | return ts; |
| | 289 | } |
| | 290 | |
| | 291 | } |
| | 292 | |
| | 293 | Track* computeAveragedSpeedTrack(Track* track) |
| | 294 | { |
| | 295 | osg::ref_ptr<Track> new_track = new Track; |
| | 296 | |
| | 297 | for(Track::TrackSegments::iterator itr = track->getTrackSegments().begin(); |
| | 298 | itr != track->getTrackSegments().end(); |
| | 299 | ++itr) |
| | 300 | { |
| | 301 | new_track->addTrackSegment(computeAveragedSpeedTrackSegment(itr->get())); |
| | 302 | } |
| | 303 | |
| | 304 | return new_track.release(); |
| | 305 | } |
| | 306 | |
| | 497 | if (!outputFilename.empty()) |
| | 498 | { |
| | 499 | std::ofstream fout(outputFilename.c_str()); |
| | 500 | |
| | 501 | fout<<"<?xml version=\"1.0\" encoding=\"utf-8\"?><gpx version=\"1.0\" creator=\"osggpx\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://www.topografix.com/GPX/1/0\" xsi:schemaLocation=\"http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd\">"<<std::endl; |
| | 502 | |
| | 503 | for(Tracks::iterator itr = tracks.begin(); |
| | 504 | itr != tracks.end(); |
| | 505 | ++itr) |
| | 506 | { |
| | 507 | Track* track = itr->get(); |
| | 508 | |
| | 509 | fout<<"<trk>"<<std::endl; |
| | 510 | fout<<"<desc>The track description</desc>"<<std::endl; |
| | 511 | for(Track::TrackSegments::iterator itr = track->getTrackSegments().begin(); |
| | 512 | itr != track->getTrackSegments().end(); |
| | 513 | ++itr) |
| | 514 | { |
| | 515 | TrackSegment* ts = itr->get(); |
| | 516 | fout<<"<trkseg>"<<std::endl; |
| | 517 | |
| | 518 | for(TrackSegment::TrackPoints::iterator pitr = ts->getTrackPoints().begin(); |
| | 519 | pitr != ts->getTrackPoints().end(); |
| | 520 | ++pitr) |
| | 521 | { |
| | 522 | fout<<"<trkpt lat=\""<<pitr->latitude<<"\" lon=\""<<pitr->longitude<<"\">"<<std::endl; |
| | 523 | fout<<"<ele>"<<pitr->elevation<<"</ele>"<<std::endl; |
| | 524 | fout<<"<time>"<<pitr->time<<"</time>"<<std::endl; |
| | 525 | fout<<"</trkpt>"<<std::endl; |
| | 526 | } |
| | 527 | |
| | 528 | fout<<"</trkseg>"<<std::endl; |
| | 529 | |
| | 530 | } |
| | 531 | fout<<"</trk>"<<std::endl; |
| | 532 | } |
| | 533 | fout<<"</gpx>"<<std::endl; |
| | 534 | } |
| | 535 | |