diff --git a/meteoinfo-chart/src/main/java/org/meteoinfo/chart/geo/MapGridLine.java b/meteoinfo-chart/src/main/java/org/meteoinfo/chart/geo/MapGridLine.java index f01bafb1..e86cb0d0 100644 --- a/meteoinfo-chart/src/main/java/org/meteoinfo/chart/geo/MapGridLine.java +++ b/meteoinfo-chart/src/main/java/org/meteoinfo/chart/geo/MapGridLine.java @@ -277,10 +277,13 @@ public class MapGridLine extends GridLine { double latMin = this.lonLatExtent.minY; double latMax = this.lonLatExtent.maxY; double delta = this.lonLatExtent.getHeight() / (this.nPoints - 1); + if (delta <= 0) { + return; + } for (double lon : this.longitudeLocations) { List points = new ArrayList<>(); double lat = latMin; - while (lat <= latMax) { + while (lat < latMax) { points.add(new PointD(lon, lat)); lat += delta; } @@ -307,10 +310,13 @@ public class MapGridLine extends GridLine { lonMax = 180; } double delta = (lonMax - lonMin) / (this.nPoints - 1); + if (delta <= 0) { + return; + } for (double lat : this.latitudeLocations) { List points = new ArrayList<>(); double lon = lonMin; - while (lon <= lonMax) { + while (lon < lonMax) { points.add(new PointD(lon, lat)); lon += delta; } diff --git a/meteoinfo-chart/src/main/java/org/meteoinfo/chart/geo/MapPlot.java b/meteoinfo-chart/src/main/java/org/meteoinfo/chart/geo/MapPlot.java index 642da64e..c24965d9 100644 --- a/meteoinfo-chart/src/main/java/org/meteoinfo/chart/geo/MapPlot.java +++ b/meteoinfo-chart/src/main/java/org/meteoinfo/chart/geo/MapPlot.java @@ -15,10 +15,13 @@ import org.meteoinfo.chart.plot.Plot2D; import org.meteoinfo.chart.plot.PlotType; import org.meteoinfo.common.*; import org.meteoinfo.data.Dataset; +import org.meteoinfo.data.mapdata.webmap.GeoPosition; +import org.meteoinfo.data.mapdata.webmap.GeoUtil; import org.meteoinfo.data.mapdata.webmap.IWebMapPanel; import org.meteoinfo.data.mapdata.webmap.TileLoadListener; import org.meteoinfo.geo.drawing.Draw; import org.meteoinfo.geo.graphic.GeoGraphicCollection; +import org.meteoinfo.geo.layer.WebMapLayer; import org.meteoinfo.geo.util.GeoProjectionUtil; import org.meteoinfo.geometry.graphic.Graphic; import org.meteoinfo.geometry.graphic.GraphicCollection; @@ -38,6 +41,7 @@ import javax.xml.parsers.ParserConfigurationException; import java.awt.*; import java.awt.geom.AffineTransform; import java.awt.geom.Line2D; +import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.io.File; import java.io.IOException; @@ -388,6 +392,39 @@ public class MapPlot extends Plot2D implements IWebMapPanel { return webMapImage == null ? 0 : webMapImage.getZoom(); } + /** + * Get geographic center with longitude/latitude + * + * @return Geographic center + */ + public PointD getGeoCenter() { + PointD viewCenter = this.getViewCenter(); + return Reproject.reprojectPoint(viewCenter, this.projInfo, + KnownCoordinateSystems.geographic.world.WGS1984); + } + + /** + * Get view center point + * + * @return The view center point + */ + public PointD getViewCenter() { + return this.drawExtent.getCenterPoint(); + } + + /** + * Set view center point + * + * @param center The view center point + */ + public void setViewCenter(PointD center) { + PointD oldCenter = this.getViewCenter(); + double dx = center.X - oldCenter.X; + double dy = center.Y - oldCenter.Y; + Extent extent = this.drawExtent.shift(dx, dy); + this.drawExtent = extent; + } + @Override public void reDraw() { if (this.parent != null) { @@ -474,16 +511,21 @@ public class MapPlot extends Plot2D implements IWebMapPanel { int barIdx = 0; for (int m = 0; m < this.graphics.getNumGraphics(); m++) { Graphic graphic = this.graphics.get(m); + if (graphic instanceof WebMapImage) { + this.drawWebMapImage(g, (WebMapImage) graphic, area); + continue; + } + ColorBreak cb = graphic.getLegend(); ShapeTypes shapeType = graphic.getGraphicN(0).getShape().getShapeType(); switch(shapeType){ case BAR: this.drawBars(g, (GraphicCollection) graphic, barIdx, area); barIdx += 1; - break; + continue; case STATION_MODEL: this.drawStationModel(g, (GraphicCollection) graphic, area); - break; + continue; } if (graphic.getExtent().intersects(this.drawExtent)) { @@ -554,6 +596,72 @@ public class MapPlot extends Plot2D implements IWebMapPanel { } } + private double getWebMapScale(WebMapImage graphic, int zoom, double width, double height) { + Point2D center = graphic.getCenter(); + double minx = center.getX() - width / 2.; + double miny = center.getY() - height / 2.; + double maxx = center.getX() + width / 2.; + double maxy = center.getY() + height / 2.; + GeoPosition pos1 = GeoUtil.getPosition(new Point2D.Double(minx, miny), zoom, graphic.getTileFactory().getInfo()); + GeoPosition pos2 = GeoUtil.getPosition(new Point2D.Double(maxx, maxy), zoom, graphic.getTileFactory().getInfo()); + PointD p1 = Reproject.reprojectPoint(new PointD(pos1.getLongitude(), pos1.getLatitude()), + KnownCoordinateSystems.geographic.world.WGS1984, this.projInfo); + PointD p2 = Reproject.reprojectPoint(new PointD(pos2.getLongitude(), pos2.getLatitude()), + KnownCoordinateSystems.geographic.world.WGS1984, this.projInfo); + if (pos2.getLongitude() - pos1.getLongitude() < 360.0 && pos2.getLongitude() <= 180) { + double xlen = Math.abs(p2.X - p1.X); + return (double) width / xlen; + } else { + double ylen = Math.abs(p2.Y - p1.Y); + return (double) height / ylen; + } + } + + private void setScale(double scale, double width, double height) { + this.xScale = scale; + this.yScale = scale; + PointD center = (PointD)this.drawExtent.getCenterPoint().clone(); + double xlen = width / scale * 0.5; + double ylen = height / scale * 0.5; + this.drawExtent.minX = center.X - xlen; + this.drawExtent.maxX = center.X + xlen; + this.drawExtent.minY = center.Y - ylen; + this.drawExtent.maxY = center.Y + ylen; + } + + void drawWebMapImage(Graphics2D g, WebMapImage graphic, Rectangle2D area) { + PointD geoCenter = this.getGeoCenter(); + graphic.setAddressLocation(new GeoPosition(geoCenter.Y, geoCenter.X)); + double webMapScale = graphic.getWebMapScale(); + if (!MIMath.doubleEquals(this.xScale, webMapScale)) { + int minZoom = graphic.getTileFactory().getInfo().getMinimumZoomLevel(); + int maxZoom = graphic.getTileFactory().getInfo().getMaximumZoomLevel(); + int newZoom = minZoom; + double scale = webMapScale; + double width = area.getWidth(); + double height = area.getHeight(); + for (int i = maxZoom; i >= minZoom; i--) { + graphic.setZoom(i); + scale = getWebMapScale(graphic, i, width, height); + if (xScale < scale) { + newZoom = i; + if (xScale < webMapScale) { + if (i < maxZoom) { + newZoom = i + 1; + scale = getWebMapScale(graphic, newZoom, width, height); + } + } + break; + } + } + this.setScale(scale, width, height); + graphic.setWebMapScale(scale); + graphic.setZoom(newZoom); + } + + graphic.draw(g, area, this.tileLoadListener); + } + /** * Add a graphic * diff --git a/meteoinfo-chart/src/main/java/org/meteoinfo/chart/graphic/WebMapImage.java b/meteoinfo-chart/src/main/java/org/meteoinfo/chart/graphic/WebMapImage.java index 80edfa9d..d8570f60 100644 --- a/meteoinfo-chart/src/main/java/org/meteoinfo/chart/graphic/WebMapImage.java +++ b/meteoinfo-chart/src/main/java/org/meteoinfo/chart/graphic/WebMapImage.java @@ -1,5 +1,6 @@ package org.meteoinfo.chart.graphic; +import org.meteoinfo.common.Extent; import org.meteoinfo.data.mapdata.webmap.*; import org.meteoinfo.data.mapdata.webmap.empty.EmptyTileFactory; import org.meteoinfo.geometry.graphic.Graphic; @@ -51,6 +52,7 @@ public class WebMapImage extends Graphic { private double webMapScale = 0.; private double width; private double height; + private Extent extent = new Extent(-180, 180, -90, 90); /** * Constructor @@ -74,6 +76,22 @@ public class WebMapImage extends Graphic { //this.setCenterPosition(new GeoPosition(0, 0)); } + /** + * Get extent + * @return Extent + */ + public Extent getExtent() { + return extent; + } + + /** + * Set extent + * @param extent The extent + */ + public void setExtent(Extent extent) { + this.extent = extent; + } + /** * Get web map scale * @return Web map scale 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 c4186475..880b4dc8 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 @@ -17,6 +17,7 @@ import org.meteoinfo.chart.ChartLegend; import org.meteoinfo.chart.ChartText; import org.meteoinfo.chart.axis.LogAxis; import org.meteoinfo.chart.axis.TimeAxis; +import org.meteoinfo.chart.graphic.WebMapImage; import org.meteoinfo.common.Extent; import org.meteoinfo.common.MIMath; import org.meteoinfo.common.PointD; @@ -281,7 +282,7 @@ public class Plot2D extends AbstractPlot2D { case BAR: this.drawBars(g, (GraphicCollection) graphic, barIdx, area); barIdx += 1; - break; + continue; } if (graphic.getExtent().intersects(this.drawExtent)) { @@ -1312,6 +1313,9 @@ public class Plot2D extends AbstractPlot2D { private int getBarIndex() { int idx = -1; for (int i = 0; i < this.graphics.size(); i++) { + if (this.graphics.get(i) instanceof WebMapImage) { + continue; + } if (this.graphics.get(i).getGraphicN(0).getShape().getShapeType() == ShapeTypes.BAR) { idx = i; break; @@ -1323,6 +1327,9 @@ public class Plot2D extends AbstractPlot2D { private int getImageIndex() { int idx = -1; for (int i = 0; i < this.graphics.size(); i++) { + if (this.graphics.get(i) instanceof WebMapImage) { + continue; + } if (this.graphics.get(i).getGraphicN(0).getShape().getShapeType() == ShapeTypes.IMAGE) { idx = i; break; @@ -1354,12 +1361,22 @@ public class Plot2D extends AbstractPlot2D { this.graphics.updateExtent(); Extent extent = (Extent)this.graphics.getExtent().clone(); if (extent.minX == extent.maxX) { - extent.minX = extent.minX - Math.abs(extent.minX); - extent.maxX = extent.maxX + Math.abs(extent.minX); + if (extent.minX == 0) { + extent.minX = -1; + extent.maxX = 1; + } else { + extent.minX = extent.minX - Math.abs(extent.minX); + extent.maxX = extent.maxX + Math.abs(extent.minX); + } } if (extent.minY == extent.maxY) { - extent.minY = extent.minY - Math.abs(extent.minY); - extent.maxY = extent.maxY + Math.abs(extent.maxY); + if (extent.minY == 0) { + extent.minY = -1; + extent.maxY = 1; + } else { + extent.minY = extent.minY - Math.abs(extent.minY); + extent.maxY = extent.maxY + Math.abs(extent.maxY); + } } int imageIdx = this.getImageIndex(); 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 7ab856b1..da95bb03 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 @@ -681,6 +681,7 @@ public class GeoProjectionUtil { } newGCollection.setLegendScheme(geoGraphic.getLegendScheme()); newGCollection.setSingleLegend(geoGraphic.isSingleLegend()); + newGCollection.setAntiAlias(geoGraphic.isAntiAlias()); newGCollection.getAttributeTable().setTable(dataTable); newGCollection.setProjInfo(toProj); diff --git a/meteoinfo-geometry/src/main/java/org/meteoinfo/geometry/legend/LegendScheme.java b/meteoinfo-geometry/src/main/java/org/meteoinfo/geometry/legend/LegendScheme.java index 65957764..0ffff3ef 100644 --- a/meteoinfo-geometry/src/main/java/org/meteoinfo/geometry/legend/LegendScheme.java +++ b/meteoinfo-geometry/src/main/java/org/meteoinfo/geometry/legend/LegendScheme.java @@ -1658,6 +1658,8 @@ package org.meteoinfo.geometry.legend; bLS.setMinValue(minValue); bLS.setMaxValue(maxValue); bLS.setUndefValue(undef); + bLS.setExtendType(extendType); + bLS.setExtendFraction(extendFraction); for (ColorBreak aCB : legendBreaks) { bLS.getLegendBreaks().add((ColorBreak) aCB.clone()); } diff --git a/meteoinfo-lab/milconfig.xml b/meteoinfo-lab/milconfig.xml index fefb366f..2d0d9505 100644 --- a/meteoinfo-lab/milconfig.xml +++ b/meteoinfo-lab/milconfig.xml @@ -1,34 +1,32 @@ - - + - + - - - - - - - - - + + - + + + + + + + + + - - - - + + + - - - - + + + @@ -36,5 +34,5 @@
- + diff --git a/meteoinfo-lab/pylib/mipylib/geolib/_graphic.py b/meteoinfo-lab/pylib/mipylib/geolib/_graphic.py index d6c79538..f81e0413 100644 --- a/meteoinfo-lab/pylib/mipylib/geolib/_graphic.py +++ b/meteoinfo-lab/pylib/mipylib/geolib/_graphic.py @@ -13,6 +13,17 @@ class GeoGraphicCollection(object): """ self._geographic = geographic + def get_graphics(self): + """ + Get graphics. + :return: Graphics. + """ + return self._geographic + + @property + def shapes(self): + return self._geographic.getShapes() + def addlabels(self, fieldname, **kwargs): """ Add labels diff --git a/meteoinfo-lab/pylib/mipylib/numeric/core/numeric$py.class b/meteoinfo-lab/pylib/mipylib/numeric/core/numeric$py.class index 05b13c05..7725279e 100644 Binary files a/meteoinfo-lab/pylib/mipylib/numeric/core/numeric$py.class and b/meteoinfo-lab/pylib/mipylib/numeric/core/numeric$py.class differ diff --git a/meteoinfo-lab/pylib/mipylib/plotlib/_axes$py.class b/meteoinfo-lab/pylib/mipylib/plotlib/_axes$py.class index 3e0281f3..f921e7d5 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 e86678b1..ecad6795 100644 --- a/meteoinfo-lab/pylib/mipylib/plotlib/_axes.py +++ b/meteoinfo-lab/pylib/mipylib/plotlib/_axes.py @@ -1488,6 +1488,10 @@ class Axes(object): # Create graphics graphics = GraphicFactory.createStepLineString(xdata, ydata, fmt, where) + antialias = kwargs.pop('antialias', None) + if antialias is not None: + graphics.setAntiAlias(antialias) + zorder = kwargs.pop('zorder', None) self.add_graphic(graphics, zorder=zorder) return graphics @@ -1603,6 +1607,10 @@ class Axes(object): # Create graphics graphics = GraphicFactory.createPoints(xdata, ydata, pbs) + antialias = kwargs.pop('antialias', None) + if antialias is not None: + graphics.setAntiAlias(antialias) + zorder = kwargs.pop('zorder', None) self.add_graphic(graphics, zorder=zorder) self._axes.setAutoExtent() @@ -2273,6 +2281,10 @@ class Axes(object): graphics = GraphicFactory.createStems(xdata, ydata, linefmt, markerfmt, \ basefmt, bottom) + antialias = kwargs.pop('antialias', None) + if antialias is not None: + graphics.setAntiAlias(antialias) + zorder = kwargs.pop('zorder', None) self.add_graphic(graphics, zorder=zorder) self._axes.setAutoExtent() @@ -2341,19 +2353,22 @@ class Axes(object): if x.ndim == 2 and y.ndim == 2: griddata_props = kwargs.pop('griddata_props', dict(method='idw', pointnum=5, convexhull=True)) a, x, y = np.griddata((x, y), a, **griddata_props) - igraphic = GraphicFactory.createContourLines(x.asarray(), y.asarray(), a.asarray(), ls, smooth) + graphics = GraphicFactory.createContourLines(x.asarray(), y.asarray(), a.asarray(), ls, smooth) 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() - self._axes.setExtent(igraphic.getExtent()) - self._axes.setDrawExtent(igraphic.getExtent()) + antialias = kwargs.pop('antialias', None) + if antialias is not None: + graphics.setAntiAlias(antialias) - return igraphic + zorder = kwargs.pop('zorder', None) + self.add_graphic(graphics, zorder=zorder) + self._axes.setExtent(graphics.getExtent()) + self._axes.setDrawExtent(graphics.getExtent()) + + return graphics def clabel(self, layer, **kwargs): """ @@ -2496,7 +2511,11 @@ class Axes(object): griddata_props = kwargs.pop('griddata_props', dict(method='idw', pointnum=5, convexhull=True)) a, x, y = np.griddata((x, y), a, **griddata_props) - igraphic = GraphicFactory.createContourPolygons(x.asarray(), y.asarray(), a.asarray(), ls, smooth) + graphics = GraphicFactory.createContourPolygons(x.asarray(), y.asarray(), a.asarray(), ls, smooth) + + antialias = kwargs.pop('antialias', None) + if antialias is not None: + graphics.setAntiAlias(antialias) visible = kwargs.pop('visible', True) if visible: @@ -2505,12 +2524,11 @@ class Axes(object): self._axes.updateDrawExtent() zorder = kwargs.pop('zorder', None) - self.add_graphic(igraphic, zorder=zorder) - # self.setAutoExtent() - self._axes.setExtent(igraphic.getExtent()) - self._axes.setDrawExtent(igraphic.getExtent()) + self.add_graphic(graphics, zorder=zorder) + self._axes.setExtent(graphics.getExtent()) + self._axes.setDrawExtent(graphics.getExtent()) - return igraphic + return graphics def imshow(self, *args, **kwargs): """ @@ -2603,6 +2621,10 @@ class Axes(object): self.set_xaxis_type(xaxistype) self._axes.updateDrawExtent() + antialias = kwargs.pop('antialias', None) + if antialias is not None: + igraphic.setAntiAlias(antialias) + zorder = kwargs.pop('zorder', None) self.add_graphic(igraphic, zorder=zorder) gridline = self._axes.getGridLine() @@ -2655,6 +2677,10 @@ class Axes(object): plotutil.setlegendscheme(ls, **kwargs) graphics = GraphicFactory.createPColorPolygons(x.asarray(), y.asarray(), a.asarray(), ls) + antialias = kwargs.pop('antialias', None) + if antialias is not None: + graphics.setAntiAlias(antialias) + visible = kwargs.pop('visible', True) if visible: zorder = kwargs.pop('zorder', None) @@ -2699,6 +2725,10 @@ class Axes(object): ls = ls.convertTo(ShapeTypes.POLYGON) plotutil.setlegendscheme(ls, **kwargs) graphics = GraphicFactory.createGridPolygons(x.asarray(), y.asarray(), a.asarray(), ls) + antialias = kwargs.pop('antialias', None) + if antialias is not None: + graphics.setAntiAlias(antialias) + visible = kwargs.pop('visible', True) if visible: zorder = kwargs.pop('zorder', None) @@ -3077,6 +3107,10 @@ class Axes(object): graphics = GraphicFactory.createPieArcs(x, colors, labels, startangle, explode, font, fontcolor, \ labeldistance, autopct, pctdistance, radius, wedgeprops) + antialias = kwargs.pop('antialias', None) + if antialias is not None: + graphics.setAntiAlias(antialias) + for graphic in graphics: self.add_graphic(graphic) @@ -3093,7 +3127,7 @@ class Axes(object): def boxplot(self, x, sym=None, vert=True, positions=None, widths=None, color=None, showcaps=True, showfliers=True, showmeans=False, \ showmedians=True, meanline=False, medianline=True, boxprops=None, medianprops=None, meanprops=None, - whiskerprops=None, capprops=None, flierprops=None): + whiskerprops=None, capprops=None, flierprops=None, **kwargs): """ Make a box and whisker plot. @@ -3221,6 +3255,10 @@ class Axes(object): showmedians, boxprops, medianprops, whiskerprops, capprops, meanprops, flierprops) + antialias = kwargs.pop('antialias', None) + if antialias is not None: + graphics.setAntiAlias(antialias) + self.add_graphic(graphics) self._axes.setAutoExtent() @@ -3437,7 +3475,7 @@ class Axes(object): :param cmap: (*string*) Color map string. :param fill_value: (*float*) Fill_value. Default is ``-9999.0``. :param isuv: (*boolean*) Is U/V or direction/speed data array pairs. Default is True. - :param size: (*float*) Base size of the arrows. + :param size: (*float*) Base size of the arrows. Default is 10. :param order: (*int*) Z-order of created layer for display. :returns: Barbs graphics. @@ -3506,17 +3544,21 @@ class Axes(object): if not cdata is None: cdata = plotutil.getplotdata(cdata) - igraphic = GraphicFactory.createBarbs(x, y, u, v, cdata, ls, isuv) + graphics = GraphicFactory.createBarbs(x, y, u, v, cdata, ls, isuv) + + antialias = kwargs.pop('antialias', None) + if antialias is not None: + graphics.setAntiAlias(antialias) 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.add_graphic(graphics, zorder=zorder) self._axes.setAutoExtent() - return igraphic + return graphics def quiver(self, *args, **kwargs): """ @@ -3614,6 +3656,10 @@ class Axes(object): self.set_xaxis_type(xaxistype) self._axes.updateDrawExtent() + antialias = kwargs.pop('antialias', None) + if antialias is not None: + igraphic.setAntiAlias(antialias) + zorder = kwargs.pop('zorder', None) self.add_graphic(igraphic, zorder=zorder) self._axes.setAutoExtent() @@ -3765,6 +3811,10 @@ class Axes(object): igraphic = GraphicFactory.createStreamlines(x._array, y._array, u._array, v._array, cdata._array, density, ls, isuv) + antialias = kwargs.pop('antialias', None) + if antialias is not None: + igraphic.setAntiAlias(antialias) + zorder = kwargs.pop('zorder', None) self.add_graphic(igraphic, zorder=zorder) self._axes.setAutoExtent() @@ -3967,6 +4017,10 @@ class Axes(object): if newlegend: self._axes.addLegend(clegend) + antialias = kwargs.pop('antialias', None) + if antialias is not None: + clegend.setAntiAlias(antialias) + return clegend def colorbar(self, mappable=None, **kwargs): @@ -4038,7 +4092,7 @@ class Axes(object): ls = self.get_legend() else: if isinstance(mappable, MILayer): - ls = mappable.legend() + ls = mappable.legend elif isinstance(mappable, LegendScheme): ls = mappable elif isinstance(mappable, ImageGraphic): @@ -4150,6 +4204,10 @@ class Axes(object): if not minortick is None: legend.setDrawMinorTick(minortick) + antialias = kwargs.pop('antialias', None) + if antialias is not None: + legend.setAntiAlias(antialias) + return legend diff --git a/meteoinfo-lab/pylib/mipylib/plotlib/_mapaxes$py.class b/meteoinfo-lab/pylib/mipylib/plotlib/_mapaxes$py.class index 707aadb9..c078d83c 100644 Binary files a/meteoinfo-lab/pylib/mipylib/plotlib/_mapaxes$py.class and b/meteoinfo-lab/pylib/mipylib/plotlib/_mapaxes$py.class differ diff --git a/meteoinfo-lab/pylib/mipylib/plotlib/_mapaxes.py b/meteoinfo-lab/pylib/mipylib/plotlib/_mapaxes.py index b53b018d..a9e36d80 100644 --- a/meteoinfo-lab/pylib/mipylib/plotlib/_mapaxes.py +++ b/meteoinfo-lab/pylib/mipylib/plotlib/_mapaxes.py @@ -12,7 +12,7 @@ import numbers from org.meteoinfo.chart import ChartScaleBar, ChartNorthArrow from org.meteoinfo.chart.plot import GridLabelPosition from org.meteoinfo.chart.geo import MapPlot -from org.meteoinfo.chart.graphic import GraphicFactory +from org.meteoinfo.chart.graphic import GraphicFactory, WebMapImage from org.meteoinfo.geo.meteodata import DrawMeteoData from org.meteoinfo.geo.mapview import MapView from org.meteoinfo.geo.io import GraphicUtil @@ -498,7 +498,6 @@ class MapAxes(Axes): if layer.layer_type == LayerTypes.IMAGE_LAYER: interpolation = kwargs.pop('interpolation', None) graphics = layer.get_graphics(xshift, interpolation) - graphics = self.add_graphic(graphics, projection=layer.proj, zorder=zorder) else: #LegendScheme ls = kwargs.pop('symbolspec', None) @@ -521,37 +520,12 @@ class MapAxes(Axes): else: layer.legend = ls graphics = layer.get_graphics(xshift) - graphics = self.add_graphic(graphics, projection=layer.proj, zorder=zorder) - #Labels - labelfield = kwargs.pop('labelfield', None) - if not labelfield is None: - labelset = layer._layer.getLabelSet() - labelset.setFieldName(labelfield) - fontname = kwargs.pop('fontname', 'Arial') - fontsize = kwargs.pop('fontsize', 14) - bold = kwargs.pop('bold', False) - if bold: - font = Font(fontname, Font.BOLD, fontsize) - else: - font = Font(fontname, Font.PLAIN, fontsize) - labelset.setLabelFont(font) - lcolor = kwargs.pop('labelcolor', None) - if not lcolor is None: - lcolor = miutil.getcolor(lcolor) - labelset.setLabelColor(lcolor) - xoffset = kwargs.pop('xoffset', 0) - labelset.setXOffset(xoffset) - yoffset = kwargs.pop('yoffset', 0) - labelset.setYOffset(yoffset) - avoidcoll = kwargs.pop('avoidcoll', True) - decimals = kwargs.pop('decimals', None) - if not decimals is None: - labelset.setAutoDecimal(False) - labelset.setDecimalDigits(decimals) - labelset.setAvoidCollision(avoidcoll) - layer._layer.addLabels() + antialias = kwargs.pop('antialias', None) + if antialias is not None: + graphics.setAntiAlias(antialias) + graphics = self.add_graphic(graphics, projection=layer.proj, zorder=zorder) self._axes.setDrawExtent(graphics.getExtent().clone()) self._axes.setExtent(graphics.getExtent().clone()) return GeoGraphicCollection(graphics) @@ -756,7 +730,7 @@ class MapAxes(Axes): graphic = GraphicFactory.createLineString(xdata, ydata, lines[0], iscurve) else: #>1 graphic = GraphicFactory.createLineString(xdata, ydata, lines, iscurve) - self.add_graphic(graphic) + graphic = self.add_graphic(graphic, proj) graphics.append(graphic) else: for i in range(0, snum): @@ -774,6 +748,11 @@ class MapAxes(Axes): graphic = self.add_graphic(graphic, proj) graphics.append(graphic) + antialias = kwargs.pop('antialias', None) + if antialias is not None: + for graphic in graphics: + graphic.setAntiAlias(antialias) + if len(graphics) > 1: return graphics else: @@ -787,7 +766,7 @@ class MapAxes(Axes): :param x: (*array_like*) Input x data. :param y: (*array_like*) Input y data. :param z: (*array_like*) Input z data. - :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 @@ -832,19 +811,20 @@ class MapAxes(Axes): ls = kwargs.pop('symbolspec', None) if ls is None: - isunique = False - colors = kwargs.get('colors', None) - if not colors is None: - if isinstance(colors, (list, tuple)) and len(colors) == x.size: - isunique = True - size = kwargs.get('size', None) - if not size is None: - if isinstance(size, (list, tuple, NDArray)) and len(size) == x.size: - isunique = True - marker = kwargs.get('marker', None) - if not marker is None: - if isinstance(marker, (list, tuple, NDArray)) and len(marker) == x.size: - isunique = True + isunique = (a.ndim == 0) + if not isunique: + colors = kwargs.get('colors', None) + if not colors is None: + if isinstance(colors, (list, tuple)) and len(colors) == x.size: + isunique = True + size = kwargs.get('size', None) + if not size is None: + if isinstance(size, (list, tuple, NDArray)) and len(size) == x.size: + isunique = True + marker = kwargs.get('marker', None) + if not marker is None: + if isinstance(marker, (list, tuple, NDArray)) and len(marker) == x.size: + isunique = True if isunique: ls = LegendManage.createUniqValueLegendScheme(x.size, ShapeTypes.POINT) else: @@ -930,19 +910,23 @@ class MapAxes(Axes): griddata_props = kwargs.pop('griddata_props', dict(method='idw', pointnum=5, convexhull=True)) a, x, y = np.griddata((x,y), a, **griddata_props) - contours = GraphicFactory.createContourLines(x.asarray(), y.asarray(), a.asarray(), ls, smooth) + graphics = GraphicFactory.createContourLines(x.asarray(), y.asarray(), a.asarray(), ls, smooth) proj = kwargs.pop('proj', migeo.projinfo()) - # Add layer + # Add graphics + antialias = kwargs.pop('antialias', None) + if antialias is not None: + graphics.setAntiAlias(antialias) + visible = kwargs.pop('visible', True) if visible: zorder = kwargs.pop('zorder', None) - contours = self.add_graphic(contours, projection=proj, zorder=zorder) - self._axes.setDrawExtent(contours.getExtent()) - self._axes.setExtent(contours.getExtent()) + contours = self.add_graphic(graphics, projection=proj, zorder=zorder) + self._axes.setDrawExtent(graphics.getExtent()) + self._axes.setExtent(graphics.getExtent()) - return contours + return graphics def contourf(self, *args, **kwargs): """ @@ -994,6 +978,10 @@ class MapAxes(Axes): proj = kwargs.pop('proj', migeo.projinfo()) # Add graphics + antialias = kwargs.pop('antialias', None) + if antialias is not None: + graphics.setAntiAlias(antialias) + visible = kwargs.pop('visible', True) if visible: zorder = kwargs.pop('zorder', None) @@ -1128,6 +1116,10 @@ class MapAxes(Axes): if not interpolation is None: igraphic.getShape().setInterpolation(interpolation) + antialias = kwargs.pop('antialias', None) + if antialias is not None: + igraphic.setAntiAlias(antialias) + if visible: zorder = kwargs.pop('zorder', None) if zorder is None: @@ -1191,6 +1183,10 @@ class MapAxes(Axes): #x, y = np.project(x, y, toproj=proj) graphics = GraphicFactory.createPColorPolygons(x.asarray(), y.asarray(), a.asarray(), ls) + antialias = kwargs.pop('antialias', None) + if antialias is not None: + graphics.setAntiAlias(antialias) + visible = kwargs.pop('visible', True) if visible: zorder = kwargs.pop('zorder', None) @@ -1241,6 +1237,10 @@ class MapAxes(Axes): graphics = GraphicFactory.createGridPolygons(x.asarray(), y.asarray(), a.asarray(), ls) # Add graphics + antialias = kwargs.pop('antialias', None) + if antialias is not None: + graphics.setAntiAlias(antialias) + proj = kwargs.pop('proj', migeo.projinfo()) visible = kwargs.pop('visible', True) if visible: @@ -1362,7 +1362,7 @@ class MapAxes(Axes): :param cmap: (*string*) Color map string. :param fill_value: (*float*) Fill_value. Default is ``-9999.0``. :param isuv: (*boolean*) Is U/V or direction/speed data array pairs. Default is True. - :param size: (*float*) Base size of the arrows. + :param size: (*float*) Base size of the arrows. Default is 10. :param proj: (*ProjectionInfo*) Map projection of the data. Default is None. :param zorder: (*int*) Z-order of created layer for display. :param select: (*boolean*) Set the return layer as selected layer or not. @@ -1507,6 +1507,10 @@ class MapAxes(Axes): cdata._array, density, ls, isuv) # Add graphics + antialias = kwargs.pop('antialias', None) + if antialias is not None: + graphics.setAntiAlias(antialias) + visible = kwargs.pop('visible', True) if visible: zorder = kwargs.pop('zorder', None) @@ -1537,6 +1541,10 @@ class MapAxes(Axes): graphics = GraphicFactory.createStationModel(smdata, ls, surface) # Add graphics + antialias = kwargs.pop('antialias', None) + if antialias is not None: + graphics.setAntiAlias(antialias) + visible = kwargs.pop('visible', True) if visible: zorder = kwargs.pop('zorder', None) @@ -1555,16 +1563,16 @@ class MapAxes(Axes): :returns: Web map layer """ - layer = WebMapLayer() + graphic = WebMapImage() if isinstance(provider, TileFactoryInfo): tf = DefaultTileFactory(provider) - layer.setTileFactory(tf) + graphic.setTileFactory(tf) else: provider = WebMapProvider.valueOf(provider) - layer.setWebMapProvider(provider) + graphic.setWebMapProvider(provider) - self.add_layer(layer, zorder) - return MILayer(layer) + self.add_graphic(graphic, zorder=zorder) + return graphic def masklayer(self, mask, graphics): """ @@ -1573,7 +1581,7 @@ class MapAxes(Axes): :param mask: (*layer or polygon graphic*) Mask object. :param graphics: (*list*) The graphics will be masked. """ - if isinstance(mask, MILayer): + if isinstance(mask, (MILayer, GeoGraphicCollection)): mask = mask.get_graphics() for graphic in graphics: diff --git a/meteoinfo-lab/pylib/mipylib/plotlib/graphic/lines.py b/meteoinfo-lab/pylib/mipylib/plotlib/graphic/lines.py index 2f2acbee..f84f65c3 100644 --- a/meteoinfo-lab/pylib/mipylib/plotlib/graphic/lines.py +++ b/meteoinfo-lab/pylib/mipylib/plotlib/graphic/lines.py @@ -3,6 +3,7 @@ from org.meteoinfo.geometry.legend import PolylineBreak from .. import plotutil from artist import Artist +import mipylib.numeric as np __all__ = ['Line2D'] @@ -27,14 +28,14 @@ class Line2D(Line2DGraphic, Artist): if legend is None: legend = plotutil.getlegendbreak('line', **kwargs)[0] - self._x = xdata - self._y = ydata - self._cdata = cdata + self._x = np.asarray(xdata) + self._y = np.asarray(ydata) + self._cdata = np.asarray(cdata) if cdata is None: - Line2DGraphic.__init__(self, xdata._array, ydata._array, legend) + Line2DGraphic.__init__(self, self._x._array, self._y._array, legend) else: - Line2DGraphic.__init__(self, xdata._array, ydata._array, cdata._array, legend) + Line2DGraphic.__init__(self, self._x._array, self._y._array, self._cdata._array, legend) if curve: self.setCurve(curve) diff --git a/meteoinfo-ndarray/src/main/java/org/meteoinfo/ndarray/math/ArrayUtil.java b/meteoinfo-ndarray/src/main/java/org/meteoinfo/ndarray/math/ArrayUtil.java index d32d4450..69ec7076 100644 --- a/meteoinfo-ndarray/src/main/java/org/meteoinfo/ndarray/math/ArrayUtil.java +++ b/meteoinfo-ndarray/src/main/java/org/meteoinfo/ndarray/math/ArrayUtil.java @@ -643,7 +643,11 @@ public class ArrayUtil { * @return Array */ public static Array array(Object data, DataType dt) { - if (data instanceof Array) { + if (data == null) { + Array a = Array.factory(DataType.OBJECT, new int[0]); + a.setObject(0, null); + return a; + } else if (data instanceof Array) { return (Array) data; } else if (data instanceof List) { return array_list((List) data, dt); 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 70e682ed..2442d97e 100644 --- a/meteoinfo-projection/src/main/java/org/meteoinfo/projection/ProjectionUtil.java +++ b/meteoinfo-projection/src/main/java/org/meteoinfo/projection/ProjectionUtil.java @@ -924,11 +924,16 @@ public class ProjectionUtil { newGCollection.add(aGraphic); } } + newGCollection.setLegendScheme(((GraphicCollection) graphic).getLegendScheme()); + newGCollection.setSingleLegend(((GraphicCollection) graphic).isSingleLegend()); + newGCollection.setAntiAlias(graphic.isAntiAlias()); return newGCollection; } else { Shape shape = projectShape(graphic.getShape(), fromProj, toProj); - return new Graphic(shape, graphic.getLegend()); + Graphic rGraphic = new Graphic(shape, graphic.getLegend()); + rGraphic.setAntiAlias(graphic.isAntiAlias()); + return rGraphic; } } @@ -953,6 +958,7 @@ public class ProjectionUtil { } newGCollection.setLegendScheme(((GraphicCollection) graphic).getLegendScheme()); newGCollection.setSingleLegend(((GraphicCollection) graphic).isSingleLegend()); + newGCollection.setAntiAlias(graphic.isAntiAlias()); return newGCollection; } catch (Exception ex) { @@ -962,7 +968,9 @@ public class ProjectionUtil { } else { List shapes = projectClipShape(graphic.getShape(), fromProj, toProj); if (shapes != null && shapes.size() > 0) { - return new Graphic(shapes.get(0), graphic.getLegend()); + Graphic rGraphic = new Graphic(shapes.get(0), graphic.getLegend()); + rGraphic.setAntiAlias(graphic.isAntiAlias()); + return rGraphic; } else { return null; }