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.volcanoes import Volcanoes
13from pyrocko.gui.vtk_util import ScatterPipe
15from .base import Element, ElementState
17guts_prefix = 'sparrow'
19km = 1e3
20COLOR_HOLOCENE = (0.98, 0.26, .32)
21COLOR_PLEISTOCENE = (1., .41, .28)
24def volcanoes_to_points(volcanoes):
25 coords = num.zeros((len(volcanoes), 3))
27 for i, v in enumerate(volcanoes):
28 coords[i, :] = v.lat, v.lon, -v.elevation - 10*km
30 station_table = table.Table()
32 station_table.add_col(('coords', '', ('lat', 'lon', 'depth')), coords)
34 return geometry.latlondepth2xyz(
35 station_table.get_col('coords'),
36 planetradius=cake.earthradius)
39def volcanoes_to_color(volcanoes):
40 colors = []
41 for v in volcanoes:
42 if v.age == 'holocene':
43 colors.append(COLOR_HOLOCENE)
44 else:
45 colors.append(COLOR_PLEISTOCENE)
46 return num.array(colors)
49class VolcanoesState(ElementState):
50 visible = Bool.T(default=True)
51 size = Float.T(default=3.0)
53 def create(self):
54 element = VolcanoesElement()
55 return element
58class VolcanoesElement(Element):
60 def __init__(self):
61 Element.__init__(self)
62 self._pipe = None
63 self._controls = None
64 self._volcanoes = None
66 def bind_state(self, state):
67 Element.bind_state(self, state)
68 self.talkie_connect(state, ['visible', 'size'], self.update)
70 def get_name(self):
71 return 'Volcanoes'
73 def set_parent(self, parent):
74 self._parent = parent
75 if not self._volcanoes:
76 self._volcanoes = Volcanoes()
78 self._parent.add_panel(
79 self.get_title_label(),
80 self._get_controls(),
81 visible=True,
82 title_controls=[
83 self.get_title_control_remove(),
84 self.get_title_control_visible()])
86 self.update()
88 def unset_parent(self):
89 self.unbind_state()
90 if not self._parent:
91 return
92 self._parent.remove_actor(self._pipe.actor)
93 self._pipe = None
95 self._parent.remove_panel(self._controls)
96 self._controls = None
98 self._parent.update_view()
99 self._parent = None
101 def update(self, *args):
102 state = self._state
104 if state.visible:
105 if self._pipe is None:
106 points = volcanoes_to_points(self._volcanoes.volcanoes)
107 self._pipe = ScatterPipe(points)
109 colors = volcanoes_to_color(self._volcanoes.volcanoes)
110 self._pipe.set_colors(colors)
112 self._pipe.set_size(state.size)
113 self._pipe.set_symbol('sphere')
114 self._parent.add_actor(self._pipe.actor)
116 else:
117 self._parent.remove_actor(self._pipe.actor)
119 self._parent.update_view()
121 def _get_controls(self):
122 if not self._controls:
123 from ..state import state_bind_slider
125 frame = qw.QFrame()
126 layout = qw.QGridLayout()
127 frame.setLayout(layout)
129 layout.addWidget(qw.QLabel('Size'), 0, 0)
131 slider = qw.QSlider(qc.Qt.Horizontal)
132 slider.setSizePolicy(
133 qw.QSizePolicy(
134 qw.QSizePolicy.Expanding, qw.QSizePolicy.Fixed))
135 slider.setMinimum(0)
136 slider.setMaximum(10)
137 slider.setSingleStep(1)
138 slider.setPageStep(1)
139 layout.addWidget(slider, 0, 1)
140 state_bind_slider(self, self._state, 'size', slider)
142 layout.addWidget(qw.QFrame(), 1, 0, 1, 2)
144 self._controls = frame
146 return self._controls
149__all__ = [
150 'VolcanoesElement',
151 'VolcanoesState'
152]