Reading KML My Tracks files in ipython

It's easy to record tracks (for instance while running) using the "My tracks" app on android systems. What about being able to re-use them?

In :doc:2014-11-22-reading-kml-my-tracks-files-in-ipython we reviewed different approches. Let's now try to use this data.

In [1]:
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np

the xmltodict solution

In [2]:
class KmlReader():
    def __init__(self, filename):
        import pandas as pd
        import xmltodict
        with open(filename) as f:
            kml_dict = xmltodict.parse(f)
        doc = kml_dict['kml']['Document']
        keypoint_folder = doc['Folder']
        Placemark = doc['Placemark']
        self.tracks_type =  Placemark[1]['ExtendedData']['Data']['value']
        track = Placemark[1]['gx:MultiTrack']['gx:Track']
        self.lon, self.lat, self.alt = [], [], []
        for when, where in zip(track['when'], track['gx:coord']):
            self.whens = pd.to_datetime(track['when'])
            for coord in track['gx:coord']:
                lon, lat, alt = coord.split(' ')
                self.lon.append(np.float(lon))
                self.lat.append(np.float(lat))
                self.alt.append(np.float(alt))

filename = '/tmp/test.kml'
track =  KmlReader(filename)
In [3]:
import pandas as pd
whens = pd.to_datetime(track.whens)
print whens[0], whens[0].ctime()
2013-04-27 12:33:51 Sat Apr 27 12:33:51 2013
In [4]:
df = pd.DataFrame(data = zip(track.whens, track.lon, track.lat, track.alt), columns=['time', 'lon', 'lat', 'alt'])
In [5]:
df
Out[5]:
time lon lat alt
0 2013-04-27 12:33:51 5.393242 43.262411 73.477097
1 2013-04-27 12:33:55 5.393219 43.262444 72.936981
2 2013-04-27 12:33:56 5.393213 43.262457 73.197395
3 2013-04-27 12:33:58 5.393202 43.262490 65.184090
4 2013-04-27 12:33:59 5.393198 43.262511 65.366005
5 2013-04-27 12:34:00 5.393193 43.262535 61.444321
6 2013-04-27 12:34:01 5.393187 43.262560 61.353985
7 2013-04-27 12:34:02 5.393182 43.262588 61.959949
8 2013-04-27 12:34:03 5.393178 43.262616 63.015228
9 2013-04-27 12:34:04 5.393176 43.262642 64.982201
10 2013-04-27 12:34:05 5.393172 43.262666 67.654190
11 2013-04-27 12:34:06 5.393163 43.262696 69.057785
12 2013-04-27 12:34:07 5.393154 43.262726 70.457108
13 2013-04-27 12:34:08 5.393145 43.262758 71.321938
14 2013-04-27 12:34:09 5.393138 43.262785 71.303345
15 2013-04-27 12:34:10 5.393130 43.262811 70.360481
16 2013-04-27 12:34:11 5.393121 43.262837 70.317429
17 2013-04-27 12:34:12 5.393112 43.262863 70.237083
18 2013-04-27 12:34:13 5.393102 43.262893 70.133751
19 2013-04-27 12:34:14 5.393094 43.262922 70.093513
20 2013-04-27 12:34:15 5.393084 43.262948 70.045280
21 2013-04-27 12:34:16 5.393066 43.262980 69.968422
22 2013-04-27 12:34:17 5.393051 43.263008 69.871803
23 2013-04-27 12:34:18 5.393032 43.263037 69.833954
24 2013-04-27 12:34:19 5.393016 43.263068 69.833076
25 2013-04-27 12:34:20 5.392996 43.263098 69.859688
26 2013-04-27 12:34:21 5.392975 43.263126 69.856659
27 2013-04-27 12:34:22 5.392955 43.263158 69.842468
28 2013-04-27 12:34:23 5.392938 43.263187 69.828461
29 2013-04-27 12:34:24 5.392922 43.263216 69.836105
... ... ... ... ...
2397 2013-04-27 13:19:25.999000 5.393512 43.261531 67.265388
2398 2013-04-27 13:19:26.999000 5.393520 43.261507 67.271210
2399 2013-04-27 13:19:27.999000 5.393536 43.261481 67.263725
2400 2013-04-27 13:19:29.999000 5.393595 43.261480 67.192612
2401 2013-04-27 13:19:30.999000 5.393635 43.261495 67.161255
2402 2013-04-27 13:19:31.999000 5.393691 43.261518 67.093140
2403 2013-04-27 13:19:32.999000 5.393748 43.261535 67.003372
2404 2013-04-27 13:19:33.999000 5.393785 43.261550 66.965759
2405 2013-04-27 13:19:34.999000 5.393821 43.261566 66.941238
2406 2013-04-27 13:19:36.999000 5.393871 43.261590 66.851234
2407 2013-04-27 13:19:37.999000 5.393886 43.261600 66.808517
2408 2013-04-27 13:19:39.999000 5.393918 43.261618 66.744225
2409 2013-04-27 13:19:40.999000 5.393945 43.261633 66.713600
2410 2013-04-27 13:19:41.999000 5.393977 43.261646 66.665375
2411 2013-04-27 13:19:42.999000 5.394010 43.261654 66.593460
2412 2013-04-27 13:19:43.999000 5.394047 43.261670 66.497551
2413 2013-04-27 13:19:44.999000 5.394077 43.261684 66.413139
2414 2013-04-27 13:19:46.999000 5.394127 43.261704 66.249512
2415 2013-04-27 13:19:47.999000 5.394151 43.261718 66.162277
2416 2013-04-27 13:19:48.999000 5.394175 43.261732 66.049507
2417 2013-04-27 13:19:49.999000 5.394201 43.261746 65.929634
2418 2013-04-27 13:19:51.999000 5.394245 43.261771 65.717690
2419 2013-04-27 13:19:52.999000 5.394269 43.261783 65.646263
2420 2013-04-27 13:19:54.999000 5.394322 43.261802 65.457573
2421 2013-04-27 13:19:55.999000 5.394355 43.261809 65.409889
2422 2013-04-27 13:19:57.999000 5.394403 43.261835 65.301704
2423 2013-04-27 13:19:58.999000 5.394425 43.261847 65.255844
2424 2013-04-27 13:20:00.999000 5.394464 43.261873 65.148201
2425 2013-04-27 13:20:01.999000 5.394480 43.261883 65.100128
2426 2013-04-27 13:20:06.999000 5.394510 43.261919 64.971428

