2019-09-21 17:42:49 +08:00

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)
####################################################