mirror of
https://github.com/meteoinfo/MeteoInfo.git
synced 2025-12-08 20:36:05 +00:00
232 lines
8.2 KiB
Python
232 lines
8.2 KiB
Python
# coding=utf-8
|
|
#-----------------------------------------------------
|
|
# Author: Yaqiang Wang
|
|
# Date: 2019-9-4
|
|
# Purpose: MeteoInfoLab axes3dgl module - using JOGL
|
|
# Note: Jython
|
|
#-----------------------------------------------------
|
|
|
|
from org.meteoinfo.chart.plot import GraphicFactory
|
|
from org.meteoinfo.legend import BreakTypes, LegendManage
|
|
from org.meteoinfo.layer import LayerTypes
|
|
from org.meteoinfo.shape import ShapeTypes
|
|
from org.meteoinfo.chart.jogl import Plot3DGL, GLForm, JOGLUtil
|
|
from javax.swing import WindowConstants
|
|
from java.awt import Font, Color, BasicStroke
|
|
|
|
import plotutil
|
|
from axes3d import Axes3D
|
|
|
|
class Axes3DGL(Axes3D):
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
axes = kwargs.pop('axes', None)
|
|
self._set_plot(axes)
|
|
|
|
figure = kwargs.pop('figure', None)
|
|
self.figure = figure
|
|
|
|
if len(args) > 0:
|
|
position = args[0]
|
|
else:
|
|
position = kwargs.pop('position', None)
|
|
outerposition = kwargs.pop('outerposition', None)
|
|
if position is None:
|
|
position = [0.13, 0.11, 0.71, 0.815]
|
|
self.active_outerposition(True)
|
|
else:
|
|
self.active_outerposition(False)
|
|
self.set_position(position)
|
|
if not outerposition is None:
|
|
self.set_outerposition(outerposition)
|
|
self.active_outerposition(True)
|
|
units = kwargs.pop('units', None)
|
|
if not units is None:
|
|
self.axes.setUnits(units)
|
|
tickfontname = kwargs.pop('tickfontname', 'Arial')
|
|
tickfontsize = kwargs.pop('tickfontsize', 14)
|
|
tickbold = kwargs.pop('tickbold', False)
|
|
if tickbold:
|
|
font = Font(tickfontname, Font.BOLD, tickfontsize)
|
|
else:
|
|
font = Font(tickfontname, Font.PLAIN, tickfontsize)
|
|
self.axes.setAxisTickFont(font)
|
|
|
|
def _set_plot(self, plot):
|
|
'''
|
|
Set plot.
|
|
|
|
:param plot: (*Axes3D*) Plot.
|
|
'''
|
|
if plot is None:
|
|
self.axes = Plot3DGL()
|
|
else:
|
|
self.axes = plot
|
|
|
|
@property
|
|
def axestype(self):
|
|
return '3d'
|
|
|
|
def get_rotation(self):
|
|
'''
|
|
Get rotation angle.
|
|
|
|
:returns: Rotation angle.
|
|
'''
|
|
return self.axes.getAngleY()
|
|
|
|
def set_rotation(self, rotation):
|
|
'''
|
|
Set rotation angle.
|
|
|
|
:param rotation: (*float*) Rotation angle.
|
|
'''
|
|
self.axes.setAngleY(rotation)
|
|
|
|
def get_elevation(self):
|
|
'''
|
|
Get elevation angle.
|
|
|
|
:returns: Elevation angle.
|
|
'''
|
|
return self.axes.getAngleX()
|
|
|
|
def set_elevation(self, elevation):
|
|
'''
|
|
Set elevation angle.
|
|
|
|
:param elevation: (*float*) Elevation angle.
|
|
'''
|
|
self.axes.setAngleX(elevation)
|
|
|
|
def set_lighting(self, enable, **kwargs):
|
|
'''
|
|
Set lighting.
|
|
|
|
:param enable: (*boolean*) Set lighting enable or not.
|
|
:param position: (*list of float*) Lighting position.
|
|
:param ambient: (*list of float*) Ambient light.
|
|
:param diffuse: (*list of float*) Diffuse light.
|
|
:param specular: (*list of float*) Specular light.
|
|
'''
|
|
lighting = self.axes.getLighting()
|
|
lighting.setEnable(enable)
|
|
position = kwargs.pop('position', None)
|
|
if not position is None:
|
|
lighting.setPosition(position)
|
|
ambient = kwargs.pop('ambient', None)
|
|
if not ambient is None:
|
|
lighting.setAmbient(ambient)
|
|
diffuse = kwargs.pop('diffuse', None)
|
|
if not diffuse is None:
|
|
lighting.setDiffuse(diffuse)
|
|
specular = kwargs.pop('specular', None)
|
|
if not specular is None:
|
|
lighting.setSpecular(specular)
|
|
|
|
def plot_layer(self, layer, **kwargs):
|
|
'''
|
|
Plot a layer in 3D axes.
|
|
|
|
:param layer: (*MILayer*) The layer to be plotted.
|
|
|
|
:returns: Graphics.
|
|
'''
|
|
ls = kwargs.pop('symbolspec', None)
|
|
offset = kwargs.pop('offset', 0)
|
|
xshift = kwargs.pop('xshift', 0)
|
|
layer = layer.layer
|
|
if layer.getLayerType() == LayerTypes.VectorLayer:
|
|
if ls is None:
|
|
ls = layer.getLegendScheme()
|
|
if len(kwargs) > 0 and layer.getLegendScheme().getBreakNum() == 1:
|
|
lb = layer.getLegendScheme().getLegendBreaks().get(0)
|
|
btype = lb.getBreakType()
|
|
geometry = 'point'
|
|
if btype == BreakTypes.PolylineBreak:
|
|
geometry = 'line'
|
|
elif btype == BreakTypes.PolygonBreak:
|
|
geometry = 'polygon'
|
|
lb, isunique = plotutil.getlegendbreak(geometry, **kwargs)
|
|
ls.getLegendBreaks().set(0, lb)
|
|
|
|
plotutil.setlegendscheme(ls, **kwargs)
|
|
layer.setLegendScheme(ls)
|
|
graphics = GraphicFactory.createGraphicsFromLayer(layer, offset, xshift)
|
|
else:
|
|
interpolation = kwargs.pop('interpolation', None)
|
|
graphics = JOGLUtil.createTexture(self.figure.getGL2(), layer, offset, xshift, interpolation)
|
|
|
|
visible = kwargs.pop('visible', True)
|
|
if visible:
|
|
self.add_graphic(graphics)
|
|
return graphics
|
|
|
|
def plot_isosurface(self, *args, **kwargs):
|
|
'''
|
|
creates a three-dimensional isosurface plot
|
|
|
|
:param x: (*array_like*) Optional. X coordinate array.
|
|
:param y: (*array_like*) Optional. Y coordinate array.
|
|
:param z: (*array_like*) Optional. Z coordinate array.
|
|
:param data: (*array_like*) 3D data array.
|
|
:param cmap: (*string*) Color map string.
|
|
:param xyaxis: (*boolean*) Draw x and y axis or not.
|
|
:param zaxis: (*boolean*) Draw z axis or not.
|
|
:param grid: (*boolean*) Draw grid or not.
|
|
:param boxed: (*boolean*) Draw boxed or not.
|
|
:param mesh: (*boolean*) Draw mesh line or not.
|
|
|
|
:returns: Legend
|
|
'''
|
|
if len(args) <= 3:
|
|
x = args[0].dimvalue(2)
|
|
y = args[0].dimvalue(1)
|
|
z = args[0].dimvalue(0)
|
|
data = args[0]
|
|
isovalue = args[1]
|
|
args = args[2:]
|
|
else:
|
|
x = args[0]
|
|
y = args[1]
|
|
z = args[2]
|
|
data = args[3]
|
|
isovalue = args[4]
|
|
args = args[5:]
|
|
cmap = plotutil.getcolormap(**kwargs)
|
|
cvalue = kwargs.pop('cvalue', None)
|
|
if not cvalue is None:
|
|
if len(args) > 0:
|
|
level_arg = args[0]
|
|
if isinstance(level_arg, int):
|
|
cn = level_arg
|
|
ls = LegendManage.createLegendScheme(data.min(), data.max(), cn, cmap)
|
|
else:
|
|
if isinstance(level_arg, NDArray):
|
|
level_arg = level_arg.aslist()
|
|
ls = LegendManage.createLegendScheme(data.min(), data.max(), level_arg, cmap)
|
|
else:
|
|
ls = LegendManage.createLegendScheme(data.min(), data.max(), cmap)
|
|
ls = ls.convertTo(ShapeTypes.Polygon)
|
|
edge = kwargs.pop('edge', True)
|
|
kwargs['edge'] = edge
|
|
plotutil.setlegendscheme(ls, **kwargs)
|
|
else:
|
|
ls = plotutil.getlegendbreak('polygon', **kwargs)[0]
|
|
graphics = JOGLUtil.isosurface(data.asarray(), x.asarray(), y.asarray(), z.asarray(), isovalue, ls)
|
|
visible = kwargs.pop('visible', True)
|
|
if visible:
|
|
self.add_graphic(graphics)
|
|
return graphics
|
|
|
|
def view(self):
|
|
'''
|
|
Open GLForm
|
|
'''
|
|
form = GLForm(self.axes)
|
|
form.setSize(600, 500)
|
|
form.setLocationRelativeTo(None)
|
|
form.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE)
|
|
form.setVisible(True)
|
|
|
|
#################################################### |