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.volcanoes import Volcanoes
15from pyrocko.gui.vtk_util import ScatterPipe
17from .base import Element, ElementState
19guts_prefix = 'sparrow'
21km = 1e3
22COLOR_HOLOCENE = (0.98, 0.26, .32)
23COLOR_PLEISTOCENE = (1., .41, .28)
26def volcanoes_to_points(volcanoes):
27 coords = num.zeros((len(volcanoes), 3))
29 for i, v in enumerate(volcanoes):
30 coords[i, :] = v.lat, v.lon, -v.elevation - 10*km
32 station_table = table.Table()
34 station_table.add_col(('coords', '', ('lat', 'lon', 'depth')), coords)
36 return geometry.latlondepth2xyz(
37 station_table.get_col('coords'),
38 planetradius=cake.earthradius)
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)
51class VolcanoesState(ElementState):
52 visible = Bool.T(default=True)
53 size = Float.T(default=3.0)
55 def create(self):
56 element = VolcanoesElement()
57 return element
60class VolcanoesElement(Element):
62 def __init__(self):
63 Element.__init__(self)
64 self._pipe = None
65 self._controls = None
66 self._volcanoes = None
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)
73 def get_name(self):
74 return 'Volcanoes'
76 def set_parent(self, parent):
77 self._parent = parent
78 if not self._volcanoes:
79 self._volcanoes = Volcanoes()
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()])
89 self.update()
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
98 self._parent.remove_panel(self._controls)
99 self._controls = None
101 self._parent.update_view()
102 self._parent = None
104 def update(self, *args):
105 state = self._state
107 if state.visible:
108 if self._pipe is None:
109 points = volcanoes_to_points(self._volcanoes.volcanoes)
110 self._pipe = ScatterPipe(points)
112 colors = volcanoes_to_color(self._volcanoes.volcanoes)
113 self._pipe.set_colors(colors)
115 self._pipe.set_size(state.size)
116 self._pipe.set_symbol('sphere')
117 self._parent.add_actor(self._pipe.actor)
119 else:
120 self._parent.remove_actor(self._pipe.actor)
122 self._parent.update_view()
124 def _get_controls(self):
125 if not self._controls:
126 from ..state import state_bind_slider
128 frame = qw.QFrame()
129 layout = qw.QGridLayout()
130 frame.setLayout(layout)
132 layout.addWidget(qw.QLabel('Size'), 0, 0)
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)
145 layout.addWidget(qw.QFrame(), 1, 0, 1, 2)
147 self._controls = frame
149 return self._controls
152__all__ = [
153 'VolcanoesElement',
154 'VolcanoesState'
155]