2427 rows × 4 columns

In [6]:
df.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 2427 entries, 0 to 2426
Data columns (total 4 columns):
time    2427 non-null datetime64[ns]
lon     2427 non-null float64
lat     2427 non-null float64
alt     2427 non-null float64
dtypes: datetime64[ns](1), float64(3)
memory usage: 94.8 KB

Looks good... Can we plot that?

In [7]:
df['alt'].plot(figsize=(15,5));
No description has been provided for this image

Another way:

In [8]:
df.plot(x='time', y='alt', figsize=(15,5), label='altitude', legend=False);
No description has been provided for this image
In [9]:
df.plot(x='time', y='lon', figsize=(15,5), label='longitude')
df.plot(x='time', y='lat', figsize=(15,5), label='lattitude', legend=False);
No description has been provided for this image
No description has been provided for this image
In [10]:
df.lon.plot(x='time', figsize=(15,5))
df.lat.plot(x='time', secondary_y=True, style='g');
No description has been provided for this image
In [11]:
df.plot(x='lon', y='lat', figsize=(15,15), legend=False);
No description has been provided for this image
In [12]:
plt.plot(df.lon.values, df.lat.values)
Out[12]:
[<matplotlib.lines.Line2D at 0x10fa2ab90>]
No description has been provided for this image

embedding that info in a map

In [13]:
from IPython.display import IFrame
from IPython.core.display import display

# Google Maps URL template for an iframe
lat, lon, zoom = df.lat.values.mean(), df.lon.values.mean(), 14
google_maps_url = "http://maps.google.com/maps?q={0}+{1}&" + \
  "ie=UTF8&t=h&z={2}&{0},{1}&output=embed".format(lat, lon, zoom)

