1# https://pyrocko.org - GPLv3 

2# 

3# The Pyrocko Developers, 21st Century 

4# ---|P------/S----------~Lg---------- 

5 

6from __future__ import absolute_import, print_function, division 

7 

8import numpy as num 

9 

10from pyrocko import table, geometry, cake 

11from pyrocko.guts import Bool, Float 

12from pyrocko.gui.qt_compat import qw, qc 

13 

14from pyrocko.dataset.volcanoes import Volcanoes 

15from pyrocko.gui.vtk_util import ScatterPipe 

16 

17from .base import Element, ElementState 

18 

19guts_prefix = 'sparrow' 

20 

21km = 1e3 

22COLOR_HOLOCENE = (0.98, 0.26, .32) 

23COLOR_PLEISTOCENE = (1., .41, .28) 

24 

25 

26def volcanoes_to_points(volcanoes): 

27 coords = num.zeros((len(volcanoes), 3)) 

28 

29 for i, v in enumerate(volcanoes): 

30 coords[i, :] = v.lat, v.lon, -v.elevation - 10*km 

31 

32 station_table = table.Table() 

33 

34 station_table.add_col(('coords', '', ('lat', 'lon', 'depth')), coords) 

35 

36 return geometry.latlondepth2xyz( 

37 station_table.get_col('coords'), 

38 planetradius=cake.earthradius) 

39 

40 

41def volcanoes_to_color(volcanoes): 

42 colors = [] 

43 for v in volcanoes: 

44 if v.age == 'holocene': 

45 colors.append(COLOR_HOLOCENE) 

46 else: 

47 colors.append(COLOR_PLEISTOCENE) 

48 return num.array(colors) 

49 

50 

51class VolcanoesState(ElementState): 

52 visible = Bool.T(default=True) 

53 size = Float.T(default=3.0) 

54 

55 def create(self): 

56 element = VolcanoesElement() 

57 return element 

58 

59 

60class VolcanoesElement(Element): 

61 

62 def __init__(self): 

63 Element.__init__(self) 

64 self._pipe = None 

65 self._controls = None 

66 self._volcanoes = None 

67 

68 def bind_state(self, state): 

69 Element.bind_state(self, state) 

70 for var in ['visible', 'size']: 

71 self.register_state_listener3(self.update, state, var) 

72 

73 def get_name(self): 

74 return 'Volcanoes' 

75 

76 def set_parent(self, parent): 

77 self._parent = parent 

78 if not self._volcanoes: 

79 self._volcanoes = Volcanoes() 

80 

81 self._parent.add_panel( 

82 self.get_name(), 

83 self._get_controls(), 

84 visible=True, 

85 title_controls=[ 

86 self.get_title_control_remove(), 

87 self.get_title_control_visible()]) 

88 

89 self.update() 

90 

91 def unset_parent(self): 

92 self.unbind_state() 

93 if not self._parent: 

94 return 

95 self._parent.remove_actor(self._pipe.actor) 

96 self._pipe = None 

97 

98 self._parent.remove_panel(self._controls) 

99 self._controls = None 

100 

101 self._parent.update_view() 

102 self._parent = None 

103 

104 def update(self, *args): 

105 state = self._state 

106 

107 if state.visible: 

108 if self._pipe is None: 

109 points = volcanoes_to_points(self._volcanoes.volcanoes) 

110 self._pipe = ScatterPipe(points) 

111 

112 colors = volcanoes_to_color(self._volcanoes.volcanoes) 

113 self._pipe.set_colors(colors) 

114 

115 self._pipe.set_size(state.size) 

116 self._pipe.set_symbol('sphere') 

117 self._parent.add_actor(self._pipe.actor) 

118 

119 else: 

120 self._parent.remove_actor(self._pipe.actor) 

121 

122 self._parent.update_view() 

123 

124 def _get_controls(self): 

125 if not self._controls: 

126 from ..state import state_bind_slider 

127 

128 frame = qw.QFrame() 

129 layout = qw.QGridLayout() 

130 frame.setLayout(layout) 

131 

132 layout.addWidget(qw.QLabel('Size'), 0, 0) 

133 

134 slider = qw.QSlider(qc.Qt.Horizontal) 

135 slider.setSizePolicy( 

136 qw.QSizePolicy( 

137 qw.QSizePolicy.Expanding, qw.QSizePolicy.Fixed)) 

138 slider.setMinimum(0) 

139 slider.setMaximum(10) 

140 slider.setSingleStep(1) 

141 slider.setPageStep(1) 

142 layout.addWidget(slider, 0, 1) 

143 state_bind_slider(self, self._state, 'size', slider) 

144 

145 layout.addWidget(qw.QFrame(), 1, 0, 1, 2) 

146 

147 self._controls = frame 

148 

149 return self._controls 

150 

151 

152__all__ = [ 

153 'VolcanoesElement', 

154 'VolcanoesState' 

155]