support extend and extendfrac parameters in contourf function

This commit is contained in:
wyq 2024-01-24 15:16:18 +08:00
parent 11a1878633
commit 283b79a264
16 changed files with 969 additions and 322 deletions

View File

@ -69,7 +69,7 @@ public class ChartColorBar extends ChartLegend {
this.tickColor = Color.black;
this.drawMinLabel = false;
this.drawMaxLabel = false;
this.extendType = ExtendType.NEITHER;
this.extendType = ls.getExtendType();
this.drawMinorTick = false;
this.minorTickNum = 5;
this.setLegendScheme(ls);
@ -525,6 +525,28 @@ public class ChartColorBar extends ChartLegend {
}
}
private PointD drawTickLine(Graphics2D g, double x, double y, float tickLen, boolean vertical, double shift) {
if (vertical) {
if (this.insideTick) {
g.draw(new Line2D.Double(x + shift, y, x + shift, y - tickLen));
} else {
g.draw(new Line2D.Double(x + shift, y, x + shift, y + tickLen));
y += tickLen;
}
y += 5;
} else {
if (this.insideTick) {
g.draw(new Line2D.Double(x - tickLen, y + shift, x, y + shift));
} else {
g.draw(new Line2D.Double(x, y + shift, x + tickLen, y + shift));
x += tickLen;
}
x += 5;
}
return new PointD(x, y);
}
private void drawHorizontal(Graphics2D g, LegendScheme ls) {
PointF aP = new PointF(0, 0);
PointF sP = new PointF(0, 0);
@ -609,9 +631,6 @@ public class ChartColorBar extends ChartLegend {
g.setStroke(new BasicStroke(this.neatLineSize));
g.setColor(this.neatLineColor);
switch (this.extendType) {
case NEITHER:
g.draw(new Rectangle.Double(0, y_shift, this.barWidth * bNum, this.barHeight));
break;
case BOTH:
Path2D p = new Path2D.Float();
p.moveTo(0, this.barHeight / 2 + y_shift);
@ -645,6 +664,9 @@ public class ChartColorBar extends ChartLegend {
p.closePath();
g.draw(p);
break;
default:
g.draw(new Rectangle.Double(0, y_shift, this.barWidth * bNum, this.barHeight));
break;
}
//Draw tick and label
@ -738,15 +760,16 @@ public class ChartColorBar extends ChartLegend {
List<Integer> labelIdxs = new ArrayList<>();
List<String> tLabels = new ArrayList<>();
int tickGap = this.getTickGap(g);
if (this.autoTick) {
int tickGap = this.getTickGap(g);
int sIdx = (bNum % tickGap) / 2;
int labNum = bNum - 1;
if (aLS.getLegendType() == LegendType.UNIQUE_VALUE) {
labNum += 1;
} else if (this.drawMinLabel) {
sIdx = 0;
labNum = bNum;
int labNum = bNum;
switch (extendType) {
case NONE:
case NEITHER:
case MAX:
sIdx = 0;
break;
}
while (sIdx < labNum) {
labelIdxs.add(sIdx);
@ -770,7 +793,36 @@ public class ChartColorBar extends ChartLegend {
}
this.barHeight = (float) this.legendWidth / this.aspect;
barWidth = (float) this.legendWidth / bNum;
int extendNum = 0;
switch (extendType) {
case BOTH:
extendNum = 2;
break;
case MIN:
case MAX:
extendNum = 1;
break;
}
float extendLength = 0;
if (extendNum == 0) {
barWidth = (float) this.legendWidth / bNum;
} else {
switch (extendFraction) {
case NONE:
extendLength = this.legendWidth * 0.05f;
barWidth = (this.legendWidth - extendLength * extendNum) / (bNum - extendNum);
break;
case AUTO:
barWidth = (float) this.legendWidth / bNum;
extendLength = barWidth;
break;
case LENGTH:
barWidth = this.legendWidth / (bNum + (extendFraction.fraction - 1) * extendNum);
extendLength = barWidth * extendFraction.fraction;
break;
}
}
float y_shift = 0;
if (this.label != null){
switch (this.labelLocation){
@ -821,59 +873,72 @@ public class ChartColorBar extends ChartLegend {
barHeight, DrawFill, DrawOutline, g);
}
} else {
double extendw = barWidth;
if (this.autoExtendFrac) {
extendw = barHeight;
}
if (i == 0) {
PointD[] Points = new PointD[4];
Points[0] = new PointD();
Points[0].X = barWidth - extendw;
Points[0].Y = aP.Y + barHeight * 0.5;
Points[1] = new PointD();
Points[1].X = barWidth;
Points[1].Y = aP.Y;
Points[2] = new PointD();
Points[2].X = barWidth;
Points[2].Y = aP.Y + barHeight;
Points[3] = new PointD();
Points[3].X = barWidth - extendw;
Points[3].Y = aP.Y + barHeight * 0.5;
if (aLS.getShapeType() == ShapeTypes.POLYGON) {
PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
aPGB.setDrawOutline(false);
Draw.drawPolygon(Points, aPGB, g);
} else {
Draw.drawPolygon(Points, FillColor, OutlineColor, DrawFill, DrawOutline, g);
switch (this.extendType) {
case BOTH:
case MIN:
PointD[] Points = new PointD[4];
Points[0] = new PointD(0, aP.Y + barHeight * 0.5);
Points[1] = new PointD(extendLength, aP.Y);
Points[2] = new PointD(extendLength, aP.Y + barHeight);
Points[3] = new PointD(0, aP.Y + barHeight * 0.5);
if (aLS.getShapeType() == ShapeTypes.POLYGON) {
PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
aPGB.setDrawOutline(false);
Draw.drawPolygon(Points, aPGB, g);
} else {
Draw.drawPolygon(Points, FillColor, OutlineColor, DrawFill, DrawOutline, g);
}
aP.X += extendLength - barWidth;
break;
default:
if (aLS.getShapeType() == ShapeTypes.POLYGON) {
PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
aPGB.setDrawOutline(false);
Draw.drawPolygonSymbol(aP.X, aP.Y, barWidth, barHeight, aPGB, g);
} else {
Draw.drawPolygonSymbol(aP.X, aP.Y, FillColor, OutlineColor, barWidth,
barHeight, DrawFill, DrawOutline, g);
}
break;
}
} else if (i == bNum - 1) {
PointD[] Points = new PointD[4];
Points[0] = new PointD();
Points[0].X = i * barWidth - 1.0f;
Points[0].Y = aP.Y + barHeight;
Points[1] = new PointD();
Points[1].X = i * barWidth - 1.0f;
Points[1].Y = aP.Y;
Points[2] = new PointD();
Points[2].X = i * barWidth + extendw;
Points[2].Y = aP.Y + barHeight * 0.5;
Points[3] = new PointD();
Points[3].X = i * barWidth - 1.0f;
Points[3].Y = aP.Y + barHeight;
switch (this.extendType) {
case BOTH:
case MAX:
PointD[] Points = new PointD[4];
Points[0] = new PointD(legendWidth - extendLength, aP.Y + barHeight);
Points[1] = new PointD(legendWidth - extendLength, aP.Y);
Points[2] = new PointD(legendWidth, aP.Y + barHeight * 0.5);
Points[3] = new PointD(legendWidth - extendLength, aP.Y + barHeight);
if (aLS.getShapeType() == ShapeTypes.POLYGON) {
PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
aPGB.setDrawOutline(false);
Draw.drawPolygon(Points, aPGB, g);
} else {
Draw.drawPolygon(Points, FillColor, OutlineColor, DrawFill, DrawOutline, g);
}
break;
default:
if (aLS.getShapeType() == ShapeTypes.POLYGON) {
PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
aPGB.setDrawOutline(false);
Draw.drawPolygonSymbol(aP.X, aP.Y, barWidth, barHeight, aPGB, g);
} else {
Draw.drawPolygonSymbol(aP.X, aP.Y, FillColor, OutlineColor, barWidth,
barHeight, DrawFill, DrawOutline, g);
}
break;
}
} else {
if (aLS.getShapeType() == ShapeTypes.POLYGON) {
PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
aPGB.setDrawOutline(false);
Draw.drawPolygon(Points, aPGB, g);
Draw.drawPolygonSymbol(aP.X, aP.Y, barWidth, barHeight, aPGB, g);
} else {
Draw.drawPolygon(Points, FillColor, OutlineColor, DrawFill, DrawOutline, g);
Draw.drawPolygonSymbol(aP.X, aP.Y, FillColor, OutlineColor, barWidth,
barHeight, DrawFill, DrawOutline, g);
}
} else if (aLS.getShapeType() == ShapeTypes.POLYGON) {
PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
aPGB.setDrawOutline(false);
Draw.drawPolygonSymbol(aP.X, aP.Y, barWidth, barHeight, aPGB, g);
} else {
Draw.drawPolygonSymbol(aP.X, aP.Y, FillColor, OutlineColor, barWidth,
barHeight, DrawFill, DrawOutline, g);
}
}
}
@ -885,22 +950,50 @@ public class ChartColorBar extends ChartLegend {
if (this.extendRect) {
g.draw(new Rectangle.Double(0, y_shift, this.barWidth * bNum, this.barHeight));
} else {
double extendw = barWidth;
if (this.autoExtendFrac) {
extendw = barHeight;
switch (this.extendType) {
case BOTH:
Path2D p = new Path2D.Double();
p.moveTo(0, this.barHeight / 2 + y_shift);
p.lineTo(extendLength, y_shift);
p.lineTo(this.barWidth * (bNum - 2) + extendLength, y_shift);
p.lineTo(this.barWidth * (bNum - 2) + extendLength * 2, this.barHeight / 2 + y_shift);
p.lineTo(this.barWidth * (bNum - 2) + extendLength, this.barHeight + y_shift);
p.lineTo(extendLength, this.barHeight + y_shift);
p.closePath();
g.draw(p);
break;
case MAX:
p = new Path2D.Double();
p.moveTo(0, y_shift);
p.lineTo(this.barWidth * (bNum - 1), y_shift);
p.lineTo(this.barWidth * (bNum - 1) + extendLength, this.barHeight / 2 + y_shift);
p.lineTo(this.barWidth * (bNum - 1), this.barHeight + y_shift);
p.lineTo(0, this.barHeight + y_shift);
p.closePath();
g.draw(p);
break;
case MIN:
p = new Path2D.Double();
p.moveTo(0, this.barHeight / 2 + y_shift);
p.lineTo(extendLength, y_shift);
p.lineTo(this.barWidth * (bNum - 1) + extendLength, y_shift);
p.lineTo(this.barWidth * (bNum - 1) + extendLength, this.barHeight + y_shift);
p.lineTo(extendLength, this.barHeight + y_shift);
p.closePath();
g.draw(p);
break;
default:
g.draw(new Rectangle.Double(0, y_shift, this.barWidth * bNum, this.barHeight));
break;
}
Path2D p = new Path2D.Double();
p.moveTo(barWidth - extendw, this.barHeight / 2 + y_shift);
p.lineTo(this.barWidth, y_shift);
p.lineTo(this.barWidth * (bNum - 1), y_shift);
p.lineTo(this.barWidth * (bNum - 1) + extendw, this.barHeight / 2 + y_shift);
p.lineTo(this.barWidth * (bNum - 1), this.barHeight + y_shift);
p.lineTo(this.barWidth, this.barHeight + y_shift);
p.closePath();
g.draw(p);
}
//Draw tick and label
aP.X = -barWidth / 2;
sP.X = 0;
if (aLS.getLegendType() == LegendType.UNIQUE_VALUE) {
sP.Y = barHeight + y_shift + 5;
} else {
sP.Y = barHeight + y_shift;
}
float tickLen = this.tickLength;
if (this.insideTick) {
if (this.barHeight < tickLen) {
@ -912,8 +1005,7 @@ public class ChartColorBar extends ChartLegend {
g.setColor(this.tickColor);
idx = 0;
for (int i = 0; i < bNum; i++) {
aP.X += barWidth;
aP.Y = barHeight / 2 + y_shift;
sP.X += barWidth;
if (labelIdxs.contains(i)) {
ColorBreak cb = aLS.getLegendBreaks().get(i);
if (this.autoTick) {
@ -927,8 +1019,7 @@ public class ChartColorBar extends ChartLegend {
}
if (aLS.getLegendType() == LegendType.UNIQUE_VALUE) {
sP.X = aP.X;
sP.Y = aP.Y + barHeight / 2 + 5;
sP.X -= barWidth / 2;
g.setColor(this.tickLabelColor);
if (this.tickLabelAngle == 0) {
Draw.drawString(g, sP.X, sP.Y, caption, XAlign.CENTER, YAlign.TOP, this.tickLabelAngle, true);
@ -938,70 +1029,87 @@ public class ChartColorBar extends ChartLegend {
Draw.drawString(g, sP.X, sP.Y, caption, XAlign.RIGHT, YAlign.CENTER, this.tickLabelAngle, true);
}
} else {
sP.X = aP.X + barWidth / 2;
sP.Y = aP.Y + barHeight / 2;
PointD ssP = (PointD)sP.clone();
if (i == 0) {
switch (extendType) {
case BOTH:
case MIN:
sP.X = sP.X - barWidth + extendLength;
break;
}
}
if (this.autoTick) {
if (i < bNum - 1) {
g.setColor(this.tickColor);
this.drawTickLine(g, sP, tickLen, true, 0);
aP = this.drawTickLine(g, sP.X, sP.Y, tickLen, true, 0);
g.setColor(this.tickLabelColor);
if (this.tickLabelAngle == 0) {
Draw.drawString(g, sP.X, sP.Y, caption, XAlign.CENTER, YAlign.TOP, this.tickLabelAngle, true);
Draw.drawString(g, aP.X, aP.Y, caption, XAlign.CENTER, YAlign.TOP, this.tickLabelAngle, true);
} else if (this.tickLabelAngle < 45) {
Draw.drawString(g, sP.X, sP.Y, caption, XAlign.RIGHT, YAlign.TOP, this.tickLabelAngle, true);
Draw.drawString(g, aP.X, aP.Y, caption, XAlign.RIGHT, YAlign.TOP, this.tickLabelAngle, true);
} else {
Draw.drawString(g, sP.X, sP.Y, caption, XAlign.RIGHT, YAlign.CENTER, this.tickLabelAngle, true);
Draw.drawString(g, aP.X, aP.Y, caption, XAlign.RIGHT, YAlign.CENTER, this.tickLabelAngle, true);
}
if (this.drawMinLabel && i == 0) {
g.setColor(this.tickColor);
this.drawTickLine(g, ssP, tickLen, true, -this.barWidth);
caption = DataConvert.removeTailingZeros(cb.getStartValue().toString());
g.setColor(this.tickLabelColor);
//Draw.drawString(g, ssP.X - this.barWidth, ssP.Y, caption, XAlign.CENTER, YAlign.TOP, this.tickLabelAngle, true);
if (this.tickLabelAngle == 0) {
Draw.drawString(g, ssP.X - this.barWidth, ssP.Y, caption, XAlign.CENTER, YAlign.TOP, this.tickLabelAngle, true);
} else if (this.tickLabelAngle < 45) {
Draw.drawString(g, ssP.X - this.barWidth, ssP.Y, caption, XAlign.RIGHT, YAlign.TOP, this.tickLabelAngle, true);
} else {
Draw.drawString(g, ssP.X - this.barWidth, ssP.Y, caption, XAlign.RIGHT, YAlign.CENTER, this.tickLabelAngle, true);
if (i == 0) {
switch (this.extendType) {
case NEITHER:
case MAX:
if (tickGap == 1) {
g.setColor(this.tickColor);
aP = this.drawTickLine(g, sP.X, sP.Y, tickLen, true, -this.barWidth);
caption = DataConvert.removeTailingZeros(cb.getStartValue().toString());
g.setColor(this.tickLabelColor);
//Draw.drawString(g, ssP.X - this.barWidth, ssP.Y, caption, XAlign.CENTER, YAlign.TOP, this.tickLabelAngle, true);
if (this.tickLabelAngle == 0) {
Draw.drawString(g, aP.X - this.barWidth, aP.Y, caption, XAlign.CENTER, YAlign.TOP, this.tickLabelAngle, true);
} else if (this.tickLabelAngle < 45) {
Draw.drawString(g, aP.X - this.barWidth, aP.Y, caption, XAlign.RIGHT, YAlign.TOP, this.tickLabelAngle, true);
} else {
Draw.drawString(g, aP.X - this.barWidth, aP.Y, caption, XAlign.RIGHT, YAlign.CENTER, this.tickLabelAngle, true);
}
}
break;
}
}
} else if (this.drawMaxLabel) {
g.setColor(this.tickColor);
this.drawTickLine(g, sP, tickLen, true, 0);
g.setColor(this.tickLabelColor);
if (this.tickLabelAngle == 0) {
Draw.drawString(g, sP.X, sP.Y, caption, XAlign.CENTER, YAlign.TOP, this.tickLabelAngle, true);
} else if (this.tickLabelAngle < 45) {
Draw.drawString(g, sP.X, sP.Y, caption, XAlign.RIGHT, YAlign.TOP, this.tickLabelAngle, true);
} else {
Draw.drawString(g, sP.X, sP.Y, caption, XAlign.RIGHT, YAlign.CENTER, this.tickLabelAngle, true);
} else {
switch (this.extendType) {
case NEITHER:
case MIN:
g.setColor(this.tickColor);
aP = this.drawTickLine(g, sP.X, sP.Y, tickLen, true, 0);
g.setColor(this.tickLabelColor);
if (this.tickLabelAngle == 0) {
Draw.drawString(g, aP.X, aP.Y, caption, XAlign.CENTER, YAlign.TOP, this.tickLabelAngle, true);
} else if (this.tickLabelAngle < 45) {
Draw.drawString(g, aP.X, aP.Y, caption, XAlign.RIGHT, YAlign.TOP, this.tickLabelAngle, true);
} else {
Draw.drawString(g, aP.X, aP.Y, caption, XAlign.RIGHT, YAlign.CENTER, this.tickLabelAngle, true);
}
break;
}
}
} else {
if (i == 0 && this.tickLocations.get(idx) == Double.parseDouble(cb.getStartValue().toString())) {
g.setColor(this.tickColor);
this.drawTickLine(g, sP, tickLen, true, -this.barWidth);
aP = this.drawTickLine(g, sP.X, sP.Y, tickLen, true, -this.barWidth);
g.setColor(this.tickLabelColor);
//Draw.drawString(g, sP.X - this.barWidth, sP.Y, caption, XAlign.CENTER, YAlign.TOP, this.tickLabelAngle, true);
if (this.tickLabelAngle == 0) {
Draw.drawString(g, sP.X - this.barWidth, sP.Y, caption, XAlign.CENTER, YAlign.TOP, this.tickLabelAngle, true);
Draw.drawString(g, aP.X - this.barWidth, aP.Y, caption, XAlign.CENTER, YAlign.TOP, this.tickLabelAngle, true);
} else if (this.tickLabelAngle < 45) {
Draw.drawString(g, sP.X - this.barWidth, sP.Y, caption, XAlign.RIGHT, YAlign.TOP, this.tickLabelAngle, true);
Draw.drawString(g, aP.X - this.barWidth, aP.Y, caption, XAlign.RIGHT, YAlign.TOP, this.tickLabelAngle, true);
} else {
Draw.drawString(g, sP.X - this.barWidth, sP.Y, caption, XAlign.RIGHT, YAlign.CENTER, this.tickLabelAngle, true);
Draw.drawString(g, aP.X - this.barWidth, aP.Y, caption, XAlign.RIGHT, YAlign.CENTER, this.tickLabelAngle, true);
}
} else {
g.setColor(this.tickColor);
this.drawTickLine(g, sP, tickLen, true, 0);
aP = this.drawTickLine(g, sP.X, sP.Y, tickLen, true, 0);
g.setColor(this.tickLabelColor);
if (this.tickLabelAngle == 0) {
Draw.drawString(g, sP.X, sP.Y, caption, XAlign.CENTER, YAlign.TOP, this.tickLabelAngle, true);
Draw.drawString(g, aP.X, aP.Y, caption, XAlign.CENTER, YAlign.TOP, this.tickLabelAngle, true);
} else if (this.tickLabelAngle < 45) {
Draw.drawString(g, sP.X, sP.Y, caption, XAlign.RIGHT, YAlign.TOP, this.tickLabelAngle, true);
Draw.drawString(g, aP.X, aP.Y, caption, XAlign.RIGHT, YAlign.TOP, this.tickLabelAngle, true);
} else {
Draw.drawString(g, sP.X, sP.Y, caption, XAlign.RIGHT, YAlign.CENTER, this.tickLabelAngle, true);
Draw.drawString(g, aP.X, aP.Y, caption, XAlign.RIGHT, YAlign.CENTER, this.tickLabelAngle, true);
}
}
}
@ -1126,9 +1234,6 @@ public class ChartColorBar extends ChartLegend {
g.setStroke(new BasicStroke(this.neatLineSize));
g.setColor(this.neatLineColor);
switch (this.extendType) {
case NEITHER:
g.draw(new Rectangle.Double(x_shift, 0, this.barWidth, this.legendHeight));
break;
case BOTH:
Path2D p = new Path2D.Double();
p.moveTo(this.barWidth / 2 + x_shift, 0);
@ -1162,6 +1267,9 @@ public class ChartColorBar extends ChartLegend {
p.closePath();
g.draw(p);
break;
default:
g.draw(new Rectangle.Double(x_shift, 0, this.barWidth, this.legendHeight));
break;
}
//Draw tick and label
@ -1250,15 +1358,16 @@ public class ChartColorBar extends ChartLegend {
List<Integer> labelIdxs = new ArrayList<>();
List<String> tLabels = new ArrayList<>();
int tickGap = this.getTickGap(g);
if (this.autoTick) {
int tickGap = this.getTickGap(g);
int sIdx = (bNum % tickGap) / 2;
int labNum = bNum - 1;
if (aLS.getLegendType() == LegendType.UNIQUE_VALUE) {
labNum += 1;
} else if (this.drawMinLabel) {
sIdx = 0;
labNum = bNum;
int labNum = bNum;
switch (extendType) {
case NONE:
case NEITHER:
case MAX:
sIdx = 0;
break;
}
while (sIdx < labNum) {
labelIdxs.add(sIdx);
@ -1290,7 +1399,36 @@ public class ChartColorBar extends ChartLegend {
}
this.barWidth = (float) this.legendHeight / this.aspect;
barHeight = (float) this.legendHeight / bNum;
int extendNum = 0;
switch (extendType) {
case BOTH:
extendNum = 2;
break;
case MIN:
case MAX:
extendNum = 1;
break;
}
float extendLength = 0;
if (extendNum == 0) {
barHeight = (float) this.legendHeight / bNum;
} else {
switch (extendFraction) {
case NONE:
extendLength = this.legendHeight * 0.05f;
barHeight = (this.legendHeight - extendLength * extendNum) / (bNum - extendNum);
break;
case AUTO:
barHeight = (float) this.legendHeight / bNum;
extendLength = barHeight;
break;
case LENGTH:
barHeight = this.legendHeight / (bNum + (extendFraction.fraction - 1) * extendNum);
extendLength = barHeight * extendFraction.fraction;
break;
}
}
aP.Y = this.legendHeight;
float x_shift = 0;
if (this.label != null){
@ -1330,11 +1468,10 @@ public class ChartColorBar extends ChartLegend {
FillColor = aCB.getColor();
break;
}
aP.Y = aP.Y - barHeight;
if (DrawShape) {
if (this.extendRect) {
aP.Y = aP.Y - barHeight;
if (aLS.getShapeType() == ShapeTypes.POLYGON) {
PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
aPGB.setDrawOutline(false);
@ -1343,55 +1480,77 @@ public class ChartColorBar extends ChartLegend {
Draw.drawPolygonSymbol(aP.X, aP.Y, FillColor, OutlineColor, barWidth,
barHeight, DrawFill, DrawOutline, g);
}
} else if (i == 0) {
PointD[] Points = new PointD[4];
Points[0] = new PointD();
Points[0].X = aP.X + barWidth * 0.5;
Points[0].Y = this.legendHeight;
Points[1] = new PointD();
Points[1].X = aP.X;
Points[1].Y = aP.Y;
Points[2] = new PointD();
Points[2].X = aP.X + barWidth;
Points[2].Y = aP.Y;
Points[3] = new PointD();
Points[3].X = aP.X + barWidth * 0.5;
Points[3].Y = this.legendHeight;
if (aLS.getShapeType() == ShapeTypes.POLYGON) {
PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
aPGB.setDrawOutline(false);
Draw.drawPolygon(Points, aPGB, g);
} else {
Draw.drawPolygon(Points, FillColor, OutlineColor, DrawFill, DrawOutline, g);
}
} else if (i == bNum - 1) {
PointD[] Points = new PointD[4];
Points[0] = new PointD();
Points[0].X = aP.X;
Points[0].Y = barHeight;
Points[1] = new PointD();
Points[1].X = aP.X + barWidth;
Points[1].Y = barHeight;
Points[2] = new PointD();
Points[2].X = aP.X + barWidth * 0.5;
Points[2].Y = 0;
Points[3] = new PointD();
Points[3].X = aP.X;
Points[3].Y = barHeight;
if (aLS.getShapeType() == ShapeTypes.POLYGON) {
PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
aPGB.setDrawOutline(false);
Draw.drawPolygon(Points, aPGB, g);
} else {
Draw.drawPolygon(Points, FillColor, OutlineColor, DrawFill, DrawOutline, g);
}
} else if (aLS.getShapeType() == ShapeTypes.POLYGON) {
PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
aPGB.setDrawOutline(false);
Draw.drawPolygonSymbol(aP.X, aP.Y, barWidth, barHeight, aPGB, g);
} else {
Draw.drawPolygonSymbol(aP.X, aP.Y, FillColor, OutlineColor, barWidth,
barHeight, DrawFill, DrawOutline, g);
if (i == 0) {
switch (this.extendType) {
case BOTH:
case MIN:
aP.Y = aP.Y - extendLength;
PointD[] Points = new PointD[4];
Points[0] = new PointD(aP.X + barWidth * 0.5, this.legendHeight);
Points[1] = new PointD(aP.X, aP.Y);
Points[2] = new PointD(aP.X + barWidth, aP.Y);
Points[3] = new PointD(aP.X + barWidth * 0.5, this.legendHeight);
if (aLS.getShapeType() == ShapeTypes.POLYGON) {
PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
aPGB.setDrawOutline(false);
Draw.drawPolygon(Points, aPGB, g);
} else {
Draw.drawPolygon(Points, FillColor, OutlineColor, DrawFill, DrawOutline, g);
}
break;
default:
aP.Y = aP.Y - barHeight;
if (aLS.getShapeType() == ShapeTypes.POLYGON) {
PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
aPGB.setDrawOutline(false);
Draw.drawPolygonSymbol(aP.X, aP.Y, barWidth, barHeight, aPGB, g);
} else {
Draw.drawPolygonSymbol(aP.X, aP.Y, FillColor, OutlineColor, barWidth,
barHeight, DrawFill, DrawOutline, g);
}
break;
}
} else if (i == bNum - 1) {
aP.Y = aP.Y - barHeight;
switch (this.extendType) {
case BOTH:
case MAX:
PointD[] Points = new PointD[4];
Points[0] = new PointD(aP.X, extendLength);
Points[1] = new PointD(aP.X + barWidth, extendLength);
Points[2] = new PointD(aP.X + barWidth * 0.5, 0);
Points[3] = new PointD(aP.X, extendLength);
if (aLS.getShapeType() == ShapeTypes.POLYGON) {
PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
aPGB.setDrawOutline(false);
Draw.drawPolygon(Points, aPGB, g);
} else {
Draw.drawPolygon(Points, FillColor, OutlineColor, DrawFill, DrawOutline, g);
}
break;
default:
if (aLS.getShapeType() == ShapeTypes.POLYGON) {
PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
aPGB.setDrawOutline(false);
Draw.drawPolygonSymbol(aP.X, aP.Y, barWidth, barHeight, aPGB, g);
} else {
Draw.drawPolygonSymbol(aP.X, aP.Y, FillColor, OutlineColor, barWidth,
barHeight, DrawFill, DrawOutline, g);
}
break;
}
} else {
aP.Y = aP.Y - barHeight;
if (aLS.getShapeType() == ShapeTypes.POLYGON) {
PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
aPGB.setDrawOutline(false);
Draw.drawPolygonSymbol(aP.X, aP.Y, barWidth, barHeight, aPGB, g);
} else {
Draw.drawPolygonSymbol(aP.X, aP.Y, FillColor, OutlineColor, barWidth,
barHeight, DrawFill, DrawOutline, g);
}
}
}
}
}
@ -1401,19 +1560,54 @@ public class ChartColorBar extends ChartLegend {
if (this.extendRect) {
g.draw(new Rectangle.Double(x_shift, 0, this.barWidth, this.barHeight * bNum));
} else {
Path2D p = new Path2D.Double();
p.moveTo(this.barWidth / 2 + x_shift, 0);
p.lineTo(x_shift, this.barHeight);
p.lineTo(x_shift, (this.barHeight * (bNum - 1)));
p.lineTo(this.barWidth / 2 + x_shift, this.barHeight * bNum);
p.lineTo(this.barWidth + x_shift, this.barHeight * (bNum - 1));
p.lineTo(this.barWidth + x_shift, this.barHeight);
p.closePath();
g.draw(p);
switch (this.extendType) {
case BOTH:
Path2D p = new Path2D.Double();
p.moveTo(this.barWidth / 2 + x_shift, 0);
p.lineTo(x_shift, extendLength);
p.lineTo(x_shift, extendLength + this.barHeight * (bNum - 2));
p.lineTo(this.barWidth / 2 + x_shift, this.legendHeight);
p.lineTo(this.barWidth + x_shift, extendLength + this.barHeight * (bNum - 2));
p.lineTo(this.barWidth + x_shift, extendLength);
p.closePath();
g.draw(p);
break;
case MAX:
p = new Path2D.Double();
p.moveTo(this.barWidth / 2 + x_shift, 0);
p.lineTo(x_shift, extendLength);
p.lineTo(x_shift, this.legendHeight);
p.lineTo(this.barWidth + x_shift, this.legendHeight);
p.lineTo(this.barWidth + x_shift, extendLength);
p.closePath();
g.draw(p);
break;
case MIN:
p = new Path2D.Double();
p.moveTo(x_shift, 0);
p.lineTo(x_shift, this.barHeight * (bNum - 1));
p.lineTo(this.barWidth / 2 + x_shift, this.barHeight * (bNum - 1) + extendLength);
p.lineTo(this.barWidth + x_shift, this.barHeight * (bNum - 1));
p.lineTo(this.barWidth + x_shift, 0);
p.closePath();
g.draw(p);
break;
default:
g.draw(new Rectangle.Double(x_shift, 0, this.barWidth, this.barHeight * bNum));
break;
}
}
//Draw ticks
g.setStroke(new BasicStroke(this.tickWidth));
aP.Y = this.legendHeight + barHeight / 2;
aP.X = barWidth / 2 + x_shift;
if (aLS.getLegendType() == LegendType.UNIQUE_VALUE) {
aP.Y = this.legendHeight - barHeight / 2;
sP.X = aP.X + barWidth / 2 + 5;
} else {
aP.Y = this.legendHeight;
sP.X = aP.X + barWidth / 2;
}
sP.Y = aP.Y;
float tickLen = this.tickLength;
if (this.insideTick) {
if (this.barWidth < tickLen) {
@ -1423,8 +1617,7 @@ public class ChartColorBar extends ChartLegend {
g.setFont(tickLabelFont);
idx = 0;
for (int i = 0; i < bNum; i++) {
aP.X = barWidth / 2 + x_shift;
aP.Y = aP.Y - barHeight;
sP.Y -= this.barHeight;
if (labelIdxs.contains(i)) {
ColorBreak cb = aLS.getLegendBreaks().get(i);
if (this.autoTick) {
@ -1438,44 +1631,59 @@ public class ChartColorBar extends ChartLegend {
}
if (aLS.getLegendType() == LegendType.UNIQUE_VALUE) {
sP.X = aP.X + barWidth / 2 + 5;
sP.Y = aP.Y;
g.setColor(this.tickLabelColor);
Draw.drawString(g, sP.X, sP.Y, caption, XAlign.LEFT, YAlign.CENTER, this.tickLabelAngle, true);
} else {
sP.X = aP.X + barWidth / 2;
sP.Y = aP.Y - barHeight / 2;
PointD ssP = (PointD)sP.clone();
if (i == 0) {
switch (extendType) {
case BOTH:
case MIN:
sP.Y = aP.Y - extendLength;
break;
}
}
if (this.autoTick) {
if (i < bNum - 1) {
g.setColor(this.tickColor);
this.drawTickLine(g, sP, tickLen, false, 0);
aP = this.drawTickLine(g, sP.X, sP.Y, tickLen, false, 0);
g.setColor(this.tickLabelColor);
Draw.drawString(g, sP.X, sP.Y, caption, XAlign.LEFT, YAlign.CENTER, this.tickLabelAngle, true);
if (this.drawMinLabel && i == 0) {
g.setColor(this.tickColor);
this.drawTickLine(g, ssP, tickLen, false, this.barHeight);
caption = DataConvert.removeTailingZeros(cb.getStartValue().toString());
g.setColor(this.tickLabelColor);
Draw.drawString(g, ssP.X, ssP.Y + this.barHeight, caption, XAlign.LEFT, YAlign.CENTER, this.tickLabelAngle, true);
Draw.drawString(g, aP.X, aP.Y, caption, XAlign.LEFT, YAlign.CENTER, this.tickLabelAngle, true);
if (i == 0) {
switch (this.extendType) {
case NEITHER:
case MAX:
if (tickGap == 1) {
g.setColor(this.tickColor);
aP = this.drawTickLine(g, sP.X, sP.Y, tickLen, false, this.barHeight);
caption = DataConvert.removeTailingZeros(cb.getStartValue().toString());
g.setColor(this.tickLabelColor);
Draw.drawString(g, aP.X, aP.Y + this.barHeight, caption, XAlign.LEFT, YAlign.CENTER, this.tickLabelAngle, true);
}
break;
}
}
} else {
switch (this.extendType) {
case NEITHER:
case MIN:
g.setColor(this.tickColor);
aP = this.drawTickLine(g, sP.X, sP.Y, tickLen, false, 0);
g.setColor(this.tickLabelColor);
Draw.drawString(g, aP.X, aP.Y, caption, XAlign.LEFT, YAlign.CENTER, this.tickLabelAngle, true);
break;
}
} else if (this.drawMaxLabel) {
g.setColor(this.tickColor);
this.drawTickLine(g, sP, tickLen, false, 0);
g.setColor(this.tickLabelColor);
Draw.drawString(g, sP.X, sP.Y, caption, XAlign.LEFT, YAlign.CENTER, this.tickLabelAngle, true);
}
} else {
if (i == 0 && this.tickLocations.get(idx) == Double.parseDouble(cb.getStartValue().toString())) {
g.setColor(this.tickColor);
this.drawTickLine(g, sP, tickLen, false, this.barHeight);
aP = this.drawTickLine(g, sP.X, sP.Y, tickLen, false, this.barHeight);
g.setColor(this.tickLabelColor);
Draw.drawString(g, sP.X, sP.Y + this.barHeight, caption, XAlign.LEFT, YAlign.CENTER, this.tickLabelAngle, true);
Draw.drawString(g, aP.X, aP.Y + this.barHeight, caption, XAlign.LEFT, YAlign.CENTER, this.tickLabelAngle, true);
} else {
g.setColor(this.tickColor);
this.drawTickLine(g, sP, tickLen, false, 0);
aP = this.drawTickLine(g, sP.X, sP.Y, tickLen, false, 0);
g.setColor(this.tickLabelColor);
Draw.drawString(g, sP.X, sP.Y, caption, XAlign.LEFT, YAlign.CENTER, this.tickLabelAngle, true);
Draw.drawString(g, aP.X, aP.Y, caption, XAlign.LEFT, YAlign.CENTER, this.tickLabelAngle, true);
}
}
}

View File

@ -71,7 +71,7 @@ public class ChartLegend {
private boolean autoRowColNum = true;
private Dimension symbolDimension;
protected boolean extendRect;
protected boolean autoExtendFrac;
protected ExtendFraction extendFraction;
protected float xshift;
protected float yshift;
// </editor-fold>
@ -107,8 +107,8 @@ public class ChartLegend {
this.tickLabelColor = Color.black;
this.tickLabelAngle = 0;
this.symbolDimension = new Dimension(16, 10);
this.extendRect = true;
this.autoExtendFrac = false;
this.extendRect = false;
this.extendFraction = ls.getExtendFraction();
this.xshift = 0;
this.yshift = 0;
}
@ -699,23 +699,19 @@ public class ChartLegend {
}
/**
* Get if auto set extend fraction - extend has save width and height Only
* valid for colorbar
*
* @return Boolean
* Get extend fraction
* @return Extend fraction
*/
public boolean isAutoExtendFrac() {
return this.autoExtendFrac;
public ExtendFraction getExtendFraction() {
return this.extendFraction;
}
/**
* Set if auto set extend fraction - extend has save width and height Only
* valid for colorbar
*
* Set extend fraction
* @param value
*/
public void setAutoExtendFrac(boolean value) {
this.autoExtendFrac = value;
public void setExtendFraction(ExtendFraction value) {
this.extendFraction = value;
}
/**

View File

@ -3341,6 +3341,112 @@ public class GraphicFactory {
return new ImageGraphic(ishape, ls);
}
/**
* Create image
*
* @param data Grid data array
* @param xa X coordinates array
* @param ya Y coordinates array
* @param ls Legend scheme
* @param extent Extent
* @return Image graphic
*/
public static Graphic createImage(Array data, Array xa, Array ya, LegendScheme ls, List<Number> extent) {
int width, height, breakNum;
width = (int) xa.getSize();
height = (int) ya.getSize();
BufferedImage aImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
if (ls.getColorMap() == null) {
breakNum = ls.getValidBreakNum();
double[] breakValue = new double[breakNum];
Color[] breakColor = new Color[breakNum];
Color undefColor = Color.white;
int idx = 0;
for (ColorBreak cb : ls.getLegendBreaks()) {
if (cb.isNoData()) {
undefColor = cb.getColor();
} else {
breakValue[idx] = Double.parseDouble(cb.getEndValue().toString());
breakColor[idx] = cb.getColor();
idx += 1;
}
}
Color defaultColor = breakColor[breakNum - 1]; //Last color
double oneValue;
Color oneColor;
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
oneValue = data.getDouble(i * width + j);
if (Double.isNaN(oneValue)) {
oneColor = undefColor;
} else {
oneColor = defaultColor;
if (ls.getLegendType() == LegendType.GRADUATED_COLOR) {
for (int k = 0; k < breakNum - 1; k++) {
if (oneValue < breakValue[k]) {
oneColor = breakColor[k];
break;
}
}
} else {
for (int k = 0; k < breakNum - 1; k++) {
if (oneValue == breakValue[k]) {
oneColor = breakColor[k];
break;
}
}
}
}
aImage.setRGB(j, height - i - 1, oneColor.getRGB());
}
}
} else {
ColorMap colorMap = ls.getColorMap();
int n = colorMap.getColorCount();
Normalize normalize = ls.getNormalize();
double v;
Color fillColor = colorMap.getFillColor();
Color color;
int idx;
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
v = data.getDouble(i * width + j);
if (Double.isNaN(v)) {
color = fillColor;
} else {
idx = (int) (normalize.apply(v).floatValue() * n);
if (idx < 0)
idx = 0;
else if (idx >= n)
idx = n - 1;
color = colorMap.getColor(idx);
}
aImage.setRGB(j, height - i - 1, color.getRGB());
}
}
}
ImageShape ishape = new ImageShape();
double xmin, xmax, ymin, ymax;
if (extent == null) {
double xdelta = BigDecimalUtil.mul(xa.getDouble(1) - xa.getDouble(0), 0.5);
xmin = BigDecimalUtil.sub(xa.getDouble(0), xdelta);
xmax = BigDecimalUtil.add(xa.getDouble(width - 1), xdelta);
double ydelta = BigDecimalUtil.mul(ya.getDouble(1) - ya.getDouble(0), 0.5);
ymin = BigDecimalUtil.sub(ya.getDouble(0), ydelta);
ymax = BigDecimalUtil.add(ya.getDouble(height - 1), ydelta);
} else {
xmin = extent.get(0).doubleValue();
xmax = extent.get(1).doubleValue();
ymin = extent.get(2).doubleValue();
ymax = extent.get(3).doubleValue();
}
ishape.setPoint(new PointD(xmin, ymin));
ishape.setImage(aImage);
ishape.setExtent(new Extent(xmin, xmax, ymin, ymax));
return new ImageGraphic(ishape, ls);
}
/**
* Create image
*

View File

@ -893,16 +893,41 @@ public class MIMath {
* @return Value array
*/
public static double[] getIntervalValues(double min, double max, double interval, int n) {
double[] cValues;
min = BigDecimalUtil.add(min, interval);
double mod = BigDecimalUtil.mod(min, interval);
min = BigDecimalUtil.sub(min, mod);
return getIntervalValues(min, max, interval, n, false);
}
cValues = new double[n];
/**
* Create values by interval
*
* @param min Minimum value
* @param max Maximum value
* @param interval Interval value
* @param n Value number
* @param isExtend Extend values or not
* @return Value array
*/
public static double[] getIntervalValues(double min, double max, double interval, int n, boolean isExtend) {
double minV = BigDecimalUtil.add(min, interval);
double mod = BigDecimalUtil.mod(minV, interval);
minV = BigDecimalUtil.sub(minV, mod);
List<Double> values = new ArrayList<>();
for (int i = 0; i < n; i++) {
cValues[i] = BigDecimalUtil.add(min, BigDecimalUtil.mul(i, interval));
values.add(BigDecimalUtil.add(minV, BigDecimalUtil.mul(i, interval)));
}
//Extend values
if (isExtend) {
if (values.get(0) > min) {
values.add(0, BigDecimalUtil.sub(values.get(0), interval));
}
if (values.get(values.size() - 1) < max) {
values.add(BigDecimalUtil.add(values.get(values.size() - 1), interval));
}
}
double[] cValues = values.stream().mapToDouble(Double::doubleValue).toArray();
return cValues;
}
@ -915,6 +940,19 @@ public class MIMath {
* @return Values
*/
public static double[] getIntervalValues(double min, double max, int n) {
return getIntervalValues(min, max, n, false);
}
/**
* Get interval values
*
* @param min Minimum value
* @param max Maximum value
* @param n Level number
* @param isExtend Extend values or not
* @return Values
*/
public static double[] getIntervalValues(double min, double max, int n, boolean isExtend) {
int aD, aE;
double range;
String eStr;
@ -939,7 +977,7 @@ public class MIMath {
double bb = b.setScale(ln, RoundingMode.HALF_UP).doubleValue();
double interval = BigDecimalUtil.mul(bb, Math.pow(10, aE));
return getIntervalValues(min, max, interval, n);
return getIntervalValues(min, max, interval, n, isExtend);
}
/**
@ -1142,10 +1180,7 @@ public class MIMath {
}
}
double[] cValues = new double[values.size()];
for (i = 0; i < values.size(); i++) {
cValues[i] = values.get(i);
}
double[] cValues = values.stream().mapToDouble(Double::doubleValue).toArray();
r.add(cValues);
r.add(cDelt);

View File

@ -24,8 +24,10 @@ import org.meteoinfo.geo.drawing.ContourDraw;
import org.meteoinfo.geo.drawing.Draw;
import org.meteoinfo.geo.layer.*;
import org.meteoinfo.geo.legend.LegendManage;
import org.meteoinfo.geometry.colors.ExtendType;
import org.meteoinfo.geometry.geoprocess.GeometryUtil;
import org.meteoinfo.geometry.graphic.Graphic;
import org.meteoinfo.geometry.graphic.GraphicCollection;
import org.meteoinfo.geometry.legend.*;
import org.meteoinfo.geometry.shape.*;
import org.meteoinfo.geometry.geoprocess.GeoComputation;
@ -33,6 +35,7 @@ import org.meteoinfo.math.meteo.MeteoMath;
import org.meteoinfo.ndarray.Array;
import org.meteoinfo.ndarray.DataType;
import org.meteoinfo.ndarray.IndexIterator;
import org.meteoinfo.ndarray.math.ArrayMath;
import org.meteoinfo.ndarray.math.ArrayUtil;
import org.meteoinfo.table.DataTable;
import org.meteoinfo.table.Field;
@ -871,6 +874,161 @@ public class DrawMeteoData {
return createShadedLayer(gridData, ls, lName, fieldName, isSmooth);
}
/**
* Create shaded layer
*
* @param va Grid data array
* @param xa X array
* @param ya Y array
* @param ls Legend scheme
* @param lName Layer name
* @param fieldName Field name
* @param isSmooth If smooth the contour lines
* @return Vector layer
*/
public static VectorLayer createShadedLayer(Array va, Array xa, Array ya, LegendScheme ls, String lName, String fieldName, 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);
//Create contour polygon layer
VectorLayer layer = new VectorLayer(ShapeTypes.POLYGON);
Field field = new Field(fieldName + "_Low", DataType.DOUBLE);
layer.editAddField(field);
field = new Field(fieldName + "_High", DataType.DOUBLE);
layer.editAddField(field);
//Add polygon shape
double v, min, max;
ColorBreak cbb = ls.findLegendBreak(0);
ExtendType extendType = ls.getExtendType();
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);
}
}
int shapeNum = layer.getShapeNum();
try {
if (layer.editInsertShape(aPolygonShape, shapeNum)) {
layer.editCellValue(fieldName + "_Low", shapeNum, aPolygonShape.lowValue);
layer.editCellValue(fieldName + "_High", shapeNum, aPolygonShape.highValue);
}
} catch (Exception ex) {
Logger.getLogger(DrawMeteoData.class.getName()).log(Level.SEVERE, null, ex);
}
}
layer.setLayerName(lName);
ls.setFieldName(fieldName + "_Low");
layer.setLegendScheme(ls);
layer.setLayerDrawType(LayerDrawType.SHADED);
return layer;
}
/**
* Create shaded layer
*
@ -883,7 +1041,7 @@ public class DrawMeteoData {
* @param isSmooth If smooth the contour lines
* @return Vector layer
*/
public static VectorLayer createShadedLayer(Array data, Array x, Array y, LegendScheme aLS, String lName, String fieldName, boolean isSmooth) {
public static VectorLayer createShadedLayer_bak(Array data, Array x, Array y, LegendScheme aLS, String lName, String fieldName, boolean isSmooth) {
GridData gridData = new GridData(data, x, y);
return createShadedLayer(gridData, aLS, lName, fieldName, isSmooth);
}
@ -934,8 +1092,6 @@ public class DrawMeteoData {
}
ContourPolygons = ContourDraw.tracingPolygons(gridData.getData(), ContourLines, borders, cValues);
//wContour.Global.Polygon aPolygon;
//Color aColor;
double aValue;
int valueIdx;
VectorLayer aLayer = new VectorLayer(ShapeTypes.POLYGON);
@ -945,7 +1101,6 @@ public class DrawMeteoData {
aLayer.editAddField(aDC);
for (Polygon aPolygon : ContourPolygons) {
//aPolygon = ContourPolygon;
aValue = aPolygon.LowValue;
PointD aPoint;
List<PointD> pList = new ArrayList<>();
@ -981,22 +1136,11 @@ public class DrawMeteoData {
if (valueIdx < 0) {
valueIdx = -valueIdx - 1;
}
//valueIdx = Arrays.asList(cValues).indexOf(aValue);
if (valueIdx >= cValues.length - 1) {
aPolygonShape.highValue = maxData;
} else {
aPolygonShape.highValue = cValues[valueIdx + 1];
}
// if (!aPolygon.IsBorder) {
// if (!aPolygon.IsHighCenter) {
// aPolygonShape.highValue = aValue;
// if (valueIdx == 0) {
// aPolygonShape.lowValue = minData;
// } else {
// aPolygonShape.lowValue = cValues[valueIdx - 1];
// }
// }
// }
if (!aPolygon.IsHighCenter && aPolygon.HighValue == aPolygon.LowValue) {
aPolygonShape.highValue = aValue;
if (valueIdx == 0) {
@ -1020,9 +1164,6 @@ public class DrawMeteoData {
ls.setFieldName(fieldName + "_Low");
aLayer.setLegendScheme(ls);
aLayer.setLayerDrawType(LayerDrawType.SHADED);
// for (org.meteoinfo.legend.ColorBreak cb : aLayer.getLegendScheme().getLegendBreaks()){
// System.out.println(cb.getColor().getAlpha());
// }
return aLayer;
}

View File

@ -4,7 +4,8 @@ public enum ExtendType {
NEITHER,
BOTH,
MIN,
MAX;
MAX,
NONE;
/**
* Get is extend max or not

View File

@ -0,0 +1,9 @@
package org.meteoinfo.geometry.legend;
public enum ExtendFraction {
NONE,
AUTO,
LENGTH;
public float fraction = 1.0f;
}

View File

@ -906,7 +906,7 @@ public class LegendManage {
if (extendType.isExtendMin()) {
ColorBreak cb = new ColorBreak();
cb.setColor(colors[0]);
cb.setStartValue(Double.MIN_VALUE);
cb.setStartValue(-Double.MAX_VALUE);
cb.setEndValue(values.getDouble(0));
cb.setCaption("< " + DataConvert.removeTailingZeros(cb.getEndValue().toString()));
legendScheme.addLegendBreak(0, cb);
@ -1082,15 +1082,13 @@ public class LegendManage {
* @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);
}
public static LegendScheme createLegendScheme(double min, double max, ColorMap ct, ExtendType extendType) {
double[] values = (double[]) MIMath.getIntervalValues(min, max, true).get(0);
Color[] colors = ct.getColors(values.length - 1);
LegendScheme ls = createLegendScheme(values, colors);
ls.setExtendType(extendType);
return ls;
}
/**
@ -1364,7 +1362,10 @@ public class LegendManage {
* @return LegendScheme
*/
public static LegendScheme createLegendScheme(double min, double max, int n, ColorMap ct) {
return createLegendScheme(min, max, n, ct, false);
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);
}
/**
@ -1377,18 +1378,15 @@ public class LegendManage {
* @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);
public static LegendScheme createLegendScheme(double min, double max, int n, ColorMap ct,
ExtendType extendType) {
double[] values = MIMath.getIntervalValues(min, max, n, true);
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);
LegendScheme ls = createLegendScheme(values, colors);
ls.setExtendType(extendType);
return createLegendScheme(min, max, values, colors, LegendType.GRADUATED_COLOR, ShapeTypes.IMAGE, false, -9999.0);
}
return ls;
}
/**

View File

@ -49,7 +49,8 @@ package org.meteoinfo.geometry.legend;
private String fieldName = "";
private LegendType legendType = LegendType.SINGLE_SYMBOL;
private ShapeTypes shapeType;
private ExtendType extendType = ExtendType.NEITHER;
private ExtendType extendType = ExtendType.NONE;
private ExtendFraction extendFraction = ExtendFraction.NONE;
private List<ColorBreak> legendBreaks;
private boolean hasNoData;
private double minValue;
@ -220,6 +221,22 @@ package org.meteoinfo.geometry.legend;
extendType = value;
}
/**
* Get extend fraction
* @return Extend fraction
*/
public ExtendFraction getExtendFraction() {
return this.extendFraction;
}
/**
* Set extend fraction
* @param value
*/
public void setExtendFraction(ExtendFraction value) {
this.extendFraction = value;
}
/**
* Set extend type
* @param value Extend type

View File

@ -1,34 +1,32 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<MeteoInfo File="milconfig.xml" Type="configurefile">
<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\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"/>
<Path OpenPath="D:\Working\MIScript\Jython\mis\io\awx">
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\common_math"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\common_math\interpolate"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\imshow"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\surf"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\isosurface"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\funny"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\array"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\contour"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\meteo\wrf"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io\awx"/>
</Path>
<File>
<OpenedFiles>
<OpenedFile File="D:\Working\MIScript\Jython\mis\traj\hy_conc_geojson.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\plot_types\contour\contourf_bgcolor.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"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\io\awx\awx_fy4a_2.py"/>
</OpenedFiles>
<RecentFiles>
<RecentFile File="D:\Working\MIScript\Jython\mis\traj\hy_conc_geojson.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\plot_types\contour\contourf_bgcolor.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"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\io\awx\awx_fy4a_2.py"/>
</RecentFiles>
</File>
<Font>
@ -36,5 +34,5 @@
</Font>
<LookFeel DockWindowDecorated="true" LafDecorated="true" Name="FlatDarkLaf"/>
<Figure DoubleBuffering="true"/>
<Startup MainFormLocation="-7,0" MainFormSize="1370,786"/>
<Startup MainFormLocation="-7,0" MainFormSize="1361,807"/>
</MeteoInfo>

View File

@ -14,7 +14,7 @@ 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.geometry.legend import BarBreak, PolygonBreak, PolylineBreak, \
PointBreak, LineStyles, PointStyle, LegendScheme, LegendType, LegendManage
PointBreak, LineStyles, PointStyle, LegendScheme, LegendType, LegendManage, ExtendFraction
from org.meteoinfo.geometry.shape import ShapeTypes
from org.meteoinfo.geometry.graphic import Graphic, GraphicCollection
from org.meteoinfo.geometry.colors import ExtendType
@ -2311,7 +2311,7 @@ class Axes(object):
the order specified.
:param smooth: (*boolean*) Smooth contour lines or not.
:returns: (*VectoryLayer*) Contour VectoryLayer created from array data.
:returns: (*contour graphics*) Contour graphics created from array data.
"""
n = len(args)
ls = kwargs.pop('symbolspec', None)
@ -2447,9 +2447,15 @@ class Axes(object):
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 extendfrac: (*string or float*) {None, 'auto', length}, If set to None, both the minimum
and maximum triangular colorbar extensions will have a length of 5% of the interior colorbar
length (this is the default setting). If set to 'auto', makes the triangular colorbar
extensions the same lengths as the interior boxes. If a scalar, indicates the length of both
the minimum and maximum triangular colorbar extensions as a fraction of the interior colorbar
length.
:param smooth: (*boolean*) Smooth contour lines or not.
:returns: (*VectoryLayer*) Contour filled VectoryLayer created from array data.
:returns: (*GraphicCollection*) Contour filled graphics created from array data.
"""
n = len(args)
ls = kwargs.pop('symbolspec', None)
@ -2479,17 +2485,25 @@ class Axes(object):
level_arg = args[0]
if isinstance(level_arg, int):
cn = level_arg
ls = LegendManage.createLegendScheme(vmin, vmax, cn, cmap, True)
ls = LegendManage.createLegendScheme(vmin, vmax, cn, cmap, extend)
else:
if isinstance(level_arg, NDArray):
level_arg = level_arg.aslist()
ls = LegendManage.createLegendScheme(level_arg, cmap, extend)
else:
ls = LegendManage.createLegendScheme(vmin, vmax, cmap, True)
ls = LegendManage.createLegendScheme(vmin, vmax, cmap, extend)
ls = ls.convertTo(ShapeTypes.POLYGON)
if 'edgecolor' not in kwargs.keys():
kwargs['edgecolor'] = None
plotutil.setlegendscheme(ls, **kwargs)
extendfrac = kwargs.pop('extendfrac', None)
if extendfrac is not None:
if extendfrac == 'auto':
efrac = ExtendFraction.AUTO
else:
efrac = ExtendFraction.LENGTH
efrac.fraction = extendfrac
ls.setExtendFraction(efrac)
# norm = kwargs.pop('norm', colors.Normalize(vmin, vmax))
# ls.setNormalize(norm._norm)
# ls.setColorMap(cmap)
@ -2518,7 +2532,7 @@ class Axes(object):
Display an image on the axes.
:param X: (*array_like*) 2-D or 3-D (RGB or RGBA) image value array or BufferedImage.
:param levs: (*array_like*) Optional. A list of floating point numbers indicating the level curves
:param levels: (*array_like*) Optional. A list of floating point numbers indicating the level curves
to draw, in increasing order.
:param cmap: (*string*) Color map string.
:param colors: (*list*) If None (default), the colormap specified by cmap will be used. If a
@ -2527,6 +2541,108 @@ class Axes(object):
the order specified.
:param interpolation: (*string*) Interpolation option [None | bilinear | bicubic].
:returns: (*Image graphic*) Image graphic created from array data.
"""
n = len(args)
cmap = plotutil.getcolormap(**kwargs)
fill_value = kwargs.pop('fill_value', -9999.0)
xaxistype = None
isrgb = False
isimage = False
extent = None
if n >= 3:
xdata = args[0]
ydata = args[1]
extent = [xdata[0], xdata[-1], ydata[0], ydata[-1]]
args = args[2:]
X = args[0]
if isinstance(X, (list, tuple)):
isrgb = True
elif isinstance(X, BufferedImage):
isimage = True
elif X.ndim > 2:
isrgb = True
else:
if n < 3:
if isinstance(X, DimArray):
xdata = X.dimvalue(-1)
ydata = X.dimvalue(-2)
else:
ny, nx = X.shape
xdata = np.arange(nx)
ydata = np.arange(ny)
args = args[1:]
extent = kwargs.pop('extent', extent)
if isrgb:
if isinstance(X, (list, tuple)):
rgbd = []
for d in rgbdata:
rgbd.append(d.asarray())
rgbdata = rgbd
else:
rgbdata = X.asarray()
igraphic = GraphicFactory.createImage(rgbdata, extent)
ls = None
elif isimage:
igraphic = GraphicFactory.createImage(X)
ls = None
else:
ls = kwargs.pop('symbolspec', None)
if ls is None:
vmin = kwargs.pop('vmin', X.min())
vmax = kwargs.pop('vmax', X.max())
if len(args) > 0:
level_arg = args[0]
if isinstance(level_arg, int):
cn = level_arg
ls = LegendManage.createImageLegend(X._array, cn, cmap)
else:
if isinstance(level_arg, NDArray):
level_arg = level_arg.aslist()
ls = LegendManage.createImageLegend(X._array, level_arg, cmap)
else:
ls = plotutil.getlegendscheme(args, vmin, vmax, **kwargs)
norm = kwargs.pop('norm', colors.Normalize(vmin, vmax))
ls.setNormalize(norm._norm)
ls.setColorMap(cmap)
ls = ls.convertTo(ShapeTypes.IMAGE)
plotutil.setlegendscheme(ls, **kwargs)
igraphic = GraphicFactory.createImage(X._array, xdata._array, ydata._array, ls, extent)
interpolation = kwargs.pop('interpolation', None)
if not interpolation is None:
igraphic.getShape().setInterpolation(interpolation)
if not xaxistype is None:
self.set_xaxis_type(xaxistype)
self._axes.updateDrawExtent()
zorder = kwargs.pop('zorder', None)
self.add_graphic(igraphic, zorder=zorder)
self._axes.setAutoExtent()
gridline = self._axes.getGridLine()
gridline.setTop(True)
if ls is None:
return igraphic
else:
return ls
def imshow_bak(self, *args, **kwargs):
"""
Display an image on the axes.
:param X: (*array_like*) 2-D or 3-D (RGB or RGBA) image value array or BufferedImage.
:param levels: (*array_like*) Optional. A list of floating point numbers indicating the level curves
to draw, in increasing order.
: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
the order specified.
:param interpolation: (*string*) Interpolation option [None | bilinear | bicubic].
:returns: (*Image graphic*) Image graphic created from array data.
"""
n = len(args)
@ -3986,7 +4102,7 @@ class Axes(object):
for out-of- range values. These are set for a given colormap using the colormap set_under and
set_over methods.
:param extendrect: (*boolean*) If ``True`` the minimum and maximum colorbar extensions will be
rectangular (the default). If ``False`` the extensions will be triangular.
rectangular. If ``False`` the extensions will be triangular (the default).
:param extendfrac: [None | 'auto' | length] If set to *None*, both the minimum and maximum triangular
colorbar extensions with have a length of 5% of the interior colorbar length (the default). If
set to 'auto', makes the triangular colorbar extensions the same lengths as the interior boxes
@ -3994,7 +4110,7 @@ class Axes(object):
as a fraction of the interior colorbar length.
:param ticks: [None | list of ticks] If None, ticks are determined automatically from the input.
:param ticklabels: [None | list of ticklabels] Tick labels.
:param tickin: (*boolean*) Draw tick line inside or outside of the colorbar.
:param tickin: (*boolean*) Draw tick line inside or outside the colorbar.
:param tickrotation: (*float*) Set tick label rotation angle.
:param xshift: (*float*) X shift of the colorbar with pixel coordinate.
:param yshift: (*float*) Y shift of the colorbar with pixel coordinate.
@ -4074,13 +4190,19 @@ class Axes(object):
legend.setPlotOrientation(PlotOrientation.VERTICAL)
legend.setPosition(LegendPosition.RIGHT_OUTSIDE)
legend.setDrawNeatLine(False)
extend = kwargs.pop('extend', 'neither')
legend.setExtendType(extend)
extendrect = kwargs.pop('extendrect', True)
extend = kwargs.pop('extend', None)
if extend is not None:
legend.setExtendType(extend)
extendrect = kwargs.pop('extendrect', False)
legend.setExtendRect(extendrect)
extendfrac = kwargs.pop('extendfrac', None)
if extendfrac == 'auto':
legend.setAutoExtendFrac(True)
if extendfrac is not None:
if extendfrac == 'auto':
efrac = ExtendFraction.AUTO
else:
efrac = ExtendFraction.LENGTH
efrac.fraction = extendfrac
legend.setExtendFraction(efrac)
tickvisible = kwargs.pop('tickvisible', None)
if not tickvisible is None:
legend.setTickVisible(tickvisible)

View File

@ -1045,17 +1045,17 @@ class MapAxes(Axes):
:param x: (*array_like*) Optional. X coordinate array.
:param y: (*array_like*) Optional. Y coordinate array.
:param z: (*array_like*) 2-D z value array.
:param levs: (*array_like*) Optional. A list of floating point numbers indicating the level curves
:param levels: (*array_like*) Optional. A list of floating point numbers indicating the level curves
to draw, in increasing order.
: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 proj: (*ProjectionInfo*) Map projection of the data. Default is None.
:param isadd: (*boolean*) Add layer or not. Default is ``True``.
:param zorder: (*int*) Z-order of created layer for display.
:param smooth: (*boolean*) Smooth countour lines or not.
:param smooth: (*boolean*) Smooth contour lines or not.
:param select: (*boolean*) Set the return layer as selected layer or not.
:returns: (*VectoryLayer*) Contour VectoryLayer created from array data.
@ -1071,6 +1071,9 @@ class MapAxes(Axes):
y = args[1]
a = args[2]
args = args[3:]
if not kwargs.has_key('extend'):
kwargs['extend'] = 'neither'
ls = plotutil.getlegendscheme(args, a.min(), a.max(), **kwargs)
ls = ls.convertTo(ShapeTypes.POLYGON)
if not kwargs.has_key('edgecolor'):

View File

@ -10,9 +10,8 @@ import datetime
from org.meteoinfo.geometry.legend import LineStyles, HatchStyle, ColorBreak, PointBreak, PolylineBreak, \
PolygonBreak, ArrowBreak, ArrowLineBreak, ArrowPolygonBreak, StreamlineBreak, \
PointStyle, MarkerType, LegendScheme
#from org.meteoinfo.geo.legend import LegendManage
from org.meteoinfo.geometry.legend import LegendManage
PointStyle, MarkerType, LegendScheme, LegendManage, ExtendFraction
from org.meteoinfo.geometry.colors import ExtendType
from org.meteoinfo.common.colors import ColorUtil, ColorMap
from org.meteoinfo.geometry.shape import ShapeTypes
from org.meteoinfo.chart import ChartText
@ -576,29 +575,43 @@ def getlegendbreak(geometry, **kwargs):
def getlegendscheme(args, min, max, **kwargs):
ls = kwargs.pop('symbolspec', None)
if ls is None:
extend = kwargs.pop('extend', None)
if extend is not None:
extend = ExtendType.valueOf(extend.upper())
cmap = getcolormap(**kwargs)
level_arg = kwargs.pop('levels', None)
if level_arg is None and len(args) > 0:
level_arg = args[0]
if level_arg is None:
ls = LegendManage.createLegendScheme(min, max, cmap)
if extend is None:
ls = LegendManage.createLegendScheme(min, max, cmap)
else:
ls = LegendManage.createLegendScheme(min, max, cmap, extend)
else:
if isinstance(level_arg, int):
cn = level_arg
ls = LegendManage.createLegendScheme(min, max, cn, cmap)
if extend is None:
ls = LegendManage.createLegendScheme(min, max, cn, cmap)
else:
ls = LegendManage.createLegendScheme(min, max, cn, cmap, extend)
else:
if isinstance(level_arg, NDArray):
level_arg = level_arg.aslist()
ls = LegendManage.createLegendScheme(min, max, level_arg, cmap)
if extend is None:
ls = LegendManage.createLegendScheme(min, max, level_arg, cmap)
else:
ls = LegendManage.createLegendScheme(level_arg, cmap, extend)
extendfrac = kwargs.pop('extendfrac', None)
if extendfrac is not None:
if extendfrac == 'auto':
efrac = ExtendFraction.AUTO
else:
efrac = ExtendFraction.LENGTH
efrac.fraction = extendfrac
ls.setExtendFraction(efrac)
# ecobj = kwargs.pop('edgecolor', None)
# if not ecobj is None:
# edgecolor = getcolor(ecobj)
# ls = ls.convertTo(ShapeTypes.POLYGON)
# for lb in ls.getLegendBreaks():
# lb.setDrawOutline(True)
# lb.setOutlineColor(edgecolor)
return ls