1# https://pyrocko.org - GPLv3
2#
3# The Pyrocko Developers, 21st Century
4# ---|P------/S----------~Lg----------
6from __future__ import absolute_import, print_function, division
8import numpy as num
10from pyrocko import table, geometry, cake
11from pyrocko.guts import Bool, Float
12from pyrocko.gui.qt_compat import qw, qc
14from pyrocko.dataset.tectonics import PeterBird2003
15from pyrocko.gui import vtk_util
16import vtk
17from matplotlib.pyplot import cm
19from .base import Element, ElementState
21guts_prefix = 'sparrow'
23km = 1e3
24COLOR_PLATES = (0.1, 0.0, .0)
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 = []
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()
44 station_table.add_col(('coords', '', ('lat', 'lon', 'depth')), coords)
46 return geometry.latlondepth2xyz(
47 station_table.get_col('coords'),
48 planetradius=cake.earthradius)
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)
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)
66 def create(self):
67 element = PlatesBoundsElement()
68 return element
71class PlatelinesPipe(object):
72 def __init__(self, plates=None):
74 self.mapper = vtk.vtkDataSetMapper()
75 self._polyline_grid = {}
76 self._opacity = 1.0
77 self.plates = plates
79 actor = vtk.vtkActor()
80 actor.SetMapper(self.mapper)
82 prop = actor.GetProperty()
83 prop.SetDiffuseColor(1, 1, 1)
85 self.prop = prop
86 self.actor = actor
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))
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])
100 def set_opacity(self, opacity):
101 opacity = float(opacity)
102 if self._opacity != opacity:
103 self.prop.SetOpacity(opacity)
104 self._opacity = opacity
107class PlatesBoundsElement(Element):
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 = []
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)
125 def unbind_state(self):
126 self._listerners = []
128 def get_name(self):
129 return 'Plate bounds'
131 def set_parent(self, parent):
132 self._parent = parent
133 if not self._plates:
134 PB = PeterBird2003()
135 self._plates = PB.get_plates()
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()])
145 self.update()
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)
153 self._pipe = None
155 if self._controls:
156 self._parent.remove_panel(self._controls)
157 self._controls = None
159 self._parent.update_view()
160 self._parent = None
162 def update(self, *args):
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)
179 self._parent.update_view()
181 def _get_controls(self):
182 if self._controls is None:
183 from ..state import state_bind_slider
185 frame = qw.QFrame()
186 layout = qw.QGridLayout()
187 layout.setAlignment(qc.Qt.AlignTop)
188 frame.setLayout(layout)
190 layout.addWidget(qw.QLabel('Opacity'), 0, 0)
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)
203 layout.addWidget(qw.QFrame(), 1, 0, 1, 2)
205 self._controls = frame
207 return self._controls
210__all__ = [
211 'PlatesBoundsElement',
212 'PlatesBoundsState'
213]