1# https://pyrocko.org - GPLv3
2#
3# The Pyrocko Developers, 21st Century
4# ---|P------/S----------~Lg----------
6import numpy as num
8from pyrocko import table, geometry, cake
9from pyrocko.guts import Bool, Float
10from pyrocko.gui.qt_compat import qw, qc
12from pyrocko.dataset.tectonics import PeterBird2003
13from pyrocko.gui import vtk_util
14import vtk
15from matplotlib.pyplot import cm
17from .base import Element, ElementState
19guts_prefix = 'sparrow'
21km = 1e3
22COLOR_PLATES = (0.1, 0.0, .0)
25def plates_to_points(plates):
26 num_all_nodes = 0
27 for plate in plates:
28 num_all_nodes = num_all_nodes + len(plate.points)
29 coords = num.zeros((num_all_nodes, 3))
30 x = []
31 y = []
33 for plate in plates:
34 num_nodes = len(plate.points)
35 for i in range(0, num_nodes):
36 x.append(plate.points[i][0])
37 y.append(plate.points[i][1])
38 for i in range(0, num_all_nodes):
39 coords[i, :] = x[i], y[i], -10*km
40 station_table = table.Table()
42 station_table.add_col(('coords', '', ('lat', 'lon', 'depth')), coords)
44 return geometry.latlondepth2xyz(
45 station_table.get_col('coords'),
46 planetradius=cake.earthradius)
49def plates_to_color(plates):
50 colors = []
51 colors_iter_map = iter(cm.terrain(num.linspace(0, 1, len(plates))))
52 for plate in plates:
53 color = next(colors_iter_map)
54 colors.append(color)
55 return num.array(colors)
58class PlatesBoundsState(ElementState):
59 visible = Bool.T(default=True)
60 opacity = Float.T(default=1.0)
61 color_by_slip_type = Bool.T(default=False)
62 lines = Bool.T(default=True)
64 def create(self):
65 element = PlatesBoundsElement()
66 return element
69class PlatelinesPipe(object):
70 def __init__(self, plates=None):
72 self.mapper = vtk.vtkDataSetMapper()
73 self._polyline_grid = {}
74 self._opacity = 1.0
75 self.plates = plates
77 actor = vtk.vtkActor()
78 actor.SetMapper(self.mapper)
80 prop = actor.GetProperty()
81 prop.SetDiffuseColor(1, 1, 1)
83 self.prop = prop
84 self.actor = actor
86 def plate_to_lines(self, plate):
87 lines = []
88 poly = []
89 num_nodes = len(plate.points)
90 for i in range(0, num_nodes):
91 poly.append((plate.points[i][0], plate.points[i][1]))
92 lines.append(num.asarray(poly))
94 self._polyline_grid[0] = vtk_util.make_multi_polyline(
95 lines_latlon=lines, depth=-100.)
96 vtk_util.vtk_set_input(self.mapper, self._polyline_grid[0])
98 def set_opacity(self, opacity):
99 opacity = float(opacity)
100 if self._opacity != opacity:
101 self.prop.SetOpacity(opacity)
102 self._opacity = opacity
105class PlatesBoundsElement(Element):
107 def __init__(self):
108 Element.__init__(self)
109 self._parent = None
110 self._state = None
111 self._pipe = None
112 self._controls = None
113 self._plates = None
114 self._listeners = []
115 self._plate_line = None
116 self._plate_lines = []
118 def bind_state(self, state):
119 Element.bind_state(self, state)
120 for var in ['visible', 'opacity']:
121 self.register_state_listener3(self.update, state, var)
123 def unbind_state(self):
124 self._listerners = []
126 def get_name(self):
127 return 'Plate bounds'
129 def set_parent(self, parent):
130 self._parent = parent
131 if not self._plates:
132 PB = PeterBird2003()
133 self._plates = PB.get_plates()
135 self._parent.add_panel(
136 self.get_name(),
137 self._get_controls(),
138 visible=True,
139 title_controls=[
140 self.get_title_control_remove(),
141 self.get_title_control_visible()])
143 self.update()
145 def unset_parent(self):
146 self.unbind_state()
147 if self._plate_lines:
148 for i, plate in enumerate(self._plate_lines):
149 self._parent.remove_actor(plate.actor)
151 self._pipe = None
153 if self._controls:
154 self._parent.remove_panel(self._controls)
155 self._controls = None
157 self._parent.update_view()
158 self._parent = None
160 def update(self, *args):
162 state = self._state
163 if state.visible:
164 colors = plates_to_color(self._plates)
165 for i, plate in enumerate(self._plates):
166 self._plate_line = PlatelinesPipe(plates=plate)
167 self._plate_line.plate_to_lines(plate)
168 self._parent.add_actor(self._plate_line.actor)
169 prop = self._plate_line.actor.GetProperty()
170 prop.SetDiffuseColor(colors[i][0:3])
171 self._plate_line.set_opacity(state.opacity)
172 self._plate_lines.append(self._plate_line)
173 if not state.visible and self._plate_lines:
174 for i, plate in enumerate(self._plate_lines):
175 self._parent.remove_actor(plate.actor)
177 self._parent.update_view()
179 def _get_controls(self):
180 if self._controls is None:
181 from ..state import state_bind_slider
183 frame = qw.QFrame()
184 layout = qw.QGridLayout()
185 layout.setAlignment(qc.Qt.AlignTop)
186 frame.setLayout(layout)
188 layout.addWidget(qw.QLabel('Opacity'), 0, 0)
190 slider = qw.QSlider(qc.Qt.Horizontal)
191 slider.setSizePolicy(
192 qw.QSizePolicy(
193 qw.QSizePolicy.Expanding, qw.QSizePolicy.Fixed))
194 slider.setMinimum(0)
195 slider.setMaximum(10)
196 slider.setSingleStep(1)
197 slider.setPageStep(1)
198 layout.addWidget(slider, 0, 1)
199 state_bind_slider(self, self._state, 'opacity', slider)
201 layout.addWidget(qw.QFrame(), 1, 0, 1, 2)
203 self._controls = frame
205 return self._controls
208__all__ = [
209 'PlatesBoundsElement',
210 'PlatesBoundsState'
211]