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

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

import numpy as num

import vtk

from pyrocko import util, plot
from pyrocko.guts import Bool, Float
from pyrocko.gui.qt_compat import qw
from pyrocko.color import Color


from pyrocko.gui import vtk_util
from .base import Element, ElementState
from .. import common
from pyrocko.geometry import r2d, d2r

km = 1000.

guts_prefix = 'sparrow'


def nice_value_circle(step):
    step = plot.nice_value(step)
    if step > 30.:
        return 30.

    return step


def ticks(vmin, vmax, vstep):
    vmin = num.floor(vmin / vstep) * vstep
    vmax = num.ceil(vmax / vstep) * vstep
    n = int(round((vmax - vmin) / vstep))
    return vmin + num.arange(n+1) * vstep


class LatLonGrid(object):
    def __init__(self, r, step_major, step_minor, lat, lon, delta, depth):

        lat_min, lat_max, lon_min, lon_max, lon_closed = common.cover_region(
            lat, lon, delta, step_major, avoid_poles=True)

        if delta < 30.:
            step_major_lon = nice_value_circle(step_major/num.cos(lat*d2r))
        else:
            step_major_lon = step_major

        lat_majors = ticks(lat_min, lat_max, step_major)
        lon_majors = ticks(lon_min, lon_max, step_major_lon)

        lat_minors = util.arange2(lat_min, lat_max, step_minor)

        if lon_closed:
            lon_minors = util.arange2(-180., 180., step_minor)
        else:
            lon_minors = util.arange2(lon_min, lon_max, step_minor)

        lines = []
        for lat_major in lat_majors:
            points = num.zeros((lon_minors.size, 2))
            points[:, 0] = lat_major
            points[:, 1] = lon_minors
            lines.append(points)

        for lon_major in lon_majors:
            points = num.zeros((lat_minors.size, 2))
            points[:, 0] = lat_minors
            points[:, 1] = lon_major
            lines.append(points)

        polyline_grid = vtk_util.make_multi_polyline(
            lines_latlon=lines, depth=depth)

        mapper = vtk.vtkDataSetMapper()
        vtk_util.vtk_set_input(mapper, polyline_grid)

        actor = vtk.vtkActor()
        actor.SetMapper(mapper)

        prop = actor.GetProperty()
        self.prop = prop

        prop.SetOpacity(0.15)

        self._color = None
        self.set_color(Color('white'))

        self.actor = actor

    def set_color(self, color):
        if self._color is None or self._color != color:
            self.prop.SetDiffuseColor(color.rgb)
            self._color = color


[docs]class GridState(ElementState): visible = Bool.T(default=True) color = Color.T(default=Color.D('white')) depth = Float.T(default=-1.0*km) def create(self): element = GridElement() return element
class GridElement(Element): def __init__(self): Element.__init__(self) self._controls = None self._grid = None self._stepsizes = self.get_stepsizes(10.) def get_name(self): return 'Grid' def bind_state(self, state): Element.bind_state(self, state) self.talkie_connect(state, ['visible', 'color', 'depth'], self.update) def set_parent(self, parent): Element.set_parent(self, 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, ['distance', 'lat', 'lon'], self.update) self.update() def unset_parent(self): self.unbind_state() if self._parent: if self._grid: self._parent.remove_actor(self._grid.actor) self._grid = None if self._controls: self._parent.remove_panel(self._controls) self._controls = None self._parent.update_view() self._parent = None def get_stepsizes(self, distance): factor = 10. step_major = nice_value_circle(min(10.0, factor * distance)) step_minor = min(1.0, step_major) return step_major, step_minor def update(self, *args): state = self._state pstate = self._parent.state stepsizes = self.get_stepsizes(pstate.distance) if self._grid: self._parent.remove_actor(self._grid.actor) self._grid = None if state.visible and not self._grid: delta = pstate.distance * r2d * 0.5 self._grid = LatLonGrid( 1.0, stepsizes[0], stepsizes[1], pstate.lat, pstate.lon, delta, state.depth) self._parent.add_actor(self._grid.actor) if self._grid: self._grid.set_color(state.color) self._parent.update_view() def _get_controls(self): if not self._controls: from ..state import state_bind_combobox_color, \ state_bind_lineedit frame = qw.QFrame() layout = qw.QGridLayout() frame.setLayout(layout) # color layout.addWidget(qw.QLabel('Color'), 0, 0) cb = common.strings_to_combobox( ['black', 'white']) layout.addWidget(cb, 0, 1) state_bind_combobox_color(self, self._state, 'color', cb) layout.addWidget(qw.QLabel('Depth [km]'), 1, 0) le = qw.QLineEdit() layout.addWidget(le, 1, 1) state_bind_lineedit( self, self._state, 'depth', le, from_string=lambda s: float(s)*1000., to_string=lambda v: str(v/1000.)) layout.addWidget(qw.QFrame(), 2, 0, 1, 2) self._controls = frame return self._controls __all__ = [ 'GridElement', 'GridState']