いつもの通り皆様にはがっかりネタでしょうな。
ワタシには楽しい。「気圧補正と気温補正で気圧高度は結構ぴったり合う」を、「GPS の位置情報と精度を「本気で」可視化」と同じノリで。graph についてはこれ。
プログラムはこんなである:
1 # -*- coding: utf-8 -*-
2 import sys
3 # please edit next line for your environment.
4 sys.path.append("/sdcard/kivy-my-site-packages")
5
6 from datetime import datetime
7 import numpy as np
8 from kivy.lang import Builder
9 from kivy.app import App
10 from kivy.properties import StringProperty
11 from kivy.uix.boxlayout import BoxLayout
12 from kivy.clock import Clock
13 from kivy.garden.mapview import MapView, MapMarker, MapSource
14 from kivy.garden.graph import Graph, LinePlot
15
16 ###
17 import math
18
19 # values bellow are at base=0 (<11km)
20 _P0 = 1013.25 # static pressure (Pa) at MSL
21 _T0 = 273.15 + 15 # standard temperature (K) at MSL
22 _L0 = 6.49 / 1000. # standard temperature lapse rate (K/m) in ISA
23 _R = 8.31432 # universal gas constant in N·m /(mol·K)
24 _g0 = 9.80665 # gravitational acceleration in m/s**2
25 _M = 0.0289644 # molar mass of Earth's air in kg/mol
26
27 #
28 def a2p(h, delta_T=0):
29 t = _T0 + delta_T
30 return _P0 * math.pow((t / (t + _L0 * h)), _g0*_M/(_R*_L0))
31 #
32 def p2a(p, hA, pA, delta_T=0):
33 delta_p = pA - a2p(hA, delta_T)
34
35 t = _T0 + delta_T
36 return (t / _L0) * (np.power((p - delta_p) / _P0, -_R*_L0/(_g0*_M)) - 1)###
37
38 Builder.load_string('''
39 <GardenMapviewDemo>:
40 orientation: 'vertical'
41
42 elev_graph: elev_graph
43 map: map
44
45 Graph:
46 id: elev_graph
47 size_hint: (1, None)
48 height: 500
49 background_color: (0.5, 0.5, 0.5, 1)
50 xlabel: 'time'
51 ylabel: 'elevation'
52 x_grid: True
53 y_grid: True
54 x_grid_label: True
55 y_grid_label: True
56 y_ticks_major: 25
57 x_ticks_major: 300
58
59 MapView:
60 id: map
61 zoom: 17
62 ''')
63
64 class GardenMapviewDemo(BoxLayout):
65 def __init__(self):
66 super(GardenMapviewDemo, self).__init__()
67 self.map.map_source = MapSource(
68 url='http://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png',
69 attribution='http://maps.gsi.go.jp/development/ichiran.html')
70
71 temp = []
72 self._index = 0
73 self._added_markers = []
74 with open("./2016-08-10-with-DEM5.csv") as fi:
75 fi.readline() # skip header
76 hA, pA = None, None
77 for i, line in enumerate(fi.readlines()):
78 t = list(map(float, line.split(",")))[:7]
79 if not hA:
80 hA, pA = t[6], t[4]
81 t.append(p2a(t[4], hA, pA, 15))
82 #
83 # 0: time
84 # 1, 2: lon, lat
85 # 3: alt(GPS)
86 # 4: pressure
87 # 5: alt(pressure)
88 # 6: elev(DEM5)
89 # 7: alt(pressure with corr)
90 #
91 temp.append(t)
92 self._data_all = np.array(temp)
93 self._data_all[:,0] -= self._data_all[0,0]
94 #
95 self.elev_graph.xmax = float(self._data_all[-1,0])
96 elev_max = max(
97 self._data_all[:,3].max(),
98 self._data_all[:,6].max(),
99 self._data_all[:,7].max(),
100 )
101 self.elev_graph.ymax = float(elev_max + 10)
102 self.plot = [
103 LinePlot(color=[0, 1, 0, 1], line_width=1),
104 LinePlot(color=[1, 0, 0, 1], line_width=1),
105 LinePlot(color=[1, 1, 0, 1], line_width=1),
106 ]
107 for p in self.plot:
108 self.elev_graph.add_plot(p)
109 #
110 #self.update_view()
111 Clock.schedule_once(self.update_view, 30)
112
113 def update_view(self, *arg, **kwarg):
114 if self._added_markers:
115 for m in self._added_markers:
116 self.map.remove_marker(m)
117 self._added_markers = []
118
119 # kivy's xxxProperty can't treat numpy types...
120 cur = map(float, list(self._data_all[self._index]))
121
122 self.map.center_on(cur[2], cur[1])
123 m = MapMarker(lon=cur[1], lat=cur[2])
124 self.map.add_marker(m)
125 self._added_markers.append(m)
126 #
127 self.plot[0].points.append((cur[0], cur[3]))
128 self.plot[1].points.append((cur[0], cur[6]))
129 self.plot[2].points.append((cur[0], cur[7]))
130 #
131
132 if self._index < len(self._data_all) - 1:
133 elapse = self._data_all[self._index + 1][0] - \
134 self._data_all[self._index][0]
135 self._index += 1
136 Clock.schedule_once(self.update_view, elapse / 50)
137
138 class GardenMapviewDemoApp(App):
139 def build(self):
140 return GardenMapviewDemo()
141
142
143 if __name__ == '__main__':
144 GardenMapviewDemoApp().run()
mapview が futures と requests を必要とすることをお忘れなく。データの 2016-08-10-with-DEM5.csv は「気圧補正と気温補正で気圧高度は結構ぴったり合う」のものと内容は同じだけれど、時刻データが文字列でダルかったので UNIX time_t な float に直して使ってたりする。そんだけ。
うーん、mapview も graph も手を入れたいこといっぱいあって、結構ストレスだわ。こういうデータの見方って(特にフィールド系の自然科学やってるヒトたちには)すごくわかりやすくていいと思うのね。だからこんなんが手軽にちゃちゃっと作れるのっていいと思うんだ。だとすればもちっと問題が少なくないと困る。今のままだとちょっと「自力で何でもどうにか出来てしまう人」にしか薦められない。