support colorful streamline in 2D plot

This commit is contained in:
wyq 2024-01-10 10:55:30 +08:00
parent 1ae26ce3ca
commit cac71057b7
15 changed files with 546 additions and 287 deletions

View File

@ -106,6 +106,15 @@ public class ChartText3D extends ChartText {
public void setDraw3D(boolean value) {
this.draw3D = value;
}
/**
* Get point
*
* @return The point coordinates
*/
public PointZ getPoint() {
return new PointZ(x, y, z);
}
/**
* Set point
@ -127,6 +136,15 @@ public class ChartText3D extends ChartText {
aExtent.maxZ = z;
this.setExtent(aExtent);
}
/**
* Set point
*
* @param point The point
*/
public void setPoint(PointZ point) {
setPoint(point.X, point.Y, point.Z);
}
/**
* Update angle

View File

@ -375,9 +375,6 @@ public class GraphicFactory {
x = xIter.getDoubleNext();
y = yIter.getDoubleNext();
z = zIter.getDoubleNext();
//x = xdata.getDouble(j * xn + i);
//y = ydata.getDouble(j * xn + i);
//z = zdata.getDouble(j * xn + i);
cb = ls.findLegendBreak(z);
if (Double.isNaN(y) || Double.isNaN(x)) {
if (points.isEmpty()) {
@ -7175,6 +7172,70 @@ public class GraphicFactory {
return gc;
}
/**
* Create streamline
*
* @param xdata X data array
* @param ydata Y data array
* @param udata U/WindDirection data array
* @param vdata V/WindSpeed data array
* @param cdata Color data array
* @param density Streamline density
* @param ls Legend scheme
* @param isUV Is U/V or not
* @return GraphicCollection
*/
public static GraphicCollection createStreamlines(Array xdata, Array ydata, Array udata, Array vdata,
Array cdata, int density, LegendScheme ls, boolean isUV) {
GraphicCollection gc = new GraphicCollection();
if (!isUV) {
Array[] uvData = MeteoMath.ds2uv(udata, vdata);
udata = uvData[0];
vdata = uvData[1];
}
double[][] u = (double[][])ArrayUtil.copyToNDJavaArray_Double(udata);
double[][] v = (double[][])ArrayUtil.copyToNDJavaArray_Double(vdata);
double[] x = (double[]) ArrayUtil.copyToNDJavaArray_Double(xdata);
double[] y = (double[]) ArrayUtil.copyToNDJavaArray_Double(ydata);
List<PolyLine> streamlines = Contour.tracingStreamline(u, v,
x, y, density);
PolyLine line;
ColorBreakCollection cbc;
int ny = u.length;
int nx = u[0].length;
double c = 0;
ColorBreak cb;
for (int i = 0; i < streamlines.size(); i++) {
line = streamlines.get(i);
PolylineShape aPolyline = new PolylineShape();
PointD p;
List<PointD> pList = new ArrayList<>();
cbc = new ColorBreakCollection();
for (int j = 0; j < line.PointList.size(); j++) {
p = new PointD();
p.X = (line.PointList.get(j)).X;
p.Y = (line.PointList.get(j)).Y;
int[] idx = ArrayUtil.gridIndex(xdata, ydata, p.X, p.Y);
if (idx != null) {
int yi = idx[0];
int xi = idx[1];
c = cdata.getDouble(yi * nx + xi);
}
cb = ls.findLegendBreak(c);
cbc.add(cb);
pList.add(p);
}
aPolyline.setPoints(pList);
aPolyline.setValue(density);
gc.add(new Graphic(aPolyline, cbc));
}
gc.setSingleLegend(false);
gc.setLegendScheme(ls);
return gc;
}
/**
* Trace 3D streamlines
* @param xa X coordinate array

View File

@ -3941,6 +3941,7 @@ public class GLPlot extends Plot {
float strWidth = 0;
Rectangle2D rect;
float xShift = this.tickSpace * this.dpiScale;
this.updateTextRender(legend.getTickLabelFont());
for (int i = 0; i < bNum; i++) {
if (labelIdxs.contains(i)) {
ColorBreak cb = ls.getLegendBreaks().get(i);
@ -4090,6 +4091,7 @@ public class GLPlot extends Plot {
float strWidth = 0;
Rectangle2D rect;
float xShift = this.tickSpace * this.dpiScale;
this.updateTextRender(legend.getTickLabelFont());
for (int i = 0; i < legend.getTickLocations().size(); i++) {
yy = y + minMaxHeight * normalize.apply(legend.getTickLocations().get(i)).floatValue();
String label = legend.getTickLabels().get(i).getText();

View File

@ -1,6 +1,7 @@
package org.meteoinfo.chart.jogl;
import org.joml.Vector3f;
import org.meteoinfo.chart.ChartText3D;
import org.meteoinfo.chart.graphic.*;
import org.meteoinfo.chart.jogl.tessellator.Primitive;
import org.meteoinfo.chart.jogl.tessellator.TessPolygon;
@ -132,53 +133,64 @@ public class SphericalTransform {
} else if (graphic instanceof VolumeGraphic) {
return graphic;
} else {
GraphicCollection3D graphics = (GraphicCollection3D) graphic;
for (int i = 0; i < graphics.getNumGraphics(); i++) {
Graphic gg = graphics.getGraphicN(i);
Shape shape = gg.getGraphicN(0).getShape();
boolean isTess = false;
if (shape instanceof PolygonZShape) {
PolygonBreak pb = (PolygonBreak) gg.getGraphicN(0).getLegend();
isTess = pb.isDrawFill();
}
if (isTess) {
PolygonZShape polygonZShape = (PolygonZShape) shape;
List<PolygonZ> polygonZS = (List<PolygonZ>) polygonZShape.getPolygons();
for (int j = 0; j < polygonZS.size(); j++) {
PolygonZ polygonZ = polygonZS.get(j);
TessPolygon tessPolygon = new TessPolygon(polygonZ);
for (Primitive primitive : tessPolygon.getPrimitives()) {
for (int k = 0; k < primitive.vertices.size(); k++) {
primitive.vertices.set(k, transform(primitive.vertices.get(k)));
}
}
List<PointZ> outLine = (List<PointZ>) tessPolygon.getOutLine();
for (int k = 0; k < outLine.size(); k++) {
outLine.set(k, transform(outLine.get(k)));
}
for (int k = 0; k < tessPolygon.getHoleLineNumber(); k++) {
List<PointZ> holeLine = (List<PointZ>) tessPolygon.getHoleLine(k);
for (int l = 0; l < holeLine.size(); l++) {
holeLine.set(l, transform(holeLine.get(l)));
}
}
polygonZS.set(j, tessPolygon);
if (graphic instanceof GraphicCollection3D) {
GraphicCollection3D graphics = (GraphicCollection3D) graphic;
for (int i = 0; i < graphics.getNumGraphics(); i++) {
Graphic gg = graphics.getGraphicN(i);
Shape shape = gg.getGraphicN(0).getShape();
boolean isTess = false;
if (shape instanceof PolygonZShape) {
PolygonBreak pb = (PolygonBreak) gg.getGraphicN(0).getLegend();
isTess = pb.isDrawFill();
}
if (isTess) {
PolygonZShape polygonZShape = (PolygonZShape) shape;
List<PolygonZ> polygonZS = (List<PolygonZ>) polygonZShape.getPolygons();
for (int j = 0; j < polygonZS.size(); j++) {
PolygonZ polygonZ = polygonZS.get(j);
TessPolygon tessPolygon = new TessPolygon(polygonZ);
for (Primitive primitive : tessPolygon.getPrimitives()) {
primitive.vertices.replaceAll(SphericalTransform::transform);
}
List<PointZ> outLine = (List<PointZ>) tessPolygon.getOutLine();
outLine.replaceAll(SphericalTransform::transform);
for (int k = 0; k < tessPolygon.getHoleLineNumber(); k++) {
List<PointZ> holeLine = (List<PointZ>) tessPolygon.getHoleLine(k);
holeLine.replaceAll(SphericalTransform::transform);
}
polygonZS.set(j, tessPolygon);
}
} else {
List<PointZ> points = (List<PointZ>) shape.getPoints();
points.replaceAll(SphericalTransform::transform);
if (shape instanceof PolygonZShape)
((PolygonZShape) shape).setPoints_keep(points);
else
shape.setPoints(points);
}
gg.setShape(shape);
graphics.setGraphicN(i, gg);
}
graphics.updateExtent();
return graphics;
} else {
Graphic gg = graphic.getGraphicN(0);
Shape shape = gg.getShape();
if (shape instanceof ChartText3D) {
PointZ p = ((ChartText3D) shape).getPoint();
((ChartText3D) shape).setPoint(SphericalTransform.transform(p));
} else {
List<PointZ> points = (List<PointZ>) shape.getPoints();
for (int j = 0; j < points.size(); j++) {
points.set(j, transform(points.get(j)));
}
points.replaceAll(SphericalTransform::transform);
if (shape instanceof PolygonZShape)
((PolygonZShape) shape).setPoints_keep(points);
else
shape.setPoints(points);
}
gg.setShape(shape);
graphics.setGraphicN(i, gg);
return gg;
}
graphics.updateExtent();
return graphics;
}
}
}

View File

@ -470,7 +470,11 @@ public class Plot2D extends AbstractPlot2D {
sXY = projToScreen(wPoint.X, wPoint.Y, area);
points[i] = new PointF((float) sXY[0], (float) sXY[1]);
}
Draw.drawPolyline(points, cpc, g);
if (cpc.get(0) instanceof StreamlineBreak) {
Draw.drawStreamline(points, cpc, g);
} else {
Draw.drawPolyline(points, cpc, g);
}
}
}

View File

@ -67,7 +67,7 @@ import java.util.zip.ZipInputStream;
public static String getVersion(){
String version = GlobalUtil.class.getPackage().getImplementationVersion();
if (version == null || version.equals("")) {
version = "3.7.7";
version = "3.7.8";
}
return version;
}

View File

@ -3004,7 +3004,7 @@ public class Draw {
int interval = alb.getInterval() * 3;
for (int i = 0; i < points.length; i++) {
if (i > 0 && i < points.length - 2 && i % interval == 0) {
//Draw arraw
//Draw arrow
p1 = points[i];
p2 = points[i + 1];
u = p2.X - p1.X;
@ -3056,6 +3056,75 @@ public class Draw {
}
}
/**
* Draw streamline
*
* @param points The points
* @param cbc The streamline breaks
* @param g Graphics2D
*/
public static void drawStreamline(PointF[] points, ColorBreakCollection cbc, Graphics2D g) {
drawPolyline(points, cbc, g);
PointF p1, p2;
double u, v, radian, angle;
StreamlineBreak slb = (StreamlineBreak) cbc.get(0);
int interval = slb.getInterval() * 3;
for (int i = 0; i < points.length; i++) {
if (i > 0 && i < points.length - 2 && i % interval == 0) {
//Draw arraw
p1 = points[i];
p2 = points[i + 1];
u = p2.X - p1.X;
v = p2.Y - p1.Y;
radian = Math.atan(v / u);
angle = radian * 180 / Math.PI;
angle = angle + 90;
if (u < 0) {
angle = angle + 180;
}
if (angle >= 360) {
angle = angle - 360;
}
//Draw arrow
slb = (StreamlineBreak) cbc.get(i);
Draw.drawArraw(g, p1, angle, slb.getArrowHeadLength(), slb.getArrowHeadWidth(),
slb.getArrowOverhang(), slb.getArrowFillColor(), slb.getArrowOutlineColor());
}
}
//Draw symbol
if (slb.isDrawSymbol()) {
Object rend = g.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
Rectangle clip = g.getClipBounds();
PointF p;
if (clip != null) {
g.setClip(null);
for (int i = 0; i < points.length; i++) {
p = new PointF(points[i].X, points[i].Y);
if (p.X >= clip.x && p.X <= clip.x + clip.width && p.Y >= clip.y && p.Y <= clip.y + clip.height) {
if (i % slb.getSymbolInterval() == 0) {
drawPoint(slb.getSymbolStyle(), p, slb.getSymbolFillColor(), slb.getSymbolColor(),
slb.getSymbolSize(), slb.isDrawSymbolOutline(), slb.isFillSymbol(), g);
}
}
}
g.setClip(clip);
} else {
for (int i = 0; i < points.length; i++) {
if (i % slb.getSymbolInterval() == 0) {
p = new PointF(points[i].X, points[i].Y);
drawPoint(slb.getSymbolStyle(), p, slb.getSymbolFillColor(), slb.getSymbolColor(),
slb.getSymbolSize(), slb.isDrawSymbolOutline(), slb.isFillSymbol(), g);
}
}
}
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, rend);
}
}
/**
* Draw polyline
*

View File

@ -5399,16 +5399,20 @@ public class MapView extends JPanel implements IWebMapPanel {
// }
}
private void drawPolylineLayer(VectorLayer aLayer, Graphics2D g, double LonShift) {
LegendScheme aLS = aLayer.getLegendScheme();
private void drawPolylineLayer(VectorLayer aLayer, Graphics2D g, double lonShift) {
LegendScheme ls = aLayer.getLegendScheme();
if (aLS.isGeometry()) {
if (ls.isGeometry()) {
for (int s = 0; s < aLayer.getShapeNum(); s++) {
PolylineShape aPLS = (PolylineShape) aLayer.getShapes().get(s);
if (!aPLS.isVisible()) {
PolylineShape pls = (PolylineShape) aLayer.getShapes().get(s);
if (!pls.isVisible()) {
continue;
}
drawPolylineShape(g, aPLS, aLS, LonShift);
if (ls.getLegendBreak(0) instanceof StreamlineBreak) {
drawStreamline(g, pls, ls, lonShift);
} else {
drawPolylineShape(g, pls, ls, lonShift);
}
}
} else {
//PointD wPoint;
@ -5416,52 +5420,26 @@ public class MapView extends JPanel implements IWebMapPanel {
//double[] screenXY;
switch (aLayer.getLayerDrawType()) {
// case TrajLine:
// //Draw start point symbol
// PointF aPF = new PointF();
// for (int s = 0; s < aLayer.getShapeNum(); s++) {
// PolylineShape aPLS = (PolylineShape) aLayer.getShapes().get(s);
// wPoint = aPLS.getPoints().get(0);
// aPF.X = (float) (wPoint.X + LonShift);
// aPF.Y = (float) (wPoint.Y);
// if (MIMath.pointInExtent(aPF, _drawExtent)) {
// screenXY = projToScreen(wPoint.X, wPoint.Y, LonShift);
// aPF.X = (float) screenXY[0];
// aPF.Y = (float) screenXY[1];
// Draw.drawPoint(PointStyle.UpTriangle, aPF, this.getForeground(),
// this.getForeground(), 10, true, true, g);
// }
// }
// break;
case STREAMLINE:
isStreamline = true;
break;
}
for (int s = 0; s < aLayer.getShapeNum(); s++) {
PolylineShape aPLS = (PolylineShape) aLayer.getShapes().get(s);
if (!aPLS.isVisible()) {
PolylineShape pls = (PolylineShape) aLayer.getShapes().get(s);
if (!pls.isVisible()) {
continue;
}
if (aPLS.getLegendIndex() < 0) {
if (pls.getLegendIndex() < 0) {
continue;
}
PolylineBreak aPLB = (PolylineBreak) aLS.getLegendBreaks().get(aPLS.getLegendIndex());
PolylineBreak aPLB = (PolylineBreak) ls.getLegendBreaks().get(pls.getLegendIndex());
if (aPLB.isDrawPolyline() || aPLB.isDrawSymbol()) {
drawPolylineShape(g, aPLS, aPLB, LonShift, isStreamline);
drawPolylineShape(g, pls, aPLB, lonShift, isStreamline);
}
}
}
// //Draw identifer shape
// if (_drawIdentiferShape) {
// PolylineShape aPLS = (PolylineShape) aLayer.getShapes().get(aLayer.getIdentiferShape());
// PolylineBreak aPLB = new PolylineBreak();
// aPLB.setColor(Color.red);
// aPLB.setSize(2);
// drawPolylineShape(g, aPLS, aPLB, LonShift, isStreamline);
// }
}
private static float[] getDashPattern(LineStyles style) {
@ -5534,32 +5512,6 @@ public class MapView extends JPanel implements IWebMapPanel {
if (isStreamline) {
Draw.drawPolyline(Points, aPLB, g);
/*int len = (int) (aPLS.getValue() * 3);
PointF aPoint;
for (int i = 0; i < Points.length; i++) {
if (i > 0 && i < Points.length - 2 && i % len == 0) {
//Draw arraw
aPoint = Points[i];
PointF bPoint = Points[i + 1];
double U = bPoint.X - aPoint.X;
double V = bPoint.Y - aPoint.Y;
double angle = Math.atan((V) / (U)) * 180 / Math.PI;
if (Double.isNaN(angle)) {
continue;
}
angle = angle + 90;
if (U < 0) {
angle = angle + 180;
}
if (angle >= 360) {
angle = angle - 360;
}
Draw.drawArraw(g, aPoint, angle);
}
}*/
}
g.draw(path);
@ -5655,6 +5607,90 @@ public class MapView extends JPanel implements IWebMapPanel {
}
}
private void drawStreamline(Graphics2D g, PolylineShape aPLS, LegendScheme ls, double LonShift) {
Extent shapeExtent = MIMath.shiftExtentLon(aPLS.getExtent(), LonShift);
if (!MIMath.isExtentCross(shapeExtent, _drawExtent)) {
return;
}
int len1 = aPLS.getPoints().size();
GeneralPath path = new GeneralPath(GeneralPath.WIND_EVEN_ODD, len1);
List<PointF> drawPs = new ArrayList<>();
double value;
boolean isZ = ls.getFieldName().equals("Geometry_Z");
StreamlineBreak slb = (StreamlineBreak) ls.getLegendBreak(0);
int interval = slb.getInterval() * 3;
PointF p1, p2;
double u, v, radian, angle;
Color color = Color.black;
for (Polyline aline : aPLS.getPolylines()) {
double[] sXY;
for (int i = 0; i < aline.getPointList().size(); i++) {
PointZ wPoint = (PointZ) aline.getPointList().get(i);
sXY = projToScreen(wPoint.X, wPoint.Y, LonShift);
if (i == 0) {
path.moveTo(sXY[0], sXY[1]);
} else {
path.lineTo(sXY[0], sXY[1]);
if (isZ) {
value = wPoint.Z;
} else {
value = wPoint.M;
}
PolylineBreak aPLB = (PolylineBreak) ls.findLegendBreak(value);
color = aPLB.getColor();
Float size = aPLB.getWidth();
float[] dashPattern = getDashPattern(aPLB.getStyle());
BasicStroke pen = new BasicStroke(size, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, dashPattern, 0.0f);
g.setColor(color);
g.setStroke(pen);
g.draw(path);
path.reset();
path.moveTo(sXY[0], sXY[1]);
//Draw symbol
if (aPLB.isDrawSymbol()) {
Object rend = g.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
for (int j = 0; j < drawPs.size(); j++) {
Draw.drawPoint(aPLB.getSymbolStyle(), new PointF((float) sXY[0], (float) sXY[1]), aPLB.getSymbolFillColor(), aPLB.getSymbolColor(),
aPLB.getSymbolSize(), true, aPLB.isFillSymbol(), g);
}
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, rend);
}
}
drawPs.add(new PointF((float) sXY[0], (float) sXY[1]));
if (i > 1 && i < aline.getPointList().size() - 1 && i % interval == 0) {
//Draw arraw
p1 = drawPs.get(i - 1);
p2 = drawPs.get(i);
u = p2.X - p1.X;
v = p2.Y - p1.Y;
radian = Math.atan(v / u);
angle = radian * 180 / Math.PI;
angle = angle + 90;
if (u < 0) {
angle = angle + 180;
}
if (angle >= 360) {
angle = angle - 360;
}
//Draw arrow
Draw.drawArraw(g, p1, angle, slb.getArrowHeadLength(), slb.getArrowHeadWidth(),
slb.getArrowOverhang(), color, color);
}
}
}
//Draw selected vertices
if (aPLS.isEditing()) {
for (PointF drawP : drawPs) {
Draw.drawSelectedVertice(g, drawP, 8, Color.red, Color.cyan);
}
}
}
private void drawPolygonShape(Graphics2D g, PolygonShape aPGS, PolygonBreak aPGB, double LonShift) {
drawPolygonShape(g, aPGS, aPGB, LonShift, false);
}

