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 for var in ['visible', 'size']:
69 self.register_state_listener3(self.update, state, var)
71 def get_name(self):
72 return 'Volcanoes'
74 def set_parent(self, parent):
75 self._parent = parent
76 if not self._volcanoes:
77 self._volcanoes = Volcanoes()
79 self._parent.add_panel(
80 self.get_name(),
81 self._get_controls(),
82 visible=True,
83 title_controls=[
84 self.get_title_control_remove(),
85 self.get_title_control_visible()])
87 self.update()
89 def unset_parent(self):
90 self.unbind_state()
91 if not self._parent:
92 return
93 self._parent.remove_actor(self._pipe.actor)
94 self._pipe = None
96 self._parent.remove_panel(self._controls)
97 self._controls = None
99 self._parent.update_view()
100 self._parent = None
102 def update(self, *args):
103 state = self._state
105 if state.visible:
106 if self._pipe is None:
107 points = volcanoes_to_points(self._volcanoes.volcanoes)
108 self._pipe = ScatterPipe(points)
110 colors = volcanoes_to_color(self._volcanoes.volcanoes)
111 self._pipe.set_colors(colors)
113 self._pipe.set_size(state.size)
114 self._pipe.set_symbol('sphere')
115 self._parent.add_actor(self._pipe.actor)
117 else:
118 self._parent.remove_actor(self._pipe.actor)
120 self._parent.update_view()
122 def _get_controls(self):
123 if not self._controls:
124 from ..state import state_bind_slider
126 frame = qw.QFrame()
127 layout = qw.QGridLayout()
128 frame.setLayout(layout)
130 layout.addWidget(qw.QLabel('Size'), 0, 0)
132 slider = qw.QSlider(qc.Qt.Horizontal)
133 slider.setSizePolicy(
134 qw.QSizePolicy(
135 qw.QSizePolicy.Expanding, qw.QSizePolicy.Fixed))
136 slider.setMinimum(0)
137 slider.setMaximum(10)
138 slider.setSingleStep(1)
139 slider.setPageStep(1)
140 layout.addWidget(slider, 0, 1)
141 state_bind_slider(self, self._state, 'size', slider)
143 layout.addWidget(qw.QFrame(), 1, 0, 1, 2)
145 self._controls = frame
147 return self._controls
150__all__ = [
151 'VolcanoesElement',
152 'VolcanoesState'
153]