mirror of
https://github.com/meteoinfo/MeteoInfo.git
synced 2025-12-08 20:36:05 +00:00
add Wedge patch
This commit is contained in:
parent
44d08ee8d1
commit
8c32998bec
@ -1049,8 +1049,8 @@ public class Plot2D extends AbstractPlot2D {
|
||||
double height = this.projYLength(extent.getHeight(), area);
|
||||
Float wedgeWidth = aShape.getWedgeWidth();
|
||||
if (wedgeWidth == null) {
|
||||
Draw.drawPie(new PointF((float)x, (float)y),
|
||||
(float) width, (float) height, startAngle, sweepAngle, aPGB, g);
|
||||
Draw.drawArc(new PointF((float)x, (float)y),
|
||||
(float) width, (float) height, startAngle, sweepAngle, aPGB, g, aShape.getClosure());
|
||||
} else {
|
||||
wedgeWidth = (float)this.projXLength(wedgeWidth, area);
|
||||
Draw.drawPie(new PointF((float)x, (float)y),
|
||||
|
||||
@ -2495,8 +2495,7 @@ public class Draw {
|
||||
break;
|
||||
case ARC:
|
||||
ArcShape arcShape = (ArcShape) aGraphic.getShape();
|
||||
drawArc(points, arcShape.getAngle(), arcShape.getStartAngle(), arcShape.getSweepAngle(),
|
||||
(PolygonBreak) aGraphic.getLegend(), g);
|
||||
drawArc(points, arcShape, (PolygonBreak) aGraphic.getLegend(), g);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -3943,6 +3942,32 @@ public class Draw {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw arc
|
||||
*
|
||||
* @param aPoint Start point
|
||||
* @param width Width
|
||||
* @param height Height
|
||||
* @param startAngle Start angle
|
||||
* @param sweepAngle Sweep angle
|
||||
* @param aPGB Polygon break
|
||||
* @param g Graphics2D
|
||||
* @param type Closure type
|
||||
*/
|
||||
public static void drawArc(PointF aPoint, float width, float height, float startAngle, float sweepAngle,
|
||||
PolygonBreak aPGB, Graphics2D g, int type) {
|
||||
Color aColor = aPGB.getColor();
|
||||
if (aPGB.isDrawFill()) {
|
||||
g.setColor(aColor);
|
||||
g.fill(new Arc2D.Float(aPoint.X, aPoint.Y, width, height, startAngle, sweepAngle, type));
|
||||
}
|
||||
if (aPGB.isDrawOutline()) {
|
||||
g.setColor(aPGB.getOutlineColor());
|
||||
g.setStroke(new BasicStroke(aPGB.getOutlineSize()));
|
||||
g.draw(new Arc2D.Float(aPoint.X, aPoint.Y, width, height, startAngle, sweepAngle, type));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw pie
|
||||
*
|
||||
@ -4215,6 +4240,74 @@ public class Draw {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw Arc
|
||||
*
|
||||
* @param points The points
|
||||
* @param angle The angle
|
||||
* @param startAngle Arc start angle
|
||||
* @param sweepAngle Arc sweep angle
|
||||
* @param aPGB The polygon break
|
||||
* @param g Graphics2D
|
||||
* @param type Closure type
|
||||
*/
|
||||
public static void drawArc(PointF[] points, float angle, float startAngle, float sweepAngle,
|
||||
PolygonBreak aPGB, Graphics2D g, int type) {
|
||||
float sx = Math.min(points[0].X, points[2].X);
|
||||
float sy = Math.min(points[0].Y, points[2].Y);
|
||||
float width = Math.abs(points[2].X - points[0].X);
|
||||
float height = Math.abs(points[2].Y - points[0].Y);
|
||||
|
||||
if (angle != 0) {
|
||||
AffineTransform tempTrans = g.getTransform();
|
||||
AffineTransform myTrans = (AffineTransform) tempTrans.clone();
|
||||
myTrans.translate(sx + width / 2, sy + height / 2);
|
||||
g.setTransform(myTrans);
|
||||
|
||||
Draw.drawArc(new PointF((float)sx, (float)sy),
|
||||
(float) width, (float) height, startAngle, sweepAngle, aPGB, g, type);
|
||||
|
||||
g.setTransform(tempTrans);
|
||||
} else {
|
||||
Draw.drawArc(new PointF((float)sx, (float)sy),
|
||||
(float) width, (float) height, startAngle, sweepAngle, aPGB, g, type);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw Arc
|
||||
*
|
||||
* @param points The points
|
||||
* @param angle The angle
|
||||
* @param startAngle Arc start angle
|
||||
* @param sweepAngle Arc sweep angle
|
||||
* @param aPGB The polygon break
|
||||
* @param g Graphics2D
|
||||
* @param type Closure type
|
||||
*/
|
||||
public static void drawArc(PointF[] points, ArcShape arcShape,
|
||||
PolygonBreak legend, Graphics2D g) {
|
||||
float sx = Math.min(points[0].X, points[2].X);
|
||||
float sy = Math.min(points[0].Y, points[2].Y);
|
||||
float width = Math.abs(points[2].X - points[0].X);
|
||||
float height = Math.abs(points[2].Y - points[0].Y);
|
||||
|
||||
if (arcShape.getAngle() != 0) {
|
||||
AffineTransform tempTrans = g.getTransform();
|
||||
AffineTransform myTrans = (AffineTransform) tempTrans.clone();
|
||||
myTrans.translate(sx + width / 2, sy + height / 2);
|
||||
g.setTransform(myTrans);
|
||||
|
||||
Draw.drawArc(new PointF((float)sx, (float)sy), (float) width, (float) height,
|
||||
arcShape.getStartAngle(), arcShape.getSweepAngle(), legend, g, arcShape.getClosure());
|
||||
|
||||
g.setTransform(tempTrans);
|
||||
} else {
|
||||
Draw.drawArc(new PointF((float)sx, (float)sy), (float) width, (float) height,
|
||||
arcShape.getStartAngle(), arcShape.getSweepAngle(), legend, g, arcShape.getClosure());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw selected vertices rectangles
|
||||
*
|
||||
|
||||
@ -1943,7 +1943,7 @@ public class DrawMeteoData {
|
||||
aPoint.X = xIter.getDoubleNext();
|
||||
aPoint.Y = yIter.getDoubleNext();
|
||||
v = iter.getDoubleNext();
|
||||
if (Double.isNaN(aPoint.X) || Double.isNaN(aPoint.Y)) {
|
||||
if (Double.isNaN(aPoint.X) || Double.isNaN(aPoint.Y) || Double.isNaN(v)) {
|
||||
continue;
|
||||
}
|
||||
PointShape aPointShape = new PointShape();
|
||||
|
||||
@ -383,6 +383,24 @@ public class GraphicCollection extends Graphic implements Iterator {
|
||||
*/
|
||||
public void addAll(List<Graphic> gs) {
|
||||
this.graphics.addAll(gs);
|
||||
|
||||
// Update extent
|
||||
int i = 0;
|
||||
Extent extent;
|
||||
for (Graphic g : gs) {
|
||||
if (g instanceof GraphicCollection) {
|
||||
extent = g.getExtent();
|
||||
} else {
|
||||
extent = g.getShape().getExtent();
|
||||
}
|
||||
if (i == 0) {
|
||||
_extent = extent;
|
||||
} else {
|
||||
_extent = MIMath.getLagerExtent(_extent, extent);
|
||||
}
|
||||
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -15,6 +15,7 @@ package org.meteoinfo.geometry.shape;
|
||||
|
||||
import org.meteoinfo.common.PointD;
|
||||
|
||||
import java.awt.geom.Arc2D;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@ -28,6 +29,7 @@ public class ArcShape extends EllipseShape {
|
||||
private float sweepAngle;
|
||||
private float explode = 0;
|
||||
private Float wedgeWidth = null;
|
||||
private int closure = Arc2D.PIE;
|
||||
// </editor-fold>
|
||||
// <editor-fold desc="Constructor">
|
||||
/**
|
||||
@ -122,6 +124,22 @@ public class ArcShape extends EllipseShape {
|
||||
public void setWedgeWidth(Float value) {
|
||||
this.wedgeWidth = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get closure type
|
||||
* @return Closure type
|
||||
*/
|
||||
public int getClosure() {
|
||||
return this.closure;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set closure type
|
||||
* @param value Closure type
|
||||
*/
|
||||
public void setClosure(int value) {
|
||||
this.closure = value;
|
||||
}
|
||||
// </editor-fold>
|
||||
// <editor-fold desc="Methods">
|
||||
|
||||
@ -166,6 +184,13 @@ public class ArcShape extends EllipseShape {
|
||||
aPGS.setPoints(new ArrayList<>(this.getPoints()));
|
||||
aPGS.setVisible(this.isVisible());
|
||||
aPGS.setSelected(this.isSelected());
|
||||
aPGS.setClosure(this.closure);
|
||||
aPGS.setExplode(this.explode);
|
||||
aPGS.setStartAngle(this.startAngle);
|
||||
aPGS.setSweepAngle(this.sweepAngle);
|
||||
aPGS.setAngle(this.angle);
|
||||
aPGS.setWedgeWidth(this.wedgeWidth);
|
||||
aPGS.setLegendIndex(this.getLegendIndex());
|
||||
|
||||
return aPGS;
|
||||
}
|
||||
|
||||
@ -1,34 +1,36 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<MeteoInfo File="milconfig.xml" Type="configurefile">
|
||||
<Path OpenPath="D:\Working\MIScript\Jython\mis\io\micaps">
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io\savefig"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\dataframe"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\contour"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\contour"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\streamplot"/>
|
||||
<Path OpenPath="D:\Working\MIScript\Jython\mis\plot_types\patch">
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\satellite"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\satellite\omi"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\wind"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\pie"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io\micaps"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\map\topology"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\array"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\plot"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io\radar"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\map"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\map\projection"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\surf"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\funny"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io\micaps"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\patch"/>
|
||||
</Path>
|
||||
<File>
|
||||
<OpenedFiles>
|
||||
<OpenedFile File="D:\MyProgram\java\MeteoInfoDev\toolbox\meteoview3d\_reload.py"/>
|
||||
<OpenedFile File="D:\MyProgram\java\MeteoInfoDev\toolbox\meteoview3d\mainGUI.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\contour\contour3_1.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\io\micaps\mdfs_dataframe_2.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\plot_types\patch\wind_circle_2.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\plot_types\patch\wind_circle_1.py"/>
|
||||
</OpenedFiles>
|
||||
<RecentFiles>
|
||||
<RecentFile File="D:\MyProgram\java\MeteoInfoDev\toolbox\meteoview3d\_reload.py"/>
|
||||
<RecentFile File="D:\MyProgram\java\MeteoInfoDev\toolbox\meteoview3d\mainGUI.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\contour\contour3_1.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\io\micaps\mdfs_dataframe_2.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\plot_types\patch\wind_circle_2.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\plot_types\patch\wind_circle_1.py"/>
|
||||
</RecentFiles>
|
||||
</File>
|
||||
<Font>
|
||||
@ -36,5 +38,5 @@
|
||||
</Font>
|
||||
<LookFeel DockWindowDecorated="true" LafDecorated="true" Name="FlatDarkLaf"/>
|
||||
<Figure DoubleBuffering="true"/>
|
||||
<Startup MainFormLocation="-7,0" MainFormSize="1399,787"/>
|
||||
<Startup MainFormLocation="-7,-7" MainFormSize="1293,685"/>
|
||||
</MeteoInfo>
|
||||
|
||||
Binary file not shown.
@ -1052,9 +1052,12 @@ class Axes(object):
|
||||
"""
|
||||
Add a patch.
|
||||
|
||||
:param patch: (*Graphic*) The patch to be added.
|
||||
:param patch: (*Graphic or list of graphics*) The patch(s) to be added.
|
||||
"""
|
||||
self._axes.addGraphic(patch)
|
||||
if isinstance(patch, (list, tuple)):
|
||||
self._axes.addGraphics(patch)
|
||||
else:
|
||||
self._axes.addGraphic(patch)
|
||||
self._axes.setAutoExtent()
|
||||
|
||||
def add_graphic(self, graphic, projection=None, zorder=None):
|
||||
|
||||
@ -5,7 +5,7 @@ from org.meteoinfo.geometry.shape import ShapeUtil, CircleShape, EllipseShape, \
|
||||
from . import plotutil
|
||||
import mipylib.numeric as np
|
||||
|
||||
__all__ = ['Arc','Circle','Ellipse','Rectangle','Polygon']
|
||||
__all__ = ['Arc','Circle','Ellipse','Rectangle','Polygon','Wedge']
|
||||
|
||||
class Circle(Graphic):
|
||||
"""
|
||||
@ -87,6 +87,7 @@ class Arc(Graphic):
|
||||
:param angle: (float) Ellipse angle. Default is `0`.
|
||||
:param theta1: (float) Starting angle of the arc in degrees. Default is `0.0`.
|
||||
:param theta2: (float) Ending angle of the arc in degrees. Default is `360`.
|
||||
:param closure: (str) Closure type ['open' | 'chord' | 'pie']. Default is `pie`.
|
||||
"""
|
||||
self._center = xy
|
||||
self._width = width
|
||||
@ -98,6 +99,19 @@ class Arc(Graphic):
|
||||
shape.setAngle(angle)
|
||||
shape.setStartAngle(theta1)
|
||||
shape.setSweepAngle(theta2 - theta1)
|
||||
self._closure = kwargs.pop('closure', None)
|
||||
if self._closure is None:
|
||||
self._closure = 'pie'
|
||||
else:
|
||||
if self._closure == 'open':
|
||||
closure = 0
|
||||
elif self._closure == 'chord':
|
||||
closure = 1
|
||||
else:
|
||||
self._closure = 'pie'
|
||||
closure = 2
|
||||
shape.setClosure(closure)
|
||||
|
||||
legend, isunique = plotutil.getlegendbreak('polygon', **kwargs)
|
||||
super(Arc, self).__init__(shape, legend)
|
||||
|
||||
@ -125,6 +139,71 @@ class Arc(Graphic):
|
||||
def theta2(self):
|
||||
return self._theta2
|
||||
|
||||
@property
|
||||
def closure(self):
|
||||
return self._closure
|
||||
|
||||
class Wedge(Graphic):
|
||||
"""
|
||||
Wedge shaped patch.
|
||||
|
||||
A wedge centered at x, y center with radius r that sweeps theta1 to theta2 (in degrees). If width is
|
||||
given, then a partial wedge is drawn from inner radius r - width to outer radius r.
|
||||
"""
|
||||
|
||||
def __init__(self, center, r, theta1, theta2, **kwargs):
|
||||
"""
|
||||
Create an arc at anchor point *xy* = (*x*, *y*) with given *width* and *height*.
|
||||
|
||||
:param center: (float, float) xy coordinates of wedge center point.
|
||||
:param r: (float) Radius.
|
||||
:param theta1: (float) Starting angle of the arc in degrees.
|
||||
:param theta2: (float) Ending angle of the arc in degrees.
|
||||
:param closure: (str) Closure type ['open' | 'chord' | 'pie']. Default is `pie`.
|
||||
"""
|
||||
self._center = center
|
||||
self._r = r
|
||||
self._theta1 = theta1
|
||||
self._theta2 = theta2
|
||||
shape = ArcShape(center[0], center[1], r * 2, r * 2)
|
||||
shape.setStartAngle(theta1)
|
||||
shape.setSweepAngle(theta2 - theta1)
|
||||
self._closure = kwargs.pop('closure', None)
|
||||
if self._closure is None:
|
||||
self._closure = 'pie'
|
||||
else:
|
||||
if self._closure == 'open':
|
||||
closure = 0
|
||||
elif self._closure == 'chord':
|
||||
closure = 1
|
||||
else:
|
||||
self._closure = 'pie'
|
||||
closure = 2
|
||||
shape.setClosure(closure)
|
||||
|
||||
legend, isunique = plotutil.getlegendbreak('polygon', **kwargs)
|
||||
super(Wedge, self).__init__(shape, legend)
|
||||
|
||||
@property
|
||||
def center(self):
|
||||
return self._center
|
||||
|
||||
@property
|
||||
def r(self):
|
||||
return self._r
|
||||
|
||||
@property
|
||||
def theta1(self):
|
||||
return self._theta1
|
||||
|
||||
@property
|
||||
def theta2(self):
|
||||
return self._theta2
|
||||
|
||||
@property
|
||||
def closure(self):
|
||||
return self._closure
|
||||
|
||||
class Rectangle(Graphic):
|
||||
"""
|
||||
A rectangle patch.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user