View File

@ -36,6 +36,7 @@ import org.meteoinfo.ndarray.IndexIterator;
import org.meteoinfo.ndarray.math.ArrayUtil;
import org.meteoinfo.table.DataTable;
import org.meteoinfo.table.Field;
import wcontour.Contour;
import wcontour.global.PolyLine;
import wcontour.global.Polygon;
@ -1651,21 +1652,146 @@ public class DrawMeteoData {
/**
* Create streamline layer by U/V or wind direction/speed grid data
*
* @param u U grid data
* @param v V grid data
* @param x X array
* @param y Y array
* @param udata U data array
* @param vdata V data array
* @param xdata X array
* @param ydata Y array
* @param density Density
* @param aLS Legend scheme
* @param ls Legend scheme
* @param lName Layer name
* @param isUV If is U/V
* @return Vector layer
*/
public static VectorLayer createStreamlineLayer(Array u, Array v, Array x, Array y, int density, LegendScheme aLS,
public static VectorLayer createStreamlineLayer(Array udata, Array vdata, Array xdata, Array ydata, int density, LegendScheme ls,
String lName, boolean isUV) {
GridData uData = new GridData(u, x, y);
GridData vData = new GridData(v, x, y);
return createStreamlineLayer(uData, vData, density, aLS, lName, isUV);
if (!isUV) {
Array[] uvData = MeteoMath.ds2uv(udata, vdata);
udata = uvData[0];
vdata = uvData[1];
}
double[][] u = (double[][])ArrayUtil.copyToNDJavaArray_Double(udata);
double[][] v = (double[][])ArrayUtil.copyToNDJavaArray_Double(vdata);
double[] x = (double[]) ArrayUtil.copyToNDJavaArray_Double(xdata);
double[] y = (double[]) ArrayUtil.copyToNDJavaArray_Double(ydata);
List<PolyLine> streamlines = Contour.tracingStreamline(u, v,
x, y, density);
PolyLine aLine;
VectorLayer aLayer = new VectorLayer(ShapeTypes.POLYLINE_Z);
aLayer.editAddField("ID", DataType.INT);
for (int i = 0; i < streamlines.size() - 1; i++) {
aLine = streamlines.get(i);
PolylineShape aPolyline = new PolylineShape();
PointD aPoint;
List<PointD> pList = new ArrayList<>();
for (int j = 0; j < aLine.PointList.size(); j++) {
aPoint = new PointD();
aPoint.X = (aLine.PointList.get(j)).X;
aPoint.Y = (aLine.PointList.get(j)).Y;
pList.add(aPoint);
}
aPolyline.setPoints(pList);
aPolyline.setValue(density);
int shapeNum = aLayer.getShapeNum();
try {
if (aLayer.editInsertShape(aPolyline, shapeNum)) {
aLayer.editCellValue("ID", shapeNum, shapeNum + 1);
}
} catch (Exception ex) {
Logger.getLogger(DrawMeteoData.class.getName()).log(Level.SEVERE, null, ex);
}
}
aLayer.setLayerName(lName);
ls.setFieldName("ID");
if (ls.getShapeType() != ShapeTypes.POLYLINE)
ls = ls.convertTo(ShapeTypes.POLYLINE);
aLayer.setLegendScheme(ls);
aLayer.setLayerDrawType(LayerDrawType.STREAMLINE);
return aLayer;
}
/**
* Create streamline layer by U/V or wind direction/speed grid data
*
* @param udata U data array
* @param vdata V data array
* @param xdata X array
* @param ydata Y array
* @param cdata Color data array
* @param density Density
* @param ls Legend scheme
* @param lName Layer name
* @param isUV If is U/V
* @return Vector layer
*/
public static VectorLayer createStreamlineLayer(Array udata, Array vdata, Array xdata, Array ydata, Array cdata,
int density, LegendScheme ls, String lName, boolean isUV) {
if (!isUV) {
Array[] uvData = MeteoMath.ds2uv(udata, vdata);
udata = uvData[0];
vdata = uvData[1];
}
double[][] u = (double[][])ArrayUtil.copyToNDJavaArray_Double(udata);
double[][] v = (double[][])ArrayUtil.copyToNDJavaArray_Double(vdata);
double[] x = (double[]) ArrayUtil.copyToNDJavaArray_Double(xdata);
double[] y = (double[]) ArrayUtil.copyToNDJavaArray_Double(ydata);
List<PolyLine> streamlines = Contour.tracingStreamline(u, v,
x, y, density);
int ny = u.length;
int nx = u[0].length;
PolyLine aLine;
VectorLayer aLayer = new VectorLayer(ShapeTypes.POLYLINE_Z);
aLayer.editAddField("ID", DataType.INT);
for (int i = 0; i < streamlines.size() - 1; i++) {
aLine = streamlines.get(i);
PolylineZShape aPolyline = new PolylineZShape();
PointZ p;
List<PointD> pList = new ArrayList<>();
double c = 0;
for (int j = 0; j < aLine.PointList.size(); j++) {
p = new PointZ();
p.X = (aLine.PointList.get(j)).X;
p.Y = (aLine.PointList.get(j)).Y;
int[] idx = ArrayUtil.gridIndex(xdata, ydata, p.X, p.Y);
if (idx != null) {
int yi = idx[0];
int xi = idx[1];
c = cdata.getDouble(yi * nx + xi);
}
p.Z = c;
pList.add(p);
}
aPolyline.setPoints(pList);
aPolyline.setValue(density);
int shapeNum = aLayer.getShapeNum();
try {
if (aLayer.editInsertShape(aPolyline, shapeNum)) {
aLayer.editCellValue("ID", shapeNum, shapeNum + 1);
}
} catch (Exception ex) {
Logger.getLogger(DrawMeteoData.class.getName()).log(Level.SEVERE, null, ex);
}
}
aLayer.setLayerName(lName);
ls.setFieldName("Geometry_Z");
if (ls.getShapeType() != ShapeTypes.POLYLINE)
ls = ls.convertTo(ShapeTypes.POLYLINE);
aLayer.setLegendScheme(ls);
aLayer.setLayerDrawType(LayerDrawType.STREAMLINE);
return aLayer;
}
/**

View File

@ -1,30 +1,32 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<MeteoInfo File="milconfig.xml" Type="configurefile">
<Path OpenPath="D:\Working\MIScript\Jython\mis\test">
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\city"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io\burf"/>
<Path OpenPath="D:\Working\MIScript\Jython\mis\meteo\wrf">
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\traj"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\traj\calculate"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\LaSW"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\LaSW\airship"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\text"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io\numpy"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\isosurface"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io\matlab"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\array"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\3d_earth"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\chart"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\chart\legend"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\wind"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\map"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\map\webmap"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io\netcdf"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\test"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\meteo"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\meteo\wrf"/>
</Path>
<File>
<OpenedFiles>
<OpenedFile File="D:\Working\MIScript\Jython\mis\io\numpy\load_npz_2.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\test\test_class_inherit.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\plot_types\wind\streamplot_cdata_map_1.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\3d_earth\plot_cuace_earth_isosurface_streamline.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\meteo\wrf\wrf_destagger_uv_webmap.py"/>
</OpenedFiles>
<RecentFiles>
<RecentFile File="D:\Working\MIScript\Jython\mis\io\numpy\load_npz_2.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\test\test_class_inherit.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\plot_types\wind\streamplot_cdata_map_1.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\3d_earth\plot_cuace_earth_isosurface_streamline.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\meteo\wrf\wrf_destagger_uv_webmap.py"/>
</RecentFiles>
</File>
<Font>
@ -32,5 +34,5 @@
</Font>
<LookFeel DockWindowDecorated="true" LafDecorated="true" Name="FlatDarkLaf"/>
<Figure DoubleBuffering="true"/>
<Startup MainFormLocation="-7,-7" MainFormSize="1293,685"/>
<Startup MainFormLocation="-7,0" MainFormSize="1383,794"/>
</MeteoInfo>

View File

@ -1240,12 +1240,6 @@ class Axes(object):
xx = np.zeros(ydata.shape)
xx[:, :] = xdata
xdata = xx
# if ydata.islondim(0):
# xaxistype = 'lon'
# elif ydata.islatdim(0):
# xaxistype = 'lat'
# elif ydata.istimedim(0):
# xaxistype = 'time'
else:
xdata = np.arange(ydata.shape[-1])
if ydata.ndim == 2:
@ -1264,12 +1258,6 @@ class Axes(object):
xx = np.zeros(ydata.shape)
xx[:, :] = xdata
xdata = xx
# if ydata.islondim(0):
# xaxistype = 'lon'
# elif ydata.islatdim(0):
# xaxistype = 'lat'
# elif ydata.istimedim(0):
# xaxistype = 'time'
else:
xdata = np.arange(ydata.shape[-1])
if ydata.ndim == 2:
@ -1307,7 +1295,8 @@ class Axes(object):
# Set plot data styles
zvalues = kwargs.pop('zvalues', None)
if zvalues is None:
cdata = kwargs.pop('cdata', zvalues)
if cdata is None:
lines = []
legend = kwargs.pop('legend', None)
if not legend is None:
@ -1349,19 +1338,18 @@ class Axes(object):
else:
ls = kwargs.pop('symbolspec', None)
if ls is None:
if isinstance(zvalues, (list, tuple)):
zvalues = np.array(zvalues)
if isinstance(cdata, (list, tuple)):
cdata = np.array(cdata)
levels = kwargs.pop('levs', None)
if levels is None:
levels = kwargs.pop('levels', None)
levels = kwargs.pop('levels', levels)
if levels is None:
cnum = kwargs.pop('cnum', None)
if cnum is None:
ls = plotutil.getlegendscheme([], zvalues.min(), zvalues.max(), **kwargs)
ls = plotutil.getlegendscheme([], cdata.min(), cdata.max(), **kwargs)
else:
ls = plotutil.getlegendscheme([cnum], zvalues.min(), zvalues.max(), **kwargs)
ls = plotutil.getlegendscheme([cnum], cdata.min(), cdata.max(), **kwargs)
else:
ls = plotutil.getlegendscheme([levels], zvalues.min(), zvalues.max(), **kwargs)
ls = plotutil.getlegendscheme([levels], cdata.min(), cdata.max(), **kwargs)
ls = plotutil.setlegendscheme_line(ls, **kwargs)
if not xaxistype is None:
@ -1382,7 +1370,7 @@ class Axes(object):
self.add_graphic(graphic, zorder=zorder)
graphics.append(graphic)
else:
if zvalues is None:
if cdata is None:
# Add data series
snum = len(xdatalist)
if snum == 1:
@ -1416,7 +1404,7 @@ class Axes(object):
else:
xdata = plotutil.getplotdata(xdatalist[0])
ydata = plotutil.getplotdata(ydatalist[0])
zdata = plotutil.getplotdata(zvalues)
zdata = plotutil.getplotdata(cdata)
graphic = GraphicFactory.createLineString(xdata, ydata, zdata, ls, iscurve)
self.add_graphic(graphic, zorder=zorder)
graphics.append(graphic)
@ -2313,14 +2301,14 @@ class Axes(object):
: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 smooth: (*boolean*) Smooth countour lines or not.
:param smooth: (*boolean*) Smooth contour lines or not.
:returns: (*VectoryLayer*) Contour VectoryLayer created from array data.
"""
@ -2447,14 +2435,14 @@ class Axes(object):
: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 smooth: (*boolean*) Smooth countour lines or not.
:param smooth: (*boolean*) Smooth contour lines or not.
:returns: (*VectoryLayer*) Contour filled VectoryLayer created from array data.
"""
@ -3734,15 +3722,37 @@ class Axes(object):
y = args[1]
u = args[2]
v = args[3]
alb, isunique = plotutil.getlegendbreak('line', **kwargs)
if not kwargs.has_key('headwidth'):
kwargs['headwidth'] = 8
if not kwargs.has_key('overhang'):
kwargs['overhang'] = 0.5
alb = plotutil.line2stream(alb, **kwargs)
igraphic = GraphicFactory.createStreamlines(x._array, y._array, u._array, v._array,
density, alb, isuv)
cdata = kwargs.pop('cdata', None)
if cdata is None:
alb, isunique = plotutil.getlegendbreak('line', **kwargs)
alb = plotutil.line2stream(alb, **kwargs)
igraphic = GraphicFactory.createStreamlines(x._array, y._array, u._array, v._array,
density, alb, isuv)
else:
if isinstance(cdata, (list, tuple)):
cdata = np.array(cdata)
levels = kwargs.pop('levels', None)
if levels is None:
cnum = kwargs.pop('cnum', None)
if cnum is None:
ls = plotutil.getlegendscheme([], cdata.min(), cdata.max(), **kwargs)
else:
ls = plotutil.getlegendscheme([cnum], cdata.min(), cdata.max(), **kwargs)
else:
ls = plotutil.getlegendscheme([levels], cdata.min(), cdata.max(), **kwargs)
ls = plotutil.setlegendscheme_line(ls, **kwargs)
for i in range(ls.getBreakNum()):
lb = plotutil.line2stream(ls.getLegendBreak(i), **kwargs)
ls.setLegendBreak(i, lb)
igraphic = GraphicFactory.createStreamlines(x._array, y._array, u._array, v._array,
cdata._array, density, ls, isuv)
zorder = kwargs.pop('zorder', None)
self.add_graphic(igraphic, zorder=zorder)

View File

@ -647,7 +647,7 @@ class MapAxes(Axes):
:param linewidth: (*float*) Line width.
:param color: (*Color*) Line color.
:returns: (*VectoryLayer*) Line VectoryLayer.
:returns: (*VectorLayer*) Line VectorLayer.
"""
fill_value = kwargs.pop('fill_value', -9999.0)
proj = kwargs.pop('proj', None)
@ -712,7 +712,8 @@ class MapAxes(Axes):
#Get plot data styles - Legend
zvalues = kwargs.pop('zvalues', None)
if zvalues is None:
cdata = kwargs.pop('cdata', zvalues)
if cdata is None:
lines = []
ls = kwargs.pop('legend', None)
if ls is None:
@ -734,25 +735,25 @@ class MapAxes(Axes):
else:
ls = kwargs.pop('symbolspec', None)
if ls is None:
if isinstance(zvalues, (list, tuple)):
zvalues = np.array(zvalues)
if isinstance(cdata, (list, tuple)):
cdata = np.array(cdata)
levels = kwargs.pop('levs', None)
if levels is None:
levels = kwargs.pop('levels', None)
if levels is None:
cnum = kwargs.pop('cnum', None)
if cnum is None:
ls = plotutil.getlegendscheme([], zvalues.min(), zvalues.max(), **kwargs)
ls = plotutil.getlegendscheme([], cdata.min(), cdata.max(), **kwargs)
else:
ls = plotutil.getlegendscheme([cnum], zvalues.min(), zvalues.max(), **kwargs)
ls = plotutil.getlegendscheme([cnum], cdata.min(), cdata.max(), **kwargs)
else:
ls = plotutil.getlegendscheme([levels], zvalues.min(), zvalues.max(), **kwargs)
ls = plotutil.getlegendscheme([levels], cdata.min(), cdata.max(), **kwargs)
ls = plotutil.setlegendscheme_line(ls, **kwargs)
ls.setFieldName('Geometry_Z')
aslayer = kwargs.pop('aslayer', True)
if aslayer:
if zvalues is None:
if cdata is None:
for i in range(snum):
xdatalist[i] = plotutil.getplotdata(xdatalist[i])
ydatalist[i] = plotutil.getplotdata(ydatalist[i])
@ -781,7 +782,7 @@ class MapAxes(Axes):
else:
xdata = plotutil.getplotdata(xdatalist[0])
ydata = plotutil.getplotdata(ydatalist[0])
zdata = plotutil.getplotdata(zvalues)
zdata = plotutil.getplotdata(cdata)
if is_lonlat:
layer = DrawMeteoData.createPolylineLayer(xdata, ydata, zdata, ls, \
'Plot_lines', 'ID', -180, 180)
@ -804,7 +805,7 @@ class MapAxes(Axes):
else:
iscurve = False
graphics = []
if zvalues is None:
if cdata is None:
#Add data series
if snum == 1:
xdata = plotutil.getplotdata(xdatalist[0])
@ -837,7 +838,7 @@ class MapAxes(Axes):
else:
xdata = plotutil.getplotdata(xdatalist[0])
ydata = plotutil.getplotdata(ydatalist[0])
zdata = plotutil.getplotdata(zvalues)
zdata = plotutil.getplotdata(cdata)
graphic = GraphicFactory.createLineString(xdata, ydata, zdata, ls, iscurve)
self.add_graphic(graphic, proj)
graphics.append(graphic)
@ -848,109 +849,7 @@ class MapAxes(Axes):
return graphics
else:
return graphics[0]
def plot_bak(self, *args, **kwargs):
"""
Plot lines and/or markers to the map.
:param x: (*array_like*) Input x data.
:param y: (*array_like*) Input y data.
:param style: (*string*) Line style for plot.
:param linewidth: (*float*) Line width.
:param color: (*Color*) Line color.
:returns: (*VectoryLayer*) Line VectoryLayer.
"""
fill_value = kwargs.pop('fill_value', -9999.0)
proj = kwargs.pop('proj', None)
order = kwargs.pop('order', None)
n = len(args)
xdatalist = []
ydatalist = []
styles = []
if n == 1:
ydata = plotutil.getplotdata(args[0])
if isinstance(args[0], DimArray):
xdata = args[0].dimvalue(0)
else:
xdata = []
for i in range(0, len(args[0])):
xdata.append(i)
xdatalist.append(np.asarray(xdata)._array)
ydatalist.append(np.asarray(ydata)._array)
elif n == 2:
if isinstance(args[1], basestring):
ydata = plotutil.getplotdata(args[0])
if isinstance(args[0], DimArray):
xdata = args[0].dimvalue(0)
else:
xdata = []
for i in range(0, len(args[0])):
xdata.append(i)
styles.append(args[1])
else:
xdata = plotutil.getplotdata(args[0])
ydata = plotutil.getplotdata(args[1])
xdatalist.append(np.asarray(xdata)._array)
ydatalist.append(np.asarray(ydata)._array)
else:
c = 'x'
for arg in args:
if c == 'x':
xdatalist.append(np.asarray(arg)._array)
c = 'y'
elif c == 'y':
ydatalist.append(np.asarray(arg)._array)
c = 's'
elif c == 's':
if isinstance(arg, basestring):
styles.append(arg)
c = 'x'
else:
styles.append('-')
xdatalist.append(np.asarray(arg)._array)
c = 'y'
snum = len(xdatalist)
if len(styles) == 0:
styles = None
else:
while len(styles) < snum:
styles.append('-')
#Get plot data styles - Legend
lines = []
ls = kwargs.pop('legend', None)
if ls is None:
if styles != None:
for i in range(0, len(styles)):
line = plotutil.getplotstyle(styles[i], str(i), **kwargs)
lines.append(line)
else:
for i in range(0, snum):
label = kwargs.pop('label', 'S_' + str(i + 1))
line = plotutil.getlegendbreak('line', **kwargs)[0]
line.setCaption(label)
lines.append(line)
ls = LegendScheme(lines)
layer = DrawMeteoData.createPolylineLayer(xdatalist, ydatalist, ls, \
'Plot_lines', 'ID', -180, 180)
if (proj != None):
layer.setProjInfo(proj)
# Add layer
isadd = kwargs.pop('isadd', True)
if isadd:
zorder = kwargs.pop('zorder', None)
select = kwargs.pop('select', True)
self.add_layer(layer, zorder, select)
self._axes.setDrawExtent(layer.getExtent().clone())
self._axes.setExtent(layer.getExtent().clone())
return MILayer(layer)
def scatter(self, *args, **kwargs):
"""
Make a scatter plot on a map.
@ -1660,18 +1559,38 @@ class MapAxes(Axes):
y = args[1]
u = args[2]
v = args[3]
ls = LegendManage.createSingleSymbolLegendScheme(ShapeTypes.POLYLINE)
#plotutil.setlegendscheme(ls, **kwargs)
lb, isunique = plotutil.getlegendbreak('line', **kwargs)
if not kwargs.has_key('headwidth'):
kwargs['headwidth'] = 8
if not kwargs.has_key('overhang'):
kwargs['overhang'] = 0.5
lb = plotutil.line2stream(lb, **kwargs)
ls.setLegendBreak(0, lb)
#layer = __plot_uvgriddata_m(plot, udata, vdata, None, ls, 'streamplot', isuv, proj=proj, density=density)
layer = DrawMeteoData.createStreamlineLayer(u._array, v._array, x._array, y._array, density, ls, 'layer', isuv)
cdata = kwargs.pop('cdata', None)
if cdata is None:
ls = LegendManage.createSingleSymbolLegendScheme(ShapeTypes.POLYLINE)
lb, isunique = plotutil.getlegendbreak('line', **kwargs)
lb = plotutil.line2stream(lb, **kwargs)
ls.setLegendBreak(0, lb)
layer = DrawMeteoData.createStreamlineLayer(u._array, v._array, x._array, y._array, density, ls, 'layer', isuv)
else:
if isinstance(cdata, (list, tuple)):
cdata = np.array(cdata)
levels = kwargs.pop('levels', None)
if levels is None:
cnum = kwargs.pop('cnum', None)
if cnum is None:
ls = plotutil.getlegendscheme([], cdata.min(), cdata.max(), **kwargs)
else:
ls = plotutil.getlegendscheme([cnum], cdata.min(), cdata.max(), **kwargs)
else:
ls = plotutil.getlegendscheme([levels], cdata.min(), cdata.max(), **kwargs)
ls = plotutil.setlegendscheme_line(ls, **kwargs)
for i in range(ls.getBreakNum()):
lb = plotutil.line2stream(ls.getLegendBreak(i), **kwargs)
ls.setLegendBreak(i, lb)
layer = DrawMeteoData.createStreamlineLayer(u._array, v._array, x._array, y._array, cdata._array,
density, ls, 'layer', isuv)
if not proj is None:
layer.setProjInfo(proj)

View File

@ -34,7 +34,7 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<revision>3.7.7</revision>
<revision>3.7.8</revision>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<maven.compiler.release>8</maven.compiler.release>