mirror of
https://github.com/meteoinfo/MeteoInfo.git
synced 2025-12-08 20:36:05 +00:00
update gifaddframe function to support add an BufferedImage
This commit is contained in:
parent
b02bda02f5
commit
97d6f87ce9
@ -1675,7 +1675,7 @@ public class GLChartPanel extends GLJPanel implements IChartPanel{
|
||||
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
||||
}
|
||||
Graphics2D g = image.createGraphics();
|
||||
paintGraphics(g);
|
||||
paintGraphics(g, width, height);
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
@ -24,6 +24,7 @@ import org.meteoinfo.geo.drawing.Draw;
|
||||
import org.meteoinfo.geo.layer.ImageLayer;
|
||||
import org.meteoinfo.geo.layer.VectorLayer;
|
||||
import org.meteoinfo.geo.legend.LegendManage;
|
||||
import org.meteoinfo.geometry.colors.ExtendType;
|
||||
import org.meteoinfo.geometry.colors.Normalize;
|
||||
import org.meteoinfo.geometry.colors.OpacityTransferFunction;
|
||||
import org.meteoinfo.geometry.colors.TransferFunction;
|
||||
@ -5014,7 +5015,7 @@ public class GraphicFactory {
|
||||
* @param isSmooth Is smooth or not
|
||||
* @return Contour polygons
|
||||
*/
|
||||
public static GraphicCollection createContourPolygons(Array xa, Array ya, Array va, LegendScheme ls, boolean isSmooth) {
|
||||
public static GraphicCollection createContourPolygons_bak(Array xa, Array ya, Array va, LegendScheme ls, boolean isSmooth) {
|
||||
ls = ls.convertTo(ShapeTypes.POLYGON);
|
||||
Object[] ccs = LegendManage.getContoursAndColors(ls);
|
||||
double[] cValues = (double[]) ccs[0];
|
||||
@ -5133,6 +5134,167 @@ public class GraphicFactory {
|
||||
return graphics;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create contour polygons
|
||||
*
|
||||
* @param xa X coordinate array - one dimension
|
||||
* @param ya Y coordinate array - one dimension
|
||||
* @param va Data array - two dimension
|
||||
* @param ls Legend scheme
|
||||
* @param isSmooth Is smooth or not
|
||||
* @return Contour polygons
|
||||
*/
|
||||
public static GraphicCollection createContourPolygons(Array xa, Array ya, Array va, LegendScheme ls, boolean isSmooth) {
|
||||
double minData = ArrayMath.min(va).doubleValue();
|
||||
double maxData = ArrayMath.max(va).doubleValue();
|
||||
|
||||
ls = ls.convertTo(ShapeTypes.POLYGON);
|
||||
double[] cValues = ls.getValues(minData, maxData);
|
||||
int nv = cValues.length;
|
||||
|
||||
int[] shape = va.getShape();
|
||||
int[][] S1 = new int[shape[0]][shape[1]];
|
||||
double[] x = (double[])ArrayUtil.copyToNDJavaArray_Double(xa);
|
||||
double[] y = (double[])ArrayUtil.copyToNDJavaArray_Double(ya);
|
||||
if (x[1] - x[0] < 0) {
|
||||
ArrayUtils.reverse(x);
|
||||
va = va.flip(1);
|
||||
}
|
||||
if (y[1] - y[0] < 0) {
|
||||
ArrayUtils.reverse(y);
|
||||
va = va.flip(0);
|
||||
}
|
||||
double missingValue = -9999.0;
|
||||
double[][] data = (double[][]) ArrayUtil.copyToNDJavaArray_Double(va, missingValue);
|
||||
Object[] cbs = ContourDraw.tracingContourLines(data,
|
||||
cValues, x, y, missingValue, S1);
|
||||
List<PolyLine> contourLines = (List<PolyLine>) cbs[0];
|
||||
List<wcontour.global.Border> borders = (List<wcontour.global.Border>) cbs[1];
|
||||
|
||||
if (isSmooth) {
|
||||
contourLines = Contour.smoothLines(contourLines);
|
||||
}
|
||||
List<wcontour.global.Polygon> contourPolygons = ContourDraw.tracingPolygons(data, contourLines, borders, cValues);
|
||||
|
||||
double v, min, max;
|
||||
ColorBreak cbb = ls.findLegendBreak(0);
|
||||
ExtendType extendType = ls.getExtendType();
|
||||
GraphicCollection graphics = new GraphicCollection();
|
||||
for (int i = 0; i < contourPolygons.size(); i++) {
|
||||
wcontour.global.Polygon poly = contourPolygons.get(i);
|
||||
v = poly.LowValue;
|
||||
int valueIdx = Arrays.binarySearch(cValues, v);
|
||||
if (valueIdx < 0) {
|
||||
valueIdx = -valueIdx;
|
||||
}
|
||||
if (valueIdx == nv - 1) {
|
||||
if (poly.IsHighCenter) {
|
||||
if (maxData > ls.getMaxValue()) {
|
||||
switch (extendType) {
|
||||
case NEITHER:
|
||||
case MIN:
|
||||
continue;
|
||||
}
|
||||
}
|
||||
min = v;
|
||||
max = maxData;
|
||||
} else {
|
||||
max = v;
|
||||
min = cValues[valueIdx - 1];
|
||||
}
|
||||
} else if (valueIdx == 0){
|
||||
if (poly.IsHighCenter) {
|
||||
min = v;
|
||||
max = cValues[valueIdx + 1];
|
||||
} else {
|
||||
if (minData < ls.getMinValue()) {
|
||||
switch (extendType) {
|
||||
case NEITHER:
|
||||
case MAX:
|
||||
continue;
|
||||
}
|
||||
}
|
||||
max = v;
|
||||
min = minData;
|
||||
}
|
||||
} else {
|
||||
if (poly.LowValue == poly.HighValue) {
|
||||
if (poly.IsHighCenter) {
|
||||
min = v;
|
||||
max = cValues[valueIdx + 1];
|
||||
} else {
|
||||
max = v;
|
||||
min = cValues[valueIdx - 1];
|
||||
}
|
||||
} else {
|
||||
min = v;
|
||||
max = poly.HighValue;
|
||||
}
|
||||
}
|
||||
|
||||
PointD aPoint;
|
||||
List<PointD> pList = new ArrayList<>();
|
||||
for (wcontour.global.PointD pointList : poly.OutLine.PointList) {
|
||||
aPoint = new PointD();
|
||||
aPoint.X = pointList.X;
|
||||
aPoint.Y = pointList.Y;
|
||||
pList.add(aPoint);
|
||||
}
|
||||
if (!GeoComputation.isClockwise(pList)) {
|
||||
Collections.reverse(pList);
|
||||
}
|
||||
PolygonShape aPolygonShape = new PolygonShape();
|
||||
aPolygonShape.setPoints(pList);
|
||||
aPolygonShape.setExtent(GeometryUtil.getPointsExtent(pList));
|
||||
aPolygonShape.lowValue = min;
|
||||
aPolygonShape.highValue = max;
|
||||
if (poly.HasHoles()) {
|
||||
for (PolyLine holeLine : poly.HoleLines) {
|
||||
pList = new ArrayList<>();
|
||||
for (wcontour.global.PointD pointList : holeLine.PointList) {
|
||||
aPoint = new PointD();
|
||||
aPoint.X = pointList.X;
|
||||
aPoint.Y = pointList.Y;
|
||||
pList.add(aPoint);
|
||||
}
|
||||
aPolygonShape.addHole(pList, 0);
|
||||
}
|
||||
}
|
||||
|
||||
v = aPolygonShape.lowValue;
|
||||
switch (ls.getLegendType()) {
|
||||
case UNIQUE_VALUE:
|
||||
for (int j = 0; j < ls.getBreakNum(); j++) {
|
||||
ColorBreak cb = ls.getLegendBreaks().get(j);
|
||||
if (MIMath.doubleEquals(v, Double.parseDouble(cb.getStartValue().toString()))) {
|
||||
cbb = cb;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GRADUATED_COLOR:
|
||||
int blNum = 0;
|
||||
for (int j = 0; j < ls.getBreakNum(); j++) {
|
||||
ColorBreak cb = ls.getLegendBreaks().get(j);
|
||||
blNum += 1;
|
||||
if (MIMath.doubleEquals(v, Double.parseDouble(cb.getStartValue().toString()))
|
||||
|| (v > Double.parseDouble(cb.getStartValue().toString())
|
||||
&& v < Double.parseDouble(cb.getEndValue().toString()))
|
||||
|| (blNum == ls.getBreakNum() && v == Double.parseDouble(cb.getEndValue().toString()))) {
|
||||
cbb = cb;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
graphics.add(new Graphic(aPolygonShape, cbb));
|
||||
}
|
||||
graphics.setSingleLegend(false);
|
||||
graphics.setLegendScheme(ls);
|
||||
|
||||
return graphics;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create 3D contour polygons
|
||||
*
|
||||
|
||||
@ -19,7 +19,6 @@ import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import org.meteoinfo.common.MIMath;
|
||||
//import org.meteoinfo.legend.LegendManage;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -30,6 +29,8 @@ public class ColorMap {
|
||||
private Color[] colors;
|
||||
private String name = "";
|
||||
private Color fillColor = Color.white;
|
||||
private Color overColor;
|
||||
private Color underColor;
|
||||
|
||||
final static int GRADS_RAINBOW = 0;
|
||||
// </editor-fold>
|
||||
@ -124,6 +125,54 @@ public class ColorMap {
|
||||
public void setFillColor(Color value) {
|
||||
this.fillColor = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get over color
|
||||
* @return Over color
|
||||
*/
|
||||
public Color getOverColor() {
|
||||
return overColor == null ? colors[colors.length - 1] : overColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set over color
|
||||
* @param value Over color
|
||||
*/
|
||||
public void setOverColor(Color value) {
|
||||
overColor = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get has over color or not
|
||||
* @return Has over color or not
|
||||
*/
|
||||
public boolean hasOverColor() {
|
||||
return overColor != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get under color
|
||||
* @return Under color
|
||||
*/
|
||||
public Color getUnderColor() {
|
||||
return underColor == null ? colors[0] : underColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set under color
|
||||
* @param value Under color
|
||||
*/
|
||||
public void setUnderColor(Color value) {
|
||||
underColor = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get has under color or not
|
||||
* @return Has under color or not
|
||||
*/
|
||||
public boolean hasUnderColor() {
|
||||
return underColor != null;
|
||||
}
|
||||
// </editor-fold>
|
||||
// <editor-fold desc="Methods">
|
||||
|
||||
@ -163,8 +212,10 @@ public class ColorMap {
|
||||
* @return Mapped color
|
||||
*/
|
||||
public Color map(double value) {
|
||||
if (value < 0 || value > 1) {
|
||||
return this.fillColor;
|
||||
if (value < 0) {
|
||||
return getUnderColor();
|
||||
} else if (value > 1) {
|
||||
return getOverColor();
|
||||
}
|
||||
|
||||
int idx = (int)(value * this.colors.length);
|
||||
|
||||
@ -11,7 +11,6 @@ import java.util.List;
|
||||
*/
|
||||
public class BoundaryNorm extends Normalize {
|
||||
private Array boundaries;
|
||||
private int nColors;
|
||||
private int size;
|
||||
private int nRegions; //Number of colors needed
|
||||
private int offset;
|
||||
@ -20,17 +19,15 @@ public class BoundaryNorm extends Normalize {
|
||||
/**
|
||||
* Constructor
|
||||
* @param boundaries Boundaries
|
||||
* @param nColors Number of colors
|
||||
* @param extendType Extend type
|
||||
*/
|
||||
public BoundaryNorm(Array boundaries, int nColors, ExtendType extendType) {
|
||||
public BoundaryNorm(Array boundaries, ExtendType extendType) {
|
||||
super();
|
||||
boundaries = boundaries.copyIfView();
|
||||
this.setMinValue(boundaries.getDouble(0));
|
||||
this.setMaxValue(boundaries.getDouble((int)boundaries.getSize() - 1));
|
||||
|
||||
this.boundaries = boundaries;
|
||||
this.nColors = nColors;
|
||||
this.size = (int) this.boundaries.getSize();
|
||||
this.extendType = extendType;
|
||||
this.nRegions = this.size - 1;
|
||||
@ -50,6 +47,38 @@ public class BoundaryNorm extends Normalize {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get boundaries
|
||||
* @return Boundaries
|
||||
*/
|
||||
public Array getBoundaries() {
|
||||
return this.boundaries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get extend type
|
||||
* @return Extend type
|
||||
*/
|
||||
public ExtendType getExtendType() {
|
||||
return this.extendType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get boundaries size
|
||||
* @return Boundaries size
|
||||
*/
|
||||
public int getSize() {
|
||||
return this.size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get offset
|
||||
* @return The offset
|
||||
*/
|
||||
public int getOffset() {
|
||||
return this.offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get number of color regions
|
||||
* @return Number of color regions
|
||||
@ -59,16 +88,17 @@ public class BoundaryNorm extends Normalize {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Number apply(double v) {
|
||||
public Number apply(Number v) {
|
||||
int idx = ArrayUtil.searchSorted(this.boundaries, v, true) - 1 + this.offset;
|
||||
|
||||
return idx;
|
||||
return (float) idx / this.nRegions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Array apply(Array a) {
|
||||
Array r = ArrayUtil.searchSorted(this.boundaries, a, false);
|
||||
r = ArrayMath.add(r, this.offset - 1);
|
||||
r = ArrayMath.div(r, (float) this.nRegions);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -4,5 +4,21 @@ public enum ExtendType {
|
||||
NEITHER,
|
||||
BOTH,
|
||||
MIN,
|
||||
MAX
|
||||
MAX;
|
||||
|
||||
/**
|
||||
* Get is extend max or not
|
||||
* @return Is extend max or not
|
||||
*/
|
||||
public boolean isExtendMax() {
|
||||
return this == BOTH || this == MAX;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get is extend min or not
|
||||
* @return Is extend min or not
|
||||
*/
|
||||
public boolean isExtendMin() {
|
||||
return this == BOTH || this == MIN;
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,8 +37,9 @@ public class LogNorm extends Normalize {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Number apply(double v) {
|
||||
public Number apply(Number value) {
|
||||
double range = max - min;
|
||||
double v = value.doubleValue();
|
||||
v = Math.log10(v);
|
||||
v = (v - min) / range;
|
||||
if (clip) {
|
||||
|
||||
@ -126,8 +126,9 @@ public class Normalize {
|
||||
* @param v The value
|
||||
* @return Normalized value
|
||||
*/
|
||||
public Number apply(double v) {
|
||||
public Number apply(Number value) {
|
||||
double range = maxValue - minValue;
|
||||
double v = value.doubleValue();
|
||||
v = (v - minValue) / range;
|
||||
if (clip) {
|
||||
if (v < 0)
|
||||
|
||||
@ -0,0 +1,146 @@
|
||||
package org.meteoinfo.geometry.colors;
|
||||
|
||||
import org.meteoinfo.common.MIMath;
|
||||
import org.meteoinfo.common.colors.ColorMap;
|
||||
import org.meteoinfo.geometry.legend.LegendFactory;
|
||||
import org.meteoinfo.geometry.legend.LegendScheme;
|
||||
import org.meteoinfo.geometry.shape.ShapeTypes;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
public class ScalarMappable {
|
||||
private ColorMap colorMap;
|
||||
private Normalize normalize;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public ScalarMappable() {
|
||||
this.normalize = new Normalize();
|
||||
this.colorMap = new ColorMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param colorMap Color map
|
||||
* @param normalize Normalize
|
||||
*/
|
||||
public ScalarMappable(ColorMap colorMap, Normalize normalize) {
|
||||
this.colorMap = colorMap;
|
||||
this.normalize = normalize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param opacityTransferFunction Transfer function
|
||||
* @param colorMap Color map
|
||||
*/
|
||||
public ScalarMappable(ColorMap colorMap) {
|
||||
this(colorMap, new Normalize());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get color map
|
||||
* @return Color map
|
||||
*/
|
||||
public ColorMap getColorMap() {
|
||||
return this.colorMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set color map
|
||||
* @param value Color map
|
||||
*/
|
||||
public void setColorMap(ColorMap value) {
|
||||
this.colorMap = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get normalize
|
||||
* @return Normalize
|
||||
*/
|
||||
public Normalize getNormalize() {
|
||||
return this.normalize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set normalize
|
||||
* @param value Normalize
|
||||
*/
|
||||
public void setNormalize(Normalize value) {
|
||||
this.normalize = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get color with a data value
|
||||
* @param v The data value
|
||||
* @return The color
|
||||
*/
|
||||
public Color getColor(double v) {
|
||||
float ratio = this.normalize.apply(v).floatValue();
|
||||
return this.colorMap.map(ratio);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get colors
|
||||
* @return Colors
|
||||
*/
|
||||
public Color[] getColors() {
|
||||
if (this.normalize instanceof BoundaryNorm) {
|
||||
return this.colorMap.getColors(((BoundaryNorm) this.normalize).getNRegions());
|
||||
} else {
|
||||
return this.colorMap.getColors();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* To legend scheme
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @param n Legend break number
|
||||
* @return Legend scheme
|
||||
*/
|
||||
public LegendScheme toLegendScheme(double min, double max) {
|
||||
if (min == max) {
|
||||
return LegendFactory.createSingleSymbolLegendScheme(ShapeTypes.IMAGE);
|
||||
}
|
||||
|
||||
double[] values = MIMath.getIntervalValues(min, max);
|
||||
int n = values.length;
|
||||
Color[] colors = new Color[n + 1];
|
||||
colors[0] = getColor(min);
|
||||
for (int i = 1; i < n + 1; i++) {
|
||||
colors[i] = getColor(values[i - 1]);
|
||||
}
|
||||
|
||||
LegendScheme ls = LegendFactory.createGraduatedLegendScheme(values, colors, ShapeTypes.IMAGE, min, max);
|
||||
ls.setColorMap(colorMap);
|
||||
ls.setNormalize(normalize);
|
||||
return ls;
|
||||
}
|
||||
|
||||
/**
|
||||
* To legend scheme
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @param n Legend break number
|
||||
* @return Legend scheme
|
||||
*/
|
||||
public LegendScheme toLegendScheme(double min, double max, int n) {
|
||||
if (min == max) {
|
||||
return LegendFactory.createSingleSymbolLegendScheme(ShapeTypes.IMAGE);
|
||||
}
|
||||
|
||||
double[] values = MIMath.getIntervalValues(min, max, n);
|
||||
Color[] colors = new Color[n + 1];
|
||||
colors[0] = getColor(min);
|
||||
for (int i = 1; i < n + 1; i++) {
|
||||
colors[i] = getColor(values[i - 1]);
|
||||
}
|
||||
|
||||
LegendScheme ls = LegendFactory.createGraduatedLegendScheme(values, colors, ShapeTypes.IMAGE, min, max);
|
||||
ls.setColorMap(colorMap);
|
||||
ls.setNormalize(normalize);
|
||||
return ls;
|
||||
}
|
||||
}
|
||||
@ -16,10 +16,14 @@ package org.meteoinfo.geometry.legend;
|
||||
import org.meteoinfo.common.DataConvert;
|
||||
import org.meteoinfo.common.MIMath;
|
||||
import org.meteoinfo.common.colors.ColorMap;
|
||||
import org.meteoinfo.geometry.colors.Normalize;
|
||||
import org.meteoinfo.geometry.colors.TransferFunction;
|
||||
import org.meteoinfo.geometry.colors.*;
|
||||
import org.meteoinfo.geometry.shape.Shape;
|
||||
import org.meteoinfo.geometry.shape.*;
|
||||
import org.meteoinfo.ndarray.Array;
|
||||
import org.meteoinfo.ndarray.IndexIterator;
|
||||
import org.meteoinfo.ndarray.InvalidRangeException;
|
||||
import org.meteoinfo.ndarray.math.ArrayMath;
|
||||
import org.meteoinfo.ndarray.math.ArrayUtil;
|
||||
import org.meteoinfo.ndarray.util.BigDecimalUtil;
|
||||
|
||||
import java.awt.*;
|
||||
@ -750,6 +754,176 @@ public class LegendManage {
|
||||
return legendScheme;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create graduated color legend scheme
|
||||
*
|
||||
* @param values The values
|
||||
* @param colors The colors
|
||||
* @param shapeType Shape type
|
||||
* @return The legend scheme
|
||||
*/
|
||||
public static LegendScheme createGraduatedLegendScheme(double[] values, Color[] colors, ShapeTypes shapeType) {
|
||||
int nv = values.length;
|
||||
double min = values[0];
|
||||
double max = values[nv - 1];
|
||||
|
||||
LegendScheme legendScheme = new LegendScheme(shapeType);
|
||||
legendScheme.setLegendType(LegendType.GRADUATED_COLOR);
|
||||
legendScheme.setMinValue(min);
|
||||
legendScheme.setMaxValue(max);
|
||||
int i;
|
||||
if (shapeType.isPoint()) {
|
||||
for (i = 0; i < colors.length; i++) {
|
||||
PointBreak aPB = new PointBreak();
|
||||
aPB.setColor(colors[i]);
|
||||
aPB.setOutlineColor(Color.black);
|
||||
aPB.setNoData(false);
|
||||
aPB.setDrawOutline(true);
|
||||
aPB.setDrawFill(true);
|
||||
aPB.setDrawShape(true);
|
||||
aPB.setStartValue(values[i]);
|
||||
aPB.setEndValue(values[i + 1]);
|
||||
aPB.setSize(8);
|
||||
aPB.setStyle(PointStyle.CIRCLE);
|
||||
if (aPB.getStartValue() == aPB.getEndValue()) {
|
||||
aPB.setCaption(DataConvert.removeTailingZeros(aPB.getStartValue().toString()));
|
||||
} else if (i == 0) {
|
||||
aPB.setCaption("< " + DataConvert.removeTailingZeros(aPB.getEndValue().toString()));
|
||||
} else if (i == colors.length - 1) {
|
||||
aPB.setCaption("> " + DataConvert.removeTailingZeros(aPB.getStartValue().toString()));
|
||||
} else {
|
||||
aPB.setCaption(DataConvert.removeTailingZeros(aPB.getStartValue().toString())
|
||||
+ " - " + DataConvert.removeTailingZeros(aPB.getEndValue().toString()));
|
||||
}
|
||||
|
||||
legendScheme.addLegendBreak(aPB);
|
||||
}
|
||||
} else if (shapeType.isLine()) {
|
||||
for (i = 0; i < colors.length; i++) {
|
||||
PolylineBreak aPLB = new PolylineBreak();
|
||||
aPLB.setColor(colors[i]);
|
||||
aPLB.setWidth(1.0F);
|
||||
aPLB.setStyle(LineStyles.SOLID);
|
||||
aPLB.setDrawPolyline(true);
|
||||
aPLB.setStartValue(values[i]);
|
||||
aPLB.setEndValue(values[i + 1]);
|
||||
if (aPLB.getStartValue() == aPLB.getEndValue()) {
|
||||
aPLB.setCaption(DataConvert.removeTailingZeros(aPLB.getStartValue().toString()));
|
||||
} else if (i == 0) {
|
||||
aPLB.setCaption("< " + DataConvert.removeTailingZeros(aPLB.getEndValue().toString()));
|
||||
} else if (i == colors.length - 1) {
|
||||
aPLB.setCaption("> " + DataConvert.removeTailingZeros(aPLB.getStartValue().toString()));
|
||||
} else {
|
||||
aPLB.setCaption(DataConvert.removeTailingZeros(aPLB.getStartValue().toString())
|
||||
+ " - " + DataConvert.removeTailingZeros(aPLB.getEndValue().toString()));
|
||||
}
|
||||
aPLB.setSymbolColor(aPLB.getColor());
|
||||
if (i < PointStyle.values().length) {
|
||||
aPLB.setSymbolStyle(PointStyle.values()[i]);
|
||||
}
|
||||
|
||||
legendScheme.addLegendBreak(aPLB);
|
||||
}
|
||||
} else if (shapeType.isPolygon()) {
|
||||
for (i = 0; i < colors.length; i++) {
|
||||
PolygonBreak aPGB = new PolygonBreak();
|
||||
aPGB.setColor(colors[i]);
|
||||
aPGB.setOutlineColor(Color.gray);
|
||||
aPGB.setOutlineSize(1.0F);
|
||||
aPGB.setDrawFill(true);
|
||||
aPGB.setDrawOutline(false);
|
||||
aPGB.setDrawShape(true);
|
||||
aPGB.setStartValue(values[i]);
|
||||
aPGB.setEndValue(values[i + 1]);
|
||||
if (aPGB.getStartValue() == aPGB.getEndValue()) {
|
||||
aPGB.setCaption(DataConvert.removeTailingZeros(aPGB.getStartValue().toString()));
|
||||
} else if (i == 0) {
|
||||
aPGB.setCaption("< " + DataConvert.removeTailingZeros(aPGB.getEndValue().toString()));
|
||||
} else if (i == colors.length - 1) {
|
||||
aPGB.setCaption("> " + DataConvert.removeTailingZeros(aPGB.getStartValue().toString()));
|
||||
} else {
|
||||
aPGB.setCaption(DataConvert.removeTailingZeros(aPGB.getStartValue().toString())
|
||||
+ " - " + DataConvert.removeTailingZeros(aPGB.getEndValue().toString()));
|
||||
}
|
||||
|
||||
legendScheme.addLegendBreak(aPGB);
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < colors.length; i++) {
|
||||
ColorBreak aCB = new ColorBreak();
|
||||
aCB.setColor(colors[i]);
|
||||
aCB.setStartValue(values[i]);
|
||||
aCB.setEndValue(values[i + 1]);
|
||||
if (aCB.getStartValue() == aCB.getEndValue()) {
|
||||
aCB.setCaption(DataConvert.removeTailingZeros(aCB.getStartValue().toString()));
|
||||
} else if (i == 0) {
|
||||
aCB.setCaption("< " + DataConvert.removeTailingZeros(aCB.getEndValue().toString()));
|
||||
} else if (i == colors.length - 1) {
|
||||
aCB.setCaption("> " + DataConvert.removeTailingZeros(aCB.getStartValue().toString()));
|
||||
} else {
|
||||
aCB.setCaption(DataConvert.removeTailingZeros(aCB.getStartValue().toString())
|
||||
+ " - " + DataConvert.removeTailingZeros(aCB.getEndValue().toString()));
|
||||
}
|
||||
|
||||
legendScheme.addLegendBreak(aCB);
|
||||
}
|
||||
}
|
||||
|
||||
return legendScheme;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create graduated color legend scheme
|
||||
*
|
||||
* @param norm The BoundaryNorm
|
||||
* @param colorMap The color map
|
||||
* @return The legend scheme
|
||||
*/
|
||||
public static LegendScheme createGraduatedLegendScheme(BoundaryNorm norm, ColorMap colorMap) {
|
||||
Array values = norm.getBoundaries();
|
||||
int nv = (int) values.getSize();
|
||||
double min = values.getDouble(0);
|
||||
double max = values.getDouble(nv - 1);
|
||||
|
||||
LegendScheme legendScheme = new LegendScheme(ShapeTypes.IMAGE);
|
||||
legendScheme.setLegendType(LegendType.GRADUATED_COLOR);
|
||||
legendScheme.setMinValue(min);
|
||||
legendScheme.setMaxValue(max);
|
||||
Color[] colors = colorMap.getColors(norm.getNRegions());
|
||||
ExtendType extendType = norm.getExtendType();
|
||||
legendScheme.setExtendType(extendType);
|
||||
int offset = norm.getOffset();
|
||||
for (int i = 0; i < nv - 1; i++) {
|
||||
ColorBreak cb = new ColorBreak();
|
||||
cb.setColor(colors[i + offset]);
|
||||
cb.setStartValue(values.getDouble(i));
|
||||
cb.setEndValue(values.getDouble(i + 1));
|
||||
cb.setCaption(DataConvert.removeTailingZeros(cb.getStartValue().toString())
|
||||
+ " - " + DataConvert.removeTailingZeros(cb.getEndValue().toString()));
|
||||
legendScheme.addLegendBreak(cb);
|
||||
}
|
||||
|
||||
if (extendType.isExtendMin()) {
|
||||
ColorBreak cb = new ColorBreak();
|
||||
cb.setColor(colors[0]);
|
||||
cb.setStartValue(Double.MIN_VALUE);
|
||||
cb.setEndValue(values.getDouble(0));
|
||||
cb.setCaption("< " + DataConvert.removeTailingZeros(cb.getEndValue().toString()));
|
||||
legendScheme.addLegendBreak(0, cb);
|
||||
}
|
||||
|
||||
if (extendType.isExtendMax()) {
|
||||
ColorBreak cb = new ColorBreak();
|
||||
cb.setColor(colors[colors.length - 1]);
|
||||
cb.setStartValue(values.getDouble(nv - 1));
|
||||
cb.setEndValue(Double.MAX_VALUE);
|
||||
cb.setCaption("> " + DataConvert.removeTailingZeros(cb.getStartValue().toString()));
|
||||
legendScheme.addLegendBreak(cb);
|
||||
}
|
||||
|
||||
return legendScheme;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create legend scheme
|
||||
* @param values Value list
|
||||
@ -899,6 +1073,26 @@ public class LegendManage {
|
||||
return createLegendScheme(min, max, values, colors, LegendType.GRADUATED_COLOR, ShapeTypes.IMAGE, false, -9999.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create legend scheme
|
||||
*
|
||||
* @param min Minimum
|
||||
* @param max Maximum
|
||||
* @param ct Color table
|
||||
* @param extend Extend min/max values or not
|
||||
* @return LegendScheme
|
||||
*/
|
||||
public static LegendScheme createLegendScheme(double min, double max, ColorMap ct, boolean extend) {
|
||||
double[] values = (double[]) MIMath.getIntervalValues(min, max, extend).get(0);
|
||||
if (extend) {
|
||||
Color[] colors = ct.getColors(values.length - 1);
|
||||
return createLegendScheme(values, colors);
|
||||
} else {
|
||||
Color[] colors = ct.getColors(values.length + 1);
|
||||
return createLegendScheme(min, max, values, colors, LegendType.GRADUATED_COLOR, ShapeTypes.IMAGE, false, -9999.0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create legend scheme
|
||||
*
|
||||
@ -1013,6 +1207,17 @@ public class LegendManage {
|
||||
return ls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create legend scheme
|
||||
*
|
||||
* @param values Values
|
||||
* @param colors Colors
|
||||
* @return Legend scheme
|
||||
*/
|
||||
public static LegendScheme createLegendScheme(double[] values, Color[] colors) {
|
||||
return createGraduatedLegendScheme(values, colors, ShapeTypes.IMAGE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create legend scheme
|
||||
*
|
||||
@ -1101,6 +1306,54 @@ public class LegendManage {
|
||||
return createLegendScheme(min, max, values, colors, LegendType.GRADUATED_COLOR, ShapeTypes.IMAGE, false, -9999.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create legend scheme
|
||||
*
|
||||
* @param min Minimum
|
||||
* @param max Maximum
|
||||
* @param levels Level values
|
||||
* @param ct Color table
|
||||
* @param extend Extend min/max values or not
|
||||
* @return LegendScheme
|
||||
*/
|
||||
public static LegendScheme createLegendScheme(double min, double max, List<Number> levels,
|
||||
ColorMap ct, boolean extend) {
|
||||
if (levels.size() == ct.getColorCount()){
|
||||
return createUniqValueLegendScheme(levels, ct.getColors(), ShapeTypes.IMAGE);
|
||||
}
|
||||
|
||||
double[] values = new double[levels.size()];
|
||||
for (int i = 0; i < levels.size(); i++) {
|
||||
values[i] = levels.get(i).doubleValue();
|
||||
}
|
||||
|
||||
if (extend) {
|
||||
Color[] colors = ct.getColors(values.length - 1);
|
||||
|
||||
return createLegendScheme(values, colors);
|
||||
} else {
|
||||
Color[] colors = ct.getColors(levels.size() + 1);
|
||||
|
||||
return createLegendScheme(min, max, values, colors, LegendType.GRADUATED_COLOR, ShapeTypes.IMAGE, false, -9999.0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create legend scheme
|
||||
*
|
||||
* @param levels Level values
|
||||
* @param colorMap Color map
|
||||
* @param extendType ExtendType
|
||||
* @return LegendScheme Legend scheme
|
||||
*/
|
||||
public static LegendScheme createLegendScheme(List<Number> levels, ColorMap colorMap,
|
||||
ExtendType extendType) {
|
||||
Array boundaries = ArrayUtil.array(levels);
|
||||
BoundaryNorm norm = new BoundaryNorm(boundaries, extendType);
|
||||
|
||||
return createGraduatedLegendScheme(norm, colorMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create legend scheme
|
||||
*
|
||||
@ -1111,10 +1364,31 @@ public class LegendManage {
|
||||
* @return LegendScheme
|
||||
*/
|
||||
public static LegendScheme createLegendScheme(double min, double max, int n, ColorMap ct) {
|
||||
double[] values = MIMath.getIntervalValues(min, max, n);
|
||||
Color[] colors = ct.getColors(values.length + 1);
|
||||
return createLegendScheme(min, max, n, ct, false);
|
||||
}
|
||||
|
||||
return createLegendScheme(min, max, values, colors, LegendType.GRADUATED_COLOR, ShapeTypes.IMAGE, false, -9999.0);
|
||||
/**
|
||||
* Create legend scheme
|
||||
*
|
||||
* @param min Minimum
|
||||
* @param max Maximum
|
||||
* @param n Level number
|
||||
* @param ct Color table
|
||||
* @param extend Extend min/max values or not
|
||||
* @return LegendScheme
|
||||
*/
|
||||
public static LegendScheme createLegendScheme(double min, double max, int n, ColorMap ct, boolean extend) {
|
||||
if (extend) {
|
||||
double[] values = MIMath.getIntervalValues(min, max, n);
|
||||
Color[] colors = ct.getColors(values.length - 1);
|
||||
|
||||
return createLegendScheme(values, colors);
|
||||
} else {
|
||||
double[] values = MIMath.getIntervalValues(min, max, n);
|
||||
Color[] colors = ct.getColors(values.length + 1);
|
||||
|
||||
return createLegendScheme(min, max, values, colors, LegendType.GRADUATED_COLOR, ShapeTypes.IMAGE, false, -9999.0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1137,6 +1411,89 @@ public class LegendManage {
|
||||
return ls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create image legend from array data
|
||||
*
|
||||
* @param array Array data
|
||||
* @param colorMap Color map
|
||||
* @return Legend scheme
|
||||
*/
|
||||
public static LegendScheme createImageLegend(Array array, ColorMap colorMap) {
|
||||
boolean isUnique = ArrayUtil.isUnique(array, 20);
|
||||
LegendScheme ls;
|
||||
if (isUnique) {
|
||||
try {
|
||||
Array ua = ArrayUtil.unique(array, null);
|
||||
List<Number> values = new ArrayList<>();
|
||||
IndexIterator iter = ua.getIndexIterator();
|
||||
while (iter.hasNext()) {
|
||||
values.add((Number) iter.getObjectNext());
|
||||
}
|
||||
ls = LegendManage.createUniqValueLegendScheme(values, colorMap, ShapeTypes.IMAGE);
|
||||
} catch (InvalidRangeException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
} else if (ArrayMath.containsNaN(array)) {
|
||||
ls = LegendManage.createLegendScheme(ArrayMath.min(array).doubleValue(),
|
||||
ArrayMath.max(array).doubleValue(), colorMap, Double.NaN);
|
||||
} else {
|
||||
ls = LegendManage.createLegendScheme(ArrayMath.min(array).doubleValue(),
|
||||
ArrayMath.max(array).doubleValue(), colorMap);
|
||||
}
|
||||
|
||||
return ls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create image legend from grid data
|
||||
*
|
||||
* @param array Array data
|
||||
* @param n Legend break number
|
||||
* @param colorMap Color map
|
||||
* @return Legend scheme
|
||||
*/
|
||||
public static LegendScheme createImageLegend(Array array, int n, ColorMap colorMap) {
|
||||
LegendScheme ls;
|
||||
double min = ArrayMath.min(array).doubleValue();
|
||||
double max = ArrayMath.max(array).doubleValue();
|
||||
if (ArrayMath.containsNaN(array)) {
|
||||
ls = LegendManage.createLegendScheme(min, max, n, colorMap,
|
||||
LegendType.GRADUATED_COLOR, ShapeTypes.IMAGE, true, Double.NaN);
|
||||
} else {
|
||||
ls = LegendManage.createLegendScheme(min, max, n, colorMap,
|
||||
LegendType.GRADUATED_COLOR, ShapeTypes.IMAGE, false, Double.NaN);
|
||||
}
|
||||
|
||||
return ls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create image legend from array data
|
||||
*
|
||||
* @param array Array data
|
||||
* @param levels Legend break values
|
||||
* @param colorMap Color map
|
||||
* @return Legend scheme
|
||||
*/
|
||||
public static LegendScheme createImageLegend(Array array, List<Number> levels, ColorMap colorMap) {
|
||||
LegendScheme ls;
|
||||
if (colorMap.getColorCount() == levels.size()){
|
||||
ls = LegendManage.createUniqValueLegendScheme(levels, colorMap, ShapeTypes.IMAGE);
|
||||
} else {
|
||||
double min = ArrayMath.min(array).doubleValue();
|
||||
double max = ArrayMath.max(array).doubleValue();
|
||||
if (ArrayMath.containsNaN(array)) {
|
||||
ls = LegendManage.createLegendScheme(min, max, levels, colorMap,
|
||||
LegendType.GRADUATED_COLOR, ShapeTypes.IMAGE, true, Double.NaN);
|
||||
} else {
|
||||
ls = LegendManage.createLegendScheme(min, max, levels, colorMap,
|
||||
LegendType.GRADUATED_COLOR, ShapeTypes.IMAGE, false, Double.NaN);
|
||||
}
|
||||
}
|
||||
|
||||
return ls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create random colors
|
||||
*
|
||||
|
||||
@ -13,11 +13,10 @@
|
||||
*/
|
||||
package org.meteoinfo.geometry.legend;
|
||||
|
||||
//import org.meteoinfo.data.meteodata.DrawType2D;
|
||||
|
||||
import org.meteoinfo.common.DataConvert;
|
||||
import org.meteoinfo.common.colors.ColorMap;
|
||||
import org.meteoinfo.common.colors.ColorUtil;
|
||||
import org.meteoinfo.geometry.colors.ExtendType;
|
||||
import org.meteoinfo.geometry.colors.Normalize;
|
||||
import org.meteoinfo.geometry.shape.ShapeTypes;
|
||||
import org.w3c.dom.*;
|
||||
@ -50,6 +49,7 @@ package org.meteoinfo.geometry.legend;
|
||||
private String fieldName = "";
|
||||
private LegendType legendType = LegendType.SINGLE_SYMBOL;
|
||||
private ShapeTypes shapeType;
|
||||
private ExtendType extendType = ExtendType.NEITHER;
|
||||
private List<ColorBreak> legendBreaks;
|
||||
private boolean hasNoData;
|
||||
private double minValue;
|
||||
@ -204,6 +204,30 @@ package org.meteoinfo.geometry.legend;
|
||||
shapeType = st;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get extend type
|
||||
* @return Extend type
|
||||
*/
|
||||
public ExtendType getExtendType() {
|
||||
return extendType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set extend type
|
||||
* @param value Extend type
|
||||
*/
|
||||
public void setExtendType(ExtendType value) {
|
||||
extendType = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set extend type
|
||||
* @param value Extend type
|
||||
*/
|
||||
public void setExtendType(String value) {
|
||||
extendType = ExtendType.valueOf(value.toUpperCase());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get break type
|
||||
*
|
||||
@ -455,6 +479,18 @@ package org.meteoinfo.geometry.legend;
|
||||
this.updateUniqueValueMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a legend break by index
|
||||
*
|
||||
* @param index The index
|
||||
* @param lb Legend break
|
||||
*/
|
||||
public void addLegendBreak(int index, ColorBreak lb){
|
||||
this.legendBreaks.add(index, lb);
|
||||
if (this.legendType == LegendType.UNIQUE_VALUE)
|
||||
this.updateUniqueValueMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a legend breaks
|
||||
* @param lb Legend breaks
|
||||
@ -575,6 +611,45 @@ package org.meteoinfo.geometry.legend;
|
||||
return vs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get legend values
|
||||
* @return Legend values
|
||||
*/
|
||||
public double[] getValues(double min, double max) {
|
||||
List<Double> values = new ArrayList<>();
|
||||
ColorBreak cb;
|
||||
double v = 0;
|
||||
for (int i = 0; i < legendBreaks.size(); i++) {
|
||||
cb = legendBreaks.get(i);
|
||||
if (!cb.isNoData()) {
|
||||
if (values.isEmpty()) {
|
||||
if (this.legendType == LegendType.UNIQUE_VALUE) {
|
||||
v = Double.parseDouble(cb.getEndValue().toString());
|
||||
} else {
|
||||
v = Double.parseDouble(cb.getStartValue().toString());
|
||||
if (v >= min && v <= max) {
|
||||
values.add(v);
|
||||
}
|
||||
v = Double.parseDouble(cb.getEndValue().toString());
|
||||
}
|
||||
} else {
|
||||
v = Double.parseDouble(cb.getEndValue().toString());
|
||||
}
|
||||
|
||||
if (v >= min && v <= max) {
|
||||
values.add(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double[] vs = new double[values.size()];
|
||||
for (int i = 0; i < values.size(); i++) {
|
||||
vs[i] = values.get(i);
|
||||
}
|
||||
|
||||
return vs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get color list
|
||||
*
|
||||
@ -709,6 +784,7 @@ package org.meteoinfo.geometry.legend;
|
||||
}
|
||||
|
||||
LegendScheme ls = new LegendScheme(shapeType);
|
||||
ls.extendType = this.extendType;
|
||||
ls.fieldName = this.fieldName;
|
||||
ls.hasNoData = this.hasNoData;
|
||||
ls.legendType = this.legendType;
|
||||
@ -781,6 +857,7 @@ package org.meteoinfo.geometry.legend;
|
||||
}
|
||||
|
||||
LegendScheme ls = new LegendScheme(shapeType);
|
||||
ls.extendType = this.extendType;
|
||||
ls.fieldName = this.fieldName;
|
||||
ls.hasNoData = this.hasNoData;
|
||||
ls.legendType = this.legendType;
|
||||
|
||||
@ -148,7 +148,7 @@ public class AnimatedGifEncoder {
|
||||
getImagePixels(); // convert to correct format if necessary
|
||||
analyzePixels(); // build color table & map pixels
|
||||
if (firstFrame) {
|
||||
writeLSD(); // logical screen descriptior
|
||||
writeLSD(); // logical screen description
|
||||
writePalette(); // global color table
|
||||
if (repeat >= 0) {
|
||||
// use NS app extension to indicate reps
|
||||
@ -170,7 +170,7 @@ public class AnimatedGifEncoder {
|
||||
}
|
||||
|
||||
/**
|
||||
* Flushes any pending data and closes output file.If writing to an
|
||||
* Flushes any pending data and closes output file. If writing to an
|
||||
* OutputStream, the stream is not closed.
|
||||
* @return
|
||||
*/
|
||||
|
||||
@ -1,32 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<MeteoInfo File="milconfig.xml" Type="configurefile">
|
||||
<Path OpenPath="D:\Working\MIScript\Jython\mis\io\json">
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io\netcdf"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\meteo"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\meteo\wrf"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\ascii"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types"/>
|
||||
<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"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript"/>
|
||||
<Path OpenPath="D:\Working\MIScript\Jython\mis\common_math\interpolate">
|
||||
<RecentFolder Folder="D:\Working\MIScript\cuace_dust"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\cuace_dust\py"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\traj"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io\json"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\contour"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\image"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\map"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\map\webmap"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\meteo"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\meteo\wrf"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\common_math"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\common_math\interpolate"/>
|
||||
</Path>
|
||||
<File>
|
||||
<OpenedFiles>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\io\json\test_geojson_file_read_write.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\traj\hy_conc_geojson.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\io\json\hy_conc_nuclear_geojson.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\plot_types\contour\contourf_extend_1.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\plot_types\contour\contourf_extend.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\common_math\interpolate\interp2d_1.py"/>
|
||||
</OpenedFiles>
|
||||
<RecentFiles>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\io\json\test_geojson_file_read_write.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\traj\hy_conc_geojson.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\io\json\hy_conc_nuclear_geojson.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\plot_types\contour\contourf_extend_1.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\plot_types\contour\contourf_extend.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\common_math\interpolate\interp2d_1.py"/>
|
||||
</RecentFiles>
|
||||
</File>
|
||||
<Font>
|
||||
@ -34,5 +36,5 @@
|
||||
</Font>
|
||||
<LookFeel DockWindowDecorated="true" LafDecorated="true" Name="FlatDarkLaf"/>
|
||||
<Figure DoubleBuffering="true"/>
|
||||
<Startup MainFormLocation="-7,0" MainFormSize="1330,805"/>
|
||||
<Startup MainFormLocation="-7,0" MainFormSize="1370,786"/>
|
||||
</MeteoInfo>
|
||||
|
||||
Binary file not shown.
@ -818,7 +818,8 @@ class DimDataFiles(list):
|
||||
return TDimVariable(self[0].dataset.getDataInfo().getVariable(key), self)
|
||||
else:
|
||||
return list.__getitem__(self, key)
|
||||
|
||||
|
||||
@property
|
||||
def filenames(self):
|
||||
"""
|
||||
Get file names.
|
||||
@ -907,11 +908,12 @@ class DimDataFiles(list):
|
||||
:returns: (*datetime*) The time
|
||||
"""
|
||||
return self.times[idx]
|
||||
|
||||
|
||||
@property
|
||||
def varnames(self):
|
||||
"""
|
||||
Get variable names
|
||||
"""
|
||||
return self[0].varnames()
|
||||
return self[0].varnames
|
||||
|
||||
#############################################
|
||||
Binary file not shown.
@ -110,7 +110,7 @@ def gifanimation(filename, repeat=0, delay=1000):
|
||||
|
||||
def gifaddframe(animation, dpi=None):
|
||||
"""
|
||||
Add a frame to an gif animation object
|
||||
Add a frame to a gif animation object
|
||||
|
||||
:param animation: Gif animation object
|
||||
:param dpi: (*int*) Image resolution
|
||||
@ -136,7 +136,7 @@ def gifwrite(imfns, giffn, repeat=0, delay=1000):
|
||||
:param imfns: (*list*) Input image file names.
|
||||
:param giffn: (*string*) Output gif file name.
|
||||
:param: repeat: (*int, Default 0*) Animation repeat time number. 0 means repeat forever.
|
||||
:param: delay: (*int, Default 1000*) Animation frame delay time with units of millsecond.
|
||||
:param: delay: (*int, Default 1000*) Animation frame delay time with units of millisecond.
|
||||
"""
|
||||
ImageUtil.createGifAnimator(imfns, giffn, delay, repeat)
|
||||
|
||||
Binary file not shown.
@ -12,11 +12,12 @@ from org.meteoinfo.chart.plot import Plot2D, PolarPlot, PlotOrientation
|
||||
from org.meteoinfo.chart.graphic import GraphicFactory
|
||||
from org.meteoinfo.common import XAlign, YAlign
|
||||
from org.meteoinfo.chart.axis import Axis, LonLatAxis, TimeAxis, LogAxis
|
||||
from org.meteoinfo.geo.legend import LegendManage
|
||||
#from org.meteoinfo.geo.legend import LegendManage
|
||||
from org.meteoinfo.geometry.legend import BarBreak, PolygonBreak, PolylineBreak, \
|
||||
PointBreak, LineStyles, PointStyle, LegendScheme, LegendType
|
||||
PointBreak, LineStyles, PointStyle, LegendScheme, LegendType, LegendManage
|
||||
from org.meteoinfo.geometry.shape import ShapeTypes
|
||||
from org.meteoinfo.geometry.graphic import Graphic, GraphicCollection
|
||||
from org.meteoinfo.geometry.colors import ExtendType
|
||||
from org.meteoinfo.common import MIMath, Extent
|
||||
from org.meteoinfo.geo.layer import MapLayer
|
||||
|
||||
@ -2442,6 +2443,10 @@ class Axes(object):
|
||||
string, like ‘r’ or ‘red’, all levels will be plotted in this color. If a tuple of matplotlib
|
||||
color args (string, float, rgb, etc.), different levels will be plotted in different colors in
|
||||
the order specified.
|
||||
:param extend: (*string*) {'neither', 'both', 'min', 'max'}, default: 'neither'. Determines the
|
||||
contourf-coloring of values that are outside the levels range. If 'neither', values outside
|
||||
the levels range are not colored. If 'min', 'max' or 'both', color the values below, above
|
||||
or below and above the levels range.
|
||||
:param smooth: (*boolean*) Smooth contour lines or not.
|
||||
|
||||
:returns: (*VectoryLayer*) Contour filled VectoryLayer created from array data.
|
||||
@ -2468,18 +2473,19 @@ class Axes(object):
|
||||
|
||||
vmin = kwargs.pop('vmin', a.min())
|
||||
vmax = kwargs.pop('vmax', a.max())
|
||||
extend = ExtendType.valueOf(kwargs.pop('extend', 'neither').upper())
|
||||
if ls is None:
|
||||
if len(args) > 0:
|
||||
level_arg = args[0]
|
||||
if isinstance(level_arg, int):
|
||||
cn = level_arg
|
||||
ls = LegendManage.createLegendScheme(vmin, vmax, cn, cmap)
|
||||
ls = LegendManage.createLegendScheme(vmin, vmax, cn, cmap, True)
|
||||
else:
|
||||
if isinstance(level_arg, NDArray):
|
||||
level_arg = level_arg.aslist()
|
||||
ls = LegendManage.createLegendScheme(vmin, vmax, level_arg, cmap)
|
||||
ls = LegendManage.createLegendScheme(level_arg, cmap, extend)
|
||||
else:
|
||||
ls = LegendManage.createLegendScheme(vmin, vmax, cmap)
|
||||
ls = LegendManage.createLegendScheme(vmin, vmax, cmap, True)
|
||||
ls = ls.convertTo(ShapeTypes.POLYGON)
|
||||
if 'edgecolor' not in kwargs.keys():
|
||||
kwargs['edgecolor'] = None
|
||||
@ -2517,7 +2523,7 @@ class Axes(object):
|
||||
:param cmap: (*string*) Color map string.
|
||||
:param colors: (*list*) If None (default), the colormap specified by cmap will be used. If a
|
||||
string, like ‘r’ or ‘red’, all levels will be plotted in this color. If a tuple of matplotlib
|
||||
color args (string, float, rgb, etc), different levels will be plotted in different colors in
|
||||
color args (string, float, rgb, etc.), different levels will be plotted in different colors in
|
||||
the order specified.
|
||||
:param interpolation: (*string*) Interpolation option [None | bilinear | bicubic].
|
||||
|
||||
@ -2607,7 +2613,7 @@ class Axes(object):
|
||||
|
||||
def pcolor(self, *args, **kwargs):
|
||||
"""
|
||||
Draw a pseudocolor plot.
|
||||
Draw a pseudo color plot.
|
||||
|
||||
:param x: (*array_like*) Optional. X coordinate array.
|
||||
:param y: (*array_like*) Optional. Y coordinate array.
|
||||
@ -2712,7 +2718,7 @@ class Axes(object):
|
||||
:param coordinates=['axes'|'figure'|'data'|'inches']: (*string*) Coordinate system and units for
|
||||
*X, Y*. 'axes' and 'figure' are normalized coordinate system with 0,0 in the lower left and
|
||||
1,1 in the upper right, 'data' are the axes data coordinates (Default value); 'inches' is
|
||||
position in the figure in inches, with 0,0 at the lower left corner.
|
||||
position in the figure in inches, with 0,0 in the lower left corner.
|
||||
"""
|
||||
ctext = plotutil.text(x, y, s, **kwargs)
|
||||
self._axes.addText(ctext)
|
||||
|
||||
Binary file not shown.
@ -777,3 +777,19 @@ class Figure(ChartPanel):
|
||||
|
||||
if not symbol is None:
|
||||
self.getChart().setSymbolAntialias(symbol)
|
||||
|
||||
def get_image(self):
|
||||
"""
|
||||
Get view image.
|
||||
|
||||
:return: (*BufferedImage*) Current view image.
|
||||
"""
|
||||
return self.getViewImage()
|
||||
|
||||
def draw_image(self):
|
||||
"""
|
||||
Draw view image.
|
||||
|
||||
:return: (*BufferedImage*) View image.
|
||||
"""
|
||||
return self.paintViewImage()
|
||||
|
||||
Binary file not shown.
@ -785,3 +785,19 @@ class GLFigure(GLChartPanel):
|
||||
|
||||
if not symbol is None:
|
||||
self.getChart().setSymbolAntialias(symbol)
|
||||
|
||||
def get_image(self):
|
||||
"""
|
||||
Get view image.
|
||||
|
||||
:return: (*BufferedImage*) Current view image.
|
||||
"""
|
||||
return self.getViewImage()
|
||||
|
||||
def draw_image(self):
|
||||
"""
|
||||
Draw view image.
|
||||
|
||||
:return: (*BufferedImage*) View image.
|
||||
"""
|
||||
return self.paintViewImage()
|
||||
|
||||
@ -168,4 +168,4 @@ class BoundaryNorm(Normalize):
|
||||
boundaries = np.array(boundaries)
|
||||
|
||||
extend = ExtendType.valueOf(extend.upper())
|
||||
self._norm = JBoundaryNorm(boundaries._array, ncolors, extend)
|
||||
self._norm = JBoundaryNorm(boundaries._array, ncolors, extend)
|
||||
|
||||
Binary file not shown.
@ -2329,7 +2329,7 @@ def gifanimation(filename, repeat=0, delay=1000):
|
||||
return encoder
|
||||
|
||||
|
||||
def gifaddframe(animation, width=None, height=None, dpi=None):
|
||||
def gifaddframe(animation, width=None, height=None, dpi=None, image=None):
|
||||
"""
|
||||
Add a frame to a gif animation object
|
||||
|
||||
@ -2337,18 +2337,22 @@ def gifaddframe(animation, width=None, height=None, dpi=None):
|
||||
:param width: (*int*) Image width
|
||||
:param height: (*int*) Image height
|
||||
:param dpi: (*int*) Image resolution
|
||||
:param image: (*image*) The image, default is None means the image will be created from the current
|
||||
figure.
|
||||
"""
|
||||
# chartpanel.paintGraphics()
|
||||
if dpi is None:
|
||||
if width is None or height is None:
|
||||
animation.addFrame(g_figure.paintViewImage())
|
||||
if image is None:
|
||||
if dpi is None:
|
||||
if width is None or height is None:
|
||||
animation.addFrame(g_figure.paintViewImage())
|
||||
else:
|
||||
animation.addFrame(g_figure.paintViewImage(width, height))
|
||||
else:
|
||||
animation.addFrame(g_figure.paintViewImage(width, height))
|
||||
if width is None or height is None:
|
||||
animation.addFrame(g_figure.paintViewImage(dpi))
|
||||
else:
|
||||
animation.addFrame(g_figure.paintViewImage(width, height, dpi))
|
||||
else:
|
||||
if width is None or height is None:
|
||||
animation.addFrame(g_figure.paintViewImage(dpi))
|
||||
else:
|
||||
animation.addFrame(g_figure.paintViewImage(width, height, dpi))
|
||||
animation.addFrame(image)
|
||||
|
||||
|
||||
def giffinish(animation):
|
||||
|
||||
Binary file not shown.
@ -112,6 +112,8 @@ def getcolor(style, alpha=None):
|
||||
c = Color.gray
|
||||
elif style == 'lightgray':
|
||||
c = Color.lightGray
|
||||
elif style == 'darkgray':
|
||||
c = Color.darkGray
|
||||
elif style == 'cyan' or style == 'c':
|
||||
c = Color.cyan
|
||||
elif style == 'magenta' or style == 'm':
|
||||
@ -601,6 +603,9 @@ def getlegendscheme(args, min, max, **kwargs):
|
||||
|
||||
|
||||
def setlegendscheme(ls, **kwargs):
|
||||
extend = kwargs.pop('extend', None)
|
||||
if extend is not None:
|
||||
ls.setExtendType(extend)
|
||||
st = ls.getShapeType()
|
||||
if st == ShapeTypes.POINT:
|
||||
setlegendscheme_point(ls, **kwargs)
|
||||
@ -968,7 +973,7 @@ def text(x, y, s, **kwargs):
|
||||
:param coordinates=['axes'|'figure'|'data'|'inches']: (*string*) Coordinate system and units for
|
||||
*X, Y*. 'axes' and 'figure' are normalized coordinate system with 0,0 in the lower left and
|
||||
1,1 in the upper right, 'data' are the axes data coordinates (Default value); 'inches' is
|
||||
position in the figure in inches, with 0,0 at the lower left corner.
|
||||
position in the figure in inches, with 0,0 in the lower left corner.
|
||||
|
||||
:returns: (*ChartText*) text.
|
||||
"""
|
||||
|
||||
@ -2364,6 +2364,30 @@ public class ArrayUtil {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check array is unique by unique value number
|
||||
* @param a The array
|
||||
* @param limit The limit unique value number
|
||||
* @return Is unique or not
|
||||
*/
|
||||
public static boolean isUnique(Array a, int limit) {
|
||||
IndexIterator iter = a.getIndexIterator();
|
||||
List<Object> values = new ArrayList<>();
|
||||
int n = 0;
|
||||
Object v;
|
||||
while (iter.hasNext()) {
|
||||
v = iter.getObjectNext();
|
||||
if (!values.contains(v)) {
|
||||
values.add(v);
|
||||
}
|
||||
if (values.size() > limit) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the unique elements and index of an array.
|
||||
*
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user