| Features implemented | Maximum possible grade |
|---|---|
| 1 feature | 45 |
| 2 features | 60 |
| 3 features | 75 |
| 4 features | 85 |
| 5 features | 95 |
| 6 features | 100 |
30% of your grade will be based on coding style, which includes:
~/bin/submit -c=IC210 -p=proj03 Makefile *.h *.cpp ~/bin/submit -c=IC210 -p=proj03 Makefile *.h *.cpp
cover.jpgsudo apt install libxml2-dev libgtk-3-dev libcairo2-dev
Note, if that command doesn’t work, your package lists may be out of date. In that case, you should first update your with the following pair of commands. (This might take a few minutes, but it’s a good idea to update anyway.)
sudo apt update sudo apt full-upgrade
tar -xvf p3files.tarYou will see a bunch of files.
rideX.txt and runX.txt files are plain-text
“track files”, whose format is described in the next part. You need to read
this type of file to get its input.
rideX.gpx and runX.gpx files contain the same data
as the plaintext track files above, but in a more complicated XML format that is
commonly used in actual fitness devices to store tracks. One of the
features asks you to read this kind of file in addition to the plain-text
format.
landX.txt files contain GPS coordinates and names of
landmarks that will be used for one of the features you are asked to
implement.
gps.h and gps.cpp are a header and implementation
file that define a struct and some useful functions for GPS locations, including
crucially the complicated formula to
calculate the distance on the Earth’s surface between two points.
You must use this library in your program, and must not change either
file.
main in this file.
run1.txt looks like the following:
760 38.923082 -76.560321 2017-04-02 12:00:35 38.923078 -76.560335 2017-04-02 12:00:36 38.923025 -76.560567 2017-04-02 12:00:44 38.922975 -76.560822 2017-04-02 12:00:51 ...Tracks are represented as a series of waypoints.
run1.txt. As shown above, there are 760 waypoints in the file.
run1.txt has GPS location
with latitude 38.923082° and longitude -76.560321°.
YYYY-MM-DD HH:MM:SS.
For example, the first waypoint in run1.txt has date
2017-04-02 and time 12:00:35.
gps.h header file and gps.cpp function definitions
file contain a struct gpsco and useful functions for storing and
finding the distance between GPS coordinates.
Note:
gps_dist function when you want
to compute the distance between two locations -- read gps.h carefully.
The formula for
determining the distance between two GPS coordinates is a little complicated
since our planet is round; you should be happy that you can just use this
function!
YYYY-MM-DD HH:MM:SS.
In order to easily deal with these, you might want to make use of some things in
the standard header library #include <ctime>. Look at Podcast Feeds Lab to remember how to use the tm
struct, mktime, and difftime functions to
calculate the difference between them in seconds.
main function should go in a file called track.cpp.
We also provided a Makefile so that you can compile your programs
with all the correct libraries linked in by running:
make track
This will compile your track.cpp program along with
gps.cpp. (Don't be intimidated by the very long g++ command that
you see in the Makefile - that's why we gave you the Makefile!)
You are encouraged to add your own .h and .cpp
files for other structs and groups of functions you write.
If you do that, you just need to add the names of your new .h and
.c files to the Makefile at the end of
HEADER_FILES and IMPLEMENTATION_FILES.
For example, if you added mylib.h and mylib.cpp,
your Makefile should look as follows:
HEADER_FILES = gps.h mylib.h IMPLEMENTATION_FILES = gps.cpp mylib.cpp
and then when you run make track, it will always compile
track.cpp along with any of the other .cpp files you
have in that list, along with the many libraries needed, to produce an
executable called track.
Note:
gpsco struct for the gps coordinates
and the time_t type for the time.
quit command is used to exit your program.
For example:
~$./trackFile:ride1.txtOpened ride1.txt with 1814 waypoints command:quit
linked.
To implement this feature, you have to store tracks as a linked list of waypoints and then use the linked list for the other features as well.
Once you implement this feature, your program should ignore the number at the beginning of the .txt track files and just read until the end of file. In other words, implementing the linked list feature will make your code work correctly even if the number at the beginning of the .txt file is wrong.
Your program should output the correct number of waypoints, even if the number at the begining of the file is wrong.
To document that you have implemented this feature (and make sure
your instructor looks for it to give you credit), add a function
linked to your track program that just prints out the
word “yes”, as in:
~$./trackFile:run1.txtOpened run1.txt with 760 waypoints command:linkedyes command:quit
Note: Recall that each feature can be implemented independently of the other ones and in any order. Check the other features as well and then determine when you want to implement this feature.
stats, which reports the total distance,
total time, average speed in miles per hour, and average pace in minutes per
mile.
Example runs are shown below:
~$ ~$ |
|
land1.txt looks as follows:
130 57.64 -134.35 Admiralty_Island 40.7144 -74.0042 African_Burial_Ground 42.416 -103.728 Agate_Fossil_Beds ...
landmarks function that reads in a file of landmarks
(an array is fine) and reports the minimum distance on the track to each landmark, starting with
the closest landmark.
Examples are shown below:
~$ ~$ |
|
Implement a fastest function that prompts for a target distance (in
miles) and then reports the fastest time within the track for that distance.
Conceptually, imagine yourself jogging for say 5 miles. While jogging, you wondered how fast you could run for a mile (that is, the target distance is a mile in this case). So, you ran with the top speed for a mile at some point. Now, coming back with your GPS track data, you need to extract that one-mile-segment where you ran fastest and find out the elapsed time for that segment.
Definitions (read carefully!)
See the right for example runs. |
~$ ~$ |
|
Suppose that the program receives the following command:
fastest 1.1 |
Suppose the track file has 5 waypoints, and the following information (we ignore
units for simplicity) is extracted from the track file.
distance time
--------------------------------------------------------
between waypoints 0 and 1 2.0 1.5
between waypoints 1 and 2 0.3 0.2
between waypoints 2 and 3 0.8 1.1
between waypoints 3 and 4 0.9 0.9
|
A: 1.1 (since the command was fastest 1.1).
A: 0.3 + 0.8 + 0.9 = 2.0
Waypoints between 0 and 1 (cumulative distance 2.0) -- elpased time 1.5 Waypoints between 0 and 2 (cumulative distance 2.0 + 0.3 = 2.3) -- elapsed time 1.7 Waypoints between 0 and 3 (cumulative distance 2.0 + 0.3 + 0.8 = 3.1) -- elapsed time 2.8 Waypoints between 0 and 4 (cumulative distance 2.0 + 0.3 + 0.8 + 0.9 = 4.0) -- elapsed time 3.7Waypoints between 1 and 2 (cumulative distance 0.3)// not qualified (too short) Waypoints between 1 and 3 (cumulative distance 0.3 + 0.8 = 1.1) -- elapsed time 1.3 Waypoints between 1 and 4 (cumulative distance 0.3 + 0.8 + 0.9 = 2.0) -- elapsed time 2.2Waypoints between 2 and 3 (cumulative distance 0.8)// not qualified (too short) Waypoints between 2 and 4 (cumulative distance 0.8 + 0.9 = 1.7) -- elapsed time 2.0
A: 1.3 (that is, the elapsed time between the waypoints 1 and 3 is the least among all candidate elpased times above).
visual function that displays a visual depiction of the
current track in a new window. You don’t need to overlay it over any actual
maps, just make a line drawing with a line between each pair of consecutive
points in the track. You can check any of the gpx files in
the sample files (which match with the corresponding txt file) by
uploading to websites such as http://www.gpsvisualizer.com/. Your image will be simpler
because it’s not overlaid on Google Maps, but this should give you an idea of
what the shape should look like.
In order to pop up a window in your program, you will use the GTK+ library along with a drawing library called Cairo.
These are really big libraries that are used to create many Linux applications, and using them and reading the documentation can be difficult. That’s part of what this assignment is testing!
To help get you started, check out this example program gtkexample.cpp that opens a window in GTK and draws a line in the window. To compile this program, just download it to your project directory and then do
make gtkexample
To run the program after you compiled it, from the command line, just do
./gtkexample
Warning: If you get an error message when running ./gtkexample on your laptop and a window does not open up, your VcXsrv is likely not running. See the instructions under "Launch VcXsrv" section in the course setup to launch the server (you only need to do steps 1 and 2)
on_draw_event function actually
draws the line. The way that it knows where to draw the line is based on the
last parameter, gpointer user_data. Think of the
gpointer type as a “pointer to anything” which can be casted into a
specific type. In this program, it is a
pointer to a linked list of three node structs with x and y data members, but in
your program it could be a pointer to a different kind of linked list node, or
an array of structs, or a pointer to some other struct.
|
|
export GDK_SCALE=0.5For example, to execute the above sample run with showing the picture in a smaller scale:
~$export GDK_SCALE=0.5~$./trackFile:run2.txtOpened run2.txt with 327 waypoints command:visualcommand:quit
Note: You are required to use a linked list for this feature!
Modify your program so that if the user enters a filename that ends with
.gpx, then an alternate format is accepted.
.gpx files. The full
specs are here, but since we just want the location and time for each
waypoint, it will be a bit easier.
The file format for GPX files is called XML.
<outer>
<inner attribute1="cool" font="times" attribute3="yellow">
<item1>Item 1 contents</item1>
<item2>Item 2 contents</item2>
</inner>
</outer>
outer.
outer element one child. That child has name
inner.
inner element has three attributes with names
attribute1, font, and attribute3.
inner element has two children with names
item1 and item2, and they each have some
contents.
make xmlexample
gpx files. Check out the
actual contents by directly opening the gpx files in your editor.
See how that file format works.
gpx.
gpx element has a child called trk.
trk element has a child called trkseg.
trkseg element contains the actual waypoints you care about.
trkseg is a trkpt with some
attributes and children that specify the latitude, longitude, and time for
that waypoint, in order.
xmlexample.cpp works (and learn the XML
format better), you probably need to play around with the GPX files in a bunch
of different ways. Try creating a new GPX file or modify the existing GPX files
and run the program on them.
xmlexample.cpp program uses a standard library called libxml2 in
order to read the XML files. The libxml2 library parses files as a
“tree” of XML elements, which are naturally nested inside each other.
xmlexample.cpp. You probably need almost all of it
in your code.
rss.cpp that was provided to you) which used
libxml2 library for reading podcast feeds.
~$./trackFile:ride1.gpxOpened ride1.gpx with 1814 waypoints command:quit
~$./trackFile:ride2.gpxOpened ride2.gpx with 4584 waypoints command:quit
~$./trackFile:ride3.gpxOpened ride3.gpx with 13188 waypoints command:quit