display(IFrame(google_maps_url, '425px', '350px'))
!pip install foliumimport folium map_osm = folium.Map(location=[45.5236, -122.6750]) map_osm.create_map(path='/tmp/osm.html')display(IFrame('file://tmp/osm.html', '425px', '350px'))
In [14]:
!pip install smopy
Requirement already satisfied (use --upgrade to upgrade): smopy in /usr/local/lib/python2.7/site-packages
Cleaning up...
In [15]:
import smopy
print df.lat.values.min(), df.lon.values.min(), df.lat.values.max(), df.lon.values.max()
map = smopy.Map((df.lat.values.min(), df.lon.values.min(), df.lat.values.max(), df.lon.values.max()), z=13)
map.show_ipython()
43.257541 5.379072 43.265526 5.39451
No description has been provided for this image
smopy.Map?
In [16]:
ax = map.show_mpl()
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-16-e20009c91642> in <module>()
----> 1 ax = map.show_mpl()

/usr/local/lib/python2.7/site-packages/smopy.pyc in show_mpl(self, ax, figsize, dpi)
    267             plt.ylim(self.h, 0)
    268             plt.axis('off');
--> 269             plt.tight_layout();
    270         ax.imshow(self.img);
    271         return ax

/usr/local/lib/python2.7/site-packages/matplotlib/pyplot.pyc in tight_layout(pad, h_pad, w_pad, rect)
   1286 
   1287     fig = gcf()
-> 1288     fig.tight_layout(pad=pad, h_pad=h_pad, w_pad=w_pad, rect=rect)
   1289     draw_if_interactive()
   1290 

/usr/local/lib/python2.7/site-packages/matplotlib/figure.pyc in tight_layout(self, renderer, pad, h_pad, w_pad, rect)
   1652                                          renderer,
   1653                                          pad=pad, h_pad=h_pad, w_pad=w_pad,
-> 1654                                          rect=rect)
   1655 
   1656         self.subplots_adjust(**kwargs)

/usr/local/lib/python2.7/site-packages/matplotlib/tight_layout.pyc in get_tight_layout_figure(fig, axes_list, subplotspec_list, renderer, pad, h_pad, w_pad, rect)
    350                                      subplot_list=subplot_list,
    351                                      ax_bbox_list=ax_bbox_list,
--> 352                                      pad=pad, h_pad=h_pad, w_pad=w_pad)
    353 
    354     if rect is not None:

/usr/local/lib/python2.7/site-packages/matplotlib/tight_layout.pyc in auto_adjust_subplotpars(fig, renderer, nrows_ncols, num1num2_list, subplot_list, ax_bbox_list, pad, h_pad, w_pad, rect)
    129         tight_bbox_raw = union([ax.get_tightbbox(renderer) for ax in subplots])
    130         tight_bbox = TransformedBbox(tight_bbox_raw,
--> 131                                      fig.transFigure.inverted())
    132 
    133         row1, col1 = divmod(num1, cols)

/usr/local/lib/python2.7/site-packages/matplotlib/matplotlib/transforms.pyc in __init__(self, bbox, transform, **kwargs)
   1055         *transform*: a 2D :class:`Transform`
   1056         """
-> 1057         assert bbox.is_bbox
   1058         assert isinstance(transform, Transform)
   1059         assert transform.input_dims == 2

AssertionError: 
No description has been provided for this image
map.show_mpl?map.show_ipython?%load_ext pep8_magic http://nbviewer.ipython.org/github/rossant/smopy/blob/master/examples/example1.ipynb
In [ ]:
!pip install git+https://github.com/rossant/smopy.git
In [ ]:
x, y = map.to_pixels(48.86151, 2.33474)
ax = map.show_mpl(figsize=(8, 6))
ax.plot(x, y, 'or', ms=10, mew=2);
nbviewer.ipython.org/github/vins31/gis-experiments/blob/master/Altitude roads.ipynb