Source code for pyrocko.gui.sparrow.elements.coastlines

# https://pyrocko.org - GPLv3
#
# The Pyrocko Developers, 21st Century
# ---|P------/S----------~Lg----------

import numpy as num
import vtk

from pyrocko.guts import Bool, StringChoice, Float
from pyrocko.gui.qt_compat import qw, qc
from pyrocko.color import Color


from pyrocko.gui import vtk_util
from .. import common
from .base import Element, ElementState

guts_prefix = 'sparrow'


[docs]class CoastlineResolutionChoice(StringChoice): choices = [ 'crude', 'low', 'intermediate', 'high', 'full']
class CoastlinesPipe(object): def __init__(self, resolution='low'): self.mapper = vtk.vtkDataSetMapper() self.plane = vtk.vtkPlane() self.plane.SetOrigin(0.0, 0.0, 0.0) coll = vtk.vtkPlaneCollection() coll.AddItem(self.plane) self.mapper.SetClippingPlanes(coll) self._polyline_grid = {} self._opacity = 1.0 self._line_width = 1.0 self._color = Color('white') self.set_resolution(resolution) actor = vtk.vtkActor() actor.SetMapper(self.mapper) prop = actor.GetProperty() prop.SetDiffuseColor(1, 1, 1) self.prop = prop self.actor = actor def set_resolution(self, resolution): assert resolution in CoastlineResolutionChoice.choices if resolution not in self._polyline_grid: pb = common.get_viewer().progressbars if pb: mess = 'Loading %s resolution coastlines' % resolution pb.set_status(mess, 0, can_abort=False) from pyrocko.dataset.gshhg import GSHHG g = getattr(GSHHG, resolution)() lines = [] npoly = len(g.polygons) for ipoly, poly in enumerate(g.polygons): if pb: pb.set_status( mess, float(ipoly) / npoly * 100., can_abort=False) lines.append(poly.points) self._polyline_grid[resolution] = vtk_util.make_multi_polyline( lines_latlon=lines, depth=-200.) if pb: pb.set_status(mess, 100, can_abort=False) vtk_util.vtk_set_input(self.mapper, self._polyline_grid[resolution]) def set_opacity(self, opacity): opacity = float(opacity) if self._opacity != opacity: self.prop.SetOpacity(opacity) self._opacity = opacity def set_color(self, color): if self._color != color: self.prop.SetDiffuseColor(color.rgb) self._color = color def set_line_width(self, width): width = float(width) if self._line_width != width: self.prop.SetLineWidth(width) self._line_width = width def set_clipping_plane(self, origin, normal): self.plane.SetOrigin(*origin) self.plane.SetNormal(*normal)
[docs]class CoastlinesState(ElementState): visible = Bool.T(default=True) resolution = CoastlineResolutionChoice.T(default='low') opacity = Float.T(default=0.4) color = Color.T(default=Color.D('white')) line_width = Float.T(default=1.0) def create(self): element = CoastlinesElement() return element
class CoastlinesElement(Element): def __init__(self): Element.__init__(self) self._parent = None self._controls = None self._coastlines = None def get_name(self): return 'Coastlines' def bind_state(self, state): Element.bind_state(self, state) self.talkie_connect( state, ['visible', 'resolution', 'opacity', 'color', 'line_width'], self.update) def set_parent(self, parent): self._parent = parent self._parent.add_panel( self.get_title_label(), self._get_controls(), visible=True, title_controls=[ self.get_title_control_remove(), self.get_title_control_visible()]) self.talkie_connect( self._parent.state, ['lat', 'lon', 'depth', 'distance', 'azimuth', 'dip'], self.update_clipping) self.update() self.update_clipping() def unset_parent(self): self.unbind_state() if self._parent: if self._coastlines: self._parent.remove_actor(self._coastlines.actor) self._coastlines = None if self._controls: self._parent.remove_panel(self._controls) self._controls = None self._parent.update_view() self._parent = None def update(self, *args): state = self._state if not state.visible and self._coastlines: self._parent.remove_actor(self._coastlines.actor) if state.visible: if not self._coastlines: self._coastlines = CoastlinesPipe(resolution=state.resolution) self._parent.add_actor(self._coastlines.actor) self._coastlines.set_resolution(state.resolution) self._coastlines.set_opacity(state.opacity) self._coastlines.set_color(state.color) self._coastlines.set_line_width(state.line_width) self._parent.update_view() def update_clipping(self, *args): if self._state.visible and self._coastlines: cam = self._parent.camera_params[0] origin = cam / num.linalg.norm(cam)**2 self._coastlines.set_clipping_plane(origin, cam) def _get_controls(self): if not self._controls: from ..state import state_bind_combobox, \ state_bind_slider, state_bind_combobox_color frame = qw.QFrame() layout = qw.QGridLayout() frame.setLayout(layout) layout.addWidget(qw.QLabel('Resolution'), 0, 0) cb = common.string_choices_to_combobox(CoastlineResolutionChoice) layout.addWidget(cb, 0, 1) state_bind_combobox(self, self._state, 'resolution', cb) # opacity layout.addWidget(qw.QLabel('Opacity'), 1, 0) slider = qw.QSlider(qc.Qt.Horizontal) slider.setSizePolicy( qw.QSizePolicy( qw.QSizePolicy.Expanding, qw.QSizePolicy.Fixed)) slider.setMinimum(0) slider.setMaximum(1000) layout.addWidget(slider, 1, 1) state_bind_slider( self, self._state, 'opacity', slider, factor=0.001) # color layout.addWidget(qw.QLabel('Color'), 2, 0) cb = common.strings_to_combobox( ['black', 'white']) layout.addWidget(cb, 2, 1) state_bind_combobox_color( self, self._state, 'color', cb) layout.addWidget(qw.QLabel('Line width'), 3, 0) slider = qw.QSlider(qc.Qt.Horizontal) slider.setSizePolicy( qw.QSizePolicy( qw.QSizePolicy.Expanding, qw.QSizePolicy.Fixed)) slider.setMinimum(0) slider.setMaximum(100) layout.addWidget(slider, 3, 1) state_bind_slider( self, self._state, 'line_width', slider, factor=0.1) layout.addWidget(qw.QFrame(), 5, 0, 1, 2) self._controls = frame return self._controls __all__ = [ 'CoastlinesElement', 'CoastlinesState']