add LineCollection

This commit is contained in:
wyq 2024-07-16 17:31:43 +08:00
parent 6d444c7bce
commit d20b72a7b5
20 changed files with 633 additions and 172 deletions

View File

@ -315,29 +315,29 @@ public class GraphicFactory {
* *
* @param xdata X data array * @param xdata X data array
* @param ydata Y data array * @param ydata Y data array
* @param zdata Z data array * @param cdata Color data array
* @param ls Legend scheme * @param ls Legend scheme
* @param iscurve Is curve line or not * @param iscurve Is curve line or not
* @return LineString graphic * @return LineString graphic
*/ */
public static GraphicCollection createLineString(Array xdata, Array ydata, Array zdata, LegendScheme ls, boolean iscurve) { public static GraphicCollection createLineString(Array xdata, Array ydata, Array cdata, LegendScheme ls, boolean iscurve) {
GraphicCollection gc = new GraphicCollection(); GraphicCollection gc = new GraphicCollection();
PolylineShape pls; PolylineShape pls;
List<PointD> points; List<PointD> points;
ColorBreakCollection cbc; ColorBreakCollection cbc;
double x, y, z; double x, y, c;
IndexIterator xIter = xdata.getIndexIterator();
IndexIterator yIter = ydata.getIndexIterator();
IndexIterator zIter = zdata.getIndexIterator();
ColorBreak cb; ColorBreak cb;
if (xdata.getRank() == 1) { if (xdata.getRank() == 1) {
IndexIterator xIter = xdata.getIndexIterator();
IndexIterator yIter = ydata.getIndexIterator();
IndexIterator cIter = cdata.getIndexIterator();
points = new ArrayList<>(); points = new ArrayList<>();
cbc = new ColorBreakCollection(); cbc = new ColorBreakCollection();
while (xIter.hasNext()){ while (xIter.hasNext()){
x = xIter.getDoubleNext(); x = xIter.getDoubleNext();
y = yIter.getDoubleNext(); y = yIter.getDoubleNext();
z = zIter.getDoubleNext(); c = cIter.getDoubleNext();
cb = ls.findLegendBreak(z); cb = ls.findLegendBreak(c);
if (Double.isNaN(y) || Double.isNaN(x)) { if (Double.isNaN(y) || Double.isNaN(x)) {
if (points.isEmpty()) { if (points.isEmpty()) {
continue; continue;
@ -373,34 +373,22 @@ public class GraphicFactory {
int[] shape = xdata.getShape(); int[] shape = xdata.getShape();
int yn = shape[0]; int yn = shape[0];
int xn = shape[1]; int xn = shape[1];
for (int j = 0; j < yn; j++) { Index2D xIndex = (Index2D) xdata.getIndex();
Index2D yIndex = (Index2D) ydata.getIndex();
Index2D cIndex = (Index2D) cdata.getIndex();
for (int i = 0; i < xn; i++) {
points = new ArrayList<>(); points = new ArrayList<>();
cbc = new ColorBreakCollection(); cbc = new ColorBreakCollection();
for (int i = 0; i < xn; i++) { for (int j = 0; j < yn; j++) {
x = xIter.getDoubleNext(); xIndex.set(j, i);
y = yIter.getDoubleNext(); yIndex.set(j, i);
z = zIter.getDoubleNext(); cIndex.set(j, i);
cb = ls.findLegendBreak(z); x = xdata.getDouble(xIndex);
if (Double.isNaN(y) || Double.isNaN(x)) { y = ydata.getDouble(yIndex);
if (points.isEmpty()) { c = cdata.getDouble(cIndex);
continue; cb = ls.findLegendBreak(c);
} points.add(new PointD(x, y));
if (points.size() == 1) { cbc.add(cb);
points.add((PointD) points.get(0).clone());
}
if (iscurve) {
pls = new CurveLineShape();
} else {
pls = new PolylineShape();
}
pls.setPoints(points);
gc.add(new Graphic(pls, cbc));
points = new ArrayList<>();
cbc = new ColorBreakCollection();
} else {
points.add(new PointD(x, y));
cbc.add(cb);
}
} }
if (points.size() > 1) { if (points.size() > 1) {
if (iscurve) { if (iscurve) {

View File

@ -19,15 +19,12 @@ import org.meteoinfo.geo.mapdata.ShapeFileManage;
import org.meteoinfo.geometry.legend.*; import org.meteoinfo.geometry.legend.*;
import org.meteoinfo.geometry.geoprocess.GeoComputation; import org.meteoinfo.geometry.geoprocess.GeoComputation;
import org.meteoinfo.common.colors.ColorUtil; import org.meteoinfo.common.colors.ColorUtil;
import org.meteoinfo.geometry.shape.*;
import org.meteoinfo.projection.ProjectionInfo; import org.meteoinfo.projection.ProjectionInfo;
import org.meteoinfo.table.*; import org.meteoinfo.table.*;
import org.meteoinfo.ndarray.DataType; import org.meteoinfo.ndarray.DataType;
import org.meteoinfo.geometry.graphic.Graphic; import org.meteoinfo.geometry.graphic.Graphic;
import org.meteoinfo.geometry.shape.PointShape;
import org.meteoinfo.geometry.shape.PolygonShape;
import org.meteoinfo.geometry.shape.PolylineShape;
import org.meteoinfo.geometry.shape.Shape;
import org.meteoinfo.geometry.shape.ShapeTypes;
import java.awt.Color; import java.awt.Color;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
@ -59,10 +56,6 @@ import org.meteoinfo.geo.legend.LegendManage;
import org.meteoinfo.geometry.graphic.ChartGraphic; import org.meteoinfo.geometry.graphic.ChartGraphic;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl; import org.xml.sax.helpers.AttributesImpl;
import org.meteoinfo.geometry.shape.PointZShape;
import org.meteoinfo.geometry.shape.Polygon;
import org.meteoinfo.geometry.shape.Polyline;
import org.meteoinfo.geometry.shape.PolylineZShape;
/** /**
* Vector layer class * Vector layer class
@ -2845,25 +2838,34 @@ public class VectorLayer extends MapLayer {
graphics.setAttributeTable(this._attributeTable); graphics.setAttributeTable(this._attributeTable);
graphics.setProjInfo(this._projInfo); graphics.setProjInfo(this._projInfo);
ColorBreak cb; ColorBreak cb;
if (xShift == 0) {
if (xShift != 0) {
for (Shape shape : shapes) {
for (PointD p : shape.getPoints()) {
p.X += xShift;
}
shape.updateExtent();
}
}
if (this.legendScheme.isGeometry()) {
for (Shape shape : this.shapes) {
ColorBreakCollection cbs = new ColorBreakCollection();
for (PointZ p : (List<PointZ>) shape.getPoints()) {
cb = legendScheme.findLegendBreak(p.Z);
cbs.add(cb);
}
graphics.add(new Graphic(shape, cbs));
}
} else {
for (Shape shape : this.shapes) { for (Shape shape : this.shapes) {
if (shape.getLegendIndex() >= 0) { if (shape.getLegendIndex() >= 0) {
cb = legendScheme.getLegendBreak(shape.getLegendIndex()); cb = legendScheme.getLegendBreak(shape.getLegendIndex());
graphics.add(new Graphic(shape, cb)); graphics.add(new Graphic(shape, cb));
} }
} }
} else {
for (Shape shape : shapes) {
if (shape.getLegendIndex() >= 0) {
for (PointD p : shape.getPoints()) {
p.X += xShift;
}
shape.updateExtent();
cb = legendScheme.getLegendBreak(shape.getLegendIndex());
graphics.add(new Graphic(shape, cb));
}
}
} }
graphics.setLegendScheme(legendScheme); graphics.setLegendScheme(legendScheme);
graphics.setSingleLegend(false); graphics.setSingleLegend(false);

View File

@ -17,6 +17,7 @@ public class Line2DGraphic extends Graphic {
private Array yData; private Array yData;
private Array cData; private Array cData;
private boolean curve = false; private boolean curve = false;
private LegendScheme legendScheme;
/** /**
* Constructor * Constructor
@ -90,6 +91,7 @@ public class Line2DGraphic extends Graphic {
} }
protected void updateShapeLegend(LegendScheme legendScheme) { protected void updateShapeLegend(LegendScheme legendScheme) {
this.legendScheme = legendScheme;
List<PointD> points = new ArrayList<>(); List<PointD> points = new ArrayList<>();
IndexIterator xIter = this.xData.getIndexIterator(); IndexIterator xIter = this.xData.getIndexIterator();
IndexIterator yIter = this.yData.getIndexIterator(); IndexIterator yIter = this.yData.getIndexIterator();
@ -111,12 +113,14 @@ public class Line2DGraphic extends Graphic {
if (this.shape == null) { if (this.shape == null) {
this.shape = new PolylineShape(); this.shape = new PolylineShape();
} }
this.shape.setPoints(points); if (points.size() >= 2)
this.shape.setPoints(points);
this.legend = cbc; this.legend = cbc;
} }
protected void updateShapeLegend(List<ColorBreak> cbs) { protected void updateShapeLegend(List<ColorBreak> cbs) {
this.legendScheme = new LegendScheme(cbs);
List<PointD> points = new ArrayList<>(); List<PointD> points = new ArrayList<>();
IndexIterator xIter = this.xData.getIndexIterator(); IndexIterator xIter = this.xData.getIndexIterator();
IndexIterator yIter = this.yData.getIndexIterator(); IndexIterator yIter = this.yData.getIndexIterator();
@ -211,4 +215,12 @@ public class Line2DGraphic extends Graphic {
this.yData = yData; this.yData = yData;
updateShape(); updateShape();
} }
/**
* Get legend scheme
* @return Legend scheme
*/
public LegendScheme getLegendScheme() {
return this.legendScheme;
}
} }

View File

@ -0,0 +1,250 @@
package org.meteoinfo.geometry.graphic;
import org.meteoinfo.common.PointD;
import org.meteoinfo.geometry.legend.LegendScheme;
import org.meteoinfo.geometry.legend.PolylineBreak;
import org.meteoinfo.geometry.shape.CurveLineShape;
import org.meteoinfo.geometry.shape.PolylineShape;
import org.meteoinfo.ndarray.Array;
import org.meteoinfo.ndarray.Index2D;
import org.meteoinfo.ndarray.IndexIterator;
import org.meteoinfo.ndarray.math.ArrayUtil;
import java.util.ArrayList;
import java.util.List;
public class Line2DGraphicCollection extends GraphicCollection {
private Array cData;
private List<Array> data;
private boolean curve = false;
/**
* Constructor
*/
public Line2DGraphicCollection() {
this(new ArrayList<Line2DGraphic>());
}
/**
* Constructor
* @param graphics Graphics
*/
public Line2DGraphicCollection(List<Line2DGraphic> graphics) {
super();
this.graphics = graphics;
this.legend = new PolylineBreak();
}
/**
* Constructor
* @param data Data list
* @param lineBreak Polyline break
*/
public Line2DGraphicCollection(List<Array> data, PolylineBreak lineBreak) {
super();
updateGraphics(data, lineBreak);
}
/**
* Constructor
* @param data Data list
* @param lineBreaks Polyline break list
*/
public Line2DGraphicCollection(List<Array> data, List<PolylineBreak> lineBreaks) {
super();
updateGraphics(data, lineBreaks);
}
/**
* Constructor
* @param data Data list
* @param cdata Color data
* @param ls Legend scheme
*/
public Line2DGraphicCollection(List<Array> data, Array cData, LegendScheme ls) {
this.legendScheme = ls;
this.setSingleLegend(false);
if (cData.getSize() == data.size()) {
List<PolylineBreak> lineBreaks = new ArrayList<>();
IndexIterator iterC = cData.getIndexIterator();
while (iterC.hasNext()) {
lineBreaks.add((PolylineBreak) ls.findLegendBreak(iterC.getDoubleNext()));
}
updateGraphics(data, lineBreaks);
} else {
updateGraphics(data, cData, ls);
}
}
/**
* Constructor
* @param data Data list
* @param cdata Color data
* @param ls Legend scheme
*/
public Line2DGraphicCollection(List<Array> data, List<Array> cData, LegendScheme ls) {
this.legendScheme = ls;
this.setSingleLegend(false);
updateGraphics(data, cData, ls);
}
protected void updateGraphics(List<Array> data, PolylineBreak lineBreak) {
this.data = data;
this.graphics = new ArrayList<>();
int[] origin = new int[2];
int[] shape = new int[2];
Array x, y;
try {
for (Array array : data) {
origin = new int[]{0, 0};
shape = new int[]{array.getShape()[0], 1};
x = array.section(origin, shape);
origin = new int[]{0, 1};
y = array.section(origin, shape);
this.add(new Line2DGraphic(x, y, lineBreak));
}
} catch (Exception e) {
e.printStackTrace();
}
}
protected void updateGraphics(List<Array> data, List<PolylineBreak> lineBreaks) {
this.data = data;
this.graphics = new ArrayList<>();
int[] origin = new int[2];
int[] shape = new int[2];
Array x, y;
try {
int i = 0;
for (Array array : data) {
origin = new int[]{0, 0};
shape = new int[]{array.getShape()[0], 1};
x = array.section(origin, shape);
origin = new int[]{0, 1};
y = array.section(origin, shape);
if (i >= lineBreaks.size()) {
i = 0;
}
this.add(new Line2DGraphic(x, y, lineBreaks.get(i)));
i += 1;
}
} catch (Exception e) {
e.printStackTrace();
}
}
protected void updateGraphics(List<Array> data, List<Array> cData, LegendScheme ls) {
this.data = data;
this.graphics = new ArrayList<>();
int[] origin = new int[2];
int[] shape = new int[2];
Array x, y;
try {
int i = 0;
for (Array array : data) {
origin = new int[]{0, 0};
shape = new int[]{array.getShape()[0], 1};
x = array.section(origin, shape);
origin = new int[]{0, 1};
y = array.section(origin, shape);
this.add(new Line2DGraphic(x, y, cData.get(i), ls));
i += 1;
}
} catch (Exception e) {
e.printStackTrace();
}
}
protected void updateGraphics(List<Array> data, Array cData, LegendScheme ls) {
this.data = data;
this.cData = cData;
this.graphics = new ArrayList<>();
int[] origin = new int[2];
int[] shape = new int[2];
Array x, y, c;
try {
int i = 0;
for (Array array : data) {
origin = new int[]{0, 0};
shape = new int[]{array.getShape()[0], 1};
x = array.section(origin, shape);
origin = new int[]{0, 1};
y = array.section(origin, shape);
origin = new int[]{0, i};
c = cData.section(origin, shape);
this.add(new Line2DGraphic(x, y, c, ls));
i += 1;
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Return has color data array or not
*
* @return Has color data array of not
*/
public boolean hasColorData() {
return this.cData != null;
}
/**
* Return plot as curve line or not
* @return Curve line or not
*/
public boolean isCurve() {
return this.curve;
}
/**
* Set plot as curve line or not
* @param value Curve line or not
*/
public void setCurve(boolean value) {
this.curve = value;
}
/**
* Get segments data
* @return Segments data
*/
public List<Array> getData() {
return this.data;
}
/**
* Set segments data
* @param value Segments data
*/
public void setData(List<Array> value) {
if (this.cData != null) {
updateGraphics(value, this.cData, this.legendScheme);
} else {
List<PolylineBreak> lineBreaks = getLegendBreaks();
updateGraphics(value, lineBreaks);
}
}
/**
* Set segments data
* @param value Segments data
*/
public void setData(List<Array> value, Array cData) {
updateGraphics(value, cData, this.legendScheme);
}
/**
* Get legend breaks
* @return Legend breaks
*/
public List<PolylineBreak> getLegendBreaks() {
List<PolylineBreak> lineBreaks = new ArrayList<>();
for (Line2DGraphic graphic : (List<Line2DGraphic>) this.getGraphics()) {
lineBreaks.add((PolylineBreak) graphic.legend);
}
return lineBreaks;
}
}

View File

@ -59,6 +59,9 @@ public class ColorBreakCollection extends ColorBreak implements Iterator{
* @return Color break * @return Color break
*/ */
public ColorBreak get(int idx){ public ColorBreak get(int idx){
if (idx >= this.colorBreaks.size()) {
idx = this.colorBreaks.size() - 1;
}
return this.colorBreaks.get(idx); return this.colorBreaks.get(idx);
} }

View File

@ -1,32 +1,34 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<MeteoInfo File="milconfig.xml" Type="configurefile"> <MeteoInfo File="milconfig.xml" Type="configurefile">
<Path OpenPath="D:\Working\MIScript\Jython\mis\map\projection"> <Path OpenPath="D:\Working\MIScript\Jython\mis\plot_types\contour">
<RecentFolder Folder="D:\Working\MIScript\Jython\mis"/> <RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\plot"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\map\geoshow"/> <RecentFolder Folder="D:\Working\MIScript\Jython\mis\traj"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\wind"/> <RecentFolder Folder="D:\Working\MIScript\Jython\mis\satellite"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\pcolor"/> <RecentFolder Folder="D:\Working\MIScript\Jython\mis\satellite\modis"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io"/> <RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\animation"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io\netcdf"/> <RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\annotate"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\geoshow"/> <RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\arrow"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\contour"/> <RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\bar"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl"/> <RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\boxplot"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\3d_earth"/>
<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\plot_types\plot"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\map"/> <RecentFolder Folder="D:\Working\MIScript\Jython\mis"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\map\projection"/> <RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\scatter"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\error"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\contour"/>
</Path> </Path>
<File> <File>
<OpenedFiles> <OpenedFiles>
<OpenedFile File="D:\Working\MIScript\Jython\mis\plot_types\plot\plot_cdata_3.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\plot_types\scatter\scatterm_2.py"/> <OpenedFile File="D:\Working\MIScript\Jython\mis\plot_types\scatter\scatterm_2.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\plot_types\plot\plot_cdata_1.py"/> <OpenedFile File="D:\Working\MIScript\Jython\mis\plot_types\contour\contourf_extend_both.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\map\projection\wag3_proj.py"/> <OpenedFile File="D:\Working\MIScript\Jython\mis\plot_types\contour\contourf_map_cols.py"/>
</OpenedFiles> </OpenedFiles>
<RecentFiles> <RecentFiles>
<RecentFile File="D:\Working\MIScript\Jython\mis\plot_types\plot\plot_cdata_3.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\plot_types\scatter\scatterm_2.py"/> <RecentFile File="D:\Working\MIScript\Jython\mis\plot_types\scatter\scatterm_2.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\plot_types\plot\plot_cdata_1.py"/> <RecentFile File="D:\Working\MIScript\Jython\mis\plot_types\contour\contourf_extend_both.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\map\projection\wag3_proj.py"/> <RecentFile File="D:\Working\MIScript\Jython\mis\plot_types\contour\contourf_map_cols.py"/>
</RecentFiles> </RecentFiles>
</File> </File>
<Font> <Font>
@ -34,5 +36,5 @@
</Font> </Font>
<LookFeel DockWindowDecorated="true" LafDecorated="true" Name="FlatDarkLaf"/> <LookFeel DockWindowDecorated="true" LafDecorated="true" Name="FlatDarkLaf"/>
<Figure DoubleBuffering="true"/> <Figure DoubleBuffering="true"/>
<Startup MainFormLocation="-7,0" MainFormSize="1293,765"/> <Startup MainFormLocation="-7,-7" MainFormSize="1293,765"/>
</MeteoInfo> </MeteoInfo>

View File

@ -960,7 +960,7 @@ def ncwrite(fn, data, varname, dims=None, attrs=None, gattrs=None, proj=None, la
for dimvar, dim in zip(dimvars, wdims): for dimvar, dim in zip(dimvars, wdims):
if dim.getDimType() == DimensionType.T: if dim.getDimType() == DimensionType.T:
sst = datetime.datetime(1900,1,1) sst = datetime.datetime(1900,1,1)
tt = miutil.nums2dates(dim.getDimValue()) tt = miutil.nums2dates(np.array(dim.getDimValue()))
hours = [] hours = []
for t in tt: for t in tt:
hours.append((int)((t - sst).total_seconds() // 3600)) hours.append((int)((t - sst).total_seconds() // 3600))

View File

@ -399,8 +399,15 @@ def rmaskout(data, x, y, mask):
:returns: (*list*) Maskouted data, x and y array list. :returns: (*list*) Maskouted data, x and y array list.
""" """
if not isinstance(mask, (list, ArrayList)): if not isinstance(mask, (list, tuple, ArrayList)):
if isinstance(mask, Graphic):
mask = mask.getShape()
mask = [mask] mask = [mask]
else:
for i in range(len(mask)):
if isinstance(mask[i], Graphic):
mask[i] = mask[i].getShape()
r = GeometryUtil.maskout_Remove(data.asarray(), x.asarray(), y.asarray(), mask) r = GeometryUtil.maskout_Remove(data.asarray(), x.asarray(), y.asarray(), mask)
return NDArray(r[0]), NDArray(r[1]), NDArray(r[2]) return NDArray(r[0]), NDArray(r[1]), NDArray(r[2])

View File

@ -2907,7 +2907,7 @@ def cdiff(a, dimidx):
return a.array_wrap(r) return a.array_wrap(r)
# Calculates the vertical component of the curl (ie, vorticity) # Calculates the vertical component of the curl (ie, vorticity)
def hcurl(x, y, u, v): def hcurl(*args):
""" """
Calculates the vertical component of the curl (ie, vorticity). The data should be lon/lat projection. Calculates the vertical component of the curl (ie, vorticity). The data should be lon/lat projection.
@ -2918,11 +2918,24 @@ def hcurl(x, y, u, v):
:returns: Array of the vertical component of the curl. :returns: Array of the vertical component of the curl.
""" """
if len(args) == 2:
u = args[0]
v = args[1]
x = u.dimvalue(-1)
y = v.dimvalue(-2)
elif len(args) == 4:
x = args[0]
y = args[1]
u = args[2]
v = args[3]
else:
raise ValueError("Parameter number is not correct!")
r = ArrayMath.hcurl(u._array, v._array, x._array, y._array) r = ArrayMath.hcurl(u._array, v._array, x._array, y._array)
return u.array_wrap(r) return u.array_wrap(r)
# Calculates the horizontal divergence using finite differencing # Calculates the horizontal divergence using finite differencing
def hdivg(u, v): def hdivg(*args):
""" """
Calculates the horizontal divergence using finite differencing. The data should be lon/lat projection. Calculates the horizontal divergence using finite differencing. The data should be lon/lat projection.
@ -2933,6 +2946,19 @@ def hdivg(u, v):
:returns: Array of the horizontal divergence. :returns: Array of the horizontal divergence.
""" """
if len(args) == 2:
u = args[0]
v = args[1]
x = u.dimvalue(-1)
y = v.dimvalue(-2)
elif len(args) == 4:
x = args[0]
y = args[1]
u = args[2]
v = args[3]
else:
raise ValueError("Parameter number is not correct!")
r = ArrayMath.hdivg(u._array, v._array, x._array, y._array) r = ArrayMath.hdivg(u._array, v._array, x._array, y._array)
return u.array_wrap(r) return u.array_wrap(r)

View File

@ -34,7 +34,7 @@ from mipylib.geolib.milayer import MILayer, MIXYListData
import plotutil import plotutil
import colors import colors
import mipylib.miutil as miutil import mipylib.miutil as miutil
from .graphic import Line2D, Artist, Point2DCollection from .graphic import Line2D, Artist, Point2DCollection, LineCollection
__all__ = ['Axes', 'PolarAxes'] __all__ = ['Axes', 'PolarAxes']
@ -1336,10 +1336,11 @@ class Axes(object):
xdatalist.append(arg) xdatalist.append(arg)
c = 'y' c = 'y'
snum = len(xdatalist)
if len(styles) == 0: if len(styles) == 0:
styles = None styles = None
else: else:
while len(styles) < len(xdatalist): while len(styles) < snum:
styles.append(None) styles.append(None)
# Set plot data styles # Set plot data styles
@ -1366,17 +1367,17 @@ class Axes(object):
line = plotutil.getplotstyle(styles[i], label, **kwargs) line = plotutil.getplotstyle(styles[i], label, **kwargs)
lines.append(line) lines.append(line)
else: else:
snum = len(xdatalist) if kwargs.has_key('colors'):
colors = kwargs.pop('colors', None) colors = kwargs['colors']
if colors is None: snum = len(colors) if len(colors) > snum else snum
else:
if kwargs.has_key('color'): if kwargs.has_key('color'):
color = kwargs['color'] color = kwargs['color']
color = plotutil.getcolor(color) color = plotutil.getcolor(color)
colors = [color] * snum colors = [color] * snum
else: else:
colors = plotutil.makecolors(snum) colors = plotutil.makecolors(snum)
else:
snum = len(colors) if len(colors) > snum else snum
for i in range(0, snum): for i in range(0, snum):
label = kwargs.pop('label', 'S_' + str(i + 1)) label = kwargs.pop('label', 'S_' + str(i + 1))
line = plotutil.getlegendbreak('line', **kwargs)[0] line = plotutil.getlegendbreak('line', **kwargs)[0]
@ -1401,72 +1402,53 @@ class Axes(object):
ls = plotutil.getlegendscheme([levels], cdata.min(), cdata.max(), **kwargs) ls = plotutil.getlegendscheme([levels], cdata.min(), cdata.max(), **kwargs)
ls = plotutil.setlegendscheme_line(ls, **kwargs) ls = plotutil.setlegendscheme_line(ls, **kwargs)
if not xaxistype is None:
self.set_xaxis_type(xaxistype)
timetickformat = kwargs.pop('timetickformat', None)
if not timetickformat is None:
if not xaxistype == 'time':
self._axes.setXAxis(TimeAxis('Time', True))
self._axes.getAxis(Location.BOTTOM).setTimeFormat(timetickformat)
self._axes.getAxis(Location.TOP).setTimeFormat(timetickformat)
# Add graphics # Add graphics
zorder = kwargs.pop('zorder', None)
iscurve = kwargs.pop('curve', False) iscurve = kwargs.pop('curve', False)
graphics = []
if cdata is None: if cdata is None:
# Add data series # Add data series
snum = len(xdatalist) snum = len(xdatalist)
if snum == 1: if snum == 1:
xdata = np.asarray(xdatalist[0]) xdata = np.asarray(xdatalist[0])
ydata = np.asarray(ydatalist[0]) ydata = np.asarray(ydatalist[0])
if len(lines) == 1: if ydata.ndim == 1:
colors = kwargs.pop('colors', None) graphics = Line2D(xdata, ydata, legend=lines[0], curve=iscurve)
if not colors is None: else:
colors = plotutil.getcolors(colors) if not kwargs.has_key('cmap'):
cb = lines[0] kwargs['cmap'] = 'matlab_jet'
lines = [] graphics = LineCollection(None, xydata=[xdata, ydata], **kwargs)
for cc in colors:
ncb = cb.clone()
ncb.setColor(cc)
lines.append(ncb)
graphic = GraphicFactory.createLineString(xdata._array, ydata._array, lines, iscurve)
else:
if ydata.ndim == 1:
graphic = Line2D(xdata, ydata, legend=lines[0], curve=iscurve)
else:
if xdata.ndim == 1:
xdata = xdata[:,np.newaxis].repeat(ydata.shape[1], axis=1)
graphic = GraphicFactory.createLineString(xdata._array, ydata._array, lines[0], iscurve)
else: # >1
graphic = GraphicFactory.createLineString(xdata._array, ydata._array, lines, iscurve)
self.add_graphic(graphic, zorder=zorder)
graphics.append(graphic)
else: else:
graphics = []
for i in range(0, snum): for i in range(0, snum):
label = kwargs.pop('label', 'S_' + str(i + 1)) label = kwargs.pop('label', 'S_' + str(i + 1))
xdata = np.asarray(xdatalist[i]) xdata = np.asarray(xdatalist[i])
ydata = np.asarray(ydatalist[i]) ydata = np.asarray(ydatalist[i])
graphic = Line2D(xdata, ydata, legend=lines[i], curve=iscurve) graphic = Line2D(xdata, ydata, legend=lines[i], curve=iscurve)
self.add_graphic(graphic)
graphics.append(graphic) graphics.append(graphic)
else: else:
xdata = np.asarray(xdatalist[0]) xdata = np.asarray(xdatalist[0])
ydata = np.asarray(ydatalist[0]) ydata = np.asarray(ydatalist[0])
cdata = np.asarray(cdata) cdata = np.asarray(cdata)
graphic = Line2D(xdata, ydata, legend=ls, cdata=cdata, curve=iscurve) if ydata.ndim == 1:
self.add_graphic(graphic, zorder=zorder) graphics = Line2D(xdata, ydata, legend=ls, cdata=cdata, curve=iscurve)
graphics.append(graphic) else:
graphics = LineCollection(None, xydata=[xdata, ydata], cdata=cdata, legend=ls, **kwargs)
antialias = kwargs.pop('antialias', None) antialias = kwargs.pop('antialias', None)
if antialias is not None: if antialias is not None:
for graphic in graphics: if isinstance(graphics, list):
graphic.setAntiAlias(antialias) for graphic in graphics:
graphic.setAntiAlias(antialias)
else:
graphics.setAntiAlias(antialias)
if len(graphics) > 1: zorder = kwargs.pop('zorder', None)
return graphics if isinstance(graphics, list):
for graphic in graphics:
self.add_graphic(graphic, zorder=zorder)
else: else:
return graphics[0] self.add_graphic(graphics, zorder=zorder)
return graphics
def step(self, x, y, *args, **kwargs): def step(self, x, y, *args, **kwargs):
""" """
@ -2465,7 +2447,7 @@ class Axes(object):
vmin = kwargs.pop('vmin', a.min()) vmin = kwargs.pop('vmin', a.min())
vmax = kwargs.pop('vmax', a.max()) vmax = kwargs.pop('vmax', a.max())
if not kwargs.has_key('extend'): if not kwargs.has_key('extend'):
kwargs['extend'] = 'neither' kwargs['extend'] = 'both'
ls = plotutil.getlegendscheme(args, vmin, vmax, **kwargs) ls = plotutil.getlegendscheme(args, vmin, vmax, **kwargs)
ls = ls.convertTo(ShapeTypes.POLYGON) ls = ls.convertTo(ShapeTypes.POLYGON)
if not kwargs.has_key('edgecolor'): if not kwargs.has_key('edgecolor'):
@ -4056,6 +4038,8 @@ class Axes(object):
ls = mappable.getLegendScheme() ls = mappable.getLegendScheme()
elif isinstance(mappable, GraphicCollection): elif isinstance(mappable, GraphicCollection):
ls = mappable.getLegendScheme() ls = mappable.getLegendScheme()
elif isinstance(mappable, Graphic):
ls = mappable.getLegendScheme()
else: else:
ls = plotutil.makelegend(mappable, **kwargs) ls = plotutil.makelegend(mappable, **kwargs)

View File

@ -28,12 +28,13 @@ from org.meteoinfo.data.mapdata.webmap import WebMapProvider, DefaultTileFactory
from java.awt import Font, Color from java.awt import Font, Color
from ._axes import Axes from ._axes import Axes
from .graphic import Point2DCollection from .graphic import Point2DCollection, Line2D, LineCollection
import mipylib.numeric as np import mipylib.numeric as np
from mipylib.numeric.core import NDArray, DimArray from mipylib.numeric.core import NDArray, DimArray
from mipylib.geolib.milayer import MILayer from mipylib.geolib.milayer import MILayer
from mipylib.geolib._graphic import GeoGraphicCollection from mipylib.geolib._graphic import GeoGraphicCollection
import mipylib.geolib.migeo as migeo import mipylib.geolib.migeo as migeo
from mipylib.geolib import crs
import plotutil import plotutil
import colors import colors
import mipylib.migl as migl import mipylib.migl as migl
@ -723,57 +724,50 @@ class MapAxes(Axes):
ls.setFieldName('Geometry_Z') ls.setFieldName('Geometry_Z')
iscurve = kwargs.pop('curve', False) iscurve = kwargs.pop('curve', False)
graphics = []
if cdata is None: if cdata is None:
#Add data series #Add data series
if snum == 1: if snum == 1:
xdata = plotutil.getplotdata(xdatalist[0]) xdata = np.asarray(xdatalist[0])
ydata = plotutil.getplotdata(ydatalist[0]) ydata = np.asarray(ydatalist[0])
if len(lines) == 1: if ydata.ndim == 1:
colors = kwargs.pop('colors', None) graphics = Line2D(xdata, ydata, legend=lines[0], curve=iscurve)
if not colors is None: else:
colors = plotutil.getcolors(colors) if not kwargs.has_key('cmap'):
cb = lines[0] kwargs['cmap'] = 'matlab_jet'
lines = [] graphics = LineCollection(None, xydata=[xdata, ydata], **kwargs)
for cc in colors: graphics.transform = transform
ncb = cb.clone() graphics = self.add_graphic(graphics)
ncb.setColor(cc)
lines.append(ncb)
graphic = GraphicFactory.createLineString(xdata, ydata, lines, iscurve)
else:
graphic = GraphicFactory.createLineString(xdata, ydata, lines[0], iscurve)
else: #>1
graphic = GraphicFactory.createLineString(xdata, ydata, lines, iscurve)
graphic.transform = transform
graphic = self.add_graphic(graphic)
graphics.append(graphic)
else: else:
graphics = []
for i in range(0, snum): for i in range(0, snum):
label = kwargs.pop('label', 'S_' + str(i + 1)) label = kwargs.pop('label', 'S_' + str(i + 1))
xdata = plotutil.getplotdata(xdatalist[i]) xdata = np.asarray(xdatalist[i])
ydata = plotutil.getplotdata(ydatalist[i]) ydata = np.asarray(ydatalist[i])
graphic = GraphicFactory.createLineString(xdata, ydata, lines[i], iscurve) graphic = Line2D(xdata, ydata, legend=lines[i], curve=iscurve)
graphic.transform = transform graphic.transform = transform
graphic = self.add_graphic(graphic) graphic = self.add_graphic(graphic)
graphics.append(graphic) graphics.append(graphic)
else: else:
xdata = plotutil.getplotdata(xdatalist[0]) xdata = np.asarray(xdatalist[0])
ydata = plotutil.getplotdata(ydatalist[0]) ydata = np.asarray(ydatalist[0])
zdata = plotutil.getplotdata(cdata) cdata = np.asarray(cdata)
graphic = GraphicFactory.createLineString(xdata, ydata, zdata, ls, iscurve) if ydata.ndim == 1:
graphic.transform = transform graphics = Line2D(xdata, ydata, legend=ls, cdata=cdata, curve=iscurve)
graphic = self.add_graphic(graphic) else:
graphics.append(graphic) graphics = LineCollection(None, xydata=[xdata, ydata], cdata=cdata, legend=ls, **kwargs)
graphic = GraphicFactory.createLineString(xdata._array, ydata._array, cdata._array, ls, iscurve)
graphics.transform = transform
graphics = self.add_graphic(graphics)
antialias = kwargs.pop('antialias', None) antialias = kwargs.pop('antialias', None)
if antialias is not None: if antialias is not None:
for graphic in graphics: if isinstance(graphics, list):
graphic.setAntiAlias(antialias) for graphic in graphics:
graphic.setAntiAlias(antialias)
else:
graphics.setAntiAlias(antialias)
if len(graphics) > 1: return graphics
return graphics
else:
return graphics[0]
@_add_transform @_add_transform
@ -995,7 +989,7 @@ class MapAxes(Axes):
vmin = kwargs.pop('vmin', a.min()) vmin = kwargs.pop('vmin', a.min())
vmax = kwargs.pop('vmax', a.max()) vmax = kwargs.pop('vmax', a.max())
if not kwargs.has_key('extend'): if not kwargs.has_key('extend'):
kwargs['extend'] = 'neither' kwargs['extend'] = 'both'
ls = plotutil.getlegendscheme(args, vmin, vmax, **kwargs) ls = plotutil.getlegendscheme(args, vmin, vmax, **kwargs)
ls = ls.convertTo(ShapeTypes.POLYGON) ls = ls.convertTo(ShapeTypes.POLYGON)
if not kwargs.has_key('edgecolor'): if not kwargs.has_key('edgecolor'):
@ -1091,7 +1085,10 @@ class MapAxes(Axes):
visible = kwargs.pop('visible', True) visible = kwargs.pop('visible', True)
interpolation = kwargs.pop('interpolation', None) interpolation = kwargs.pop('interpolation', None)
transform = kwargs.pop('transform', None) transform = kwargs.pop('proj', None)
if transform is None:
transform = kwargs.pop('transform', crs.PlateCarree())
if isrgb: if isrgb:
if isinstance(rgbdata, (list, tuple)): if isinstance(rgbdata, (list, tuple)):
rgbd = [] rgbd = []

View File

@ -1,4 +1,5 @@
from org.meteoinfo.geometry.graphic import GraphicCollection, Point2DGraphicCollection from org.meteoinfo.geometry.graphic import GraphicCollection, Point2DGraphicCollection, \
Line2DGraphicCollection
from java.awt import Font from java.awt import Font
from .. import plotutil from .. import plotutil
@ -6,7 +7,7 @@ from ... import miutil
from artist import Artist from artist import Artist
import mipylib.numeric as np import mipylib.numeric as np
__all__ = ['Point2DCollection'] __all__ = ['Point2DCollection','LineCollection']
class Collection(Artist): class Collection(Artist):
@ -163,3 +164,144 @@ class Point2DCollection(Collection, Point2DGraphicCollection):
self._y = ydata self._y = ydata
self.setData(xdata._array, ydata._array) self.setData(xdata._array, ydata._array)
self.stale = True self.stale = True
class LineCollection(Collection, Line2DGraphicCollection):
def __init__(self, segments, legend=None, **kwargs):
"""
Class init
Parameters
----------
segments : list of Array
A sequence (*line0*, *line1*, *line2*) of lines, where each line is a list
of points::
lineN = [(x0, y0), (x1, y1), ... (xm, ym)]
or the equivalent Mx2 numpy array with two columns. Each line
can have a different number of segments.
legend : Legend
Point legend.
xydata : List array
X and Y 2D coordinates data array for lines.
array : Array
Array data for line colors.
cdata : Array
Color data array to plot multiple color lines.
"""
Collection.__init__(self)
if segments is None:
xydata = kwargs.pop('xydata', None)
if xydata is None:
raise ValueError('Segments data is None!')
else:
if len(xydata) == 1:
ydata = xydata[0]
xdata = None
else:
xdata = xydata[0]
ydata = xydata[1]
nseg, nline = ydata.shape
if xdata is None:
xdata = np.arange(nseg)
if xdata.ndim == 1:
segments = [np.column_stack([xdata, ydata[:,i]]) for i in range(nline)]
else:
segments = [np.column_stack([xdata[:,i], ydata[:,i]]) for i in range(nline)]
if isinstance(segments, np.NDArray):
self._segments = []
ns = segments.shape[0]
for i in range(ns):
self._segments.append(segments[i])
else:
self._segments = segments
data = []
for s in self._segments:
data.append(s._array)
self._array = kwargs.pop('array', None)
self._cdata = kwargs.pop('cdata', None)
if self._array is None and self._cdata is None:
if legend is None:
legend = plotutil.getlegendbreak('line', **kwargs)[0]
kwargs['ncolors'] = len(self._segments)
legend = plotutil.getlegendbreaks(legend, **kwargs)
Line2DGraphicCollection.__init__(self, data, legend)
else:
if self._array is not None:
if legend is None:
legend = plotutil.getlegendscheme([len(self._segments)], self._array.min(), self._array.max(), **kwargs)
legend = plotutil.setlegendscheme_line(legend, **kwargs)
Line2DGraphicCollection.__init__(self, data, self._array._array, legend)
else:
if legend is None:
legend = plotutil.getlegendscheme([], self._cdata.min(), self._cdata.max(), **kwargs)
legend = plotutil.setlegendscheme_line(legend, **kwargs)
Line2DGraphicCollection.__init__(self, data, self._cdata._array, legend)
antialias = kwargs.pop('antialias', None)
if antialias is not None:
self.setAntiAlias(antialias)
@property
def visible(self):
"""
The artist is visible or not.
"""
return self.isVisible()
@visible.setter
def visible(self, val):
self.setVisible(val)
self.stale = True
@property
def segments(self):
return self._segments
@segments.setter
def segments(self, val):
self._segments = val
data = []
for s in self._segments:
data.append(s._array)
self.setData(data)
self.stale = True
def set_segments(self, val, cdata=None):
if cdata is None:
self.segments = val
else:
self._segments = val
data = []
for s in self._segments:
data.append(s._array)
self.setData(data, cdata._array)
self.stale = True
def set_xydata(self, xydata, cdata=None):
if len(xydata) == 1:
ydata = xydata[0]
xdata = None
else:
xdata = xydata[0]
ydata = xydata[1]
nseg, nline = ydata.shape
if xdata is None:
xdata = np.arange(nseg)
if xdata.ndim == 1:
segments = [np.column_stack([xdata, ydata[:,i]]) for i in range(nline)]
else:
segments = [np.column_stack([xdata[:,i], ydata[:,i]]) for i in range(nline)]
self.set_segments(segments, cdata=cdata)

View File

@ -92,6 +92,15 @@ class Line2D(Line2DGraphic, Artist):
self.setYData(ydata._array) self.setYData(ydata._array)
self.stale = True self.stale = True
@property
def cdata(self):
"""
Return the cdata.
:return: (*array*) The cdata.
"""
return self._cdata
@property @property
def data(self): def data(self):
""" """

View File

@ -120,10 +120,14 @@ def getcolor(style, alpha=None):
c = Color.magenta c = Color.magenta
elif style == 'pink' or style == 'p': elif style == 'pink' or style == 'p':
c = Color.pink c = Color.pink
elif style == 'orange' or style == 'o':
c = Color.orange
elif style == 'tan': elif style == 'tan':
c = Color(210, 180, 140) c = Color(210, 180, 140)
elif style == 'lime': elif style == 'lime':
c = Color(124, 252, 0) c = Color(124, 252, 0)
elif style == 'indigo':
c = Color(75, 0, 130)
else: else:
try: try:
c = ColorUtil.parseToColor(style) c = ColorUtil.parseToColor(style)
@ -477,6 +481,41 @@ def getplotstyle(style, caption, **kwargs):
return plb return plb
def getlegendbreaks(lb, **kwargs):
"""
Get legend break list form a legend break.
Parameters
__________
lb : The base legend break
colors : list of colors
Returns
_______
List of legend breaks.
"""
lbs = []
colors = kwargs.pop('colors', None)
if colors is None:
cmap = kwargs.pop('cmap', None)
ncolors = kwargs.pop('ncolors', 10)
if cmap is not None:
colors = makecolors(ncolors, cmap=cmap)
if colors is not None:
n = len(colors)
colors = getcolors(colors)
for cc in colors:
nlb = lb.clone()
nlb.setColor(cc)
lbs.append(nlb)
if len(lbs) == 0:
return lb
else:
return lbs
def getlegendbreak(geometry, **kwargs): def getlegendbreak(geometry, **kwargs):
fill = True fill = True
color = None color = None