/*************************************************************************** gpsdata.h - Data structures for GPS data ------------------- begin : 2004-04-14 copyright : (C) 2004 by Lars Luthman email : larsl@users.sourceforge.net ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef GPSDATA_H #define GPSDATA_H #include #include #include #include #include #include #include #include #include "../../src/qgsrect.h" /** This is the parent class for all GPS data classes (except tracksegment). It contains the variables that all GPS objects can have. */ class GPSObject { public: virtual bool parseNode(const QDomNode& node); virtual void fillElement(QDomElement& elt); QString name, cmt, desc, src, url, urlname; }; /** This is the parent class for all GPS point classes. It contains common data members and common initialization code for all point classes. */ class GPSPoint : public GPSObject { public: GPSPoint(); virtual bool parseNode(const QDomNode& node); virtual void fillElement(QDomElement& elt); double lat, lon, ele; QString sym; }; /** This is the parent class for all GPS object types that can have a nonempty bounding box (Route, Track). It contains common data members for all those classes. */ class GPSExtended : public GPSObject { public: virtual bool parseNode(const QDomNode& node); virtual void fillElement(QDomElement& elt); int number; double xMin, xMax, yMin, yMax; }; // they both have the same data members in GPX, so... typedef GPSPoint Routepoint; typedef GPSPoint Trackpoint; /** This is the waypoint class. It is a GPSPoint with an ID. */ class Waypoint : public GPSPoint { public: int id; }; /** This class represents a GPS route. */ class Route : public GPSExtended { public: bool parseNode(const QDomNode& node); void fillElement(QDomElement& elt); std::vector points; int id; }; /** This class represents a GPS track segment, which is a contiguous part of a track. See the GPX specification for a better explanation. */ class TrackSegment { public: std::vector points; }; /** This class represents a GPS tracklog. It consists of 0 or more track segments. */ class Track : public GPSExtended { public: bool parseNode(const QDomNode& node); void fillElement(QDomElement& elt); std::vector segments; int id; }; /** This class represents a set of GPS data, for example a GPS layer in QGIS. */ class GPSData { public: /** This iterator type is used to iterate over waypoints. */ typedef std::list::iterator WaypointIterator; /** This iterator type is used to iterate over routes. */ typedef std::list::iterator RouteIterator; /** This iterator type is used to iterate over tracks. */ typedef std::list::iterator TrackIterator; /** This constructor initializes the extent to a nonsense value. Don't try to use a GPSData object in QGIS without parsing a datafile into it. */ GPSData(); /** This function returns a pointer to a dynamically allocated QgsRect which is the bounding box for this dataset. You'll have to deallocate it yourself. */ QgsRect* getExtent() const; /** Returns the number of waypoints in this dataset. */ int getNumberOfWaypoints() const; /** Returns the number of waypoints in this dataset. */ int getNumberOfRoutes() const; /** Returns the number of waypoints in this dataset. */ int getNumberOfTracks() const; WaypointIterator waypointsBegin(); RouteIterator routesBegin(); TrackIterator tracksBegin(); WaypointIterator waypointsEnd(); RouteIterator routesEnd(); TrackIterator tracksEnd(); /** This function returns the waypoint with ID @c id. If there is no waypoint with that ID an exception will be thrown. */ //Waypoint& getWaypoint(int id); /** This function returns the route with index @c index. If there is no route with that index an exception will be thrown. */ //Route& getRoute(int index); /** This function returns the track with index @c index. If there is no track with that index an exception will be thrown. */ //Track& getTrack(int index); /** This function tries to add a new waypoint. An iterator to the new waypoint will be returned (it will be waypointsEnd() if the waypoint couldn't be added. */ WaypointIterator addWaypoint(double lat, double lon, QString name = "", double ele = -std::numeric_limits::max()); WaypointIterator addWaypoint(const Waypoint& wpt); /** This function tries to add a new route. It returns an iterator to the new route. */ RouteIterator addRoute(QString name = ""); RouteIterator addRoute(const Route& rte); /** This function tries to add a new track. An iterator to the new track will be returned. */ TrackIterator addTrack(QString name = ""); TrackIterator addTrack(const Track& trk); /** This function removes the waypoints whose IDs are in the list. */ void removeWaypoints(std::list const & ids); /** This function removes the routes whose IDs are in the list. */ void removeRoutes(std::list const & ids); /** This function removes the tracks whose IDs are in the list. */ void removeTracks(std::list const & ids); /** This function tries to parse a QDomDocument as a GPX tree. If it succeeds it will fill this GPSData object with the data from the QDomDocument and return true, otherwise it will return false. */ bool parseDom(QDomDocument& qdd); /** This function will fill the given QDomDocument with child nodes that represent the data in this GPSData object as a GPX tree. */ void fillDom(QDomDocument& qdd); /** This function returns a pointer to the GPSData object associated with the file @c filename. If the file does not exist or can't be parsed, NULL will be returned. If the file is already used by another layer, a pointer to the same GPSData object will be returned. And if the file is not used by any other layer, and can be parsed, a new GPSData object will be created and a pointer to it will be returned. If you use this function you should also call releaseData() with the same @c filename when you're done with the GPSData pointer, otherwise the data will stay in memory forever and you will get an ugly memory leak. */ static GPSData* getData(const QString& filename); /** Call this function when you're done with a GPSData pointer that you got earlier using getData(). Do NOT call this function if you haven't called getData() earlier with the same @c filename, that can cause data that is still in use to be deleted. */ static void releaseData(const QString& filename); /** operator<< is our friend. For debugging, not for file I/O. */ //friend std::ostream& operator<<(std::ostream& os, const GPSData& d); protected: /** This function parses a GPX file and places the data it finds in this object. If any errors are found in the XML tree the function will return false, but it doesn't do a full validity check so some errors could get through. If it succeeds it will return true. @param node The node from a QDomDocument */ bool parseGPX(QDomNode& node); std::list waypoints; std::list routes; std::list tracks; int nextWaypoint, nextRoute, nextTrack; double xMin, xMax, yMin, yMax; /** This is used internally to store GPS data objects (one per file). */ typedef std::map > DataMap; /** This is the static container that maps filenames to GPSData objects and does reference counting, so several providers can use the same GPSData object. */ static DataMap dataObjects; }; #endif