Show
Ignore:
Timestamp:
03/05/10 12:21:36 (5 years ago)
Author:
robert
Message:

Added an "-a" speed averager option and a "-o filename" output option.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/examples/osggpx/osggpx.cpp

    r10949 r11160  
    9999double convertTime(const std::string& timestr) 
    100100{ 
    101     //osg::notify(osg::NOTICE)<<"       time = "<<timestr<<std::endl; 
     101    osg::notify(osg::NOTICE)<<"       time = "<<timestr<<std::endl; 
    102102    return 0; 
    103103} 
     
    219219            new_points[i].longitude = (orig_points[i-1].longitude+orig_points[i].longitude+orig_points[i+1].longitude)/3.0; 
    220220            new_points[i].elevation = (orig_points[i-1].elevation+orig_points[i].elevation+orig_points[i+1].elevation)/3.0; 
     221            new_points[i].time = (orig_points[i-1].time+orig_points[i].time+orig_points[i+1].time)/3.0; 
    221222        } 
    222223        return new_ts.release(); 
     
    229230 
    230231} 
     232 
     233TrackSegment* 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 
     293Track* 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 
    231307 
    232308Track* computeSmoothedTrack(Track* track) 
     
    292368    Tracks tracks; 
    293369 
     370    bool average = false; 
     371    while (arguments.read("-a") || arguments.read("--average")) average = true; 
     372 
    294373    bool smooth = false; 
    295374    while (arguments.read("-s") || arguments.read("--smooth")) smooth = true; 
     375 
     376    std::string outputFilename; 
     377    while (arguments.read("-o",outputFilename)) {} 
    296378 
    297379    std::string trackFilename; 
     
    316398 
    317399        group->addChild(createTrackModel(track, osg::Vec4(1.0,1.0,1.0,1.0))); 
     400 
     401        // smooth the track 
     402        if (average) 
     403        { 
     404            for(Track::TrackSegments::iterator itr = track->getTrackSegments().begin(); 
     405                itr != track->getTrackSegments().end(); 
     406                ++itr) 
     407            { 
     408                *itr = computeAveragedSpeedTrackSegment(itr->get()); 
     409            } 
     410        } 
    318411 
    319412        // smooth the track 
     
    402495    } 
    403496 
     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 
    404536    osgViewer::Viewer viewer(arguments); 
    405537    viewer.setCameraManipulator(new osgGA::TerrainManipulator);