diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 248393a5d..d3d454c13 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -58,6 +58,7 @@ IF(DYNAMIC_OPENSCENEGRAPH) ADD_SUBDIRECTORY(osglightpoint) ADD_SUBDIRECTORY(osglogicop) ADD_SUBDIRECTORY(osglogo) + ADD_SUBDIRECTORY(osggpx) ADD_SUBDIRECTORY(osgmanipulator) ADD_SUBDIRECTORY(osgmovie) ADD_SUBDIRECTORY(osgmultiplerendertargets) diff --git a/examples/osggpx/CMakeLists.txt b/examples/osggpx/CMakeLists.txt new file mode 100644 index 000000000..7523603f4 --- /dev/null +++ b/examples/osggpx/CMakeLists.txt @@ -0,0 +1,5 @@ + +SET(TARGET_SRC osggpx.cpp ) + +#### end var setup ### +SETUP_EXAMPLE(osggpx) diff --git a/examples/osggpx/osggpx.cpp b/examples/osggpx/osggpx.cpp new file mode 100644 index 000000000..2ed009b30 --- /dev/null +++ b/examples/osggpx/osggpx.cpp @@ -0,0 +1,409 @@ +/* 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=="trk") + { + osg::ref_ptr 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") + { + 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::readNodeFiles(arguments); + if (loadedModel.valid()) group->addChild(loadedModel.get()); + + for(Tracks::iterator itr = tracks.begin(); + itr != tracks.end(); + ++itr) + { + Track* track = itr->get(); + + group->addChild(createTrackModel(track, osg::Vec4(1.0,1.0,1.0,1.0))); + + // smooth the track + if (smooth) + { + for(Track::TrackSegments::iterator itr = track->getTrackSegments().begin(); + itr != track->getTrackSegments().end(); + ++itr) + { + *itr = computeSmoothedTrackSegment(*itr); + } + + for(Track::TrackSegments::iterator itr = track->getTrackSegments().begin(); + itr != track->getTrackSegments().end(); + ++itr) + { + *itr = computeSmoothedTrackSegment(*itr); + } + + for(Track::TrackSegments::iterator itr = track->getTrackSegments().begin(); + itr != track->getTrackSegments().end(); + ++itr) + { + *itr = computeSmoothedTrackSegment(*itr); + } + + for(Track::TrackSegments::iterator itr = track->getTrackSegments().begin(); + itr != track->getTrackSegments().end(); + ++itr) + { + *itr = computeSmoothedTrackSegment(*itr); + } + } + + 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="<