/* OpenSceneGraph example, osggpx. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include class TrackSegment : public osg::Object { public: TrackSegment() {} TrackSegment(const TrackSegment& ts, const osg::CopyOp=osg::CopyOp::SHALLOW_COPY) {} META_Object(osg, TrackSegment) struct TrackPoint { TrackPoint(): latitude(0.0), longitude(0.0), elevation(0.0), time(0.0) {} double latitude; double longitude; double elevation; double time; }; typedef std::vector< TrackPoint > TrackPoints; void addTrackPoint(const TrackPoint& trackPoint) { _trackPoints.push_back(trackPoint); } TrackPoints& getTrackPoints() { return _trackPoints; } const TrackPoints& getTrackPoints() const { return _trackPoints; } protected: virtual ~TrackSegment() {} TrackPoints _trackPoints; }; class Track : public osg::Object { public: Track() {} Track(const Track& track, const osg::CopyOp=osg::CopyOp::SHALLOW_COPY) {} META_Object(osg, Track) typedef std::vector< osg::ref_ptr > TrackSegments; void addTrackSegment(TrackSegment* trackSegment) { _trackSegments.push_back(trackSegment); } TrackSegments& getTrackSegments() { return _trackSegments; } const TrackSegments& getTrackSegments() const { return _trackSegments; } protected: virtual ~Track() {} TrackSegments _trackSegments; }; double convertTime(const std::string& timestr) { osg::notify(osg::NOTICE)<<" time = "< doc = new osgDB::XmlNode; doc->read(input); osgDB::XmlNode* root = 0; for(osgDB::XmlNode::Children::iterator itr = doc->children.begin(); itr != doc->children.end() && !root; ++itr) { if ((*itr)->name=="gpx") root = itr->get(); } if (!root) return 0; std::string latitude("lat"); std::string longitude("lon"); for(osgDB::XmlNode::Children::iterator itr = root->children.begin(); itr != root->children.end(); ++itr) { if ((*itr)->name=="rte") { osg::ref_ptr track = new Track; track->setName(filename); osg::ref_ptr trackSegment = new TrackSegment; for(osgDB::XmlNode::Children::iterator sitr = (*itr)->children.begin(); sitr != (*itr)->children.end(); ++sitr) { if ((*sitr)->name=="rtept" ) { osgDB::XmlNode* trkpt = sitr->get(); TrackSegment::TrackPoint point; bool valid = false; if (trkpt->properties.count(latitude)!=0) { valid = true; point.latitude = osg::asciiToDouble(trkpt->properties[latitude].c_str()); } if (trkpt->properties.count(longitude)!=0) { valid = true; point.longitude = osg::asciiToDouble(trkpt->properties[longitude].c_str()); } for(osgDB::XmlNode::Children::iterator pitr = trkpt->children.begin(); pitr != trkpt->children.end(); ++pitr) { if ((*pitr)->name=="ele") point.elevation = osg::asciiToDouble((*pitr)->contents.c_str()); else if ((*pitr)->name=="time") point.time = convertTime((*pitr)->contents); } if (valid) { osg::notify(osg::NOTICE)<<" point.latitude="< track = new Track; track->setName(filename); for(osgDB::XmlNode::Children::iterator citr = (*itr)->children.begin(); citr != (*itr)->children.end(); ++citr) { if ((*citr)->name=="trkseg") { osg::ref_ptr trackSegment = new TrackSegment; for(osgDB::XmlNode::Children::iterator sitr = (*citr)->children.begin(); sitr != (*citr)->children.end(); ++sitr) { if ((*sitr)->name=="trkpt" || (*sitr)->name=="rtept" ) { osgDB::XmlNode* trkpt = sitr->get(); TrackSegment::TrackPoint point; bool valid = false; if (trkpt->properties.count(latitude)!=0) { valid = true; point.latitude = osg::asciiToDouble(trkpt->properties[latitude].c_str()); } if (trkpt->properties.count(longitude)!=0) { valid = true; point.longitude = osg::asciiToDouble(trkpt->properties[longitude].c_str()); } for(osgDB::XmlNode::Children::iterator pitr = trkpt->children.begin(); pitr != trkpt->children.end(); ++pitr) { if ((*pitr)->name=="ele") point.elevation = osg::asciiToDouble((*pitr)->contents.c_str()); else if ((*pitr)->name=="time") point.time = convertTime((*pitr)->contents); } if (valid) { // osg::notify(osg::NOTICE)<<" point.latitude="< track = readTrack(trackFilename); if (track.valid()) tracks.push_back(track.get()); } osg::ref_ptr em = new osg::EllipsoidModel; osg::ref_ptr group = new osg::Group; osg::ref_ptr loadedModel = osgDB::readRefNodeFiles(arguments); if (loadedModel.valid()) group->addChild(loadedModel); for(Tracks::iterator titr = tracks.begin(); titr != tracks.end(); ++titr) { Track* track = titr->get(); group->addChild(createTrackModel(track, osg::Vec4(1.0,1.0,1.0,1.0))); // smooth the track if (average) { for(Track::TrackSegments::iterator itr = track->getTrackSegments().begin(); itr != track->getTrackSegments().end(); ++itr) { *itr = computeAveragedSpeedTrackSegment(itr->get()); } } // smooth the track if (smooth) { for(Track::TrackSegments::iterator itr = track->getTrackSegments().begin(); itr != track->getTrackSegments().end(); ++itr) { *itr = computeSmoothedTrackSegment(itr->get()); } for(Track::TrackSegments::iterator itr = track->getTrackSegments().begin(); itr != track->getTrackSegments().end(); ++itr) { *itr = computeSmoothedTrackSegment(itr->get()); } for(Track::TrackSegments::iterator itr = track->getTrackSegments().begin(); itr != track->getTrackSegments().end(); ++itr) { *itr = computeSmoothedTrackSegment(itr->get()); } for(Track::TrackSegments::iterator itr = track->getTrackSegments().begin(); itr != track->getTrackSegments().end(); ++itr) { *itr = computeSmoothedTrackSegment(itr->get()); } } double totalDistance = 0.0; double totalAscent = 0.0; double totalDescent = 0.0; osg::notify(osg::NOTICE)<<"Track read "<getName()<getTrackSegments().begin(); itr != track->getTrackSegments().end(); ++itr) { TrackSegment* ts = itr->get(); const TrackSegment::TrackPoints& points = ts->getTrackPoints(); if (points.size()>1) { TrackSegment::TrackPoints::iterator pitr = ts->getTrackPoints().begin(); osg::Vec3d previousPos; double previousElevation = pitr->elevation; em->convertLatLongHeightToXYZ(osg::DegreesToRadians(pitr->latitude), osg::DegreesToRadians(pitr->longitude), 0.0, previousPos.x(), previousPos.y(), previousPos.z()); ++pitr; for(; pitr != ts->getTrackPoints().end(); ++pitr) { osg::Vec3d newPos; double newElevation = pitr->elevation; em->convertLatLongHeightToXYZ(osg::DegreesToRadians(pitr->latitude), osg::DegreesToRadians(pitr->longitude), 0.0, newPos.x(), newPos.y(), newPos.z()); double distance = (newPos-previousPos).length(); totalDistance += distance; if (newElevation>previousElevation) totalAscent += (newElevation-previousElevation); else totalDescent += (previousElevation-newElevation); osg::notify(osg::NOTICE)<<" distance="<"<get(); fout<<""<The track description"<getTrackSegments().begin(); itr != track->getTrackSegments().end(); ++itr) { TrackSegment* ts = itr->get(); fout<<""<getTrackPoints().begin(); pitr != ts->getTrackPoints().end(); ++pitr) { fout<<"latitude<<"\" lon=\""<longitude<<"\">"<"<elevation<<""<"<time<<""<"<"<"<"<