/*************************************************************************** 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 "../../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 all have the same data members in GPX, so... typedef GPSPoint Waypoint; typedef GPSPoint Routepoint; typedef GPSPoint Trackpoint; /** This class represents a GPS route. */ class Route : public GPSExtended { public: bool parseNode(const QDomNode& node); void fillElement(QDomElement& elt); std::vector points; }; /** 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; }; /** This class represents a set of GPS data, for example a GPS layer in QGIS. */ class GPSData { public: /** 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; /** This function returns the waypoint with index @c index. If there is no waypoint with that index an exception will be thrown. */ Waypoint& getWaypoint(int index); /** 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. If the waypoint was added successfully its index will be returned, otherwise a negative number will be returned. */ int addWaypoint(double lat, double lon, QString name = "", double ele = -std::numeric_limits::max()); /** This function tries to add a new route. If the route was added successfully its index will be returned, otherwise a negative number will be returned. */ int addRoute(QString name = ""); /** This function tries to add a new track. If the track was added successfully its index will be returned, otherwise a negative number will be returned. */ int addTrack(QString name = ""); /** This function removes the waypoint with index @c index. If @c checkRoutes is @c true the waypoint will only be removed if it is not used in a route, otherwise the function will return false. */ bool removeWaypoint(int index, bool checkRoutes = false); /** This function removes the route with index @c index. */ void removeRoute(int index); /** This function removes the track with index @c index. */ void removeTrack(int index); /** 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. */ 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::vector waypoints; std::vector routes; std::vector tracks; 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