mirror of
https://github.com/meteoinfo/MeteoInfo.git
synced 2025-12-08 20:36:05 +00:00
270 lines
7.5 KiB
Python
270 lines
7.5 KiB
Python
from org.meteoinfo.geometry.graphic import Graphic
|
|
from org.meteoinfo.geometry.shape import ShapeUtil, CircleShape, EllipseShape, \
|
|
RectangleShape, ArcShape
|
|
|
|
from .. import plotutil
|
|
import mipylib.numeric as np
|
|
|
|
__all__ = ['Arc','Circle','Ellipse','Rectangle','Polygon','Wedge']
|
|
|
|
class Circle(Graphic):
|
|
"""
|
|
A circle patch.
|
|
"""
|
|
|
|
def __init__(self, xy, radius=5, **kwargs):
|
|
"""
|
|
Create a true circle at center *xy* = (*x*, *y*) with given *radius*.
|
|
|
|
:param xy: (float, float) xy coordinates of circle centre.
|
|
:param radius: (float) Circle radius.
|
|
"""
|
|
self._center = xy
|
|
self._radius = radius
|
|
shape = CircleShape(xy[0], xy[1], radius)
|
|
legend, isunique = plotutil.getlegendbreak('polygon', **kwargs)
|
|
super(Circle, self).__init__(shape, legend)
|
|
|
|
@property
|
|
def center(self):
|
|
return self._center
|
|
|
|
@property
|
|
def radius(self):
|
|
return self._radius
|
|
|
|
class Ellipse(Graphic):
|
|
"""
|
|
A ellipse patch.
|
|
"""
|
|
|
|
def __init__(self, xy, width, height, angle=0, **kwargs):
|
|
"""
|
|
Create an ellipse at center *xy* = (*x*, *y*) with given *width* and *height*.
|
|
|
|
:param xy: (float, float) xy coordinates of ellipse centre.
|
|
:param width: (float) Ellipse width.
|
|
:param height: (float) Ellipse height.
|
|
:param angle: (float) Ellipse angle. Default is 0.
|
|
"""
|
|
self._center = xy
|
|
self._width = width
|
|
self._height = height
|
|
self._angle = angle
|
|
shape = EllipseShape(xy[0], xy[1], width, height)
|
|
shape.setAngle(angle)
|
|
legend, isunique = plotutil.getlegendbreak('polygon', **kwargs)
|
|
super(Ellipse, self).__init__(shape, legend)
|
|
|
|
@property
|
|
def center(self):
|
|
return self._center
|
|
|
|
@property
|
|
def width(self):
|
|
return self._width
|
|
|
|
@property
|
|
def height(self):
|
|
return self._height
|
|
|
|
@property
|
|
def angle(self):
|
|
return self._angle
|
|
|
|
class Arc(Graphic):
|
|
"""
|
|
An Arc patch.
|
|
"""
|
|
|
|
def __init__(self, xy, width, height, angle=0, theta1=0.0, theta2=360.0, **kwargs):
|
|
"""
|
|
Create an arc at anchor point *xy* = (*x*, *y*) with given *width* and *height*.
|
|
|
|
:param xy: (float, float) xy coordinates of anchor point.
|
|
:param width: (float) Ellipse width.
|
|
:param height: (float) Ellipse height.
|
|
: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
|
|
self._height = height
|
|
self._angle = angle
|
|
self._theta1 = theta1
|
|
self._theta2 = theta2
|
|
shape = ArcShape(xy[0], xy[1], width, height)
|
|
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)
|
|
|
|
@property
|
|
def center(self):
|
|
return self._center
|
|
|
|
@property
|
|
def width(self):
|
|
return self._width
|
|
|
|
@property
|
|
def height(self):
|
|
return self._height
|
|
|
|
@property
|
|
def angle(self):
|
|
return self._angle
|
|
|
|
@property
|
|
def theta1(self):
|
|
return self._theta1
|
|
|
|
@property
|
|
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.
|
|
"""
|
|
|
|
def __init__(self, xy, width, height, angle=0, **kwargs):
|
|
"""
|
|
Create a rectangle at anchor point *xy* = (*x*, *y*) with given *width* and *height*.
|
|
|
|
:param xy: (float, float) xy coordinates of anchor point.
|
|
:param width: (float) Rectangle width.
|
|
:param height: (float) Rectangle height.
|
|
:param angle: (float) Rectangle angle. Default is 0.
|
|
"""
|
|
self._center = xy
|
|
self._width = width
|
|
self._height = height
|
|
self._angle = angle
|
|
shape = RectangleShape(xy[0], xy[1], width, height)
|
|
shape.setAngle(angle)
|
|
legend, isunique = plotutil.getlegendbreak('polygon', **kwargs)
|
|
super(Rectangle, self).__init__(shape, legend)
|
|
|
|
@property
|
|
def center(self):
|
|
return self._center
|
|
|
|
@property
|
|
def width(self):
|
|
return self._width
|
|
|
|
@property
|
|
def height(self):
|
|
return self._height
|
|
|
|
@property
|
|
def angle(self):
|
|
return self._angle
|
|
|
|
class Polygon(Graphic):
|
|
"""
|
|
A general polygon patch.
|
|
"""
|
|
|
|
def __init__(self, xy, closed=True, **kwargs):
|
|
"""
|
|
Create a polygon with *xy* point array.
|
|
|
|
:param xy: (array_like) xy point array.
|
|
:param closed: (bool) If *closed* is *True*, the polygon will be closed so the
|
|
starting and ending points are the same.
|
|
"""
|
|
if isinstance(xy, (list, tuple)):
|
|
xy = np.array(xy)
|
|
|
|
self._xy = xy
|
|
self._closed = closed
|
|
shape = ShapeUtil.createPolygonShape(xy._array)
|
|
legend, isunique = plotutil.getlegendbreak('polygon', **kwargs)
|
|
super(Polygon, self).__init__(shape, legend)
|
|
|
|
@property
|
|
def xy(self):
|
|
return self._xy |