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.tectonics import PeterBird2003 

15from pyrocko.gui import vtk_util 

16import vtk 

17from matplotlib.pyplot import cm 

18 

19from .base import Element, ElementState 

20 

21guts_prefix = 'sparrow' 

22 

23km = 1e3 

24COLOR_PLATES = (0.1, 0.0, .0) 

25 

26 

27def plates_to_points(plates): 

28 num_all_nodes = 0 

29 for plate in plates: 

30 num_all_nodes = num_all_nodes + len(plate.points) 

31 coords = num.zeros((num_all_nodes, 3)) 

32 x = [] 

33 y = [] 

34 

35 for plate in plates: 

36 num_nodes = len(plate.points) 

37 for i in range(0, num_nodes): 

38 x.append(plate.points[i][0]) 

39 y.append(plate.points[i][1]) 

40 for i in range(0, num_all_nodes): 

41 coords[i, :] = x[i], y[i], -10*km 

42 station_table = table.Table() 

43 

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

45 

46 return geometry.latlondepth2xyz( 

47 station_table.get_col('coords'), 

48 planetradius=cake.earthradius) 

49 

50 

51def plates_to_color(plates): 

52 colors = [] 

53 colors_iter_map = iter(cm.terrain(num.linspace(0, 1, len(plates)))) 

54 for plate in plates: 

55 color = next(colors_iter_map) 

56 colors.append(color) 

57 return num.array(colors) 

58 

59 

60class PlatesBoundsState(ElementState): 

61 visible = Bool.T(default=True) 

62 opacity = Float.T(default=1.0) 

63 color_by_slip_type = Bool.T(default=False) 

64 lines = Bool.T(default=True) 

65 

66 def create(self): 

67 element = PlatesBoundsElement() 

68 return element 

69 

70 

71class PlatelinesPipe(object): 

72 def __init__(self, plates=None): 

73 

74 self.mapper = vtk.vtkDataSetMapper() 

75 self._polyline_grid = {} 

76 self._opacity = 1.0 

77 self.plates = plates 

78 

79 actor = vtk.vtkActor() 

80 actor.SetMapper(self.mapper) 

81 

82 prop = actor.GetProperty() 

83 prop.SetDiffuseColor(1, 1, 1) 

84 

85 self.prop = prop 

86 self.actor = actor 

87 

88 def plate_to_lines(self, plate): 

89 lines = [] 

90 poly = [] 

91 num_nodes = len(plate.points) 

92 for i in range(0, num_nodes): 

93 poly.append((plate.points[i][0], plate.points[i][1])) 

94 lines.append(num.asarray(poly)) 

95 

96 self._polyline_grid[0] = vtk_util.make_multi_polyline( 

97 lines_latlon=lines, depth=-100.) 

98 vtk_util.vtk_set_input(self.mapper, self._polyline_grid[0]) 

99 

100 def set_opacity(self, opacity): 

101 opacity = float(opacity) 

102 if self._opacity != opacity: 

103 self.prop.SetOpacity(opacity) 

104 self._opacity = opacity 

105 

106 

107class PlatesBoundsElement(Element): 

108 

109 def __init__(self): 

110 Element.__init__(self) 

111 self._parent = None 

112 self._state = None 

113 self._pipe = None 

114 self._controls = None 

115 self._plates = None 

116 self._listeners = [] 

117 self._plate_line = None 

118 self._plate_lines = [] 

119 

120 def bind_state(self, state): 

121 Element.bind_state(self, state) 

122 for var in ['visible', 'opacity']: 

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

124 

125 def unbind_state(self): 

126 self._listerners = [] 

127 

128 def get_name(self): 

129 return 'Plate bounds' 

130 

131 def set_parent(self, parent): 

132 self._parent = parent 

133 if not self._plates: 

134 PB = PeterBird2003() 

135 self._plates = PB.get_plates() 

136 

137 self._parent.add_panel( 

138 self.get_name(), 

139 self._get_controls(), 

140 visible=True, 

141 title_controls=[ 

142 self.get_title_control_remove(), 

143 self.get_title_control_visible()]) 

144 

145 self.update() 

146 

147 def unset_parent(self): 

148 self.unbind_state() 

149 if self._plate_lines: 

150 for i, plate in enumerate(self._plate_lines): 

151 self._parent.remove_actor(plate.actor) 

152 

153 self._pipe = None 

154 

155 if self._controls: 

156 self._parent.remove_panel(self._controls) 

157 self._controls = None 

158 

159 self._parent.update_view() 

160 self._parent = None 

161 

162 def update(self, *args): 

163 

164 state = self._state 

165 if state.visible: 

166 colors = plates_to_color(self._plates) 

167 for i, plate in enumerate(self._plates): 

168 self._plate_line = PlatelinesPipe(plates=plate) 

169 self._plate_line.plate_to_lines(plate) 

170 self._parent.add_actor(self._plate_line.actor) 

171 prop = self._plate_line.actor.GetProperty() 

172 prop.SetDiffuseColor(colors[i][0:3]) 

173 self._plate_line.set_opacity(state.opacity) 

174 self._plate_lines.append(self._plate_line) 

175 if not state.visible and self._plate_lines: 

176 for i, plate in enumerate(self._plate_lines): 

177 self._parent.remove_actor(plate.actor) 

178 

179 self._parent.update_view() 

180 

181 def _get_controls(self): 

182 if self._controls is None: 

183 from ..state import state_bind_slider 

184 

185 frame = qw.QFrame() 

186 layout = qw.QGridLayout() 

187 layout.setAlignment(qc.Qt.AlignTop) 

188 frame.setLayout(layout) 

189 

190 layout.addWidget(qw.QLabel('Opacity'), 0, 0) 

191 

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

193 slider.setSizePolicy( 

194 qw.QSizePolicy( 

195 qw.QSizePolicy.Expanding, qw.QSizePolicy.Fixed)) 

196 slider.setMinimum(0) 

197 slider.setMaximum(10) 

198 slider.setSingleStep(1) 

199 slider.setPageStep(1) 

200 layout.addWidget(slider, 0, 1) 

201 state_bind_slider(self, self._state, 'opacity', slider) 

202 

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

204 

205 self._controls = frame 

206 

207 return self._controls 

208 

209 

210__all__ = [ 

211 'PlatesBoundsElement', 

212 'PlatesBoundsState' 

213]