diff --git a/meteoinfo-chart/src/main/java/org/meteoinfo/chart/ChartWindArrow.java b/meteoinfo-chart/src/main/java/org/meteoinfo/chart/ChartWindArrow.java
index 4ee2c851..e0cb87e8 100644
--- a/meteoinfo-chart/src/main/java/org/meteoinfo/chart/ChartWindArrow.java
+++ b/meteoinfo-chart/src/main/java/org/meteoinfo/chart/ChartWindArrow.java
@@ -408,8 +408,7 @@ public class ChartWindArrow {
g.draw(rect);
}
}
- //Draw.drawArraw(this.color, new PointF(x, y), this.windArrow, g, zoom);
- Draw.drawArraw(new PointF(x, y), windArrow, arrowBreak, g, zoom);
+ Draw.drawArrow(new PointF(x, y), windArrow, arrowBreak, g, zoom);
g.setColor(this.labelColor);
Draw.drawString(g, this.label, x, y + dim.height + this.labelSep);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, rendering);
diff --git a/meteoinfo-chart/src/main/java/org/meteoinfo/chart/jogl/MapPlot3D.java b/meteoinfo-chart/src/main/java/org/meteoinfo/chart/jogl/MapPlot3D.java
index 282779ee..b288506d 100644
--- a/meteoinfo-chart/src/main/java/org/meteoinfo/chart/jogl/MapPlot3D.java
+++ b/meteoinfo-chart/src/main/java/org/meteoinfo/chart/jogl/MapPlot3D.java
@@ -1,10 +1,58 @@
package org.meteoinfo.chart.jogl;
+import org.meteoinfo.geometry.graphic.Graphic;
import org.meteoinfo.projection.KnownCoordinateSystems;
import org.meteoinfo.projection.ProjectionInfo;
+import org.meteoinfo.projection.ProjectionUtil;
public class MapPlot3D extends Plot3DGL {
- private ProjectionInfo projInfo = KnownCoordinateSystems.geographic.world.WGS1984;
+ private ProjectionInfo projInfo;
+ /**
+ * Constructor
+ */
+ public MapPlot3D() {
+ super();
+ this.projInfo = KnownCoordinateSystems.geographic.world.WGS1984;
+ }
+ /**
+ * Constructor
+ * @param projInfo Projection info
+ */
+ public MapPlot3D(ProjectionInfo projInfo) {
+ super();
+ this.projInfo = projInfo;
+ }
+
+ /**
+ * Get projection info
+ * @return Projection info
+ */
+ public ProjectionInfo getProjInfo() {
+ return this.projInfo;
+ }
+
+ /**
+ * Set projection info
+ * @param value Projection info
+ */
+ public void setProjInfo(ProjectionInfo value) {
+ this.projInfo = value;
+ }
+
+ /**
+ * Add a graphic
+ *
+ * @param graphic The graphic
+ * @param proj The graphic projection
+ */
+ public void addGraphic(Graphic graphic, ProjectionInfo proj) {
+ if (proj.equals(this.projInfo)) {
+ super.addGraphic(graphic);
+ } else {
+ Graphic nGraphic = ProjectionUtil.projectGraphic(graphic, proj, this.projInfo);
+ super.addGraphic(nGraphic);
+ }
+ }
}
diff --git a/meteoinfo-chart/src/main/java/org/meteoinfo/chart/jogl/Plot3DGL.java b/meteoinfo-chart/src/main/java/org/meteoinfo/chart/jogl/Plot3DGL.java
index 62a5f49f..94c2a5a1 100644
--- a/meteoinfo-chart/src/main/java/org/meteoinfo/chart/jogl/Plot3DGL.java
+++ b/meteoinfo-chart/src/main/java/org/meteoinfo/chart/jogl/Plot3DGL.java
@@ -44,6 +44,8 @@ import org.meteoinfo.geometry.legend.*;
import org.meteoinfo.geometry.shape.Shape;
import org.meteoinfo.geometry.shape.*;
import org.meteoinfo.math.meteo.MeteoMath;
+import org.meteoinfo.projection.ProjectionInfo;
+import org.meteoinfo.projection.ProjectionUtil;
import javax.imageio.ImageIO;
import javax.swing.*;
@@ -73,6 +75,7 @@ import static com.jogamp.opengl.GL2ES3.GL_TEXTURE_BASE_LEVEL;
public class Plot3DGL extends Plot implements GLEventListener {
//
+ protected ProjectionInfo projInfo;
protected boolean sampleBuffers = false;
protected Color background = Color.white;
protected boolean doScreenShot;
@@ -130,6 +133,7 @@ public class Plot3DGL extends Plot implements GLEventListener {
* Constructor
*/
public Plot3DGL() {
+ this.projInfo = null;
this.doScreenShot = false;
this.legends = new ArrayList<>();
//this.legends.add(new ChartColorBar(new LegendScheme(ShapeTypes.Polygon, 5)));
@@ -173,6 +177,21 @@ public class Plot3DGL extends Plot implements GLEventListener {
//
//
+ /**
+ * Get projection info
+ * @return Projection info
+ */
+ public ProjectionInfo getProjInfo() {
+ return this.projInfo;
+ }
+
+ /**
+ * Set projection info
+ * @param value Projection info
+ */
+ public void setProjInfo(ProjectionInfo value) {
+ this.projInfo = value;
+ }
/**
* Get is sample buffers or not
@@ -967,6 +986,21 @@ public class Plot3DGL extends Plot implements GLEventListener {
this.setDrawExtent((Extent3D) this.extent.clone());
}
+ /**
+ * Add a graphic
+ *
+ * @param graphic The graphic
+ * @param proj The graphic projection
+ */
+ public void addGraphic(Graphic graphic, ProjectionInfo proj) {
+ if (proj == null || proj.equals(this.projInfo)) {
+ addGraphic(graphic);
+ } else {
+ Graphic nGraphic = ProjectionUtil.projectGraphic(graphic, proj, this.projInfo);
+ addGraphic(nGraphic);
+ }
+ }
+
/**
* Remove a graphic by index
*
diff --git a/meteoinfo-chart/src/main/java/org/meteoinfo/chart/plot/Plot2D.java b/meteoinfo-chart/src/main/java/org/meteoinfo/chart/plot/Plot2D.java
index e475cb03..48a47621 100644
--- a/meteoinfo-chart/src/main/java/org/meteoinfo/chart/plot/Plot2D.java
+++ b/meteoinfo-chart/src/main/java/org/meteoinfo/chart/plot/Plot2D.java
@@ -430,7 +430,7 @@ public class Plot2D extends AbstractPlot2D {
double[] sXY = projToScreen(p.X, p.Y, area);
PointF pf = new PointF((float) sXY[0], (float) sXY[1]);
float zoom = aPB.getSize() / 10;
- Draw.drawArraw(pf, aPS, aPB, g, zoom);
+ Draw.drawArrow(pf, aPS, aPB, g, zoom);
}
private void drawPolyline(Graphics2D g, PolylineShape aPLS, PointBreak aPB, Rectangle2D area) {
diff --git a/meteoinfo-geo/src/main/java/org/meteoinfo/geo/drawing/Draw.java b/meteoinfo-geo/src/main/java/org/meteoinfo/geo/drawing/Draw.java
index cf4408e0..00f1494e 100644
--- a/meteoinfo-geo/src/main/java/org/meteoinfo/geo/drawing/Draw.java
+++ b/meteoinfo-geo/src/main/java/org/meteoinfo/geo/drawing/Draw.java
@@ -631,7 +631,7 @@ public class Draw {
g.setColor(aColor);
g.draw(new Line2D.Float(sP.X, sP.Y, eP.X, eP.Y));
- drawArraw(g, eP, angle);
+ drawArrow(g, eP, angle);
return new Rectangle2D.Double(Math.min(sP.X, eP.X), Math.min(sP.Y, eP.Y),
Math.abs(eP.X - sP.X), Math.abs(eP.Y - sP.Y));
@@ -656,17 +656,17 @@ public class Draw {
* Draw wind arrow
*
* @param sP Start point
- * @param aArraw The arrow
+ * @param arrow The arrow
* @param pb PointBreak
* @param g Graphics2D
* @param zoom Zoom
* @return Border rectangle
*/
- public static Rectangle2D drawArraw(PointF sP, WindArrow aArraw, ArrowBreak pb, Graphics2D g, double zoom) {
+ public static Rectangle2D drawArrow(PointF sP, WindArrow arrow, ArrowBreak pb, Graphics2D g, double zoom) {
PointF eP = new PointF(0, 0);
//PointF eP1 = new PointF(0, 0);
- double len = aArraw.length;
- double angle = aArraw.angle + 180;
+ double len = arrow.length;
+ double angle = arrow.angle + 180;
if (angle >= 360) {
angle -= 360;
}
@@ -686,19 +686,23 @@ public class Draw {
g.draw(new Line2D.Float(sP.X, sP.Y, eP.X, eP.Y));
float headWidth = pb.getHeadWidth();
float headLength = pb.getHeadLength();
+ if (len < headLength && pb.isAutoScale()) {
+ headWidth = headWidth * (float) len / headLength;
+ headLength = (float) len;
+ }
drawArraw(g, eP, angle, headLength, headWidth, pb.getOverhang());
return new Rectangle2D.Double(Math.min(sP.X, eP.X), Math.min(sP.Y, eP.Y),
Math.abs(eP.X - sP.X), Math.abs(eP.Y - sP.Y));
}
/**
- * Draw arraw
+ * Draw arrow
*
* @param g Graphics2D
* @param sP Start point
* @param angle Angle
*/
- public static void drawArraw(Graphics2D g, PointF sP, double angle) {
+ public static void drawArrow(Graphics2D g, PointF sP, double angle) {
GeneralPath path = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 5);
Rectangle.Float rect = new Rectangle.Float(-4, -4, 8, 8);
PointF[] pt = new PointF[5];
diff --git a/meteoinfo-geo/src/main/java/org/meteoinfo/geo/mapview/MapView.java b/meteoinfo-geo/src/main/java/org/meteoinfo/geo/mapview/MapView.java
index 78a45215..a4368758 100644
--- a/meteoinfo-geo/src/main/java/org/meteoinfo/geo/mapview/MapView.java
+++ b/meteoinfo-geo/src/main/java/org/meteoinfo/geo/mapview/MapView.java
@@ -4826,7 +4826,7 @@ public class MapView extends JPanel implements IWebMapPanel {
sPoint.X = (float) xy[0];
sPoint.Y = (float) xy[1];
//Draw.drawArraw(aColor, sPoint, aArraw, g, zoom);
- Draw.drawArraw(sPoint, aArraw, aPB, g, zoom);
+ Draw.drawArrow(sPoint, aArraw, aPB, g, zoom);
}
break;
case UNIQUE_VALUE:
@@ -4843,7 +4843,7 @@ public class MapView extends JPanel implements IWebMapPanel {
sPoint.Y = (float) xy[1];
aPB = (ArrowBreak) aLS.getLegendBreak(aArraw.getLegendIndex());
- Draw.drawArraw(sPoint, aArraw, aPB, g, zoom);
+ Draw.drawArrow(sPoint, aArraw, aPB, g, zoom);
/*String vStr = aLayer.getCellValue(aLS.getFieldName(), shapeIdx).toString().trim();
if (vStr.isEmpty()) {
diff --git a/meteoinfo-geo/src/main/java/org/meteoinfo/geo/util/GeoProjectionUtil.java b/meteoinfo-geo/src/main/java/org/meteoinfo/geo/util/GeoProjectionUtil.java
index 3f39dae6..75828b01 100644
--- a/meteoinfo-geo/src/main/java/org/meteoinfo/geo/util/GeoProjectionUtil.java
+++ b/meteoinfo-geo/src/main/java/org/meteoinfo/geo/util/GeoProjectionUtil.java
@@ -405,7 +405,7 @@ public class GeoProjectionUtil {
if (oLayer.getLabelPoints().size() > 0) {
if (projectLabels) {
- oLayer.setLabelPoints(ProjectionUtil.projectGraphics(oLayer.getLabelPoints(), fromProj, toProj));
+ oLayer.setLabelPoints(ProjectionUtil.projectGraphic(oLayer.getLabelPoints(), fromProj, toProj));
} else {
oLayer.setLabelPoints(new ArrayList<>(oLayer.getLabelPoints()));
}
@@ -639,7 +639,7 @@ public class GeoProjectionUtil {
oLayer.getAttributeTable().setTable(aTable);
if (oLayer.getLabelPoints().size() > 0) {
- oLayer.setLabelPoints(ProjectionUtil.projectGraphics(oLayer.getLabelPoints(), fromProj, toProj));
+ oLayer.setLabelPoints(ProjectionUtil.projectGraphic(oLayer.getLabelPoints(), fromProj, toProj));
}
}
diff --git a/meteoinfo-geometry/src/main/java/org/meteoinfo/geometry/legend/ArrowBreak.java b/meteoinfo-geometry/src/main/java/org/meteoinfo/geometry/legend/ArrowBreak.java
index 7d5518be..5a7919cd 100644
--- a/meteoinfo-geometry/src/main/java/org/meteoinfo/geometry/legend/ArrowBreak.java
+++ b/meteoinfo-geometry/src/main/java/org/meteoinfo/geometry/legend/ArrowBreak.java
@@ -15,6 +15,7 @@ public class ArrowBreak extends PointBreak {
private float headWidth;
private float headLength;
private float overhang;
+ private boolean autoScale;
//
//
/**
@@ -23,10 +24,9 @@ public class ArrowBreak extends PointBreak {
public ArrowBreak() {
super();
this.outlineColor = null;
- this.width = 1;
- this.headWidth = this.width * 5;
- this.headLength = this.headWidth * 1.5f;
+ this.initWidth(1);
this.overhang = 0;
+ this.autoScale = true;
}
/**
@@ -55,6 +55,7 @@ public class ArrowBreak extends PointBreak {
this.headWidth = this.width * 5;
this.headLength = this.headWidth * 1.5f;
this.overhang = 0;
+ this.autoScale = true;
}
//
//
@@ -121,7 +122,33 @@ public class ArrowBreak extends PointBreak {
public void setOverhang(float value) {
this.overhang = value;
}
+
+ /**
+ * Get whether automatically scale the arrow size
+ * @return Whether automatically scale the arrow size
+ */
+ public boolean isAutoScale() {
+ return this.autoScale;
+ }
+
+ /**
+ * Set whether automatically scale the arrow size
+ * @param value Whether automatically scale the arrow size
+ */
+ public void setAutoScale(boolean value) {
+ this.autoScale = value;
+ }
//
//
+
+ /**
+ * Initialize width
+ * @param width Width
+ */
+ public void initWidth(float width) {
+ this.width = width;
+ this.headWidth = this.width * 5;
+ this.headLength = this.headWidth * 5 / 3;
+ }
//
}
diff --git a/meteoinfo-geometry/src/main/java/org/meteoinfo/geometry/shape/PolygonShape.java b/meteoinfo-geometry/src/main/java/org/meteoinfo/geometry/shape/PolygonShape.java
index 7ec2d22d..b4b2d019 100644
--- a/meteoinfo-geometry/src/main/java/org/meteoinfo/geometry/shape/PolygonShape.java
+++ b/meteoinfo-geometry/src/main/java/org/meteoinfo/geometry/shape/PolygonShape.java
@@ -284,7 +284,7 @@ public class PolygonShape extends Shape implements Cloneable {
*
* @param polygons polygon list
*/
- public void setPolygons(List polygons) {
+ public void setPolygons(List extends Polygon> polygons) {
_polygons = polygons;
updatePartsPoints();
}
diff --git a/meteoinfo-lab/milconfig.xml b/meteoinfo-lab/milconfig.xml
index a919c2b6..4f6bef2d 100644
--- a/meteoinfo-lab/milconfig.xml
+++ b/meteoinfo-lab/milconfig.xml
@@ -1,30 +1,32 @@
-
-
-
-
-
-
-
+
-
-
+
+
+
+
+
+
+
+
+
+
diff --git a/meteoinfo-lab/pylib/mipylib/plotlib/_axes$py.class b/meteoinfo-lab/pylib/mipylib/plotlib/_axes$py.class
index b18dcd84..ab2c4f87 100644
Binary files a/meteoinfo-lab/pylib/mipylib/plotlib/_axes$py.class and b/meteoinfo-lab/pylib/mipylib/plotlib/_axes$py.class differ
diff --git a/meteoinfo-lab/pylib/mipylib/plotlib/_axes.py b/meteoinfo-lab/pylib/mipylib/plotlib/_axes.py
index 6e031a49..8bd66ef1 100644
--- a/meteoinfo-lab/pylib/mipylib/plotlib/_axes.py
+++ b/meteoinfo-lab/pylib/mipylib/plotlib/_axes.py
@@ -692,6 +692,7 @@ class Axes(object):
ax2.axes.getAxis(Location.LEFT).setVisible(False)
ax2.axes.getAxis(Location.TOP).setVisible(False)
axis = ax2.axes.getAxis(Location.RIGHT)
+ axis.setDrawTickLine(True)
axis.setDrawTickLabel(True)
axis.setDrawLabel(True)
return ax2
@@ -952,13 +953,17 @@ class Axes(object):
self.axes.addGraphic(patch)
self.axes.setAutoExtent()
- def add_graphic(self, graphic):
+ def add_graphic(self, graphic, projection=None):
'''
Add a graphic
:param graphic: (*Graphic*) The graphic to be added.
+ :param projection: (*Projection*) The projection
'''
- self.axes.addGraphic(graphic)
+ if projection is None:
+ self.axes.addGraphic(graphic)
+ else:
+ self.axes.addGraphic(graphic, projection)
def get_graphics(self):
'''
diff --git a/meteoinfo-lab/pylib/mipylib/plotlib/_axes3dgl$py.class b/meteoinfo-lab/pylib/mipylib/plotlib/_axes3dgl$py.class
index 0dbe8343..9b5da2e7 100644
Binary files a/meteoinfo-lab/pylib/mipylib/plotlib/_axes3dgl$py.class and b/meteoinfo-lab/pylib/mipylib/plotlib/_axes3dgl$py.class differ
diff --git a/meteoinfo-lab/pylib/mipylib/plotlib/_axes3dgl.py b/meteoinfo-lab/pylib/mipylib/plotlib/_axes3dgl.py
index 43f771de..70f9d780 100644
--- a/meteoinfo-lab/pylib/mipylib/plotlib/_axes3dgl.py
+++ b/meteoinfo-lab/pylib/mipylib/plotlib/_axes3dgl.py
@@ -13,7 +13,7 @@ from org.meteoinfo.geo.legend import LegendManage
from org.meteoinfo.geo.layer import LayerTypes
from org.meteoinfo.geometry.shape import ShapeTypes
from org.meteoinfo.geometry.graphic import Graphic, GraphicCollection
-from org.meteoinfo.chart.jogl import Plot3DGL, GLForm, JOGLUtil, EarthPlot3D
+from org.meteoinfo.chart.jogl import Plot3DGL, GLForm, JOGLUtil, EarthPlot3D, MapPlot3D
from org.meteoinfo.math.interpolate import InterpolationMethod
from org.meteoinfo.image import ImageUtil
from org.meteoinfo.common import Extent3D
@@ -33,7 +33,7 @@ import mipylib.numeric as np
from mipylib import migl
from mipylib.geolib import migeo
-__all__ = ['Axes3DGL','EarthAxes3D']
+__all__ = ['Axes3DGL','MapAxes3D','EarthAxes3D']
class Axes3DGL(Axes3D):
@@ -653,7 +653,8 @@ class Axes3DGL(Axes3D):
visible = kwargs.pop('visible', True)
if visible:
- self.add_graphic(graphics)
+ projection = kwargs.pop('projection', migeo.projinfo())
+ self.add_graphic(graphics, projection)
return graphics
def plot_layer(self, layer, **kwargs):
@@ -1556,6 +1557,37 @@ class Axes3DGL(Axes3D):
form.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE)
form.setVisible(True)
+class MapAxes3D(Axes3DGL):
+ """
+ Map 3D axes.
+ """
+
+ def __init__(self, *args, **kwargs):
+ super(MapAxes3D, self).__init__(*args, **kwargs)
+
+ projection = kwargs.pop('projection', None)
+ if not projection is None:
+ self.axes.setProjInfo(projection)
+
+ def _set_plot(self, plot):
+ """
+ Set plot.
+
+ :param plot: (*EarthPlot3D*) Plot.
+ """
+ if plot is None:
+ self.axes = MapPlot3D()
+ else:
+ self.axes = plot
+
+ @property
+ def axestype(self):
+ return '3d_Map'
+
+ @property
+ def projection(self):
+ return self.axes.getProjInfo()
+
class EarthAxes3D(Axes3DGL):
"""
Earth spherical 3D axes.
diff --git a/meteoinfo-lab/pylib/mipylib/plotlib/miplot$py.class b/meteoinfo-lab/pylib/mipylib/plotlib/miplot$py.class
index bb3784b4..e39bd940 100644
Binary files a/meteoinfo-lab/pylib/mipylib/plotlib/miplot$py.class and b/meteoinfo-lab/pylib/mipylib/plotlib/miplot$py.class differ
diff --git a/meteoinfo-lab/pylib/mipylib/plotlib/miplot.py b/meteoinfo-lab/pylib/mipylib/plotlib/miplot.py
index 8540c82c..aa883a99 100644
--- a/meteoinfo-lab/pylib/mipylib/plotlib/miplot.py
+++ b/meteoinfo-lab/pylib/mipylib/plotlib/miplot.py
@@ -26,7 +26,7 @@ from org.meteoinfo.chart.form import ChartForm
from org.meteoinfo.geometry.shape import ShapeTypes
from ._axes import Axes, PolarAxes
from ._axes3d import Axes3D
-from ._axes3dgl import Axes3DGL, EarthAxes3D
+from ._axes3dgl import Axes3DGL, MapAxes3D, EarthAxes3D
from ._figure import Figure
from ._glfigure import GLFigure
from ._mapaxes import MapAxes
@@ -1329,15 +1329,18 @@ def axes3d(*args, **kwargs):
"""
opengl = kwargs.pop('opengl', True)
if opengl:
- projection = kwargs.pop('projection', None)
+ projection = kwargs.get('projection', None)
if projection is None:
earth = kwargs.pop('earth', False)
- else:
- earth = projection == 'earth'
- if earth:
+ if earth:
+ projection == 'earth'
+
+ if projection is None:
+ return axes3dgl(*args, **kwargs)
+ elif projection == 'earth':
return axes3d_earth(*args, **kwargs)
else:
- return axes3dgl(*args, **kwargs)
+ return axes3d_map(*args, **kwargs)
else:
kwargs['axestype'] = '3d'
return axes(*args, **kwargs)
@@ -1361,6 +1364,25 @@ def axes3dgl(*args, **kwargs):
draw_if_interactive()
return ax
+def axes3d_map(*args, **kwargs):
+ """
+ Add an map 3d axes with JOGL to the figure.
+
+ :returns: The axes.
+ """
+ global g_axes
+
+ ax = MapAxes3D(*args, **kwargs)
+ g_axes = ax
+
+ if not batchmode:
+ if g_figure is None or isinstance(g_figure, Figure):
+ glfigure(**kwargs)
+ g_figure.set_axes(ax)
+
+ draw_if_interactive()
+ return ax
+
def axes3d_earth(*args, **kwargs):
"""
Add an earth 3d axes with JOGL to the figure.
diff --git a/meteoinfo-lab/pylib/mipylib/plotlib/plotutil$py.class b/meteoinfo-lab/pylib/mipylib/plotlib/plotutil$py.class
index d0fed57d..450397fd 100644
Binary files a/meteoinfo-lab/pylib/mipylib/plotlib/plotutil$py.class and b/meteoinfo-lab/pylib/mipylib/plotlib/plotutil$py.class differ
diff --git a/meteoinfo-lab/pylib/mipylib/plotlib/plotutil.py b/meteoinfo-lab/pylib/mipylib/plotlib/plotutil.py
index c0c40645..129c9fde 100644
--- a/meteoinfo-lab/pylib/mipylib/plotlib/plotutil.py
+++ b/meteoinfo-lab/pylib/mipylib/plotlib/plotutil.py
@@ -654,11 +654,13 @@ def point2arrow(pb, **kwargs):
'''
arrowbreak = ArrowBreak(pb)
width = kwargs.pop('width', 1.)
- arrowbreak.setWidth(width)
- headwidth = kwargs.pop('headwidth', width * 5.)
- arrowbreak.setHeadWidth(headwidth)
- headlength = kwargs.pop('headlength', headwidth * 1.5)
- arrowbreak.setHeadLength(headlength)
+ arrowbreak.initWidth(width)
+ headwidth = kwargs.pop('headwidth', None)
+ if not headwidth is None:
+ arrowbreak.setHeadWidth(headwidth)
+ headlength = kwargs.pop('headlength', None)
+ if not headlength is None:
+ arrowbreak.setHeadLength(headlength)
overhang = kwargs.pop('overhang', None)
if not overhang is None:
arrowbreak.setOverhang(overhang)
diff --git a/meteoinfo-projection/src/main/java/org/meteoinfo/projection/ProjectionUtil.java b/meteoinfo-projection/src/main/java/org/meteoinfo/projection/ProjectionUtil.java
index 532330c0..2675d91e 100644
--- a/meteoinfo-projection/src/main/java/org/meteoinfo/projection/ProjectionUtil.java
+++ b/meteoinfo-projection/src/main/java/org/meteoinfo/projection/ProjectionUtil.java
@@ -529,55 +529,109 @@ public class ProjectionUtil {
* @return Projected polygon shape
*/
public static PolygonShape projectPolygonShape(PolygonShape aPGS, ProjectionInfo fromProj, ProjectionInfo toProj) {
- List polygons = new ArrayList<>();
- for (int i = 0; i < aPGS.getPolygons().size(); i++) {
- Polygon aPG = aPGS.getPolygons().get(i);
- Polygon bPG = null;
- for (int r = 0; r < aPG.getRingNumber(); r++) {
- List pList = (List) aPG.getRings().get(r);
- List newPoints = new ArrayList<>();
- for (int j = 0; j < pList.size(); j++) {
- double[][] points = new double[1][];
- PointD wPoint = pList.get(j);
- points[0] = new double[]{wPoint.X, wPoint.Y};
- try {
- Reproject.reprojectPoints(points, fromProj, toProj, 0, points.length);
- if (!Double.isNaN(points[0][0]) && !Double.isNaN(points[0][1])) {
- wPoint = new PointD();
- wPoint.X = points[0][0];
- wPoint.Y = points[0][1];
- newPoints.add(wPoint);
+ if (aPGS instanceof PolygonZShape) {
+ List polygons = new ArrayList<>();
+ for (int i = 0; i < aPGS.getPolygons().size(); i++) {
+ PolygonZ aPG = (PolygonZ) aPGS.getPolygons().get(i);
+ PolygonZ bPG = null;
+ for (int r = 0; r < aPG.getRingNumber(); r++) {
+ List pList = (List) aPG.getRings().get(r);
+ List newPoints = new ArrayList<>();
+ for (int j = 0; j < pList.size(); j++) {
+ double[][] points = new double[1][];
+ PointZ wPoint = pList.get(j);
+ points[0] = new double[]{wPoint.X, wPoint.Y};
+ try {
+ Reproject.reprojectPoints(points, fromProj, toProj, 0, points.length);
+ if (!Double.isNaN(points[0][0]) || !Double.isInfinite(points[0][0]) ||
+ !Double.isNaN(points[0][1]) || !Double.isInfinite(points[0][1])) {
+ wPoint = new PointZ();
+ wPoint.X = points[0][0];
+ wPoint.Y = points[0][1];
+ newPoints.add(wPoint);
+ }
+ } catch (Exception e) {
+ break;
}
- } catch (Exception e) {
- break;
}
- }
- if (r == 0) {
- if (newPoints.size() > 2) {
- bPG = new Polygon();
- bPG.setOutLine(newPoints);
+ if (r == 0) {
+ if (newPoints.size() > 2) {
+ bPG = new PolygonZ();
+ bPG.setOutLine(newPoints);
+ } else {
+ break;
+ }
} else {
- break;
- }
- } else {
- if (newPoints.size() > 2) {
- bPG.addHole(newPoints);
+ if (newPoints.size() > 2) {
+ bPG.addHole(newPoints);
+ }
}
}
+
+ if (bPG != null) {
+ polygons.add(bPG);
+ }
}
- if (bPG != null) {
- polygons.add(bPG);
+ if (polygons.size() > 0) {
+ ((PolygonZShape) aPGS).setPolygons(polygons);
+
+ return aPGS;
+ } else {
+ return null;
}
- }
-
- if (polygons.size() > 0) {
- aPGS.setPolygons(polygons);
-
- return aPGS;
} else {
- return null;
+ List polygons = new ArrayList<>();
+ for (int i = 0; i < aPGS.getPolygons().size(); i++) {
+ Polygon aPG = aPGS.getPolygons().get(i);
+ Polygon bPG = null;
+ for (int r = 0; r < aPG.getRingNumber(); r++) {
+ List pList = (List) aPG.getRings().get(r);
+ List newPoints = new ArrayList<>();
+ for (int j = 0; j < pList.size(); j++) {
+ double[][] points = new double[1][];
+ PointD wPoint = pList.get(j);
+ points[0] = new double[]{wPoint.X, wPoint.Y};
+ try {
+ Reproject.reprojectPoints(points, fromProj, toProj, 0, points.length);
+ if (!Double.isNaN(points[0][0]) && !Double.isNaN(points[0][1])) {
+ wPoint = new PointD();
+ wPoint.X = points[0][0];
+ wPoint.Y = points[0][1];
+ newPoints.add(wPoint);
+ }
+ } catch (Exception e) {
+ break;
+ }
+ }
+
+ if (r == 0) {
+ if (newPoints.size() > 2) {
+ bPG = new Polygon();
+ bPG.setOutLine(newPoints);
+ } else {
+ break;
+ }
+ } else {
+ if (newPoints.size() > 2) {
+ bPG.addHole(newPoints);
+ }
+ }
+ }
+
+ if (bPG != null) {
+ polygons.add(bPG);
+ }
+ }
+
+ if (polygons.size() > 0) {
+ aPGS.setPolygons(polygons);
+
+ return aPGS;
+ } else {
+ return null;
+ }
}
}
@@ -590,11 +644,23 @@ public class ProjectionUtil {
* @return Projected graphic
*/
public static Graphic projectGraphic(Graphic graphic, ProjectionInfo fromProj, ProjectionInfo toProj) {
- Shape shape = projectShape(graphic.getShape(), fromProj, toProj);
- return new Graphic(shape, graphic.getLegend());
+ if (graphic instanceof GraphicCollection) {
+ GraphicCollection newGCollection = new GraphicCollection();
+ for (Graphic aGraphic : ((GraphicCollection) graphic).getGraphics()) {
+ aGraphic.setShape(projectShape(aGraphic.getShape(), fromProj, toProj));
+ if (aGraphic.getShape() != null) {
+ newGCollection.add(aGraphic);
+ }
+ }
+
+ return newGCollection;
+ } else {
+ Shape shape = projectShape(graphic.getShape(), fromProj, toProj);
+ return new Graphic(shape, graphic.getLegend());
+ }
}
- public static GraphicCollection projectGraphics(GraphicCollection aGCollection, ProjectionInfo fromProj, ProjectionInfo toProj) {
+ public static GraphicCollection projectGraphic(GraphicCollection aGCollection, ProjectionInfo fromProj, ProjectionInfo toProj) {
GraphicCollection newGCollection = new GraphicCollection();
for (Graphic aGraphic : aGCollection.getGraphics()) {
aGraphic.setShape(projectShape(aGraphic.getShape(), fromProj, toProj));
@@ -606,7 +672,7 @@ public class ProjectionUtil {
return newGCollection;
}
- public static List projectGraphics(List graphics, ProjectionInfo fromProj, ProjectionInfo toProj) {
+ public static List projectGraphic(List graphics, ProjectionInfo fromProj, ProjectionInfo toProj) {
List newGraphics = new ArrayList<>();
for (Graphic aGraphic : graphics) {
Shape aShape = projectShape(aGraphic.getShape(), fromProj, toProj);
@@ -634,6 +700,7 @@ public class ProjectionUtil {
break;
case POLYGON:
case POLYGON_M:
+ case POLYGON_Z:
case RECTANGLE:
newShape = projectPolygonShape((PolygonShape) aShape, fromProj, toProj);
break;