diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index f65d2590..ae46cc1f 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -6,16 +6,20 @@
-
-
+
+
+
+
+
+
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
index dea81a50..aef94361 100644
--- a/.idea/encodings.xml
+++ b/.idea/encodings.xml
@@ -11,8 +11,12 @@
+
+
+
+
diff --git a/.idea/modules.xml b/.idea/modules.xml
index 17b8190b..4766f0f0 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -6,7 +6,9 @@
+
+
diff --git a/MeteoInfoLab/MeteoInfoLab.iml b/MeteoInfoLab/MeteoInfoLab.iml
index 53ab16e2..42681240 100644
--- a/MeteoInfoLab/MeteoInfoLab.iml
+++ b/MeteoInfoLab/MeteoInfoLab.iml
@@ -22,6 +22,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/MeteoInfoLab/milconfig.xml b/MeteoInfoLab/milconfig.xml
index f5aa03fb..02eae897 100644
--- a/MeteoInfoLab/milconfig.xml
+++ b/MeteoInfoLab/milconfig.xml
@@ -1,29 +1,32 @@
-
-
-
+
-
-
+
+
+
+
+
-
+
+
-
+
+
diff --git a/MeteoInfoLab/pylib/mipylib/dataset/__init__$py.class b/MeteoInfoLab/pylib/mipylib/dataset/__init__$py.class
index 1f33134b..8781f64f 100644
Binary files a/MeteoInfoLab/pylib/mipylib/dataset/__init__$py.class and b/MeteoInfoLab/pylib/mipylib/dataset/__init__$py.class differ
diff --git a/MeteoInfoLab/pylib/mipylib/dataset/__init__.py b/MeteoInfoLab/pylib/mipylib/dataset/__init__.py
index 54fe417b..a2a4017a 100644
--- a/MeteoInfoLab/pylib/mipylib/dataset/__init__.py
+++ b/MeteoInfoLab/pylib/mipylib/dataset/__init__.py
@@ -1,5 +1,6 @@
import midata
from .midata import *
+import ncutil
from .dimvariable import DimVariable
__all__ = ['ncutil', 'DimVariable']
diff --git a/MeteoInfoLab/pylib/mipylib/dataset/dimvariable$py.class b/MeteoInfoLab/pylib/mipylib/dataset/dimvariable$py.class
index c31bd0e2..9b7dc6ce 100644
Binary files a/MeteoInfoLab/pylib/mipylib/dataset/dimvariable$py.class and b/MeteoInfoLab/pylib/mipylib/dataset/dimvariable$py.class differ
diff --git a/MeteoInfoLab/pylib/mipylib/dataset/dimvariable.py b/MeteoInfoLab/pylib/mipylib/dataset/dimvariable.py
index 3edf7899..a9b91e37 100644
--- a/MeteoInfoLab/pylib/mipylib/dataset/dimvariable.py
+++ b/MeteoInfoLab/pylib/mipylib/dataset/dimvariable.py
@@ -6,7 +6,7 @@
#-----------------------------------------------------
from org.meteoinfo.ndarray import Dimension, DimensionType, Range, Array, MAMath
from org.meteoinfo.math import ArrayMath, ArrayUtil
-from org.meteoinfo.global import PointD
+from org.meteoinfo.common import PointD
from org.meteoinfo.projection import KnownCoordinateSystems, Reproject
from org.meteoinfo.data.meteodata import Attribute
from ucar.nc2 import Attribute as NCAttribute
diff --git a/MeteoInfoLab/pylib/mipylib/geolib/geoutil$py.class b/MeteoInfoLab/pylib/mipylib/geolib/geoutil$py.class
index 464b15c5..f2f74e84 100644
Binary files a/MeteoInfoLab/pylib/mipylib/geolib/geoutil$py.class and b/MeteoInfoLab/pylib/mipylib/geolib/geoutil$py.class differ
diff --git a/MeteoInfoLab/pylib/mipylib/geolib/geoutil.py b/MeteoInfoLab/pylib/mipylib/geolib/geoutil.py
index e6f4823a..69676af8 100644
--- a/MeteoInfoLab/pylib/mipylib/geolib/geoutil.py
+++ b/MeteoInfoLab/pylib/mipylib/geolib/geoutil.py
@@ -1,58 +1,58 @@
-#-----------------------------------------------------
-# Author: Yaqiang Wang
-# Date: 2017-11-28
-# Purpose: MeteoInfo geoutil module
-# Note: Jython
-#-----------------------------------------------------
-
-from org.meteoinfo.shape import ShapeUtil, PointShape
-from org.meteoinfo.global import PointD
-import mipylib.numeric as np
-
-__all__ = [
- 'makeshapes'
- ]
-
-def makeshapes(x, y, type=None, z=None, m=None):
- """
- Make shapes by x and y coordinates.
-
- :param x: (*array_like*) X coordinates.
- :param y: (*array_like*) Y coordinates.
- :param type: (*string*) Shape type [point | line | polygon].
- :param z: (*array_like*) Z coordinates.
- :param m: (*array_like*) M coordinates.
-
- :returns: Shapes
- """
- shapes = []
- if isinstance(x, (int, float)):
- shape = PointShape()
- shape.setPoint(PointD(x, y))
- shapes.append(shape)
- else:
- x = np.asarray(x)._array
- y = np.asarray(y)._array
- if not z is None:
- if m is None:
- m = np.zeros(len(z))._array
- else:
- m = np.asarray(m)._array
- z = np.asarray(z)._array
- if type == 'point':
- if z is None:
- shapes = ShapeUtil.createPointShapes(x, y)
- else:
- shapes = ShapeUtil.createPointShapes(x, y, z, m)
- elif type == 'line':
- if z is None:
- shapes = ShapeUtil.createPolylineShapes(x, y)
- else:
- shapes = ShapeUtil.createPolylineShapes(x, y, z, m)
- elif type == 'polygon':
- if z is None:
- shapes = ShapeUtil.createPolygonShapes(x, y)
- else:
- shapes = ShapeUtil.createPolygonShape(x, y, z, m)
- return shapes
+#-----------------------------------------------------
+# Author: Yaqiang Wang
+# Date: 2017-11-28
+# Purpose: MeteoInfo geoutil module
+# Note: Jython
+#-----------------------------------------------------
+
+from org.meteoinfo.shape import ShapeUtil, PointShape
+from org.meteoinfo.common import PointD
+import mipylib.numeric as np
+
+__all__ = [
+ 'makeshapes'
+ ]
+
+def makeshapes(x, y, type=None, z=None, m=None):
+ """
+ Make shapes by x and y coordinates.
+
+ :param x: (*array_like*) X coordinates.
+ :param y: (*array_like*) Y coordinates.
+ :param type: (*string*) Shape type [point | line | polygon].
+ :param z: (*array_like*) Z coordinates.
+ :param m: (*array_like*) M coordinates.
+
+ :returns: Shapes
+ """
+ shapes = []
+ if isinstance(x, (int, float)):
+ shape = PointShape()
+ shape.setPoint(PointD(x, y))
+ shapes.append(shape)
+ else:
+ x = np.asarray(x)._array
+ y = np.asarray(y)._array
+ if not z is None:
+ if m is None:
+ m = np.zeros(len(z))._array
+ else:
+ m = np.asarray(m)._array
+ z = np.asarray(z)._array
+ if type == 'point':
+ if z is None:
+ shapes = ShapeUtil.createPointShapes(x, y)
+ else:
+ shapes = ShapeUtil.createPointShapes(x, y, z, m)
+ elif type == 'line':
+ if z is None:
+ shapes = ShapeUtil.createPolylineShapes(x, y)
+ else:
+ shapes = ShapeUtil.createPolylineShapes(x, y, z, m)
+ elif type == 'polygon':
+ if z is None:
+ shapes = ShapeUtil.createPolygonShapes(x, y)
+ else:
+ shapes = ShapeUtil.createPolygonShape(x, y, z, m)
+ return shapes
\ No newline at end of file
diff --git a/MeteoInfoLab/pylib/mipylib/geolib/migeo$py.class b/MeteoInfoLab/pylib/mipylib/geolib/migeo$py.class
index 51b06d24..719e584e 100644
Binary files a/MeteoInfoLab/pylib/mipylib/geolib/migeo$py.class and b/MeteoInfoLab/pylib/mipylib/geolib/migeo$py.class differ
diff --git a/MeteoInfoLab/pylib/mipylib/geolib/migeo.py b/MeteoInfoLab/pylib/mipylib/geolib/migeo.py
index a25ebd2a..55aa55da 100644
--- a/MeteoInfoLab/pylib/mipylib/geolib/migeo.py
+++ b/MeteoInfoLab/pylib/mipylib/geolib/migeo.py
@@ -16,8 +16,8 @@ from org.meteoinfo.math import ArrayMath, ArrayUtil
from org.meteoinfo.data.mapdata import MapDataManage, AttributeTable
from org.meteoinfo.projection import KnownCoordinateSystems, Reproject
from org.meteoinfo.projection.info import ProjectionInfo
-from org.meteoinfo.global import PointD
-from org.meteoinfo.io import IOUtil
+from org.meteoinfo.common import PointD
+from org.meteoinfo.common.io import IOUtil
from org.meteoinfo.geoprocess.analysis import ResampleMethods
from milayer import MILayer
diff --git a/MeteoInfoLab/pylib/mipylib/miutil$py.class b/MeteoInfoLab/pylib/mipylib/miutil$py.class
index a9bc19c3..c15c33cf 100644
Binary files a/MeteoInfoLab/pylib/mipylib/miutil$py.class and b/MeteoInfoLab/pylib/mipylib/miutil$py.class differ
diff --git a/MeteoInfoLab/pylib/mipylib/miutil.py b/MeteoInfoLab/pylib/mipylib/miutil.py
index 569eed3c..75187f65 100644
--- a/MeteoInfoLab/pylib/mipylib/miutil.py
+++ b/MeteoInfoLab/pylib/mipylib/miutil.py
@@ -5,8 +5,8 @@
# Note: Jython
#-----------------------------------------------------
-from org.meteoinfo.global import PointD
-from org.meteoinfo.global.util import JDateUtil
+from org.meteoinfo.common import PointD
+from org.meteoinfo.common.util import JDateUtil
from org.meteoinfo.ndarray import Complex
from org.meteoinfo.shape import PointShape, ShapeUtil
from java.util import Locale
diff --git a/MeteoInfoLab/pylib/mipylib/numeric/core/dimarray$py.class b/MeteoInfoLab/pylib/mipylib/numeric/core/dimarray$py.class
index 8fa9be8c..2a3ab362 100644
Binary files a/MeteoInfoLab/pylib/mipylib/numeric/core/dimarray$py.class and b/MeteoInfoLab/pylib/mipylib/numeric/core/dimarray$py.class differ
diff --git a/MeteoInfoLab/pylib/mipylib/numeric/core/dimarray.py b/MeteoInfoLab/pylib/mipylib/numeric/core/dimarray.py
index d3b62a20..78fb7c55 100644
--- a/MeteoInfoLab/pylib/mipylib/numeric/core/dimarray.py
+++ b/MeteoInfoLab/pylib/mipylib/numeric/core/dimarray.py
@@ -9,7 +9,7 @@ from org.meteoinfo.data import GridData, GridArray
from org.meteoinfo.math import ArrayMath, ArrayUtil
from org.meteoinfo.geoprocess import GeometryUtil
from org.meteoinfo.geoprocess.analysis import ResampleMethods
-from org.meteoinfo.global import PointD
+from org.meteoinfo.common import PointD
from org.meteoinfo.ndarray import Array, Range, MAMath, DataType, Dimension, DimensionType
from multiarray import NDArray
import math
diff --git a/MeteoInfoLab/pylib/mipylib/plotlib/_axes$py.class b/MeteoInfoLab/pylib/mipylib/plotlib/_axes$py.class
index c4944625..9ff0b5ae 100644
Binary files a/MeteoInfoLab/pylib/mipylib/plotlib/_axes$py.class and b/MeteoInfoLab/pylib/mipylib/plotlib/_axes$py.class differ
diff --git a/MeteoInfoLab/pylib/mipylib/plotlib/_axes.py b/MeteoInfoLab/pylib/mipylib/plotlib/_axes.py
index e5349018..aaeac407 100644
--- a/MeteoInfoLab/pylib/mipylib/plotlib/_axes.py
+++ b/MeteoInfoLab/pylib/mipylib/plotlib/_axes.py
@@ -14,7 +14,7 @@ from org.meteoinfo.chart.axis import Axis, LonLatAxis, TimeAxis, LogAxis
from org.meteoinfo.legend import LegendManage, BarBreak, PolygonBreak, PolylineBreak, \
PointBreak, LineStyles, PointStyle, LegendScheme, LegendType
from org.meteoinfo.shape import ShapeTypes, Graphic, GraphicCollection
-from org.meteoinfo.global import MIMath, Extent
+from org.meteoinfo.common import MIMath, Extent
from org.meteoinfo.layer import MapLayer
from java.awt import Font, Color, BasicStroke
diff --git a/MeteoInfoLab/pylib/mipylib/plotlib/_mapaxes$py.class b/MeteoInfoLab/pylib/mipylib/plotlib/_mapaxes$py.class
index 4fe95a53..7d3bddc9 100644
Binary files a/MeteoInfoLab/pylib/mipylib/plotlib/_mapaxes$py.class and b/MeteoInfoLab/pylib/mipylib/plotlib/_mapaxes$py.class differ
diff --git a/MeteoInfoLab/pylib/mipylib/plotlib/_mapaxes.py b/MeteoInfoLab/pylib/mipylib/plotlib/_mapaxes.py
index 232d4f46..6404ed7c 100644
--- a/MeteoInfoLab/pylib/mipylib/plotlib/_mapaxes.py
+++ b/MeteoInfoLab/pylib/mipylib/plotlib/_mapaxes.py
@@ -16,7 +16,7 @@ from org.meteoinfo.map import MapView
from org.meteoinfo.legend import BreakTypes, LegendManage, LegendScheme, LegendType
from org.meteoinfo.shape import Shape, PolylineShape, PolygonShape, ShapeTypes, Graphic
from org.meteoinfo.projection.info import ProjectionInfo
-from org.meteoinfo.global import Extent
+from org.meteoinfo.common import Extent
from org.meteoinfo.layer import LayerTypes, WebMapLayer
from org.meteoinfo.data.mapdata.webmap import WebMapProvider
from org.meteoinfo.layout import ScaleBarType
diff --git a/MeteoInfoLab/src/main/java/org/meteoinfo/laboratory/MeteoInfoLab.java b/MeteoInfoLab/src/main/java/org/meteoinfo/laboratory/MeteoInfoLab.java
index 48fef15b..9cbdd277 100644
--- a/MeteoInfoLab/src/main/java/org/meteoinfo/laboratory/MeteoInfoLab.java
+++ b/MeteoInfoLab/src/main/java/org/meteoinfo/laboratory/MeteoInfoLab.java
@@ -21,9 +21,9 @@ import com.formdev.flatlaf.FlatDarculaLaf;
import com.formdev.flatlaf.FlatDarkLaf;
import com.formdev.flatlaf.FlatIntelliJLaf;
import com.formdev.flatlaf.FlatLightLaf;
+import org.meteoinfo.common.util.GlobalUtil;
import org.meteoinfo.global.DataConvert;
import org.meteoinfo.global.util.FontUtil;
-import org.meteoinfo.global.util.GlobalUtil;
import org.meteoinfo.laboratory.gui.FrmMain;
import org.meteoinfo.console.jython.MyPythonInterpreter;
import org.python.core.Py;
diff --git a/MeteoInfoLab/src/main/java/org/meteoinfo/laboratory/gui/EditorDockable.java b/MeteoInfoLab/src/main/java/org/meteoinfo/laboratory/gui/EditorDockable.java
index af05bf61..9c1c7035 100644
--- a/MeteoInfoLab/src/main/java/org/meteoinfo/laboratory/gui/EditorDockable.java
+++ b/MeteoInfoLab/src/main/java/org/meteoinfo/laboratory/gui/EditorDockable.java
@@ -1,733 +1,733 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.meteoinfo.laboratory.gui;
-
-import bibliothek.gui.dock.common.DefaultSingleCDockable;
-import bibliothek.gui.dock.common.action.CAction;
-import java.awt.AWTException;
-import java.awt.Component;
-import java.awt.Font;
-import java.awt.Robot;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.KeyEvent;
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import javax.swing.JButton;
-import javax.swing.JFileChooser;
-import javax.swing.JMenuItem;
-import javax.swing.JOptionPane;
-import javax.swing.JPopupMenu;
-import javax.swing.JPopupMenu.Separator;
-import javax.swing.JTabbedPane;
-import javax.swing.JTextArea;
-import javax.swing.SwingWorker;
-import javax.swing.event.ChangeEvent;
-import javax.swing.text.BadLocationException;
-
-import com.formdev.flatlaf.extras.FlatSVGIcon;
-import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
-import org.fife.ui.rsyntaxtextarea.TextEditorPane;
-import org.fife.ui.rsyntaxtextarea.Theme;
-import org.meteoinfo.console.editor.JTextAreaPrintStream;
-import org.meteoinfo.console.editor.JTextAreaWriter;
-import org.meteoinfo.console.editor.MITextEditorPane;
-import org.meteoinfo.console.editor.TextEditor;
-import org.meteoinfo.global.GenericFileFilter;
-import org.meteoinfo.console.jython.JIntrospect;
-import org.meteoinfo.ui.ButtonTabComponent;
-import org.python.util.PythonInterpreter;
-
-/**
- *
- * @author yaqiang
- */
-public class EditorDockable extends DefaultSingleCDockable {
-
- private final FrmMain parent;
- //private String startupPath;
- private final JTabbedPane tabbedPanel;
- private Font textFont;
- private PythonInterpreter interp;
- private Theme theme;
-
- public EditorDockable(FrmMain parent, String id, String title, CAction... actions) {
- super(id, title, actions);
-
- this.parent = parent;
- this.setTitleIcon(new FlatSVGIcon("org/meteoinfo/laboratory/icons/editor.svg"));
- String lfName = this.parent.getOptions().getLookFeel();
- String themeName = "default";
- switch (lfName) {
- case "FlatDarculaLaf":
- case "FlatDarkLaf":
- themeName = "dark";
- break;
- }
- try {
- theme = Theme.load(getClass().getResourceAsStream(
- "/org/fife/ui/rsyntaxtextarea/themes/" + themeName + ".xml"));
- } catch (IOException ioe) { // Never happens
- ioe.printStackTrace();
- }
- tabbedPanel = new JTabbedPane();
- tabbedPanel.addChangeListener((ChangeEvent e) -> {
- JTabbedPane sourceTabbedPane = (JTabbedPane) e.getSource();
- TextEditor te = (TextEditor) sourceTabbedPane.getSelectedComponent();
- if (te != null) {
- EditorDockable.this.setTitleText("Editor - " + te.getFileName());
- }
- });
- this.getContentPane().add(tabbedPanel);
- //this.setCloseable(false);
- }
-
-// /**
-// * Set startup path
-// *
-// * @param path Startup path
-// */
-// public void setStartupPath(String path) {
-// this.startupPath = path;
-// }
- /**
- * Get tabbed pane
- *
- * @return Tabbed pane
- */
- public JTabbedPane getTabbedPane() {
- return this.tabbedPanel;
- }
-
- /**
- * Get font
- *
- * @return Font
- */
- public Font getTextFont() {
- return this.textFont;
- }
-
- /**
- * Set font
- *
- * @param font Font
- */
- public void setTextFont(Font font) {
- this.textFont = font;
- for (Component tab : this.tabbedPanel.getComponents()) {
- if (tab instanceof TextEditor) {
- ((TextEditor) tab).setTextFont(this.textFont);
- }
- }
- }
-
- /**
- * Set python interpreter
- *
- * @param value Python interpreter
- */
- public void setInterp(PythonInterpreter value) {
- this.interp = value;
- }
-
- /**
- * Add a new text editor
- *
- * @param title Title
- * @return Text editor
- */
- public final TextEditor addNewTextEditor(String title) {
- final TextEditor tab = new TextEditor(tabbedPanel, title);
- tabbedPanel.add(tab, title);
- tabbedPanel.setSelectedComponent(tab);
- final MITextEditorPane textArea = (MITextEditorPane) tab.getTextArea();
- textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_PYTHON);
- textArea.discardAllEdits();
- this.theme.apply(textArea);
- tab.setTextFont(this.textFont);
-
- //Evaluate menu
- JPopupMenu popup = textArea.getPopupMenu();
- JMenuItem evaluate = new JMenuItem("Evaluate Selection");
- evaluate.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- try {
- runCodeLines(textArea);
- } catch (InterruptedException ex) {
- Logger.getLogger(EditorDockable.class.getName()).log(Level.SEVERE, null, ex);
- } catch (BadLocationException ex) {
- Logger.getLogger(EditorDockable.class.getName()).log(Level.SEVERE, null, ex);
- }
- }
- });
- popup.insert(evaluate, 0);
- popup.insert(new Separator(), 1);
-
- //Comment menu
- JMenuItem comment = new JMenuItem("Comment or Uncomment");
- comment.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- try {
- comment(textArea);
- } catch (InterruptedException ex) {
- Logger.getLogger(EditorDockable.class.getName()).log(Level.SEVERE, null, ex);
- } catch (BadLocationException ex) {
- Logger.getLogger(EditorDockable.class.getName()).log(Level.SEVERE, null, ex);
- }
- }
- });
- popup.insert(comment, 2);
-
- //Insert Tab menu
- JMenuItem insertTab = new JMenuItem("Insert Tab");
- insertTab.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- try {
- insertTab(textArea);
- } catch (InterruptedException ex) {
- Logger.getLogger(EditorDockable.class.getName()).log(Level.SEVERE, null, ex);
- } catch (AWTException ex) {
- Logger.getLogger(EditorDockable.class.getName()).log(Level.SEVERE, null, ex);
- }
- }
- });
- popup.insert(insertTab, 3);
-
- //Delete Tab menu
- JMenuItem delTab = new JMenuItem("Delete Tab");
- delTab.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- try {
- delTab(textArea);
- } catch (InterruptedException ex) {
- Logger.getLogger(EditorDockable.class.getName()).log(Level.SEVERE, null, ex);
- } catch (BadLocationException ex) {
- Logger.getLogger(EditorDockable.class.getName()).log(Level.SEVERE, null, ex);
- }
- }
- });
- popup.insert(delTab, 4);
-
- tab.getTextArea().setDirty(false);
- tab.setTitle(title);
-
- //Set name completion
- JIntrospect nameComplete = new JIntrospect(this.interp);
- textArea.setNameCompletion(nameComplete);
-
-// //Set language support - code auto completion
-// JythonLanguageSupport ac = new JythonLanguageSupport();
-// ac.install(textArea);
-// JythonCompletionProvider cp = ac.getProvider();
-// if (this.interp != null)
-// ((JythonSourceCompletionProvider)cp.getDefaultCompletionProvider()).setInterp(interp);
- ButtonTabComponent btc = new ButtonTabComponent(tabbedPanel);
- JButton button = btc.getTabButton();
- button.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- closeFile(tab);
- }
- });
- tabbedPanel.setTabComponentAt(tabbedPanel.indexOfComponent(tab), btc);
-
- return tab;
- }
-
- /**
- * Get active text editor
- *
- * @return Active text editor
- */
- public TextEditor getActiveTextEditor() {
- if (this.tabbedPanel.getTabCount() == 0) {
- return null;
- } else {
- return (TextEditor) this.tabbedPanel.getSelectedComponent();
- }
- }
-
- /**
- * Get all text editors
- *
- * @return All text editors
- */
- public List getAllTextEditor() {
- List tes = new ArrayList<>();
- Component comp;
- for (int i = 0; i < this.tabbedPanel.getComponentCount(); i++) {
- comp = this.tabbedPanel.getComponent(i);
- if (comp instanceof TextEditor)
- tes.add((TextEditor) comp);
- }
-
- return tes;
- }
-
- /**
- * Set active text editor
- *
- * @param te Text editor
- */
- public void setActiveTextEditor(TextEditor te) {
- this.tabbedPanel.setSelectedComponent(te);
- this.setTitleText("Editor - " + te.getFileName());
- }
-
- private TextEditorPane getActiveTextArea() {
- TextEditor textEditor = getActiveTextEditor();
- if (textEditor != null) {
- return textEditor.getTextArea();
- } else {
- return null;
- }
- }
-
- /**
- * Close file
- */
- public void closeFile() {
- closeFile(this.getActiveTextEditor());
- }
-
- private void closeFile(TextEditor textEditor) {
- //TextEditor textEditor = getActiveTextEditor();
- if (textEditor != null) {
- boolean ifClose = true;
- if (textEditor.getTextArea().isDirty()) {
- String fName = textEditor.getFileName();
- if (fName.isEmpty()) {
- fName = "New file";
- }
- int result = JOptionPane.showConfirmDialog(null, MessageFormat.format("Save changes to \"{0}\"", fName), "Save?", JOptionPane.YES_NO_CANCEL_OPTION);
- if (result == JOptionPane.YES_OPTION) {
- if (!doSave(textEditor)) {
- ifClose = false;
- }
- } else if (result == JOptionPane.CANCEL_OPTION) {
- ifClose = false;
- }
- }
-
- if (ifClose) {
- removeTextEditor(textEditor);
- }
- }
- }
-
- /**
- * Close all files
- */
- public void closeAllFiles() {
- while (this.tabbedPanel.getTabCount() > 0) {
- this.closeFile();
- }
-// for (int i = 0; i < this.tabbedPanel.getTabCount(); i++) {
-// this.closeFile((TextEditor) this.tabbedPanel.getComponentAt(0));
-// }
- }
-
- /**
- * Save file
- *
- * @param editor The text editor
- * @return Boolean
- */
- public boolean doSave(TextEditor editor) {
- if (editor.getFileName().isEmpty()) {
- return doSaveAs_Jython(editor);
- } else {
- editor.saveFile(editor.getFile());
- return true;
- }
- }
-
- /**
- * Save as
- *
- * @param editor The text editor
- * @return Boolean
- */
- public boolean doSaveAs_Jython(TextEditor editor) {
- JFileChooser aDlg = new JFileChooser();
- String[] fileExts = new String[]{"py"};
- GenericFileFilter mapFileFilter = new GenericFileFilter(fileExts, "Python File (*.py)");
- aDlg.setFileFilter(mapFileFilter);
- if (editor.getFile() != null) {
- aDlg.setSelectedFile(editor.getFile());
- } else {
- File dir = new File(System.getProperty("user.dir"));
- if (dir.isDirectory()) {
- aDlg.setCurrentDirectory(dir);
- }
- }
- if (aDlg.showSaveDialog(parent) == JFileChooser.APPROVE_OPTION) {
- File file = aDlg.getSelectedFile();
- System.setProperty("user.dir", file.getParent());
- String extent = ((GenericFileFilter) aDlg.getFileFilter()).getFileExtent();
- String fileName = file.getAbsolutePath();
- if (!fileName.substring(fileName.length() - extent.length()).equals(extent)) {
- fileName = fileName + "." + extent;
- }
- file = new File(fileName);
- if (file.exists()) {
- int overwrite = JOptionPane.showConfirmDialog(null, "File exists! Overwrite it?", "Confirm", JOptionPane.YES_NO_OPTION);
- if (overwrite == JOptionPane.NO_OPTION) {
- return false;
- }
- }
- editor.saveFile(file);
- this.setTitleText(editor.getFileName());
- return true;
- }
- return false;
- }
-
- private void removeTextEditor(TextEditor editor) {
- this.tabbedPanel.remove(editor);
- }
-
- /**
- * Open Jython script file
- */
- public void doOpen_Jython() {
- // TODO add your handling code here:
- JFileChooser aDlg = new JFileChooser();
- aDlg.setMultiSelectionEnabled(true);
- aDlg.setAcceptAllFileFilterUsed(false);
- //File dir = new File(this._parent.getCurrentDataFolder());
- File dir = new File(System.getProperty("user.dir"));
- if (dir.isDirectory()) {
- aDlg.setCurrentDirectory(dir);
- }
- String[] fileExts = new String[]{"py"};
- GenericFileFilter mapFileFilter = new GenericFileFilter(fileExts, "Jython File (*.py)");
- aDlg.setFileFilter(mapFileFilter);
- if (JFileChooser.APPROVE_OPTION == aDlg.showOpenDialog(parent)) {
- File[] files = aDlg.getSelectedFiles();
- //this._parent.setCurrentDataFolder(files[0].getParent());
- System.setProperty("user.dir", files[0].getParent());
- this.openFiles(files);
- }
- }
-
- /**
- * Open files
- *
- * @param fileNames File name list
- */
- public void openFiles(List fileNames) {
- List files = new ArrayList<>();
- for (String fn : fileNames) {
- File file = new File(fn);
- if (file.exists()) {
- files.add(file);
- }
- }
-
- if (files.size() > 0) {
- File[] fs = new File[files.size()];
- for (int i = 0; i < files.size(); i++) {
- fs[i] = files.get(i);
- }
- this.openFiles(fs);
- }
- }
-
- /**
- * Open script files
- *
- * @param files The files
- */
- public void openFiles(File[] files) {
- // Close default untitled document if it is still empty
- if (this.tabbedPanel.getTabCount() == 1) {
- TextEditor textEditor = getActiveTextEditor();
- if (textEditor.getTextArea().getDocument().getLength() == 0 && textEditor.getFileName().isEmpty()) {
- this.removeTextEditor(textEditor);
- }
- }
-
- // Open file(s)
- for (File file : files) {
- boolean isExist = false;
- for (int i = 0; i < this.tabbedPanel.getTabCount(); i++) {
- TextEditor te = (TextEditor) this.tabbedPanel.getComponentAt(i);
- if (file.getAbsolutePath().equals(te.getFileName())) {
- isExist = true;
- this.setActiveTextEditor(te);
- break;
- }
- }
- if (isExist) {
- continue;
- }
- TextEditor editor = addNewTextEditor(file.getName());
- editor.openFile(file);
- this.setTitleText(editor.getFileName());
- }
- }
-
- /**
- * Open script file
- *
- * @param file The file
- */
- public void openFile(File file) {
- // Close default untitled document if it is still empty
- if (this.tabbedPanel.getTabCount() == 1) {
- TextEditor textEditor = getActiveTextEditor();
- if (textEditor.getTextArea().getDocument().getLength() == 0 && textEditor.getFileName().isEmpty()) {
- this.removeTextEditor(textEditor);
- }
- }
-
- // Open file
- boolean isExist = false;
- for (int i = 0; i < this.tabbedPanel.getTabCount(); i++) {
- TextEditor te = (TextEditor) this.tabbedPanel.getComponentAt(i);
- if (file.getAbsolutePath().equals(te.getFileName())) {
- isExist = true;
- this.setActiveTextEditor(te);
- break;
- }
- }
- if (!isExist) {
- TextEditor editor = addNewTextEditor(file.getName());
- editor.openFile(file);
- this.parent.getOptions().addRecentFile(file.getAbsolutePath());
- this.setTitleText(editor.getFileName());
- }
- }
-
- /**
- * Get opened file names
- *
- * @return Opened file names
- */
- public List getOpenedFiles() {
- List fns = new ArrayList<>();
- for (int i = 0; i < this.tabbedPanel.getTabCount(); i++) {
- TextEditor te = (TextEditor) this.tabbedPanel.getComponentAt(i);
- fns.add(te.getFileName());
- }
-
- return fns;
- }
-
- private void runCodeLines(MITextEditorPane textArea) throws InterruptedException, BadLocationException {
- int sLine = textArea.getLineOfOffset(textArea.getSelectionStart());
- int sIdx = textArea.getLineStartOffset(sLine);
- int eLine = textArea.getLineOfOffset(textArea.getSelectionEnd());
- int eIdx = textArea.getLineEndOffset(eLine);
- textArea.setSelectionStart(sIdx);
- textArea.setSelectionEnd(eIdx);
- String code = textArea.getSelectedText();
-
- this.parent.getConsoleDockable().run(code);
- }
-
- /**
- * Toggle comment to the selected lines
- */
- public void Comment() {
- try {
- comment((MITextEditorPane)this.getActiveTextArea());
- } catch (InterruptedException ex) {
- Logger.getLogger(EditorDockable.class.getName()).log(Level.SEVERE, null, ex);
- } catch (BadLocationException ex) {
- Logger.getLogger(EditorDockable.class.getName()).log(Level.SEVERE, null, ex);
- }
- }
-
- private void comment(MITextEditorPane textArea) throws InterruptedException, BadLocationException {
- int sLine = textArea.getLineOfOffset(textArea.getSelectionStart());
- int sIdx = textArea.getLineStartOffset(sLine);
- int eLine = textArea.getLineOfOffset(textArea.getSelectionEnd());
- int eIdx = textArea.getLineEndOffset(eLine);
- textArea.setSelectionStart(sIdx);
- textArea.setSelectionEnd(eIdx);
- String text = textArea.getSelectedText();
-
- String[] lines = text.split("\n");
- StringBuilder sb = new StringBuilder();
- for (String line : lines) {
- String nLine = line.trim();
- if (nLine.startsWith("#")) {
- sb.append(line.replaceFirst("#", ""));
- } else {
- sb.append("#" + line);
- }
-
- sb.append("\n");
- }
- text = sb.toString();
- textArea.replaceSelection(text);
- }
-
- /**
- * Delete first 4 spaces to the seleted lines
- */
- public void delTab() {
- try {
- delTab((MITextEditorPane)this.getActiveTextArea());
- } catch (InterruptedException ex) {
- Logger.getLogger(EditorDockable.class.getName()).log(Level.SEVERE, null, ex);
- } catch (BadLocationException ex) {
- Logger.getLogger(EditorDockable.class.getName()).log(Level.SEVERE, null, ex);
- }
- }
-
- private void delTab(MITextEditorPane textArea) throws InterruptedException, BadLocationException {
- int sLine = textArea.getLineOfOffset(textArea.getSelectionStart());
- int sIdx = textArea.getLineStartOffset(sLine);
- int eLine = textArea.getLineOfOffset(textArea.getSelectionEnd());
- int eIdx = textArea.getLineEndOffset(eLine);
- textArea.setSelectionStart(sIdx);
- textArea.setSelectionEnd(eIdx);
- String text = textArea.getSelectedText();
-
- String[] lines = text.split("\n");
- StringBuilder sb = new StringBuilder();
- for (String line : lines) {
- if (line.startsWith(" "))
- sb.append(line.substring(4));
- else if (line.startsWith(" "))
- sb.append(line.substring(3));
- else if (line.startsWith(" "))
- sb.append(line.substring(2));
- else if (line.startsWith(" "))
- sb.append(line.substring(1));
- else
- sb.append(line);
-
- sb.append("\n");
- }
- text = sb.toString();
- textArea.replaceSelection(text);
- }
-
- /**
- * Insert first 4 spaces to the seleted lines
- */
- public void insertTab() {
- try {
- insertTab((MITextEditorPane)this.getActiveTextArea());
- } catch (InterruptedException ex) {
- Logger.getLogger(EditorDockable.class.getName()).log(Level.SEVERE, null, ex);
- } catch (AWTException ex) {
- Logger.getLogger(EditorDockable.class.getName()).log(Level.SEVERE, null, ex);
- }
- }
-
- private void insertTab(MITextEditorPane textArea) throws InterruptedException, AWTException {
- Robot robot = new Robot();
- robot.keyPress(KeyEvent.VK_TAB);
- }
-
- /**
- * Run Jython script
- *
- * @param jTextArea_Output
- */
- public void runPythonScript(final JTextArea jTextArea_Output) {
-
- SwingWorker worker = new SwingWorker() {
- PrintStream oout = System.out;
- PrintStream oerr = System.err;
-
- @Override
- protected String doInBackground() throws Exception {
- JTextAreaWriter writer = new JTextAreaWriter(jTextArea_Output);
- JTextAreaPrintStream printStream = new JTextAreaPrintStream(System.out, jTextArea_Output);
- jTextArea_Output.setText("");
-
- // Create an instance of the PythonInterpreter
- //Py.getSystemState().setdefaultencoding("utf-8");
- //UPythonInterpreter interp = new UPythonInterpreter();
- PythonInterpreter interp = new PythonInterpreter();
- interp.setOut(writer);
- interp.setErr(writer);
- System.setOut(printStream);
- System.setErr(printStream);
- //System.out.println("Out test!");
- //System.err.println("Error test!");
-
-// boolean isDebug = java.lang.management.ManagementFactory.getRuntimeMXBean().
-// getInputArguments().toString().contains("jdwp");
- //String pluginPath = startupPath + File.separator + "plugins";
- //List jarfns = GlobalUtil.getFiles(pluginPath, ".jar");
- //String path = startupPath + File.separator + "pylib";
-// if (isDebug) {
-// path = "D:/MyProgram/Distribution/Java/MeteoInfo/MeteoInfo/pylib";
-// }
- try {
- interp.exec("import sys");
- interp.set("milapp", EditorDockable.this.parent);
- //interp.exec("sys.path.append('" + path + "')");
- //interp.exec("import mipylib");
- //interp.exec("from mipylib.miscript import *");
- //interp.exec("from meteoinfo.numeric.JNumeric import *");
- //interp.exec("mis = MeteoInfoScript()");
- //interp.set("miapp", _parent);
- //for (String jarfn : jarfns) {
- // interp.exec("sys.path.append('" + jarfn + "')");
- //}
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- TextEditorPane textArea = getActiveTextArea();
- //textArea.setEncoding(fn);
- String code = textArea.getText();
-// if (code.contains("coding=utf-8")){
-// code = code.replace("coding=utf-8", "coding = utf-8");
-// }
- String encoding = EncodingUtil.findEncoding(code);
- if (encoding != null) {
- try {
- interp.execfile(new ByteArrayInputStream(code.getBytes(encoding)));
- } catch (Exception e) {
- e.printStackTrace();
- }
- } else {
- try {
- interp.execfile(new ByteArrayInputStream(code.getBytes()));
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-// try {
-// //interp.exec(code);
-// interp.execfile(new ByteArrayInputStream(code.getBytes()));
-// } catch (Exception e) {
-// e.printStackTrace();
-// }
-
- return "";
- }
-
- @Override
- protected void done() {
- System.setOut(oout);
- System.setErr(oerr);
- }
- };
- worker.execute();
- }
-}
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.meteoinfo.laboratory.gui;
+
+import bibliothek.gui.dock.common.DefaultSingleCDockable;
+import bibliothek.gui.dock.common.action.CAction;
+import java.awt.AWTException;
+import java.awt.Component;
+import java.awt.Font;
+import java.awt.Robot;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyEvent;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.JButton;
+import javax.swing.JFileChooser;
+import javax.swing.JMenuItem;
+import javax.swing.JOptionPane;
+import javax.swing.JPopupMenu;
+import javax.swing.JPopupMenu.Separator;
+import javax.swing.JTabbedPane;
+import javax.swing.JTextArea;
+import javax.swing.SwingWorker;
+import javax.swing.event.ChangeEvent;
+import javax.swing.text.BadLocationException;
+
+import com.formdev.flatlaf.extras.FlatSVGIcon;
+import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
+import org.fife.ui.rsyntaxtextarea.TextEditorPane;
+import org.fife.ui.rsyntaxtextarea.Theme;
+import org.meteoinfo.common.GenericFileFilter;
+import org.meteoinfo.console.editor.JTextAreaPrintStream;
+import org.meteoinfo.console.editor.JTextAreaWriter;
+import org.meteoinfo.console.editor.MITextEditorPane;
+import org.meteoinfo.console.editor.TextEditor;
+import org.meteoinfo.console.jython.JIntrospect;
+import org.meteoinfo.ui.ButtonTabComponent;
+import org.python.util.PythonInterpreter;
+
+/**
+ *
+ * @author yaqiang
+ */
+public class EditorDockable extends DefaultSingleCDockable {
+
+ private final FrmMain parent;
+ //private String startupPath;
+ private final JTabbedPane tabbedPanel;
+ private Font textFont;
+ private PythonInterpreter interp;
+ private Theme theme;
+
+ public EditorDockable(FrmMain parent, String id, String title, CAction... actions) {
+ super(id, title, actions);
+
+ this.parent = parent;
+ this.setTitleIcon(new FlatSVGIcon("org/meteoinfo/laboratory/icons/editor.svg"));
+ String lfName = this.parent.getOptions().getLookFeel();
+ String themeName = "default";
+ switch (lfName) {
+ case "FlatDarculaLaf":
+ case "FlatDarkLaf":
+ themeName = "dark";
+ break;
+ }
+ try {
+ theme = Theme.load(getClass().getResourceAsStream(
+ "/org/fife/ui/rsyntaxtextarea/themes/" + themeName + ".xml"));
+ } catch (IOException ioe) { // Never happens
+ ioe.printStackTrace();
+ }
+ tabbedPanel = new JTabbedPane();
+ tabbedPanel.addChangeListener((ChangeEvent e) -> {
+ JTabbedPane sourceTabbedPane = (JTabbedPane) e.getSource();
+ TextEditor te = (TextEditor) sourceTabbedPane.getSelectedComponent();
+ if (te != null) {
+ EditorDockable.this.setTitleText("Editor - " + te.getFileName());
+ }
+ });
+ this.getContentPane().add(tabbedPanel);
+ //this.setCloseable(false);
+ }
+
+// /**
+// * Set startup path
+// *
+// * @param path Startup path
+// */
+// public void setStartupPath(String path) {
+// this.startupPath = path;
+// }
+ /**
+ * Get tabbed pane
+ *
+ * @return Tabbed pane
+ */
+ public JTabbedPane getTabbedPane() {
+ return this.tabbedPanel;
+ }
+
+ /**
+ * Get font
+ *
+ * @return Font
+ */
+ public Font getTextFont() {
+ return this.textFont;
+ }
+
+ /**
+ * Set font
+ *
+ * @param font Font
+ */
+ public void setTextFont(Font font) {
+ this.textFont = font;
+ for (Component tab : this.tabbedPanel.getComponents()) {
+ if (tab instanceof TextEditor) {
+ ((TextEditor) tab).setTextFont(this.textFont);
+ }
+ }
+ }
+
+ /**
+ * Set python interpreter
+ *
+ * @param value Python interpreter
+ */
+ public void setInterp(PythonInterpreter value) {
+ this.interp = value;
+ }
+
+ /**
+ * Add a new text editor
+ *
+ * @param title Title
+ * @return Text editor
+ */
+ public final TextEditor addNewTextEditor(String title) {
+ final TextEditor tab = new TextEditor(tabbedPanel, title);
+ tabbedPanel.add(tab, title);
+ tabbedPanel.setSelectedComponent(tab);
+ final MITextEditorPane textArea = (MITextEditorPane) tab.getTextArea();
+ textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_PYTHON);
+ textArea.discardAllEdits();
+ this.theme.apply(textArea);
+ tab.setTextFont(this.textFont);
+
+ //Evaluate menu
+ JPopupMenu popup = textArea.getPopupMenu();
+ JMenuItem evaluate = new JMenuItem("Evaluate Selection");
+ evaluate.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ try {
+ runCodeLines(textArea);
+ } catch (InterruptedException ex) {
+ Logger.getLogger(EditorDockable.class.getName()).log(Level.SEVERE, null, ex);
+ } catch (BadLocationException ex) {
+ Logger.getLogger(EditorDockable.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+ });
+ popup.insert(evaluate, 0);
+ popup.insert(new Separator(), 1);
+
+ //Comment menu
+ JMenuItem comment = new JMenuItem("Comment or Uncomment");
+ comment.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ try {
+ comment(textArea);
+ } catch (InterruptedException ex) {
+ Logger.getLogger(EditorDockable.class.getName()).log(Level.SEVERE, null, ex);
+ } catch (BadLocationException ex) {
+ Logger.getLogger(EditorDockable.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+ });
+ popup.insert(comment, 2);
+
+ //Insert Tab menu
+ JMenuItem insertTab = new JMenuItem("Insert Tab");
+ insertTab.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ try {
+ insertTab(textArea);
+ } catch (InterruptedException ex) {
+ Logger.getLogger(EditorDockable.class.getName()).log(Level.SEVERE, null, ex);
+ } catch (AWTException ex) {
+ Logger.getLogger(EditorDockable.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+ });
+ popup.insert(insertTab, 3);
+
+ //Delete Tab menu
+ JMenuItem delTab = new JMenuItem("Delete Tab");
+ delTab.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ try {
+ delTab(textArea);
+ } catch (InterruptedException ex) {
+ Logger.getLogger(EditorDockable.class.getName()).log(Level.SEVERE, null, ex);
+ } catch (BadLocationException ex) {
+ Logger.getLogger(EditorDockable.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+ });
+ popup.insert(delTab, 4);
+
+ tab.getTextArea().setDirty(false);
+ tab.setTitle(title);
+
+ //Set name completion
+ JIntrospect nameComplete = new JIntrospect(this.interp);
+ textArea.setNameCompletion(nameComplete);
+
+// //Set language support - code auto completion
+// JythonLanguageSupport ac = new JythonLanguageSupport();
+// ac.install(textArea);
+// JythonCompletionProvider cp = ac.getProvider();
+// if (this.interp != null)
+// ((JythonSourceCompletionProvider)cp.getDefaultCompletionProvider()).setInterp(interp);
+ ButtonTabComponent btc = new ButtonTabComponent(tabbedPanel);
+ JButton button = btc.getTabButton();
+ button.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ closeFile(tab);
+ }
+ });
+ tabbedPanel.setTabComponentAt(tabbedPanel.indexOfComponent(tab), btc);
+
+ return tab;
+ }
+
+ /**
+ * Get active text editor
+ *
+ * @return Active text editor
+ */
+ public TextEditor getActiveTextEditor() {
+ if (this.tabbedPanel.getTabCount() == 0) {
+ return null;
+ } else {
+ return (TextEditor) this.tabbedPanel.getSelectedComponent();
+ }
+ }
+
+ /**
+ * Get all text editors
+ *
+ * @return All text editors
+ */
+ public List getAllTextEditor() {
+ List tes = new ArrayList<>();
+ Component comp;
+ for (int i = 0; i < this.tabbedPanel.getComponentCount(); i++) {
+ comp = this.tabbedPanel.getComponent(i);
+ if (comp instanceof TextEditor)
+ tes.add((TextEditor) comp);
+ }
+
+ return tes;
+ }
+
+ /**
+ * Set active text editor
+ *
+ * @param te Text editor
+ */
+ public void setActiveTextEditor(TextEditor te) {
+ this.tabbedPanel.setSelectedComponent(te);
+ this.setTitleText("Editor - " + te.getFileName());
+ }
+
+ private TextEditorPane getActiveTextArea() {
+ TextEditor textEditor = getActiveTextEditor();
+ if (textEditor != null) {
+ return textEditor.getTextArea();
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Close file
+ */
+ public void closeFile() {
+ closeFile(this.getActiveTextEditor());
+ }
+
+ private void closeFile(TextEditor textEditor) {
+ //TextEditor textEditor = getActiveTextEditor();
+ if (textEditor != null) {
+ boolean ifClose = true;
+ if (textEditor.getTextArea().isDirty()) {
+ String fName = textEditor.getFileName();
+ if (fName.isEmpty()) {
+ fName = "New file";
+ }
+ int result = JOptionPane.showConfirmDialog(null, MessageFormat.format("Save changes to \"{0}\"", fName), "Save?", JOptionPane.YES_NO_CANCEL_OPTION);
+ if (result == JOptionPane.YES_OPTION) {
+ if (!doSave(textEditor)) {
+ ifClose = false;
+ }
+ } else if (result == JOptionPane.CANCEL_OPTION) {
+ ifClose = false;
+ }
+ }
+
+ if (ifClose) {
+ removeTextEditor(textEditor);
+ }
+ }
+ }
+
+ /**
+ * Close all files
+ */
+ public void closeAllFiles() {
+ while (this.tabbedPanel.getTabCount() > 0) {
+ this.closeFile();
+ }
+// for (int i = 0; i < this.tabbedPanel.getTabCount(); i++) {
+// this.closeFile((TextEditor) this.tabbedPanel.getComponentAt(0));
+// }
+ }
+
+ /**
+ * Save file
+ *
+ * @param editor The text editor
+ * @return Boolean
+ */
+ public boolean doSave(TextEditor editor) {
+ if (editor.getFileName().isEmpty()) {
+ return doSaveAs_Jython(editor);
+ } else {
+ editor.saveFile(editor.getFile());
+ return true;
+ }
+ }
+
+ /**
+ * Save as
+ *
+ * @param editor The text editor
+ * @return Boolean
+ */
+ public boolean doSaveAs_Jython(TextEditor editor) {
+ JFileChooser aDlg = new JFileChooser();
+ String[] fileExts = new String[]{"py"};
+ GenericFileFilter mapFileFilter = new GenericFileFilter(fileExts, "Python File (*.py)");
+ aDlg.setFileFilter(mapFileFilter);
+ if (editor.getFile() != null) {
+ aDlg.setSelectedFile(editor.getFile());
+ } else {
+ File dir = new File(System.getProperty("user.dir"));
+ if (dir.isDirectory()) {
+ aDlg.setCurrentDirectory(dir);
+ }
+ }
+ if (aDlg.showSaveDialog(parent) == JFileChooser.APPROVE_OPTION) {
+ File file = aDlg.getSelectedFile();
+ System.setProperty("user.dir", file.getParent());
+ String extent = ((GenericFileFilter) aDlg.getFileFilter()).getFileExtent();
+ String fileName = file.getAbsolutePath();
+ if (!fileName.substring(fileName.length() - extent.length()).equals(extent)) {
+ fileName = fileName + "." + extent;
+ }
+ file = new File(fileName);
+ if (file.exists()) {
+ int overwrite = JOptionPane.showConfirmDialog(null, "File exists! Overwrite it?", "Confirm", JOptionPane.YES_NO_OPTION);
+ if (overwrite == JOptionPane.NO_OPTION) {
+ return false;
+ }
+ }
+ editor.saveFile(file);
+ this.setTitleText(editor.getFileName());
+ return true;
+ }
+ return false;
+ }
+
+ private void removeTextEditor(TextEditor editor) {
+ this.tabbedPanel.remove(editor);
+ }
+
+ /**
+ * Open Jython script file
+ */
+ public void doOpen_Jython() {
+ // TODO add your handling code here:
+ JFileChooser aDlg = new JFileChooser();
+ aDlg.setMultiSelectionEnabled(true);
+ aDlg.setAcceptAllFileFilterUsed(false);
+ //File dir = new File(this._parent.getCurrentDataFolder());
+ File dir = new File(System.getProperty("user.dir"));
+ if (dir.isDirectory()) {
+ aDlg.setCurrentDirectory(dir);
+ }
+ String[] fileExts = new String[]{"py"};
+ GenericFileFilter mapFileFilter = new GenericFileFilter(fileExts, "Jython File (*.py)");
+ aDlg.setFileFilter(mapFileFilter);
+ if (JFileChooser.APPROVE_OPTION == aDlg.showOpenDialog(parent)) {
+ File[] files = aDlg.getSelectedFiles();
+ //this._parent.setCurrentDataFolder(files[0].getParent());
+ System.setProperty("user.dir", files[0].getParent());
+ this.openFiles(files);
+ }
+ }
+
+ /**
+ * Open files
+ *
+ * @param fileNames File name list
+ */
+ public void openFiles(List fileNames) {
+ List files = new ArrayList<>();
+ for (String fn : fileNames) {
+ File file = new File(fn);
+ if (file.exists()) {
+ files.add(file);
+ }
+ }
+
+ if (files.size() > 0) {
+ File[] fs = new File[files.size()];
+ for (int i = 0; i < files.size(); i++) {
+ fs[i] = files.get(i);
+ }
+ this.openFiles(fs);
+ }
+ }
+
+ /**
+ * Open script files
+ *
+ * @param files The files
+ */
+ public void openFiles(File[] files) {
+ // Close default untitled document if it is still empty
+ if (this.tabbedPanel.getTabCount() == 1) {
+ TextEditor textEditor = getActiveTextEditor();
+ if (textEditor.getTextArea().getDocument().getLength() == 0 && textEditor.getFileName().isEmpty()) {
+ this.removeTextEditor(textEditor);
+ }
+ }
+
+ // Open file(s)
+ for (File file : files) {
+ boolean isExist = false;
+ for (int i = 0; i < this.tabbedPanel.getTabCount(); i++) {
+ TextEditor te = (TextEditor) this.tabbedPanel.getComponentAt(i);
+ if (file.getAbsolutePath().equals(te.getFileName())) {
+ isExist = true;
+ this.setActiveTextEditor(te);
+ break;
+ }
+ }
+ if (isExist) {
+ continue;
+ }
+ TextEditor editor = addNewTextEditor(file.getName());
+ editor.openFile(file);
+ this.setTitleText(editor.getFileName());
+ }
+ }
+
+ /**
+ * Open script file
+ *
+ * @param file The file
+ */
+ public void openFile(File file) {
+ // Close default untitled document if it is still empty
+ if (this.tabbedPanel.getTabCount() == 1) {
+ TextEditor textEditor = getActiveTextEditor();
+ if (textEditor.getTextArea().getDocument().getLength() == 0 && textEditor.getFileName().isEmpty()) {
+ this.removeTextEditor(textEditor);
+ }
+ }
+
+ // Open file
+ boolean isExist = false;
+ for (int i = 0; i < this.tabbedPanel.getTabCount(); i++) {
+ TextEditor te = (TextEditor) this.tabbedPanel.getComponentAt(i);
+ if (file.getAbsolutePath().equals(te.getFileName())) {
+ isExist = true;
+ this.setActiveTextEditor(te);
+ break;
+ }
+ }
+ if (!isExist) {
+ TextEditor editor = addNewTextEditor(file.getName());
+ editor.openFile(file);
+ this.parent.getOptions().addRecentFile(file.getAbsolutePath());
+ this.setTitleText(editor.getFileName());
+ }
+ }
+
+ /**
+ * Get opened file names
+ *
+ * @return Opened file names
+ */
+ public List getOpenedFiles() {
+ List fns = new ArrayList<>();
+ for (int i = 0; i < this.tabbedPanel.getTabCount(); i++) {
+ TextEditor te = (TextEditor) this.tabbedPanel.getComponentAt(i);
+ fns.add(te.getFileName());
+ }
+
+ return fns;
+ }
+
+ private void runCodeLines(MITextEditorPane textArea) throws InterruptedException, BadLocationException {
+ int sLine = textArea.getLineOfOffset(textArea.getSelectionStart());
+ int sIdx = textArea.getLineStartOffset(sLine);
+ int eLine = textArea.getLineOfOffset(textArea.getSelectionEnd());
+ int eIdx = textArea.getLineEndOffset(eLine);
+ textArea.setSelectionStart(sIdx);
+ textArea.setSelectionEnd(eIdx);
+ String code = textArea.getSelectedText();
+
+ this.parent.getConsoleDockable().run(code);
+ }
+
+ /**
+ * Toggle comment to the selected lines
+ */
+ public void Comment() {
+ try {
+ comment((MITextEditorPane)this.getActiveTextArea());
+ } catch (InterruptedException ex) {
+ Logger.getLogger(EditorDockable.class.getName()).log(Level.SEVERE, null, ex);
+ } catch (BadLocationException ex) {
+ Logger.getLogger(EditorDockable.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+
+ private void comment(MITextEditorPane textArea) throws InterruptedException, BadLocationException {
+ int sLine = textArea.getLineOfOffset(textArea.getSelectionStart());
+ int sIdx = textArea.getLineStartOffset(sLine);
+ int eLine = textArea.getLineOfOffset(textArea.getSelectionEnd());
+ int eIdx = textArea.getLineEndOffset(eLine);
+ textArea.setSelectionStart(sIdx);
+ textArea.setSelectionEnd(eIdx);
+ String text = textArea.getSelectedText();
+
+ String[] lines = text.split("\n");
+ StringBuilder sb = new StringBuilder();
+ for (String line : lines) {
+ String nLine = line.trim();
+ if (nLine.startsWith("#")) {
+ sb.append(line.replaceFirst("#", ""));
+ } else {
+ sb.append("#" + line);
+ }
+
+ sb.append("\n");
+ }
+ text = sb.toString();
+ textArea.replaceSelection(text);
+ }
+
+ /**
+ * Delete first 4 spaces to the seleted lines
+ */
+ public void delTab() {
+ try {
+ delTab((MITextEditorPane)this.getActiveTextArea());
+ } catch (InterruptedException ex) {
+ Logger.getLogger(EditorDockable.class.getName()).log(Level.SEVERE, null, ex);
+ } catch (BadLocationException ex) {
+ Logger.getLogger(EditorDockable.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+
+ private void delTab(MITextEditorPane textArea) throws InterruptedException, BadLocationException {
+ int sLine = textArea.getLineOfOffset(textArea.getSelectionStart());
+ int sIdx = textArea.getLineStartOffset(sLine);
+ int eLine = textArea.getLineOfOffset(textArea.getSelectionEnd());
+ int eIdx = textArea.getLineEndOffset(eLine);
+ textArea.setSelectionStart(sIdx);
+ textArea.setSelectionEnd(eIdx);
+ String text = textArea.getSelectedText();
+
+ String[] lines = text.split("\n");
+ StringBuilder sb = new StringBuilder();
+ for (String line : lines) {
+ if (line.startsWith(" "))
+ sb.append(line.substring(4));
+ else if (line.startsWith(" "))
+ sb.append(line.substring(3));
+ else if (line.startsWith(" "))
+ sb.append(line.substring(2));
+ else if (line.startsWith(" "))
+ sb.append(line.substring(1));
+ else
+ sb.append(line);
+
+ sb.append("\n");
+ }
+ text = sb.toString();
+ textArea.replaceSelection(text);
+ }
+
+ /**
+ * Insert first 4 spaces to the seleted lines
+ */
+ public void insertTab() {
+ try {
+ insertTab((MITextEditorPane)this.getActiveTextArea());
+ } catch (InterruptedException ex) {
+ Logger.getLogger(EditorDockable.class.getName()).log(Level.SEVERE, null, ex);
+ } catch (AWTException ex) {
+ Logger.getLogger(EditorDockable.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+
+ private void insertTab(MITextEditorPane textArea) throws InterruptedException, AWTException {
+ Robot robot = new Robot();
+ robot.keyPress(KeyEvent.VK_TAB);
+ }
+
+ /**
+ * Run Jython script
+ *
+ * @param jTextArea_Output
+ */
+ public void runPythonScript(final JTextArea jTextArea_Output) {
+
+ SwingWorker worker = new SwingWorker() {
+ PrintStream oout = System.out;
+ PrintStream oerr = System.err;
+
+ @Override
+ protected String doInBackground() throws Exception {
+ JTextAreaWriter writer = new JTextAreaWriter(jTextArea_Output);
+ JTextAreaPrintStream printStream = new JTextAreaPrintStream(System.out, jTextArea_Output);
+ jTextArea_Output.setText("");
+
+ // Create an instance of the PythonInterpreter
+ //Py.getSystemState().setdefaultencoding("utf-8");
+ //UPythonInterpreter interp = new UPythonInterpreter();
+ PythonInterpreter interp = new PythonInterpreter();
+ interp.setOut(writer);
+ interp.setErr(writer);
+ System.setOut(printStream);
+ System.setErr(printStream);
+ //System.out.println("Out test!");
+ //System.err.println("Error test!");
+
+// boolean isDebug = java.lang.management.ManagementFactory.getRuntimeMXBean().
+// getInputArguments().toString().contains("jdwp");
+ //String pluginPath = startupPath + File.separator + "plugins";
+ //List jarfns = GlobalUtil.getFiles(pluginPath, ".jar");
+ //String path = startupPath + File.separator + "pylib";
+// if (isDebug) {
+// path = "D:/MyProgram/Distribution/Java/MeteoInfo/MeteoInfo/pylib";
+// }
+ try {
+ interp.exec("import sys");
+ interp.set("milapp", EditorDockable.this.parent);
+ //interp.exec("sys.path.append('" + path + "')");
+ //interp.exec("import mipylib");
+ //interp.exec("from mipylib.miscript import *");
+ //interp.exec("from meteoinfo.numeric.JNumeric import *");
+ //interp.exec("mis = MeteoInfoScript()");
+ //interp.set("miapp", _parent);
+ //for (String jarfn : jarfns) {
+ // interp.exec("sys.path.append('" + jarfn + "')");
+ //}
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ TextEditorPane textArea = getActiveTextArea();
+ //textArea.setEncoding(fn);
+ String code = textArea.getText();
+// if (code.contains("coding=utf-8")){
+// code = code.replace("coding=utf-8", "coding = utf-8");
+// }
+ String encoding = EncodingUtil.findEncoding(code);
+ if (encoding != null) {
+ try {
+ interp.execfile(new ByteArrayInputStream(code.getBytes(encoding)));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ } else {
+ try {
+ interp.execfile(new ByteArrayInputStream(code.getBytes()));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+// try {
+// //interp.exec(code);
+// interp.execfile(new ByteArrayInputStream(code.getBytes()));
+// } catch (Exception e) {
+// e.printStackTrace();
+// }
+
+ return "";
+ }
+
+ @Override
+ protected void done() {
+ System.setOut(oout);
+ System.setErr(oerr);
+ }
+ };
+ worker.execute();
+ }
+}
diff --git a/MeteoInfoLab/src/main/java/org/meteoinfo/laboratory/gui/FileExplorer.java b/MeteoInfoLab/src/main/java/org/meteoinfo/laboratory/gui/FileExplorer.java
index fc655def..4e960018 100644
--- a/MeteoInfoLab/src/main/java/org/meteoinfo/laboratory/gui/FileExplorer.java
+++ b/MeteoInfoLab/src/main/java/org/meteoinfo/laboratory/gui/FileExplorer.java
@@ -22,7 +22,7 @@ import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
import com.formdev.flatlaf.extras.FlatSVGIcon;
-import org.meteoinfo.global.util.JDateUtil;
+import org.meteoinfo.common.util.JDateUtil;
import org.meteoinfo.laboratory.event.CurrentPathChangedEvent;
import org.meteoinfo.laboratory.event.ICurrentPathChangedListener;
import org.meteoinfo.table.IconRenderer;
diff --git a/MeteoInfoLab/src/main/java/org/meteoinfo/laboratory/gui/FrmAbout.java b/MeteoInfoLab/src/main/java/org/meteoinfo/laboratory/gui/FrmAbout.java
index 5e23ff1e..61e957dc 100644
--- a/MeteoInfoLab/src/main/java/org/meteoinfo/laboratory/gui/FrmAbout.java
+++ b/MeteoInfoLab/src/main/java/org/meteoinfo/laboratory/gui/FrmAbout.java
@@ -4,6 +4,8 @@
*/
package org.meteoinfo.laboratory.gui;
+import org.meteoinfo.common.util.GlobalUtil;
+
import java.awt.Cursor;
import java.awt.Desktop;
import java.io.IOException;
@@ -11,7 +13,6 @@ import java.net.URI;
import java.net.URISyntaxException;
import java.util.logging.Level;
import java.util.logging.Logger;
-import org.meteoinfo.global.util.GlobalUtil;
/**
*
diff --git a/MeteoInfoLab/src/main/java/org/meteoinfo/laboratory/gui/FrmAppsManager.java b/MeteoInfoLab/src/main/java/org/meteoinfo/laboratory/gui/FrmAppsManager.java
index e88117e1..60f31fc1 100644
--- a/MeteoInfoLab/src/main/java/org/meteoinfo/laboratory/gui/FrmAppsManager.java
+++ b/MeteoInfoLab/src/main/java/org/meteoinfo/laboratory/gui/FrmAppsManager.java
@@ -15,9 +15,10 @@ import java.util.logging.Logger;
import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.xml.parsers.ParserConfigurationException;
+
+import org.meteoinfo.common.util.GlobalUtil;
import org.meteoinfo.laboratory.application.Application;
import org.meteoinfo.laboratory.application.AppCollection;
-import org.meteoinfo.global.util.GlobalUtil;
import org.meteoinfo.plugin.IPlugin;
import org.meteoinfo.ui.CheckBoxListEntry;
import org.python.core.PyObject;
diff --git a/MeteoInfoLib/MeteoInfoLib.iml b/MeteoInfoLib/MeteoInfoLib.iml
index ff1ddf53..f8c4cec5 100644
--- a/MeteoInfoLib/MeteoInfoLib.iml
+++ b/MeteoInfoLib/MeteoInfoLib.iml
@@ -12,6 +12,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/MeteoInfoLib/pom.xml b/MeteoInfoLib/pom.xml
index fc6ad5d4..32963e46 100644
--- a/MeteoInfoLib/pom.xml
+++ b/MeteoInfoLib/pom.xml
@@ -47,6 +47,11 @@
+
+ ${project.groupId}
+ meteoinfo-math
+ ${project.version}
+ ${project.groupId}meteoinfo-ndarray
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/bak/ArrayMath.java b/MeteoInfoLib/src/main/java/org/meteoinfo/bak/ArrayMath.java
deleted file mode 100644
index ed9f3a17..00000000
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/bak/ArrayMath.java
+++ /dev/null
@@ -1,6718 +0,0 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.meteoinfo.bak;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import org.meteoinfo.math.meteo.MeteoMath;
-import org.meteoinfo.data.analysis.Statistics;
-import org.meteoinfo.geoprocess.GeoComputation;
-import org.meteoinfo.global.MIMath;
-import org.meteoinfo.global.PointD;
-import org.meteoinfo.layer.VectorLayer;
-import org.meteoinfo.ndarray.Complex;
-import org.meteoinfo.shape.PolygonShape;
-import org.python.core.PyComplex;
-import org.meteoinfo.ndarray.Array;
-import org.meteoinfo.ndarray.DataType;
-import org.meteoinfo.ndarray.Index;
-import org.meteoinfo.ndarray.IndexIterator;
-import org.meteoinfo.ndarray.InvalidRangeException;
-import org.meteoinfo.ndarray.MAMath;
-import org.meteoinfo.ndarray.Range;
-
-/**
- *
- * @author wyq
- */
-public class ArrayMath {
-
- public static double fill_value = -9999.0;
-
- //
- /**
- * Get data type
- *
- * @param o Object
- * @return Data type
- */
- public static DataType getDataType(Object o) {
- if (o instanceof Integer) {
- return DataType.INT;
- } else if (o instanceof Float) {
- return DataType.FLOAT;
- } else if (o instanceof Double) {
- return DataType.DOUBLE;
- } else if (o instanceof Boolean) {
- return DataType.BOOLEAN;
- } else {
- return DataType.OBJECT;
- }
- }
-
- private static DataType commonType(DataType aType, DataType bType) {
- if (aType == bType) {
- return aType;
- }
-
- if (aType == DataType.OBJECT || bType == DataType.OBJECT) {
- return DataType.OBJECT;
- }
-
- short anb = ArrayMath.typeToNBytes(aType);
- short bnb = ArrayMath.typeToNBytes(bType);
- if (anb == bnb) {
- switch (aType) {
- case INT:
- case LONG:
- return bType;
- case FLOAT:
- case DOUBLE:
- return aType;
- }
- }
-
- return (anb > bnb) ? aType : bType;
- }
-
- /**
- * Return the number of bytes per element for the given typecode.
- *
- * @param dataType Data type
- * @return Bytes number
- */
- public static short typeToNBytes(final DataType dataType) {
- switch (dataType) {
- case BYTE:
- return 1;
- case SHORT:
- return 2;
- case INT:
- case FLOAT:
- return 4;
- case LONG:
- case DOUBLE:
- return 8;
- default:
- return 0;
- }
- }
-
- /**
- * Check if an array is complex data type
- *
- * @param a The array
- * @return Complex data type or not
- */
- public static boolean isComplex(Array a) {
- Object a0 = a.getObject(0);
- return a0 instanceof Complex;
- }
-
- /**
- * Check if an array is numeric array
- *
- * @param a The array
- * @return Numeric or not
- */
- public static boolean isNumeric(Array a) {
- boolean r = a.getDataType().isNumeric();
- if (!r) {
- r = isComplex(a);
- }
- return r;
- }
-
- //
- //
- /**
- * Broadcast check for two arrays.
- *
- * @param a Array a
- * @param b Array b
- * @return Can broadcast (1), can not broadcast (-1), same dimensions (0)
- */
- public static int broadcastCheck(Array a, Array b) {
- int[] ashape = a.getShape();
- int[] bshape = b.getShape();
- int n = ashape.length;
- int m = bshape.length;
- if (n != m) {
- int len = Math.min(n, m);
- int na, nb;
- for (int i = 0; i < len; i++) {
- na = ashape[n - i - 1];
- nb = bshape[m - i - 1];
- if (na != nb && na != 1 && nb != 1) {
- return -1;
- }
- }
- return 1;
- } else {
- boolean sameDim = true;
- for (int i = 0; i < n; i++) {
- if (ashape[i] != bshape[i]) {
- sameDim = false;
- break;
- }
- }
- if (sameDim) {
- return 0;
- } else {
- for (int i = 0; i < n; i++) {
- if (ashape[i] != bshape[i] && ashape[i] != 1 && bshape[i] != 1) {
- return -1;
- }
- }
- return 1;
- }
- }
- }
-
- /**
- * Get broadcast shape from two arrays
- *
- * @param a Array a
- * @param b Array b
- * @return Broadcast shape
- */
- public static int[] broadcast(Array a, Array b) {
- int[] ashape = a.getShape();
- int[] bshape = b.getShape();
- int n = ashape.length;
- int m = bshape.length;
- if (n == m) {
- int[] shape = new int[n];
- for (int i = 0; i < n; i++) {
- shape[i] = Math.max(ashape[i], bshape[i]);
- }
- return shape;
- } else {
- int len = Math.max(n, m);
- int[] shape = new int[len];
- int na, nb;
- for (int i = 0; i < len; i++) {
- if (m < n) {
- na = ashape[n - i - 1];
- if (m - i - 1 >= 0) {
- nb = bshape[m - i - 1];
- shape[n - i - 1] = Math.max(na, nb);
- } else {
- shape[n - i - 1] = na;
- }
- } else {
- nb = bshape[m - i - 1];
- if (n - i - 1 >= 0) {
- na = ashape[n - i - 1];
- shape[m - i - 1] = Math.max(na, nb);
- } else {
- shape[m - i - 1] = nb;
- }
- }
- }
- return shape;
- }
- }
-
- private static void setIndex(int broadcast, Index aindex, Index bindex, int[] current, int n, int na, int nb) {
- if (broadcast == 0) {
- aindex.set(current);
- bindex.set(current);
- } else {
- int ia, ib;
- for (int j = 0; j < n; j++) {
- ia = na - j - 1;
- if (ia >= 0) {
- if (aindex.getShape(ia) == 1) {
- aindex.setDim(ia, 0);
- } else {
- aindex.setDim(ia, current[n - j - 1]);
- }
- }
- ib = nb - j - 1;
- if (ib >= 0) {
- if (bindex.getShape(ib) == 1) {
- bindex.setDim(ib, 0);
- } else {
- bindex.setDim(ib, current[n - j - 1]);
- }
- }
- }
- }
- }
-
- private static void setIndex(Index aindex, Index bindex, int[] current, int n, int na, int nb) {
- int ia, ib;
- for (int j = 0; j < n; j++) {
- ia = na - j - 1;
- if (ia >= 0) {
- if (aindex.getShape(ia) == 1) {
- aindex.setDim(ia, 0);
- } else {
- aindex.setDim(ia, current[n - j - 1]);
- }
- }
- ib = nb - j - 1;
- if (ib >= 0) {
- if (bindex.getShape(ib) == 1) {
- bindex.setDim(ib, 0);
- } else {
- bindex.setDim(ib, current[n - j - 1]);
- }
- }
- }
- }
-
- /**
- * Array add
- *
- * @param a Array a
- * @param b Array b
- * @return Added array
- */
- public static Array add(Array a, Array b) {
- DataType type = ArrayMath.commonType(a.getDataType(), b.getDataType());
- switch (type) {
- case SHORT:
- case INT:
- case BOOLEAN:
- return ArrayMath.addInt(a, b);
- case FLOAT:
- return ArrayMath.addFloat(a, b);
- case DOUBLE:
- return ArrayMath.addDouble(a, b);
- case OBJECT:
- if (isComplex(a) || isComplex(b)) {
- return ArrayMath.addComplex(a, b);
- }
- break;
- }
- return null;
- }
-
- /**
- * Array add
- *
- * @param a Array a
- * @param b Number b
- * @return Added array
- */
- public static Array add(Array a, Number b) {
- DataType bType = ArrayMath.getDataType(b);
- DataType type = ArrayMath.commonType(a.getDataType(), bType);
- switch (type) {
- case SHORT:
- case INT:
- case BOOLEAN:
- return ArrayMath.addInt(a, b.intValue());
- case FLOAT:
- return ArrayMath.addFloat(a, b.floatValue());
- case DOUBLE:
- return ArrayMath.addDouble(a, b.doubleValue());
- case OBJECT:
- if (isComplex(a)) {
- return ArrayMath.addComplex(a, b.doubleValue());
- }
- break;
- }
- return null;
- }
-
- /**
- * Array add
- *
- * @param a Array a
- * @param b Complex number b
- * @return Added array
- */
- public static Array add(Array a, Complex b) {
- return addComplex(a, b);
- }
-
- /**
- * Array add
- *
- * @param a Array a
- * @param b Complex number b
- * @return Added array
- */
- public static Array add(Array a, PyComplex b) {
- return addComplex(a, new Complex(b.real, b.imag));
- }
-
- private static Array addInt_bak(Array a, Array b) {
- int broadcast = broadcastCheck(a, b);
- if (broadcast != -1) {
- int[] shape;
- if (broadcast == 0) {
- shape = a.getShape();
- } else {
- shape = broadcast(a, b);
- }
- Array r = Array.factory(DataType.INT, shape);
- Index index = r.getIndex();
- Index aindex = a.getIndex();
- Index bindex = b.getIndex();
- int n = r.getRank();
- int na = a.getRank();
- int nb = b.getRank();
- int[] current;
- for (int i = 0; i < r.getSize(); i++) {
- current = index.getCurrentCounter();
- setIndex(broadcast, aindex, bindex, current, n, na, nb);
- if (a.getInt(aindex) == Integer.MIN_VALUE || b.getInt(bindex) == Integer.MIN_VALUE) {
- r.setInt(i, Integer.MIN_VALUE);
- } else {
- r.setInt(i, a.getInt(aindex) + b.getInt(bindex));
- }
- index.incr();
- }
- return r;
- } else {
- return null;
- }
- }
-
- private static Array addInt(Array a, Array b) {
- int broadcast = broadcastCheck(a, b);
- switch (broadcast) {
- case 0:
- Array r = Array.factory(DataType.INT, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- if (a.getInt(i) == Integer.MIN_VALUE || b.getInt(i) == Integer.MIN_VALUE) {
- r.setInt(i, Integer.MIN_VALUE);
- } else {
- r.setInt(i, a.getInt(i) + b.getInt(i));
- }
- }
- return r;
- case 1:
- int[] shape = broadcast(a, b);
- r = Array.factory(DataType.INT, shape);
- Index index = r.getIndex();
- Index aindex = a.getIndex();
- Index bindex = b.getIndex();
- int n = r.getRank();
- int na = a.getRank();
- int nb = b.getRank();
- int[] current;
- for (int i = 0; i < r.getSize(); i++) {
- current = index.getCurrentCounter();
- setIndex(aindex, bindex, current, n, na, nb);
- if (a.getInt(aindex) == Integer.MIN_VALUE || b.getInt(bindex) == Integer.MIN_VALUE) {
- r.setInt(i, Integer.MIN_VALUE);
- } else {
- r.setInt(i, a.getInt(aindex) + b.getInt(bindex));
- }
- index.incr();
- }
- return r;
- default:
- return null;
- }
- }
-
- private static Array addInt(Array a, int b) {
- Array r = Array.factory(DataType.INT, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- if (a.getInt(i) == Integer.MIN_VALUE) {
- r.setInt(i, Integer.MIN_VALUE);
- } else {
- r.setInt(i, a.getInt(i) + b);
- }
- }
-
- return r;
- }
-
- private static Array addFloat(Array a, Array b) {
- int broadcast = broadcastCheck(a, b);
- switch (broadcast) {
- case 0:
- Array r = Array.factory(DataType.FLOAT, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- if (Float.isNaN(a.getFloat(i)) || Float.isNaN(b.getFloat(i))) {
- r.setFloat(i, Float.NaN);
- } else {
- r.setFloat(i, a.getFloat(i) + b.getFloat(i));
- }
- }
- return r;
- case 1:
- int[] shape = broadcast(a, b);
- r = Array.factory(DataType.FLOAT, shape);
- Index index = r.getIndex();
- Index aindex = a.getIndex();
- Index bindex = b.getIndex();
- int n = r.getRank();
- int na = a.getRank();
- int nb = b.getRank();
- int[] current;
- for (int i = 0; i < r.getSize(); i++) {
- current = index.getCurrentCounter();
- setIndex(aindex, bindex, current, n, na, nb);
- if (Float.isNaN(a.getFloat(aindex)) || Float.isNaN(b.getFloat(bindex))) {
- r.setFloat(i, Float.NaN);
- } else {
- r.setFloat(i, a.getFloat(aindex) + b.getFloat(bindex));
- }
- index.incr();
- }
- return r;
- default:
- return null;
- }
- }
-
- private static Array addFloat(Array a, float b) {
- Array r = Array.factory(DataType.FLOAT, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- if (Float.isNaN(a.getFloat(i))) {
- r.setFloat(i, Float.NaN);
- } else {
- r.setFloat(i, a.getFloat(i) + b);
- }
- }
-
- return r;
- }
-
- private static Array addDouble(Array a, Array b) {
- int broadcast = broadcastCheck(a, b);
- switch (broadcast) {
- case 0:
- Array r = Array.factory(DataType.DOUBLE, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- if (Double.isNaN(a.getDouble(i)) || Double.isNaN(b.getDouble(i))) {
- r.setDouble(i, Double.NaN);
- } else {
- r.setDouble(i, a.getDouble(i) + b.getDouble(i));
- }
- }
- return r;
- case 1:
- int[] shape = broadcast(a, b);
- r = Array.factory(DataType.DOUBLE, shape);
- Index index = r.getIndex();
- Index aindex = a.getIndex();
- Index bindex = b.getIndex();
- int n = r.getRank();
- int na = a.getRank();
- int nb = b.getRank();
- int[] current;
- for (int i = 0; i < r.getSize(); i++) {
- current = index.getCurrentCounter();
- setIndex(aindex, bindex, current, n, na, nb);
- if (Double.isNaN(a.getDouble(aindex)) || Double.isNaN(b.getDouble(bindex))) {
- r.setDouble(i, Double.NaN);
- } else {
- r.setDouble(i, a.getDouble(aindex) + b.getDouble(bindex));
- }
- index.incr();
- }
- return r;
- default:
- return null;
- }
- }
-
- private static Array addDouble(Array a, double b) {
- Array r = Array.factory(DataType.DOUBLE, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- if (Double.isNaN(a.getDouble(i))) {
- r.setDouble(i, Double.NaN);
- } else {
- r.setDouble(i, a.getDouble(i) + b);
- }
- }
-
- return r;
- }
-
- private static Array addComplex(Array a, Array b) {
- int broadcast = broadcastCheck(a, b);
- switch (broadcast) {
- case 0:
- Array r = Array.factory(DataType.OBJECT, a.getShape());
- if (isComplex(a)) {
- if (isComplex(b)) {
- Complex v1, v2;
- for (int i = 0; i < a.getSize(); i++) {
- v1 = (Complex) a.getObject(i);
- v2 = (Complex) b.getObject(i);
- if (v1.isNaN() || v2.isNaN()) {
- r.setObject(i, v1);
- } else {
- r.setObject(i, v1.add(v2));
- }
- }
- } else {
- Complex v;
- for (int i = 0; i < a.getSize(); i++) {
- v = (Complex) a.getObject(i);
- if (v.isNaN() || Double.isNaN(b.getDouble(i))) {
- r.setObject(i, new Complex(Double.NaN));
- } else {
- r.setObject(i, v.add(b.getDouble(i)));
- }
- }
- }
- } else {
- Complex v;
- for (int i = 0; i < a.getSize(); i++) {
- v = (Complex) b.getObject(i);
- if (v.isNaN() || Double.isNaN(a.getDouble(i))) {
- r.setObject(i, new Complex(Double.NaN));
- } else {
- r.setObject(i, v.add(a.getDouble(i)));
- }
- }
- }
- return r;
- case 1:
- int[] shape = broadcast(a, b);
- r = Array.factory(DataType.OBJECT, shape);
- Index index = r.getIndex();
- Index aindex = a.getIndex();
- Index bindex = b.getIndex();
- int n = r.getRank();
- int na = a.getRank();
- int nb = b.getRank();
- int[] current;
- if (isComplex(a)) {
- if (isComplex(b)) {
- Complex v1, v2;
- for (int i = 0; i < r.getSize(); i++) {
- current = index.getCurrentCounter();
- setIndex(aindex, bindex, current, n, na, nb);
- v1 = (Complex) a.getObject(aindex);
- v2 = (Complex) b.getObject(bindex);
- if (v1.isNaN() || v2.isNaN()) {
- r.setObject(i, v1);
- } else {
- r.setObject(i, v1.add(v2));
- }
- index.incr();
- }
- } else {
- Complex v;
- for (int i = 0; i < r.getSize(); i++) {
- current = index.getCurrentCounter();
- setIndex(aindex, bindex, current, n, na, nb);
- v = (Complex) a.getObject(aindex);
- if (v.isNaN() || Double.isNaN(b.getDouble(bindex))) {
- r.setObject(i, new Complex(Double.NaN));
- } else {
- r.setObject(i, v.add(b.getDouble(bindex)));
- }
- index.incr();
- }
- }
- } else {
- Complex v;
- for (int i = 0; i < a.getSize(); i++) {
- current = index.getCurrentCounter();
- setIndex(aindex, bindex, current, n, na, nb);
- v = (Complex) b.getObject(bindex);
- if (v.isNaN() || Double.isNaN(a.getDouble(aindex))) {
- r.setObject(i, new Complex(Double.NaN));
- } else {
- r.setObject(i, v.add(a.getDouble(aindex)));
- }
- }
- }
- return r;
- default:
- return null;
- }
- }
-
- private static Array addComplex(Array a, double b) {
- Array r = Array.factory(DataType.OBJECT, a.getShape());
- Complex v;
- for (int i = 0; i < a.getSize(); i++) {
- v = (Complex) a.getObject(i);
- if (v.isNaN()) {
- r.setObject(i, v);
- } else {
- r.setObject(i, v.add(b));
- }
- }
-
- return r;
- }
-
- private static Array addComplex(Array a, Complex b) {
- Array r = Array.factory(DataType.OBJECT, a.getShape());
- Complex v;
- for (int i = 0; i < a.getSize(); i++) {
- v = (Complex) a.getObject(i);
- if (v.isNaN()) {
- r.setObject(i, v);
- } else {
- r.setObject(i, v.add(b));
- }
- }
-
- return r;
- }
-
- /**
- * Array subtract
- *
- * @param a Array a
- * @param b Array b
- * @return Result array
- */
- public static Array sub(Array a, Array b) {
- DataType type = ArrayMath.commonType(a.getDataType(), b.getDataType());
- switch (type) {
- case SHORT:
- case INT:
- case BOOLEAN:
- return ArrayMath.subInt(a, b);
- case FLOAT:
- return ArrayMath.subFloat(a, b);
- case DOUBLE:
- return ArrayMath.subDouble(a, b);
- case OBJECT:
- if (isComplex(a) || isComplex(b)) {
- return ArrayMath.subComplex(a, b);
- }
- break;
- }
- return null;
- }
-
- /**
- * Array subtract
- *
- * @param a Array a
- * @param b Number b
- * @return Result array
- */
- public static Array sub(Array a, Number b) {
- DataType bType = ArrayMath.getDataType(b);
- DataType type = ArrayMath.commonType(a.getDataType(), bType);
- switch (type) {
- case SHORT:
- case INT:
- case BOOLEAN:
- return ArrayMath.subInt(a, b.intValue());
- case FLOAT:
- return ArrayMath.subFloat(a, b.floatValue());
- case DOUBLE:
- return ArrayMath.subDouble(a, b.doubleValue());
- case OBJECT:
- if (isComplex(a)) {
- return ArrayMath.subComplex(a, b.doubleValue());
- }
- break;
- }
- return null;
- }
-
- /**
- * Array subtract
- *
- * @param a Array a
- * @param b Complex number b
- * @return Result array
- */
- public static Array sub(Array a, Complex b) {
- return subComplex(a, b);
- }
-
- /**
- * Array subtract
- *
- * @param a Array a
- * @param b Complex number b
- * @return Result array
- */
- public static Array sub(Array a, PyComplex b) {
- return subComplex(a, new Complex(b.real, b.imag));
- }
-
- /**
- * Array subtract
- *
- * @param a Array a
- * @param b Number b
- * @return Result array
- */
- public static Array sub(Number b, Array a) {
- DataType bType = ArrayMath.getDataType(b);
- DataType type = ArrayMath.commonType(a.getDataType(), bType);
- switch (type) {
- case SHORT:
- case INT:
- case BOOLEAN:
- return ArrayMath.subInt(b.intValue(), a);
- case FLOAT:
- return ArrayMath.subFloat(b.floatValue(), a);
- case DOUBLE:
- return ArrayMath.subDouble(b.doubleValue(), a);
- case OBJECT:
- if (isComplex(a)) {
- return ArrayMath.subComplex(b.doubleValue(), a);
- }
- break;
- }
- return null;
- }
-
- /**
- * Array subtract
- *
- * @param a Array a
- * @param b Complex number b
- * @return Result array
- */
- public static Array sub(Complex b, Array a) {
- return subComplex(b, a);
- }
-
- /**
- * Array subtract
- *
- * @param a Array a
- * @param b Complex number b
- * @return Result array
- */
- public static Array sub(PyComplex b, Array a) {
- return subComplex(new Complex(b.real, b.imag), a);
- }
-
- private static Array subInt(Array a, Array b) {
- int broadcast = broadcastCheck(a, b);
- switch (broadcast) {
- case 0:
- Array r = Array.factory(DataType.INT, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setInt(i, a.getInt(i) - b.getInt(i));
- }
- return r;
- case 1:
- int[] shape = broadcast(a, b);
- r = Array.factory(DataType.INT, shape);
- Index index = r.getIndex();
- Index aindex = a.getIndex();
- Index bindex = b.getIndex();
- int n = r.getRank();
- int na = a.getRank();
- int nb = b.getRank();
- int[] current;
- for (int i = 0; i < r.getSize(); i++) {
- current = index.getCurrentCounter();
- setIndex(aindex, bindex, current, n, na, nb);
- r.setInt(i, a.getInt(aindex) - b.getInt(bindex));
- index.incr();
- }
- return r;
- default:
- return null;
- }
- }
-
- private static Array subInt(Array a, int b) {
- Array r = Array.factory(DataType.INT, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setInt(i, a.getInt(i) - b);
- }
-
- return r;
- }
-
- private static Array subInt(int b, Array a) {
- Array r = Array.factory(DataType.INT, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setInt(i, b - a.getInt(i));
- }
-
- return r;
- }
-
- private static Array subFloat(Array a, Array b) {
- int broadcast = broadcastCheck(a, b);
- switch (broadcast) {
- case 0:
- Array r = Array.factory(DataType.FLOAT, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- if (Float.isNaN(a.getFloat(i)) || Float.isNaN(b.getFloat(i))) {
- r.setFloat(i, Float.NaN);
- } else {
- r.setFloat(i, a.getFloat(i) - b.getFloat(i));
- }
- }
- return r;
- case 1:
- int[] shape = broadcast(a, b);
- r = Array.factory(DataType.FLOAT, shape);
- Index index = r.getIndex();
- Index aindex = a.getIndex();
- Index bindex = b.getIndex();
- int n = r.getRank();
- int na = a.getRank();
- int nb = b.getRank();
- int[] current;
- for (int i = 0; i < r.getSize(); i++) {
- current = index.getCurrentCounter();
- setIndex(aindex, bindex, current, n, na, nb);
- if (Float.isNaN(a.getFloat(aindex)) || Float.isNaN(b.getFloat(bindex))) {
- r.setFloat(i, Float.NaN);
- } else {
- r.setFloat(i, a.getFloat(aindex) - b.getFloat(bindex));
- }
- index.incr();
- }
- return r;
- default:
- return null;
- }
- }
-
- private static Array subFloat(Array a, float b) {
- Array r = Array.factory(DataType.FLOAT, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setFloat(i, a.getFloat(i) - b);
- }
-
- return r;
- }
-
- private static Array subFloat(float b, Array a) {
- Array r = Array.factory(DataType.FLOAT, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setFloat(i, b - a.getFloat(i));
- }
-
- return r;
- }
-
- private static Array subDouble(Array a, Array b) {
- int broadcast = broadcastCheck(a, b);
- switch (broadcast) {
- case 0:
- Array r = Array.factory(DataType.DOUBLE, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- if (Double.isNaN(a.getDouble(i)) || Double.isNaN(b.getDouble(i))) {
- r.setDouble(i, Double.NaN);
- } else {
- r.setDouble(i, a.getDouble(i) - b.getDouble(i));
- }
- }
- return r;
- case 1:
- int[] shape = broadcast(a, b);
- r = Array.factory(DataType.DOUBLE, shape);
- Index index = r.getIndex();
- Index aindex = a.getIndex();
- Index bindex = b.getIndex();
- int n = r.getRank();
- int na = a.getRank();
- int nb = b.getRank();
- int[] current;
- for (int i = 0; i < r.getSize(); i++) {
- current = index.getCurrentCounter();
- setIndex(aindex, bindex, current, n, na, nb);
- if (Double.isNaN(a.getDouble(aindex)) || Double.isNaN(b.getDouble(bindex))) {
- r.setDouble(i, Double.NaN);
- } else {
- r.setDouble(i, a.getDouble(aindex) - b.getDouble(bindex));
- }
- index.incr();
- }
- return r;
- default:
- return null;
- }
- }
-
- private static Array subDouble(Array a, double b) {
- Array r = Array.factory(DataType.DOUBLE, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setDouble(i, a.getDouble(i) - b);
- }
-
- return r;
- }
-
- private static Array subDouble(double b, Array a) {
- Array r = Array.factory(DataType.DOUBLE, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setDouble(i, b - a.getDouble(i));
- }
-
- return r;
- }
-
- private static Array subComplex(Array a, Array b) {
- int broadcast = broadcastCheck(a, b);
- switch (broadcast) {
- case 0:
- Array r = Array.factory(DataType.OBJECT, a.getShape());
- if (isComplex(a)) {
- if (isComplex(b)) {
- Complex v1, v2;
- for (int i = 0; i < a.getSize(); i++) {
- v1 = (Complex) a.getObject(i);
- v2 = (Complex) b.getObject(i);
- if (v1.isNaN() || v2.isNaN()) {
- r.setObject(i, v1);
- } else {
- r.setObject(i, v1.subtract(v2));
- }
- }
- } else {
- Complex v;
- for (int i = 0; i < a.getSize(); i++) {
- v = (Complex) a.getObject(i);
- if (v.isNaN() || Double.isNaN(b.getDouble(i))) {
- r.setObject(i, new Complex(Double.NaN));
- } else {
- r.setObject(i, v.subtract(b.getDouble(i)));
- }
- }
- }
- } else {
- Complex v;
- for (int i = 0; i < a.getSize(); i++) {
- v = (Complex) b.getObject(i);
- if (v.isNaN() || Double.isNaN(a.getDouble(i))) {
- r.setObject(i, new Complex(Double.NaN));
- } else {
- r.setObject(i, v.subtract(a.getDouble(i)));
- }
- }
- }
- return r;
- case 1:
- int[] shape = broadcast(a, b);
- r = Array.factory(DataType.OBJECT, shape);
- Index index = r.getIndex();
- Index aindex = a.getIndex();
- Index bindex = b.getIndex();
- int n = r.getRank();
- int na = a.getRank();
- int nb = b.getRank();
- int[] current;
- if (isComplex(a)) {
- if (isComplex(b)) {
- Complex v1, v2;
- for (int i = 0; i < r.getSize(); i++) {
- current = index.getCurrentCounter();
- setIndex(aindex, bindex, current, n, na, nb);
- v1 = (Complex) a.getObject(aindex);
- v2 = (Complex) b.getObject(bindex);
- if (v1.isNaN() || v2.isNaN()) {
- r.setObject(i, v1);
- } else {
- r.setObject(i, v1.subtract(v2));
- }
- index.incr();
- }
- } else {
- Complex v;
- for (int i = 0; i < r.getSize(); i++) {
- current = index.getCurrentCounter();
- setIndex(aindex, bindex, current, n, na, nb);
- v = (Complex) a.getObject(aindex);
- if (v.isNaN() || Double.isNaN(b.getDouble(bindex))) {
- r.setObject(i, new Complex(Double.NaN));
- } else {
- r.setObject(i, v.subtract(b.getDouble(bindex)));
- }
- index.incr();
- }
- }
- } else {
- Complex v;
- for (int i = 0; i < a.getSize(); i++) {
- current = index.getCurrentCounter();
- setIndex(aindex, bindex, current, n, na, nb);
- v = (Complex) b.getObject(bindex);
- if (v.isNaN() || Double.isNaN(a.getDouble(aindex))) {
- r.setObject(i, new Complex(Double.NaN));
- } else {
- r.setObject(i, v.subtract(a.getDouble(aindex)));
- }
- }
- }
- return r;
- default:
- return null;
- }
- }
-
- private static Array subComplex(Array a, double b) {
- Array r = Array.factory(DataType.OBJECT, a.getShape());
- Complex v;
- for (int i = 0; i < a.getSize(); i++) {
- v = (Complex) a.getObject(i);
- if (v.isNaN()) {
- r.setObject(i, v);
- } else {
- r.setObject(i, v.subtract(b));
- }
- }
-
- return r;
- }
-
- private static Array subComplex(Array a, Complex b) {
- Array r = Array.factory(DataType.OBJECT, a.getShape());
- Complex v;
- for (int i = 0; i < a.getSize(); i++) {
- v = (Complex) a.getObject(i);
- if (v.isNaN()) {
- r.setObject(i, v);
- } else {
- r.setObject(i, v.subtract(b));
- }
- }
-
- return r;
- }
-
- private static Array subComplex(double b, Array a) {
- Array r = Array.factory(DataType.OBJECT, a.getShape());
- Complex v;
- for (int i = 0; i < a.getSize(); i++) {
- v = (Complex) a.getObject(i);
- if (v.isNaN()) {
- r.setObject(i, v);
- } else {
- r.setObject(i, v.rSubtract(b));
- }
- }
-
- return r;
- }
-
- private static Array subComplex(Complex b, Array a) {
- Array r = Array.factory(DataType.OBJECT, a.getShape());
- Complex v;
- for (int i = 0; i < a.getSize(); i++) {
- v = (Complex) a.getObject(i);
- if (v.isNaN()) {
- r.setObject(i, v);
- } else {
- r.setObject(i, b.subtract(v));
- }
- }
-
- return r;
- }
-
- /**
- * Array mutiply
- *
- * @param a Array a
- * @param b Array b
- * @return Result array
- */
- public static Array mul(Array a, Array b) {
- DataType type = ArrayMath.commonType(a.getDataType(), b.getDataType());
- switch (type) {
- case SHORT:
- case INT:
- case BOOLEAN:
- return ArrayMath.mulInt(a, b);
- case FLOAT:
- return ArrayMath.mulFloat(a, b);
- case DOUBLE:
- return ArrayMath.mulDouble(a, b);
- case OBJECT:
- if (isComplex(a) || isComplex(b)) {
- return ArrayMath.mulComplex(a, b);
- }
- break;
- }
- return null;
- }
-
- /**
- * Array multiply
- *
- * @param a Array a
- * @param b Number b
- * @return Result array
- */
- public static Array mul(Array a, Number b) {
- DataType bType = ArrayMath.getDataType(b);
- DataType type = ArrayMath.commonType(a.getDataType(), bType);
- switch (type) {
- case SHORT:
- case INT:
- case BOOLEAN:
- return ArrayMath.mulInt(a, b.intValue());
- case FLOAT:
- return ArrayMath.mulFloat(a, b.floatValue());
- case DOUBLE:
- return ArrayMath.mulDouble(a, b.doubleValue());
- case OBJECT:
- if (isComplex(a)) {
- return ArrayMath.mulComplex(a, b.doubleValue());
- }
- break;
- }
- return null;
- }
-
- /**
- * Array multiply
- *
- * @param a Array a
- * @param b Complex number b
- * @return Result array
- */
- public static Array mul(Array a, Complex b) {
- return ArrayMath.mulComplex(a, b);
- }
-
- /**
- * Array multiply
- *
- * @param a Array a
- * @param b Complex number b
- * @return Result array
- */
- public static Array mul(Array a, PyComplex b) {
- return ArrayMath.mulComplex(a, new Complex(b.real, b.imag));
- }
-
- private static Array mulInt(Array a, Array b) {
- int broadcast = broadcastCheck(a, b);
- switch (broadcast) {
- case 0:
- Array r = Array.factory(DataType.INT, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- if (a.getInt(i) == Integer.MIN_VALUE || b.getInt(i) == Integer.MIN_VALUE) {
- r.setInt(i, Integer.MIN_VALUE);
- } else {
- r.setInt(i, a.getInt(i) * b.getInt(i));
- }
- }
- return r;
- case 1:
- int[] shape = broadcast(a, b);
- r = Array.factory(DataType.INT, shape);
- Index index = r.getIndex();
- Index aindex = a.getIndex();
- Index bindex = b.getIndex();
- int n = r.getRank();
- int na = a.getRank();
- int nb = b.getRank();
- int[] current;
- for (int i = 0; i < r.getSize(); i++) {
- current = index.getCurrentCounter();
- setIndex(aindex, bindex, current, n, na, nb);
- if (a.getInt(aindex) == Integer.MIN_VALUE || b.getInt(bindex) == Integer.MIN_VALUE) {
- r.setInt(i, Integer.MIN_VALUE);
- } else {
- r.setInt(i, a.getInt(aindex) * b.getInt(bindex));
- }
- index.incr();
- }
- return r;
- default:
- return null;
- }
- }
-
- private static Array mulInt(Array a, int b) {
- Array r = Array.factory(DataType.INT, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- if (a.getInt(i) == Integer.MIN_VALUE) {
- r.setInt(i, Integer.MIN_VALUE);
- } else {
- r.setInt(i, a.getInt(i) * b);
- }
- }
-
- return r;
- }
-
- private static Array mulFloat(Array a, Array b) {
- int broadcast = broadcastCheck(a, b);
- switch (broadcast) {
- case 0:
- Array r = Array.factory(DataType.FLOAT, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- if (Float.isNaN(a.getFloat(i)) || Float.isNaN(b.getFloat(i))) {
- r.setFloat(i, Float.NaN);
- } else {
- r.setFloat(i, a.getFloat(i) * b.getFloat(i));
- }
- }
- return r;
- case 1:
- int[] shape = broadcast(a, b);
- r = Array.factory(DataType.FLOAT, shape);
- Index index = r.getIndex();
- Index aindex = a.getIndex();
- Index bindex = b.getIndex();
- int n = r.getRank();
- int na = a.getRank();
- int nb = b.getRank();
- int[] current;
- for (int i = 0; i < r.getSize(); i++) {
- current = index.getCurrentCounter();
- setIndex(aindex, bindex, current, n, na, nb);
- if (Float.isNaN(a.getFloat(aindex)) || Float.isNaN(b.getFloat(bindex))) {
- r.setFloat(i, Float.NaN);
- } else {
- r.setFloat(i, a.getFloat(aindex) * b.getFloat(bindex));
- }
- index.incr();
- }
- return r;
- default:
- return null;
- }
- }
-
- private static Array mulFloat(Array a, float b) {
- Array r = Array.factory(DataType.FLOAT, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- if (Float.isNaN(a.getFloat(i))) {
- r.setFloat(i, Float.NaN);
- } else {
- r.setFloat(i, a.getFloat(i) * b);
- }
- }
-
- return r;
- }
-
- private static Array mulDouble(Array a, Array b) {
- int broadcast = broadcastCheck(a, b);
- switch (broadcast) {
- case 0:
- Array r = Array.factory(DataType.DOUBLE, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- if (Double.isNaN(a.getDouble(i)) || Double.isNaN(b.getDouble(i))) {
- r.setDouble(i, Double.NaN);
- } else {
- r.setDouble(i, a.getDouble(i) * b.getDouble(i));
- }
- }
- return r;
- case 1:
- int[] shape = broadcast(a, b);
- r = Array.factory(DataType.DOUBLE, shape);
- Index index = r.getIndex();
- Index aindex = a.getIndex();
- Index bindex = b.getIndex();
- int n = r.getRank();
- int na = a.getRank();
- int nb = b.getRank();
- int[] current;
- for (int i = 0; i < r.getSize(); i++) {
- current = index.getCurrentCounter();
- setIndex(aindex, bindex, current, n, na, nb);
- if (Double.isNaN(a.getDouble(aindex)) || Double.isNaN(b.getDouble(bindex))) {
- r.setDouble(i, Double.NaN);
- } else {
- r.setDouble(i, a.getDouble(aindex) * b.getDouble(bindex));
- }
- index.incr();
- }
- return r;
- default:
- return null;
- }
- }
-
- private static Array mulDouble(Array a, double b) {
- Array r = Array.factory(DataType.DOUBLE, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- if (Double.isNaN(a.getDouble(i))) {
- r.setDouble(i, Double.NaN);
- } else {
- r.setDouble(i, a.getDouble(i) * b);
- }
- }
-
- return r;
- }
-
- private static Array mulComplex(Array a, Array b) {
- int broadcast = broadcastCheck(a, b);
- switch (broadcast) {
- case 0:
- Array r = Array.factory(DataType.OBJECT, a.getShape());
- if (isComplex(a)) {
- if (isComplex(b)) {
- Complex v1, v2;
- for (int i = 0; i < a.getSize(); i++) {
- v1 = (Complex) a.getObject(i);
- v2 = (Complex) b.getObject(i);
- if (v1.isNaN() || v2.isNaN()) {
- r.setObject(i, v1);
- } else {
- r.setObject(i, v1.multiply(v2));
- }
- }
- } else {
- Complex v;
- for (int i = 0; i < a.getSize(); i++) {
- v = (Complex) a.getObject(i);
- if (v.isNaN() || Double.isNaN(b.getDouble(i))) {
- r.setObject(i, new Complex(Double.NaN));
- } else {
- r.setObject(i, v.multiply(b.getDouble(i)));
- }
- }
- }
- } else {
- Complex v;
- for (int i = 0; i < a.getSize(); i++) {
- v = (Complex) b.getObject(i);
- if (v.isNaN() || Double.isNaN(a.getDouble(i))) {
- r.setObject(i, new Complex(Double.NaN));
- } else {
- r.setObject(i, v.multiply(a.getDouble(i)));
- }
- }
- }
- return r;
- case 1:
- int[] shape = broadcast(a, b);
- r = Array.factory(DataType.OBJECT, shape);
- Index index = r.getIndex();
- Index aindex = a.getIndex();
- Index bindex = b.getIndex();
- int n = r.getRank();
- int na = a.getRank();
- int nb = b.getRank();
- int[] current;
- if (isComplex(a)) {
- if (isComplex(b)) {
- Complex v1, v2;
- for (int i = 0; i < r.getSize(); i++) {
- current = index.getCurrentCounter();
- setIndex(aindex, bindex, current, n, na, nb);
- v1 = (Complex) a.getObject(aindex);
- v2 = (Complex) b.getObject(bindex);
- if (v1.isNaN() || v2.isNaN()) {
- r.setObject(i, v1);
- } else {
- r.setObject(i, v1.multiply(v2));
- }
- index.incr();
- }
- } else {
- Complex v;
- for (int i = 0; i < r.getSize(); i++) {
- current = index.getCurrentCounter();
- setIndex(aindex, bindex, current, n, na, nb);
- v = (Complex) a.getObject(aindex);
- if (v.isNaN() || Double.isNaN(b.getDouble(bindex))) {
- r.setObject(i, new Complex(Double.NaN));
- } else {
- r.setObject(i, v.multiply(b.getDouble(bindex)));
- }
- index.incr();
- }
- }
- } else {
- Complex v;
- for (int i = 0; i < a.getSize(); i++) {
- current = index.getCurrentCounter();
- setIndex(aindex, bindex, current, n, na, nb);
- v = (Complex) b.getObject(bindex);
- if (v.isNaN() || Double.isNaN(a.getDouble(aindex))) {
- r.setObject(i, new Complex(Double.NaN));
- } else {
- r.setObject(i, v.multiply(a.getDouble(aindex)));
- }
- }
- }
- return r;
- default:
- return null;
- }
- }
-
- private static Array mulComplex(Array a, double b) {
- Array r = Array.factory(DataType.OBJECT, a.getShape());
- Complex v;
- for (int i = 0; i < a.getSize(); i++) {
- v = (Complex) a.getObject(i);
- if (v.isNaN()) {
- r.setObject(i, v);
- } else {
- r.setObject(i, v.multiply(b));
- }
- }
-
- return r;
- }
-
- private static Array mulComplex(Array a, Complex b) {
- Array r = Array.factory(DataType.OBJECT, a.getShape());
- Complex v;
- for (int i = 0; i < a.getSize(); i++) {
- v = (Complex) a.getObject(i);
- if (v.isNaN()) {
- r.setObject(i, v);
- } else {
- r.setObject(i, v.multiply(b));
- }
- }
-
- return r;
- }
-
- /**
- * Array divide
- *
- * @param a Array a
- * @param b Array b
- * @return Result array
- */
- public static Array div(Array a, Array b) {
- DataType type = ArrayMath.commonType(a.getDataType(), b.getDataType());
- switch (type) {
- case SHORT:
- case INT:
- case BOOLEAN:
- return ArrayMath.divInt(a, b);
- case FLOAT:
- return ArrayMath.divFloat(a, b);
- case DOUBLE:
- return ArrayMath.divDouble(a, b);
- case OBJECT:
- if (isComplex(a) || isComplex(b)) {
- return ArrayMath.divComplex(a, b);
- }
- break;
- }
- return null;
- }
-
- /**
- * Array divide
- *
- * @param a Array a
- * @param b Number b
- * @return Result array
- */
- public static Array div(Array a, Number b) {
- DataType bType = ArrayMath.getDataType(b);
- DataType type = ArrayMath.commonType(a.getDataType(), bType);
- switch (type) {
- case SHORT:
- case INT:
- case BOOLEAN:
- return ArrayMath.divInt(a, b.intValue());
- case FLOAT:
- return ArrayMath.divFloat(a, b.floatValue());
- case DOUBLE:
- return ArrayMath.divDouble(a, b.doubleValue());
- case OBJECT:
- if (isComplex(a)) {
- return ArrayMath.divComplex(a, b.doubleValue());
- }
- break;
- }
- return null;
- }
-
- /**
- * Array divide
- *
- * @param a Array a
- * @param b Complex number b
- * @return Result array
- */
- public static Array div(Array a, Complex b) {
- return divComplex(a, b);
- }
-
- /**
- * Array divide
- *
- * @param a Array a
- * @param b Complex number b
- * @return Result array
- */
- public static Array div(Array a, PyComplex b) {
- return divComplex(a, new Complex(b.real, b.imag));
- }
-
- /**
- * Array divide
- *
- * @param a Array a
- * @param b Number b
- * @return Result array
- */
- public static Array div(Number b, Array a) {
- DataType bType = ArrayMath.getDataType(b);
- DataType type = ArrayMath.commonType(a.getDataType(), bType);
- switch (type) {
- case SHORT:
- case INT:
- case BOOLEAN:
- return ArrayMath.divInt(b.intValue(), a);
- case FLOAT:
- return ArrayMath.divFloat(b.floatValue(), a);
- case DOUBLE:
- return ArrayMath.divDouble(b.doubleValue(), a);
- case OBJECT:
- if (isComplex(a)) {
- return ArrayMath.divComplex(b.doubleValue(), a);
- }
- break;
- }
- return null;
- }
-
- /**
- * Array divide
- *
- * @param a Array a
- * @param b Complex number b
- * @return Result array
- */
- public static Array div(Complex b, Array a) {
- return divComplex(b, a);
- }
-
- /**
- * Array divide
- *
- * @param a Array a
- * @param b Complex number b
- * @return Result array
- */
- public static Array div(PyComplex b, Array a) {
- return divComplex(new Complex(b.real, b.imag), a);
- }
-
- private static Array divInt(Array a, Array b) {
- int broadcast = broadcastCheck(a, b);
- switch (broadcast) {
- case 0:
- Array r = Array.factory(DataType.INT, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- if (a.getInt(i) == Integer.MIN_VALUE || b.getInt(i) == Integer.MIN_VALUE) {
- r.setInt(i, Integer.MIN_VALUE);
- } else {
- r.setInt(i, a.getInt(i) / b.getInt(i));
- }
- }
- return r;
- case 1:
- int[] shape = broadcast(a, b);
- r = Array.factory(DataType.INT, shape);
- Index index = r.getIndex();
- Index aindex = a.getIndex();
- Index bindex = b.getIndex();
- int n = r.getRank();
- int na = a.getRank();
- int nb = b.getRank();
- int[] current;
- for (int i = 0; i < r.getSize(); i++) {
- current = index.getCurrentCounter();
- setIndex(aindex, bindex, current, n, na, nb);
- if (a.getInt(aindex) == Integer.MIN_VALUE || b.getInt(bindex) == Integer.MIN_VALUE) {
- r.setInt(i, Integer.MIN_VALUE);
- } else {
- r.setInt(i, a.getInt(aindex) / b.getInt(bindex));
- }
- index.incr();
- }
- return r;
- default:
- return null;
- }
- }
-
- private static Array divInt(Array a, int b) {
- Array r = Array.factory(DataType.INT, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setInt(i, a.getInt(i) / b);
- }
-
- return r;
- }
-
- private static Array divInt(int b, Array a) {
- Array r = Array.factory(DataType.INT, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setInt(i, b / a.getInt(i));
- }
-
- return r;
- }
-
- private static Array divFloat(Array a, Array b) {
- int broadcast = broadcastCheck(a, b);
- switch (broadcast) {
- case 0:
- Array r = Array.factory(DataType.FLOAT, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- if (Float.isNaN(a.getFloat(i)) || Float.isNaN(b.getFloat(i))) {
- r.setFloat(i, Float.NaN);
- } else {
- r.setFloat(i, a.getFloat(i) / b.getFloat(i));
- }
- }
- return r;
- case 1:
- int[] shape = broadcast(a, b);
- r = Array.factory(DataType.FLOAT, shape);
- Index index = r.getIndex();
- Index aindex = a.getIndex();
- Index bindex = b.getIndex();
- int n = r.getRank();
- int na = a.getRank();
- int nb = b.getRank();
- int[] current;
- for (int i = 0; i < r.getSize(); i++) {
- current = index.getCurrentCounter();
- setIndex(aindex, bindex, current, n, na, nb);
- if (Float.isNaN(a.getFloat(aindex)) || Float.isNaN(b.getFloat(bindex))) {
- r.setFloat(i, Float.NaN);
- } else {
- r.setFloat(i, a.getFloat(aindex) / b.getFloat(bindex));
- }
- index.incr();
- }
- return r;
- default:
- return null;
- }
- }
-
- private static Array divFloat(Array a, float b) {
- Array r = Array.factory(DataType.FLOAT, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setFloat(i, a.getFloat(i) / b);
- }
-
- return r;
- }
-
- private static Array divFloat(float b, Array a) {
- Array r = Array.factory(DataType.FLOAT, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setFloat(i, b / a.getFloat(i));
- }
-
- return r;
- }
-
- private static Array divDouble(Array a, Array b) {
- int broadcast = broadcastCheck(a, b);
- switch (broadcast) {
- case 0:
- Array r = Array.factory(DataType.DOUBLE, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- if (Double.isNaN(a.getDouble(i)) || Double.isNaN(b.getDouble(i))) {
- r.setDouble(i, Double.NaN);
- } else {
- r.setDouble(i, a.getDouble(i) / b.getDouble(i));
- }
- }
- return r;
- case 1:
- int[] shape = broadcast(a, b);
- r = Array.factory(DataType.DOUBLE, shape);
- Index index = r.getIndex();
- Index aindex = a.getIndex();
- Index bindex = b.getIndex();
- int n = r.getRank();
- int na = a.getRank();
- int nb = b.getRank();
- int[] current;
- for (int i = 0; i < r.getSize(); i++) {
- current = index.getCurrentCounter();
- setIndex(aindex, bindex, current, n, na, nb);
- if (Double.isNaN(a.getDouble(aindex)) || Double.isNaN(b.getDouble(bindex))) {
- r.setDouble(i, Double.NaN);
- } else {
- r.setDouble(i, a.getDouble(aindex) / b.getDouble(bindex));
- }
- index.incr();
- }
- return r;
- default:
- return null;
- }
- }
-
- private static Array divDouble(Array a, double b) {
- Array r = Array.factory(DataType.DOUBLE, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setDouble(i, a.getDouble(i) / b);
- }
-
- return r;
- }
-
- private static Array divDouble(double b, Array a) {
- Array r = Array.factory(DataType.DOUBLE, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setDouble(i, b / a.getDouble(i));
- }
-
- return r;
- }
-
- private static Array divComplex(Array a, Array b) {
- int broadcast = broadcastCheck(a, b);
- switch (broadcast) {
- case 0:
- Array r = Array.factory(DataType.OBJECT, a.getShape());
- if (isComplex(a)) {
- if (isComplex(b)) {
- Complex v1, v2;
- for (int i = 0; i < a.getSize(); i++) {
- v1 = (Complex) a.getObject(i);
- v2 = (Complex) b.getObject(i);
- if (v1.isNaN() || v2.isNaN()) {
- r.setObject(i, v1);
- } else {
- r.setObject(i, v1.divide(v2));
- }
- }
- } else {
- Complex v;
- for (int i = 0; i < a.getSize(); i++) {
- v = (Complex) a.getObject(i);
- if (v.isNaN() || Double.isNaN(b.getDouble(i))) {
- r.setObject(i, new Complex(Double.NaN));
- } else {
- r.setObject(i, v.divide(b.getDouble(i)));
- }
- }
- }
- } else {
- Complex v;
- for (int i = 0; i < a.getSize(); i++) {
- v = (Complex) b.getObject(i);
- if (v.isNaN() || Double.isNaN(a.getDouble(i))) {
- r.setObject(i, new Complex(Double.NaN));
- } else {
- r.setObject(i, v.divide(a.getDouble(i)));
- }
- }
- }
- return r;
- case 1:
- int[] shape = broadcast(a, b);
- r = Array.factory(DataType.OBJECT, shape);
- Index index = r.getIndex();
- Index aindex = a.getIndex();
- Index bindex = b.getIndex();
- int n = r.getRank();
- int na = a.getRank();
- int nb = b.getRank();
- int[] current;
- if (isComplex(a)) {
- if (isComplex(b)) {
- Complex v1, v2;
- for (int i = 0; i < r.getSize(); i++) {
- current = index.getCurrentCounter();
- setIndex(aindex, bindex, current, n, na, nb);
- v1 = (Complex) a.getObject(aindex);
- v2 = (Complex) b.getObject(bindex);
- if (v1.isNaN() || v2.isNaN()) {
- r.setObject(i, v1);
- } else {
- r.setObject(i, v1.divide(v2));
- }
- index.incr();
- }
- } else {
- Complex v;
- for (int i = 0; i < r.getSize(); i++) {
- current = index.getCurrentCounter();
- setIndex(aindex, bindex, current, n, na, nb);
- v = (Complex) a.getObject(aindex);
- if (v.isNaN() || Double.isNaN(b.getDouble(bindex))) {
- r.setObject(i, new Complex(Double.NaN));
- } else {
- r.setObject(i, v.divide(b.getDouble(bindex)));
- }
- index.incr();
- }
- }
- } else {
- Complex v;
- for (int i = 0; i < a.getSize(); i++) {
- current = index.getCurrentCounter();
- setIndex(aindex, bindex, current, n, na, nb);
- v = (Complex) b.getObject(bindex);
- if (v.isNaN() || Double.isNaN(a.getDouble(aindex))) {
- r.setObject(i, new Complex(Double.NaN));
- } else {
- r.setObject(i, v.divide(a.getDouble(aindex)));
- }
- }
- }
- return r;
- default:
- return null;
- }
- }
-
- private static Array divComplex(Array a, double b) {
- Array r = Array.factory(DataType.OBJECT, a.getShape());
- Complex v;
- for (int i = 0; i < a.getSize(); i++) {
- v = (Complex) a.getObject(i);
- if (v.isNaN()) {
- r.setObject(i, v);
- } else {
- r.setObject(i, v.divide(b));
- }
- }
-
- return r;
- }
-
- private static Array divComplex(Array a, Complex b) {
- Array r = Array.factory(DataType.OBJECT, a.getShape());
- Complex v;
- for (int i = 0; i < a.getSize(); i++) {
- v = (Complex) a.getObject(i);
- if (v.isNaN()) {
- r.setObject(i, v);
- } else {
- r.setObject(i, v.divide(b));
- }
- }
-
- return r;
- }
-
- private static Array divComplex(double b, Array a) {
- Array r = Array.factory(DataType.OBJECT, a.getShape());
- Complex v;
- for (int i = 0; i < a.getSize(); i++) {
- v = (Complex) a.getObject(i);
- if (v.isNaN()) {
- r.setObject(i, v);
- } else {
- r.setObject(i, v.rDivide(b));
- }
- }
-
- return r;
- }
-
- private static Array divComplex(Complex b, Array a) {
- Array r = Array.factory(DataType.OBJECT, a.getShape());
- Complex v;
- for (int i = 0; i < a.getSize(); i++) {
- v = (Complex) a.getObject(i);
- if (v.isNaN()) {
- r.setObject(i, v);
- } else {
- r.setObject(i, b.divide(v));
- }
- }
-
- return r;
- }
-
- /**
- * Array pow function
- *
- * @param a Array a
- * @param b Number b
- * @return Result array
- */
- public static Array pow(Array a, Number b) {
- DataType bType = ArrayMath.getDataType(b);
- DataType type = ArrayMath.commonType(a.getDataType(), bType);
- switch (type) {
- case SHORT:
- case INT:
- case BOOLEAN:
- return ArrayMath.powInt(a, b.intValue());
- case FLOAT:
- case DOUBLE:
- return ArrayMath.powDouble(a, b.doubleValue());
- case OBJECT:
- if (isComplex(a)) {
- return ArrayMath.powComplex(a, b.doubleValue());
- }
- break;
- }
- return null;
- }
-
- /**
- * Array pow function
- *
- * @param a Array a
- * @param b Complex number b
- * @return Result array
- */
- public static Array pow(Array a, Complex b) {
- return powComplex(a, b);
- }
-
- /**
- * Array pow function
- *
- * @param a Array a
- * @param b Complex number b
- * @return Result array
- */
- public static Array pow(Array a, PyComplex b) {
- return powComplex(a, new Complex(b.real, b.imag));
- }
-
- /**
- * Array pow function
- *
- * @param a Number a
- * @param b Array b
- * @return Result array
- */
- public static Array pow(Number a, Array b) {
- DataType bType = ArrayMath.getDataType(a);
- DataType type = ArrayMath.commonType(b.getDataType(), bType);
- switch (type) {
- case SHORT:
- case INT:
- case BOOLEAN:
- return ArrayMath.powInt(a.intValue(), b);
- case FLOAT:
- case DOUBLE:
- return ArrayMath.powDouble(a.doubleValue(), b);
- case OBJECT:
- if (isComplex(b)) {
- return ArrayMath.powComplex(a.doubleValue(), b);
- }
- break;
- }
- return null;
- }
-
- /**
- * Array pow function
- *
- * @param a Array a
- * @param b Complex number b
- * @return Result array
- */
- public static Array pow(Complex b, Array a) {
- return powComplex(b, a);
- }
-
- /**
- * Array pow function
- *
- * @param a Array a
- * @param b Complex number b
- * @return Result array
- */
- public static Array pow(PyComplex b, Array a) {
- return powComplex(new Complex(b.real, b.imag), a);
- }
-
- /**
- * Array pow function
- *
- * @param a Number a
- * @param b Array b
- * @return Result array
- */
- public static Array pow(Array a, Array b) {
- DataType type = ArrayMath.commonType(a.getDataType(), b.getDataType());
- switch (type) {
- case SHORT:
- case INT:
- return ArrayMath.powInt(a, b);
- case FLOAT:
- case DOUBLE:
- return ArrayMath.powDouble(a, b);
- case OBJECT:
- if (isComplex(a) || isComplex(b)) {
- return ArrayMath.powComplex(a, b);
- }
- break;
- }
- return null;
- }
-
- private static Array powInt(Array a, int b) {
- Array r = Array.factory(DataType.INT, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setInt(i, (int) Math.pow(a.getInt(i), b));
- }
-
- return r;
- }
-
- private static Array powInt(int a, Array b) {
- Array r = Array.factory(DataType.INT, b.getShape());
- for (int i = 0; i < b.getSize(); i++) {
- r.setInt(i, (int) Math.pow(a, b.getInt(i)));
- }
-
- return r;
- }
-
- private static Array powInt(Array a, Array b) {
- int broadcast = broadcastCheck(a, b);
- switch (broadcast) {
- case 0:
- Array r = Array.factory(DataType.INT, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setInt(i, (int) Math.pow(a.getInt(i), b.getInt(i)));
- }
- return r;
- case 1:
- int[] shape = broadcast(a, b);
- r = Array.factory(DataType.INT, shape);
- Index index = r.getIndex();
- Index aindex = a.getIndex();
- Index bindex = b.getIndex();
- int n = r.getRank();
- int na = a.getRank();
- int nb = b.getRank();
- int[] current;
- for (int i = 0; i < r.getSize(); i++) {
- current = index.getCurrentCounter();
- setIndex(aindex, bindex, current, n, na, nb);
- r.setInt(i, (int) Math.pow(a.getInt(aindex), b.getInt(bindex)));
- index.incr();
- }
- return r;
- default:
- return null;
- }
- }
-
- private static Array powDouble(Array a, double b) {
- Array r = Array.factory(DataType.DOUBLE, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setDouble(i, Math.pow(a.getDouble(i), b));
- }
-
- return r;
- }
-
- private static Array powDouble(double a, Array b) {
- Array r = Array.factory(DataType.DOUBLE, b.getShape());
- for (int i = 0; i < b.getSize(); i++) {
- r.setDouble(i, Math.pow(a, b.getDouble(i)));
- }
-
- return r;
- }
-
- private static Array powDouble(Array a, Array b) {
- int broadcast = broadcastCheck(a, b);
- switch (broadcast) {
- case 0:
- Array r = Array.factory(DataType.DOUBLE, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- if (Double.isNaN(a.getDouble(i)) || Double.isNaN(b.getDouble(i))) {
- r.setDouble(i, Double.NaN);
- } else {
- r.setDouble(i, Math.pow(a.getDouble(i), b.getDouble(i)));
- }
- }
- return r;
- case 1:
- int[] shape = broadcast(a, b);
- r = Array.factory(DataType.DOUBLE, shape);
- Index index = r.getIndex();
- Index aindex = a.getIndex();
- Index bindex = b.getIndex();
- int n = r.getRank();
- int na = a.getRank();
- int nb = b.getRank();
- int[] current;
- for (int i = 0; i < r.getSize(); i++) {
- current = index.getCurrentCounter();
- setIndex(aindex, bindex, current, n, na, nb);
- if (Double.isNaN(a.getDouble(aindex)) || Double.isNaN(b.getDouble(bindex))) {
- r.setDouble(i, Double.NaN);
- } else {
- r.setDouble(i, Math.pow(a.getDouble(aindex), b.getDouble(bindex)));
- }
- index.incr();
- }
- return r;
- default:
- return null;
- }
- }
-
- private static Array powComplex(Array a, Array b) {
- int broadcast = broadcastCheck(a, b);
- switch (broadcast) {
- case 0:
- Array r = Array.factory(DataType.OBJECT, a.getShape());
- if (isComplex(a)) {
- if (isComplex(b)) {
- Complex v1, v2;
- for (int i = 0; i < a.getSize(); i++) {
- v1 = (Complex) a.getObject(i);
- v2 = (Complex) b.getObject(i);
- if (v1.isNaN() || v2.isNaN()) {
- r.setObject(i, v1);
- } else {
- r.setObject(i, v1.pow(v2));
- }
- }
- } else {
- Complex v;
- for (int i = 0; i < a.getSize(); i++) {
- v = (Complex) a.getObject(i);
- if (v.isNaN() || Double.isNaN(b.getDouble(i))) {
- r.setObject(i, new Complex(Double.NaN));
- } else {
- r.setObject(i, v.pow(b.getDouble(i)));
- }
- }
- }
- } else {
- Complex v;
- for (int i = 0; i < a.getSize(); i++) {
- v = (Complex) b.getObject(i);
- if (v.isNaN() || Double.isNaN(a.getDouble(i))) {
- r.setObject(i, new Complex(Double.NaN));
- } else {
- r.setObject(i, v.pow(a.getDouble(i)));
- }
- }
- }
- return r;
- case 1:
- int[] shape = broadcast(a, b);
- r = Array.factory(DataType.OBJECT, shape);
- Index index = r.getIndex();
- Index aindex = a.getIndex();
- Index bindex = b.getIndex();
- int n = r.getRank();
- int na = a.getRank();
- int nb = b.getRank();
- int[] current;
- if (isComplex(a)) {
- if (isComplex(b)) {
- Complex v1, v2;
- for (int i = 0; i < r.getSize(); i++) {
- current = index.getCurrentCounter();
- setIndex(aindex, bindex, current, n, na, nb);
- v1 = (Complex) a.getObject(aindex);
- v2 = (Complex) b.getObject(bindex);
- if (v1.isNaN() || v2.isNaN()) {
- r.setObject(i, v1);
- } else {
- r.setObject(i, v1.pow(v2));
- }
- index.incr();
- }
- } else {
- Complex v;
- for (int i = 0; i < r.getSize(); i++) {
- current = index.getCurrentCounter();
- setIndex(aindex, bindex, current, n, na, nb);
- v = (Complex) a.getObject(aindex);
- if (v.isNaN() || Double.isNaN(b.getDouble(bindex))) {
- r.setObject(i, new Complex(Double.NaN));
- } else {
- r.setObject(i, v.pow(b.getDouble(bindex)));
- }
- index.incr();
- }
- }
- } else {
- Complex v;
- for (int i = 0; i < a.getSize(); i++) {
- current = index.getCurrentCounter();
- setIndex(aindex, bindex, current, n, na, nb);
- v = (Complex) b.getObject(bindex);
- if (v.isNaN() || Double.isNaN(a.getDouble(aindex))) {
- r.setObject(i, new Complex(Double.NaN));
- } else {
- r.setObject(i, v.pow(a.getDouble(aindex)));
- }
- }
- }
- return r;
- default:
- return null;
- }
- }
-
- private static Array powComplex(Array a, double b) {
- Array r = Array.factory(DataType.OBJECT, a.getShape());
- Complex v;
- for (int i = 0; i < a.getSize(); i++) {
- v = (Complex) a.getObject(i);
- if (v.isNaN()) {
- r.setObject(i, v);
- } else {
- r.setObject(i, v.pow(b));
- }
- }
-
- return r;
- }
-
- private static Array powComplex(Array a, Complex b) {
- Array r = Array.factory(DataType.OBJECT, a.getShape());
- Complex v;
- for (int i = 0; i < a.getSize(); i++) {
- v = (Complex) a.getObject(i);
- if (v.isNaN()) {
- r.setObject(i, v);
- } else {
- r.setObject(i, v.pow(b));
- }
- }
-
- return r;
- }
-
- private static Array powComplex(double b, Array a) {
- Array r = Array.factory(DataType.OBJECT, a.getShape());
- Complex v;
- for (int i = 0; i < a.getSize(); i++) {
- v = (Complex) a.getObject(i);
- if (v.isNaN()) {
- r.setObject(i, v);
- } else {
- r.setObject(i, v.rPow(b));
- }
- }
-
- return r;
- }
-
- private static Array powComplex(Complex b, Array a) {
- Array r = Array.factory(DataType.OBJECT, a.getShape());
- Complex v;
- for (int i = 0; i < a.getSize(); i++) {
- v = (Complex) a.getObject(i);
- if (v.isNaN()) {
- r.setObject(i, v);
- } else {
- r.setObject(i, b.pow(v));
- }
- }
-
- return r;
- }
-
- /**
- * Sqrt function
- *
- * @param a Array a
- * @return Result array
- */
- public static Array sqrt(Array a) {
- return ArrayMath.pow(a, 0.5);
- }
-
- /**
- * Exponent function
- *
- * @param a Array a
- * @return Result array
- */
- public static Array exp(Array a) {
- Array r;
- if (isComplex(a)) {
- r = Array.factory(DataType.OBJECT, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setObject(i, ((Complex) a.getObject(i)).exp());
- }
- } else {
- r = Array.factory(DataType.DOUBLE, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setDouble(i, Math.exp(a.getDouble(i)));
- }
- }
-
- return r;
- }
-
- /**
- * Log function
- *
- * @param a Array a
- * @return Result array
- */
- public static Array log(Array a) {
- Array r;
- if (isComplex(a)) {
- r = Array.factory(DataType.OBJECT, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setObject(i, ((Complex) a.getObject(i)).log());
- }
- } else {
- r = Array.factory(DataType.DOUBLE, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setDouble(i, Math.log(a.getDouble(i)));
- }
- }
-
- return r;
- }
-
- /**
- * Log10 function
- *
- * @param a Array a
- * @return Result array
- */
- public static Array log10(Array a) {
- Array r = Array.factory(DataType.DOUBLE, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setDouble(i, Math.log10(a.getDouble(i)));
- }
-
- return r;
- }
-
- /**
- * Array absolute
- *
- * @param a Array a
- * @return Result array
- */
- public static Array abs(Array a) {
- Array r;
- if (isComplex(a)) {
- r = Array.factory(DataType.DOUBLE, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setDouble(i, ((Complex) a.getObject(i)).abs());
- }
- } else {
- r = Array.factory(a.getDataType(), a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setDouble(i, Math.abs(a.getDouble(i)));
- }
- }
-
- return r;
- }
-
- /**
- * Array equal
- *
- * @param a Array a
- * @param b Array b
- * @return Result array
- */
- public static Array equal(Array a, Array b) {
- Array r = Array.factory(DataType.BOOLEAN, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- if (a.getDouble(i) == b.getDouble(i)) {
- r.setBoolean(i, true);
- } else {
- r.setBoolean(i, false);
- }
- }
-
- return r;
- }
-
- /**
- * Array equal
- *
- * @param a Array a
- * @param b Number b
- * @return Result array
- */
- public static Array equal(Array a, Number b) {
- Array r = Array.factory(DataType.BOOLEAN, a.getShape());
- double v = b.doubleValue();
- if (Double.isNaN(v)) {
- for (int i = 0; i < a.getSize(); i++) {
- if (Double.isNaN(a.getDouble(i))) {
- r.setBoolean(i, true);
- } else {
- r.setBoolean(i, false);
- }
- }
- } else {
- for (int i = 0; i < a.getSize(); i++) {
- if (a.getDouble(i) == v) {
- r.setBoolean(i, true);
- } else {
- r.setBoolean(i, false);
- }
- }
- }
-
- return r;
- }
-
- /**
- * Array equal
- *
- * @param a Array a
- * @param b String b
- * @return Result array
- */
- public static Array equal(Array a, String b) {
- Array r = Array.factory(DataType.BOOLEAN, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- if (a.getObject(i).equals(b)) {
- r.setBoolean(i, true);
- } else {
- r.setBoolean(i, false);
- }
- }
-
- return r;
- }
-
- /**
- * Array less than
- *
- * @param a Array a
- * @param b Array b
- * @return Result array
- */
- public static Array lessThan(Array a, Array b) {
- Array r = Array.factory(DataType.BOOLEAN, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- if (a.getDouble(i) < b.getDouble(i)) {
- r.setBoolean(i, true);
- } else {
- r.setBoolean(i, false);
- }
- }
-
- return r;
- }
-
- /**
- * Array less than
- *
- * @param a Array a
- * @param b Number b
- * @return Result array
- */
- public static Array lessThan(Array a, Number b) {
- Array r = Array.factory(DataType.BOOLEAN, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- if (a.getDouble(i) < b.doubleValue()) {
- r.setBoolean(i, true);
- } else {
- r.setBoolean(i, false);
- }
- }
-
- return r;
- }
-
- /**
- * Array less than or equal
- *
- * @param a Array a
- * @param b Array b
- * @return Result array
- */
- public static Array lessThanOrEqual(Array a, Array b) {
- Array r = Array.factory(DataType.BOOLEAN, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- if (a.getDouble(i) <= b.getDouble(i)) {
- r.setBoolean(i, true);
- } else {
- r.setBoolean(i, false);
- }
- }
-
- return r;
- }
-
- /**
- * Array less than or equal
- *
- * @param a Array a
- * @param b Number b
- * @return Result array
- */
- public static Array lessThanOrEqual(Array a, Number b) {
- Array r = Array.factory(DataType.BOOLEAN, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- if (a.getDouble(i) <= b.doubleValue()) {
- r.setBoolean(i, true);
- } else {
- r.setBoolean(i, false);
- }
- }
-
- return r;
- }
-
- /**
- * Array greater than
- *
- * @param a Array a
- * @param b Array b
- * @return Result array
- */
- public static Array greaterThan(Array a, Array b) {
- Array r = Array.factory(DataType.BOOLEAN, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- if (a.getDouble(i) > b.getDouble(i)) {
- r.setBoolean(i, true);
- } else {
- r.setBoolean(i, false);
- }
- }
-
- return r;
- }
-
- /**
- * Array greater than
- *
- * @param a Array a
- * @param b Number b
- * @return Result array
- */
- public static Array greaterThan(Array a, Number b) {
- Array r = Array.factory(DataType.BOOLEAN, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- if (a.getDouble(i) > b.doubleValue()) {
- r.setBoolean(i, true);
- } else {
- r.setBoolean(i, false);
- }
- }
-
- return r;
- }
-
- /**
- * Array greater than or equal
- *
- * @param a Array a
- * @param b Array b
- * @return Result array
- */
- public static Array greaterThanOrEqual(Array a, Array b) {
- Array r = Array.factory(DataType.BOOLEAN, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- if (a.getDouble(i) >= b.getDouble(i)) {
- r.setBoolean(i, true);
- } else {
- r.setBoolean(i, false);
- }
- }
-
- return r;
- }
-
- /**
- * Array greater than or equal
- *
- * @param a Array a
- * @param b Number b
- * @return Result array
- */
- public static Array greaterThanOrEqual(Array a, Number b) {
- Array r = Array.factory(DataType.BOOLEAN, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- if (a.getDouble(i) >= b.doubleValue()) {
- r.setBoolean(i, true);
- } else {
- r.setBoolean(i, false);
- }
- }
-
- return r;
- }
-
- /**
- * Array not equal
- *
- * @param a Array a
- * @param b Array b
- * @return Result array
- */
- public static Array notEqual(Array a, Array b) {
- Array r = Array.factory(DataType.BOOLEAN, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- if (a.getDouble(i) != b.getDouble(i)) {
- r.setBoolean(i, true);
- } else {
- r.setBoolean(i, false);
- }
- }
-
- return r;
- }
-
- /**
- * Array not equal
- *
- * @param a Array a
- * @param b Number b
- * @return Result array
- */
- public static Array notEqual(Array a, Number b) {
- Array r = Array.factory(DataType.BOOLEAN, a.getShape());
- double v = b.doubleValue();
- if (Double.isNaN(v)) {
- for (int i = 0; i < a.getSize(); i++) {
- if (Double.isNaN(a.getDouble(i))) {
- r.setBoolean(i, false);
- } else {
- r.setBoolean(i, true);
- }
- }
- } else {
- for (int i = 0; i < a.getSize(); i++) {
- if (a.getDouble(i) != v) {
- r.setBoolean(i, true);
- } else {
- r.setBoolean(i, false);
- }
- }
- }
-
- return r;
- }
-
- /**
- * Test whether any array element evaluates to True.
- *
- * @param a The array
- * @return Boolean
- */
- public static boolean any(Array a) {
- IndexIterator ii = a.getIndexIterator();
- while (ii.hasNext()) {
- if (ii.getBooleanNext()) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Test whether any array element along a given axis evaluates to True.
- *
- * @param a Array a
- * @param axis Axis
- * @return Boolean array
- * @throws org.meteoinfo.ndarray.InvalidRangeException
- */
- public static Array any(Array a, int axis) throws InvalidRangeException {
- int[] dataShape = a.getShape();
- int[] shape = new int[dataShape.length - 1];
- int idx;
- for (int i = 0; i < dataShape.length; i++) {
- idx = i;
- if (idx == axis) {
- continue;
- } else if (idx > axis) {
- idx -= 1;
- }
- shape[idx] = dataShape[i];
- }
- Array r = Array.factory(DataType.BOOLEAN, shape);
- boolean b;
- Index indexr = r.getIndex();
- int[] current;
- for (int i = 0; i < r.getSize(); i++) {
- current = indexr.getCurrentCounter();
- List ranges = new ArrayList<>();
- for (int j = 0; j < dataShape.length; j++) {
- if (j == axis) {
- ranges.add(new Range(0, dataShape[j] - 1, 1));
- } else {
- idx = j;
- if (idx > axis) {
- idx -= 1;
- }
- ranges.add(new Range(current[idx], current[idx], 1));
- }
- }
- IndexIterator ii = a.getRangeIterator(ranges);
- b = false;
- while (ii.hasNext()) {
- if (ii.getBooleanNext()) {
- b = true;
- break;
- }
- }
- r.setBoolean(i, b);
- indexr.incr();
- }
-
- return r;
- }
-
- /**
- * Test whether all array element evaluates to True.
- *
- * @param a The array
- * @return Boolean
- */
- public static boolean all(Array a) {
- IndexIterator ii = a.getIndexIterator();
- while (ii.hasNext()) {
- if (!ii.getBooleanNext()) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Test whether all array element along a given axis evaluates to True.
- *
- * @param a Array a
- * @param axis Axis
- * @return Boolean array
- * @throws org.meteoinfo.ndarray.InvalidRangeException
- */
- public static Array all(Array a, int axis) throws InvalidRangeException {
- int[] dataShape = a.getShape();
- int[] shape = new int[dataShape.length - 1];
- int idx;
- for (int i = 0; i < dataShape.length; i++) {
- idx = i;
- if (idx == axis) {
- continue;
- } else if (idx > axis) {
- idx -= 1;
- }
- shape[idx] = dataShape[i];
- }
- Array r = Array.factory(DataType.BOOLEAN, shape);
- boolean b;
- Index indexr = r.getIndex();
- int[] current;
- for (int i = 0; i < r.getSize(); i++) {
- current = indexr.getCurrentCounter();
- List ranges = new ArrayList<>();
- for (int j = 0; j < dataShape.length; j++) {
- if (j == axis) {
- ranges.add(new Range(0, dataShape[j] - 1, 1));
- } else {
- idx = j;
- if (idx > axis) {
- idx -= 1;
- }
- ranges.add(new Range(current[idx], current[idx], 1));
- }
- }
- IndexIterator ii = a.getRangeIterator(ranges);
- b = true;
- while (ii.hasNext()) {
- if (!ii.getBooleanNext()) {
- b = false;
- break;
- }
- }
- r.setBoolean(i, b);
- indexr.incr();
- }
-
- return r;
- }
-
- /**
- * Return the array with the value of 1 when the input array element value
- * in the list b, otherwise set value as 0.
- *
- * @param a Array a
- * @param b List b
- * @return Result array
- */
- public static Array inValues(Array a, List b) {
- Array r = Array.factory(DataType.BOOLEAN, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- if (b.contains(a.getObject(i))) {
- r.setBoolean(i, true);
- } else {
- r.setBoolean(i, false);
- }
- }
-
- return r;
- }
-
- /**
- * Check if the array contains NaN value
- *
- * @param a Input array
- * @return Boolean
- */
- public static boolean containsNaN(Array a) {
- boolean hasNaN = false;
- for (int i = 0; i < a.getSize(); i++) {
- if (Double.isNaN(a.getDouble(i))) {
- hasNaN = true;
- break;
- }
- }
-
- return hasNaN;
- }
-
- /**
- * Remove NaN values in an array
- *
- * @param a The array
- * @return The array withou NaN values
- */
- public static Array removeNaN(Array a) {
- List d = new ArrayList<>();
- for (int i = 0; i < a.getSize(); i++) {
- if (!Double.isNaN(a.getDouble(i))) {
- d.add(a.getObject(i));
- }
- }
-
- if (d.isEmpty()) {
- return null;
- }
-
- Array r = Array.factory(a.getDataType(), new int[]{d.size()});
- for (int i = 0; i < d.size(); i++) {
- r.setObject(i, d.get(i));
- }
-
- return r;
- }
-
- /**
- * Remove NaN values in arrays
- *
- * @param a The arrays
- * @return The array withou NaN values
- */
- public static Array[] removeNaN(Array... a) {
- if (a.length == 1) {
- Array r0 = removeNaN(a[0]);
- return r0 == null ? null : new Array[]{removeNaN(a[0])};
- }
-
- List d = new ArrayList<>();
- int n = (int) a[0].getSize();
- int m = a.length;
- boolean isNan;
- for (int i = 0; i < n; i++) {
- isNan = false;
- for (Array aa : a) {
- if (Double.isNaN(aa.getDouble(i))) {
- isNan = true;
- break;
- }
- }
- if (!isNan) {
- for (Array aa : a) {
- d.add(aa.getObject(i));
- }
- }
- }
-
- if (d.isEmpty()) {
- return null;
- }
-
- int len = d.size() / m;
- Array[] r = new Array[m];
- for (int i = 0; i < m; i++) {
- r[i] = Array.factory(a[i].getDataType(), new int[]{len});
- int jj = i;
- for (int j = 0; j < len; j++) {
- r[i].setObject(j, d.get(jj));
- jj += m;
- }
- }
-
- return r;
- }
-
- /**
- * Return the indices of the elements that are non-zero.
- *
- * @param a Input array
- * @return Indices
- */
- public static List nonzero(Array a) {
- List> r = new ArrayList<>();
- int ndim = a.getRank();
- for (int i = 0; i < ndim; i++) {
- r.add(new ArrayList());
- }
- Index index = a.getIndex();
- int[] counter;
- double v;
- for (int i = 0; i < a.getSize(); i++) {
- v = a.getDouble(i);
- if (!Double.isNaN(v) && v != 0) {
- counter = index.getCurrentCounter();
- for (int j = 0; j < ndim; j++) {
- r.get(j).add(counter[j]);
- }
- }
- index.incr();
- }
-
- if (r.get(0).isEmpty()) {
- return null;
- }
-
- List ra = new ArrayList<>();
- for (int i = 0; i < ndim; i++) {
- ra.add(ArrayUtil.array(r.get(i)));
- }
- return ra;
- }
-
- /**
- * Bit and operation
- *
- * @param a Array a
- * @param b Number b
- * @return Result array
- */
- public static Array bitAnd(Array a, Number b) {
- Array r = Array.factory(a.getDataType(), a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setObject(i, a.getInt(i) & b.intValue());
- }
-
- return r;
- }
-
- /**
- * Bit and operation
- *
- * @param a Array a
- * @param b Array b
- * @return Result array
- */
- public static Array bitAnd(Array a, Array b) {
- Array r = Array.factory(a.getDataType(), a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setObject(i, a.getInt(i) & b.getInt(i));
- }
-
- return r;
- }
-
- /**
- * Bit or | operation
- *
- * @param a Array a
- * @param b Number b
- * @return Result array
- */
- public static Array bitOr(Array a, Number b) {
- Array r = Array.factory(a.getDataType(), a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setObject(i, a.getInt(i) | b.intValue());
- }
-
- return r;
- }
-
- /**
- * Bit or | operation
- *
- * @param a Array a
- * @param b Array b
- * @return Result array
- */
- public static Array bitOr(Array a, Array b) {
- Array r = Array.factory(a.getDataType(), a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setObject(i, a.getInt(i) | b.getInt(i));
- }
-
- return r;
- }
-
- /**
- * Bit exclusive or ^ operation
- *
- * @param a Array a
- * @param b Number b
- * @return Result array
- */
- public static Array bitXor(Array a, Number b) {
- Array r = Array.factory(a.getDataType(), a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setObject(i, a.getInt(i) ^ b.intValue());
- }
-
- return r;
- }
-
- /**
- * Bit exclusive or | operation
- *
- * @param a Array a
- * @param b Array b
- * @return Result array
- */
- public static Array bitXor(Array a, Array b) {
- Array r = Array.factory(a.getDataType(), a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setObject(i, a.getInt(i) ^ b.getInt(i));
- }
-
- return r;
- }
-
- /**
- * Bit inversion ~ operation
- *
- * @param a Array a
- * @return Result array
- */
- public static Array bitInvert(Array a) {
- Array r = Array.factory(a.getDataType(), a.getShape());
- if (a.getDataType() == DataType.BOOLEAN) {
- for (int i = 0; i < a.getSize(); i++) {
- r.setObject(i, !a.getBoolean(i));
- }
- } else {
- for (int i = 0; i < a.getSize(); i++) {
- r.setObject(i, ~a.getInt(i));
- }
- }
-
- return r;
- }
-
- /**
- * Bit left shift operation
- *
- * @param a Array a
- * @param b Number b
- * @return Result array
- */
- public static Array leftShift(Array a, Number b) {
- Array r = Array.factory(a.getDataType(), a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setObject(i, a.getInt(i) << b.intValue());
- }
-
- return r;
- }
-
- /**
- * Bit left shift operation
- *
- * @param a Array a
- * @param b Array b
- * @return Result array
- */
- public static Array leftShift(Array a, Array b) {
- Array r = Array.factory(a.getDataType(), a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setObject(i, a.getInt(i) << b.getInt(i));
- }
-
- return r;
- }
-
- /**
- * Bit right shift operation
- *
- * @param a Array a
- * @param b Number b
- * @return Result array
- */
- public static Array rightShift(Array a, Number b) {
- Array r = Array.factory(a.getDataType(), a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setObject(i, a.getInt(i) >> b.intValue());
- }
-
- return r;
- }
-
- /**
- * Bit right shift operation
- *
- * @param a Array a
- * @param b Array b
- * @return Result array
- */
- public static Array rightShift(Array a, Array b) {
- Array r = Array.factory(a.getDataType(), a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setObject(i, a.getInt(i) >> b.getInt(i));
- }
-
- return r;
- }
-
- /**
- * Integrate vector array using the composite trapezoidal rule.
- *
- * @param y Vecotr array
- * @param dx Spacing between all y elements
- * @return Definite integral as approximated by trapezoidal rule
- */
- public static double trapz(Array y, double dx) {
- int n = (int) y.getSize() - 1;
- double a = 1;
- double b = n * dx + a;
- double r = 0, v;
- int nn = 0;
- for (int i = 0; i < y.getSize(); i++) {
- v = y.getDouble(i);
- if (Double.isNaN(v)) {
- continue;
- }
- r += y.getDouble(i);
- if (i > 0 && i < n) {
- r += y.getDouble(i);
- }
- nn += 1;
- }
- if (nn >= 2) {
- r = r * ((b - a) / (2 * n));
- } else {
- r = Double.NaN;
- }
- return r;
- }
-
- /**
- * Integrate vector array using the composite trapezoidal rule.
- *
- * @param y Vecotr array
- * @param dx Spacing between all y elements
- * @param ranges
- * @return Definite integral as approximated by trapezoidal rule
- * @throws org.meteoinfo.ndarray.InvalidRangeException
- */
- public static double trapz(Array y, double dx, List ranges) throws InvalidRangeException {
- int n = 1;
- for (Range range : ranges) {
- n = n * range.length();
- }
- n -= 1;
- double a = 1;
- double b = n * dx + a;
- double r = 0;
- double v;
- IndexIterator ii = y.getRangeIterator(ranges);
- int i = 0;
- while (ii.hasNext()) {
- v = ii.getDoubleNext();
- if (Double.isNaN(v)) {
- continue;
- }
- r += v;
- if (i > 0 && i < n) {
- r += v;
- }
- i += 1;
- }
- if (i >= 2) {
- r = r * ((b - a) / (2 * n));
- } else {
- r = Double.NaN;
- }
- return r;
- }
-
- /**
- * Integrate vector array using the composite trapezoidal rule.
- *
- * @param y Vecotr array
- * @param x Spacing array between all y elements
- * @return Definite integral as approximated by trapezoidal rule
- */
- public static double trapz(Array y, Array x) {
- int n = (int) y.getSize() - 1;
- double r = 0;
- double v;
- int nn = 0;
- for (int i = 0; i < n; i++) {
- v = y.getDouble(i);
- if (Double.isNaN(v)) {
- continue;
- }
- r += (x.getDouble(i + 1) - x.getDouble(i)) * (y.getDouble(i + 1) + v);
- nn += 1;
- }
- if (nn >= 2) {
- r = r / 2;
- } else {
- r = Double.NaN;
- }
- return r;
- }
-
- /**
- * Integrate vector array using the composite trapezoidal rule.
- *
- * @param y Vecotr array
- * @param x Spacing array between all y elements
- * @param ranges Ranges
- * @return Definite integral as approximated by trapezoidal rule
- * @throws org.meteoinfo.ndarray.InvalidRangeException
- */
- public static double trapz(Array y, Array x, List ranges) throws InvalidRangeException {
- double r = 0;
- double v;
- double v0 = Double.NEGATIVE_INFINITY;
- IndexIterator ii = y.getRangeIterator(ranges);
- int i = 0, n = 0;
- while (ii.hasNext()) {
- v = ii.getDoubleNext();
- if (Double.isNaN(v)) {
- i += 1;
- continue;
- }
- if (Double.isInfinite(v0)) {
- v0 = v;
- continue;
- }
- r += (x.getDouble(i + 1) - x.getDouble(i)) * (v + v0);
- v0 = v;
- i += 1;
- n += 1;
- }
- if (n >= 2) {
- r = r / 2;
- } else {
- r = Double.NaN;
- }
- return r;
- }
-
- /**
- * Integrate vector array using the composite trapezoidal rule.
- *
- * @param a Array a
- * @param dx
- * @param axis Axis
- * @return Mean value array
- * @throws org.meteoinfo.ndarray.InvalidRangeException
- */
- public static Array trapz(Array a, double dx, int axis) throws InvalidRangeException {
- int[] dataShape = a.getShape();
- int[] shape = new int[dataShape.length - 1];
- int idx;
- for (int i = 0; i < dataShape.length; i++) {
- idx = i;
- if (idx == axis) {
- continue;
- } else if (idx > axis) {
- idx -= 1;
- }
- shape[idx] = dataShape[i];
- }
- Array r = Array.factory(DataType.DOUBLE, shape);
- double mean;
- Index indexr = r.getIndex();
- int[] current;
- for (int i = 0; i < r.getSize(); i++) {
- current = indexr.getCurrentCounter();
- List ranges = new ArrayList<>();
- for (int j = 0; j < dataShape.length; j++) {
- if (j == axis) {
- ranges.add(new Range(0, dataShape[j] - 1, 1));
- } else {
- idx = j;
- if (idx > axis) {
- idx -= 1;
- }
- ranges.add(new Range(current[idx], current[idx], 1));
- }
- }
- mean = trapz(a, dx, ranges);
- r.setDouble(i, mean);
- indexr.incr();
- }
-
- return r;
- }
-
- /**
- * Integrate vector array using the composite trapezoidal rule.
- *
- * @param a Array a
- * @param x Array x
- * @param axis Axis
- * @return Mean value array
- * @throws org.meteoinfo.ndarray.InvalidRangeException
- */
- public static Array trapz(Array a, Array x, int axis) throws InvalidRangeException {
- int[] dataShape = a.getShape();
- int[] shape = new int[dataShape.length - 1];
- int idx;
- for (int i = 0; i < dataShape.length; i++) {
- idx = i;
- if (idx == axis) {
- continue;
- } else if (idx > axis) {
- idx -= 1;
- }
- shape[idx] = dataShape[i];
- }
- Array r = Array.factory(DataType.DOUBLE, shape);
- double mean;
- Index indexr = r.getIndex();
- int[] current;
- for (int i = 0; i < r.getSize(); i++) {
- current = indexr.getCurrentCounter();
- List ranges = new ArrayList<>();
- for (int j = 0; j < dataShape.length; j++) {
- if (j == axis) {
- ranges.add(new Range(0, dataShape[j] - 1, 1));
- } else {
- idx = j;
- if (idx > axis) {
- idx -= 1;
- }
- ranges.add(new Range(current[idx], current[idx], 1));
- }
- }
- mean = trapz(a, x, ranges);
- r.setDouble(i, mean);
- indexr.incr();
- }
-
- return r;
- }
-
- /**
- * Returns an element-wise indication of the sign of a number. The sign
- * function returns -1 if x less than 0, 0 if x==0, 1 if x bigger than 0.
- * nan is returned for nan inputs.
- *
- * @param x Input array
- * @return The sign of x array
- */
- public static Array sign(Array x) {
- Array r = Array.factory(DataType.FLOAT, x.getShape());
- for (int i = 0; i < r.getSize(); i++) {
- r.setFloat(i, Math.signum(x.getFloat(i)));
- }
-
- return r;
- }
-
- //
- //
- /**
- * Matrix multiplication
- *
- * @param a Array a
- * @param b Array b
- * @return Result array
- */
- public static Array dot(Array a, Array b) {
- DataType type = ArrayMath.commonType(a.getDataType(), b.getDataType());
- int[] shape;
- if (a.getRank() == 2) {
- if (a.getShape()[1] != b.getShape()[0]) {
- return null;
- }
- if (b.getRank() == 2) {
- shape = new int[2];
- shape[0] = a.getShape()[0];
- shape[1] = b.getShape()[1];
- } else {
- shape = new int[1];
- shape[0] = a.getShape()[0];
- }
- Array r = Array.factory(type, shape);
- Index aIndex = a.getIndex();
- Index bIndex = b.getIndex();
- Index rIndex = r.getIndex();
- int n = a.getShape()[1];
- double v;
- if (b.getRank() == 2) {
- for (int i = 0; i < shape[0]; i++) {
- for (int j = 0; j < shape[1]; j++) {
- v = 0;
- for (int m = 0; m < n; m++) {
- v = v + a.getDouble(aIndex.set(i, m)) * b.getDouble(bIndex.set(m, j));
- }
- r.setDouble(rIndex.set(i, j), v);
- }
- }
- } else {
- for (int i = 0; i < shape[0]; i++) {
- v = 0;
- for (int m = 0; m < n; m++) {
- v = v + a.getDouble(aIndex.set(i, m)) * b.getDouble(bIndex.set(m));
- }
- r.setDouble(rIndex.set(i), v);
- }
- }
- return r;
- } else {
- if (a.getShape()[0] != b.getShape()[0]) {
- return null;
- }
- shape = new int[1];
- shape[0] = b.getShape()[1];
- Array r = Array.factory(type, shape);
- double v;
- int n = a.getShape()[0];
- Index bIndex = b.getIndex();
- for (int i = 0; i < shape[0]; i++) {
- v = 0;
- for (int j = 0; j < n; j++) {
- v += a.getDouble(j) * b.getDouble(bIndex.set(j, i));
- }
- r.setDouble(i, v);
- }
- return r;
- }
- }
-
- /**
- * Return the dot product of two vectors.
- *
- * @param a Vector a
- * @param b Vector b
- * @return Result
- */
- public static double vdot(Array a, Array b) {
- double r = 0;
- for (int i = 0; i < a.getSize(); i++) {
- r += a.getDouble(i) * b.getDouble(i);
- }
-
- return r;
- }
-
- //
- //
- /**
- * Convert radians to degrees function
- *
- * @param a Array a
- * @return Result array
- */
- public static Array toDegrees(Array a) {
- Array r = Array.factory(a.getDataType() == DataType.DOUBLE ? DataType.DOUBLE : DataType.FLOAT, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setDouble(i, Math.toDegrees(a.getDouble(i)));
- }
-
- return r;
- }
-
- /**
- * Convert radians to degrees function
- *
- * @param a Array a
- * @return Result array
- */
- public static Array toRadians(Array a) {
- Array r = Array.factory(a.getDataType() == DataType.DOUBLE ? DataType.DOUBLE : DataType.FLOAT, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setDouble(i, Math.toRadians(a.getDouble(i)));
- }
-
- return r;
- }
-
- /**
- * Sine function
- *
- * @param a Array a
- * @return Result array
- */
- public static Array sin(Array a) {
- Array r;
- if (isComplex(a)) {
- r = Array.factory(DataType.OBJECT, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setObject(i, ((Complex) a.getObject(i)).sin());
- }
- } else {
- r = Array.factory(a.getDataType() == DataType.DOUBLE ? DataType.DOUBLE : DataType.FLOAT, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setDouble(i, Math.sin(a.getDouble(i)));
- }
- }
-
- return r;
- }
-
- /**
- * Cosine function
- *
- * @param a Array a
- * @return Result array
- */
- public static Array cos(Array a) {
- Array r;
- if (isComplex(a)) {
- r = Array.factory(DataType.OBJECT, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setObject(i, ((Complex) a.getObject(i)).cos());
- }
- } else {
- r = Array.factory(a.getDataType() == DataType.DOUBLE ? DataType.DOUBLE : DataType.FLOAT, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setDouble(i, Math.cos(a.getDouble(i)));
- }
- }
-
- return r;
- }
-
- /**
- * Tangent function
- *
- * @param a Array a
- * @return Result array
- */
- public static Array tan(Array a) {
- Array r;
- if (isComplex(a)) {
- r = Array.factory(DataType.OBJECT, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setObject(i, ((Complex) a.getObject(i)).tan());
- }
- } else {
- r = Array.factory(a.getDataType() == DataType.DOUBLE ? DataType.DOUBLE : DataType.FLOAT, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setDouble(i, Math.tan(a.getDouble(i)));
- }
- }
-
- return r;
- }
-
- /**
- * Arc sine function
- *
- * @param a Array a
- * @return Result array
- */
- public static Array asin(Array a) {
- Array r;
- if (isComplex(a)) {
- r = Array.factory(DataType.OBJECT, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setObject(i, ((Complex) a.getObject(i)).asin());
- }
- } else {
- r = Array.factory(a.getDataType() == DataType.DOUBLE ? DataType.DOUBLE : DataType.FLOAT, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setDouble(i, Math.asin(a.getDouble(i)));
- }
- }
-
- return r;
- }
-
- /**
- * Arc cosine function
- *
- * @param a Array a
- * @return Result array
- */
- public static Array acos(Array a) {
- Array r;
- if (isComplex(a)) {
- r = Array.factory(DataType.OBJECT, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setObject(i, ((Complex) a.getObject(i)).acos());
- }
- } else {
- r = Array.factory(a.getDataType() == DataType.DOUBLE ? DataType.DOUBLE : DataType.FLOAT, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setDouble(i, Math.acos(a.getDouble(i)));
- }
- }
-
- return r;
- }
-
- /**
- * Arc tangen function
- *
- * @param a Array a
- * @return Result array
- */
- public static Array atan(Array a) {
- Array r;
- if (isComplex(a)) {
- r = Array.factory(DataType.OBJECT, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setObject(i, ((Complex) a.getObject(i)).atan());
- }
- } else {
- r = Array.factory(a.getDataType() == DataType.DOUBLE ? DataType.DOUBLE : DataType.FLOAT, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setDouble(i, Math.atan(a.getDouble(i)));
- }
- }
-
- return r;
- }
-
- /**
- * Arc tangen function
- *
- * @param a Array a
- * @param b Array b
- * @return Result array
- */
- public static Array atan2(Array a, Array b) {
- Array r = Array.factory(a.getDataType() == DataType.DOUBLE ? DataType.DOUBLE : DataType.FLOAT, a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- r.setDouble(i, Math.atan2(a.getDouble(i), b.getDouble(i)));
- }
-
- return r;
- }
-
- /**
- * Convert cartesian to polar coordinate
- *
- * @param x X array
- * @param y Y array
- * @return Angle and radius
- */
- public static Array[] cartesianToPolar(Array x, Array y) {
- Array r = Array.factory(DataType.DOUBLE, x.getShape());
- Array B = Array.factory(DataType.DOUBLE, x.getShape());
- double[] rr;
- for (int i = 0; i < x.getSize(); i++) {
- rr = cartesianToPolar(x.getDouble(i), y.getDouble(i));
- r.setDouble(i, rr[1]);
- B.setDouble(i, rr[0]);
- }
-
- return new Array[]{B, r};
- }
-
- /**
- * Convert poar to cartesian coordinate
- *
- * @param r Radius
- * @param B Angle in radians
- * @return X and y in cartesian coordinate
- */
- public static Array[] polarToCartesian(Array B, Array r) {
- Array x = Array.factory(DataType.DOUBLE, r.getShape());
- Array y = Array.factory(DataType.DOUBLE, r.getShape());
- double[] rr;
- for (int i = 0; i < r.getSize(); i++) {
- rr = polarToCartesian(B.getDouble(i), r.getDouble(i));
- x.setDouble(i, rr[0]);
- y.setDouble(i, rr[1]);
- }
-
- return new Array[]{x, y};
- }
-
- /**
- * Convert cartesian to polar coordinate
- *
- * @param x X
- * @param y Y
- * @return Angle and radius
- */
- public static double[] cartesianToPolar(double x, double y) {
- double r; // Radius
- double B; // Angle in radians
- r = Math.hypot(x, y);
- if (y >= 0) {
- if (x == 0) {
- B = Math.PI / 2;// 90°
- } else {
- B = Math.asin(x / y);
- }
- } else if (x == 0) {
- B = 3 * Math.PI / 2;// 270°
- } else {
- B = Math.asin(x / y);
- }
- return new double[]{B, r};
- }
-
- /**
- * Convert poar to cartesian coordinate
- *
- * @param r Radius
- * @param B Angle in radians
- * @return X and y in cartesian coordinate
- */
- public static double[] polarToCartesian(double B, double r) {
- double x = Math.cos(B) * r;
- double y = Math.sin(B) * r;
-
- return new double[]{x, y};
- }
-
- //
- //
- /**
- * Copy array
- *
- * @param a Input array
- * @return Copied array
- */
- public static Array copy(Array a) {
- Array r = Array.factory(a.getDataType(), a.getShape());
- MAMath.copy(r, a);
- return r;
- }
-
- /**
- * Section array
- *
- * @param a Array a
- * @param origin Origin array
- * @param size Size array
- * @param stride Stride array
- * @return Result array
- * @throws InvalidRangeException
- */
- public static Array section(Array a, int[] origin, int[] size, int[] stride) throws InvalidRangeException {
- Array r = a.section(origin, size, stride);
- Array rr = Array.factory(r.getDataType(), r.getShape());
- MAMath.copy(rr, r);
- return rr;
- }
-
- /**
- * Section array
- *
- * @param a Array a
- * @param ranges Ranges
- * @return Result array
- * @throws InvalidRangeException
- */
- public static Array section(Array a, List ranges) throws InvalidRangeException {
- Array r = a.section(ranges);
- Array rr = Array.factory(r.getDataType(), r.getShape());
- MAMath.copy(rr, r);
- return rr;
- }
-
- /**
- * Take elements from an array along an axis.
- *
- * @param a The array
- * @param ranges The indices of the values to extract.
- * @return The returned array has the same type as a.
- */
- public static Array take(Array a, List
- //
- /**
- * Get minimum value
- *
- * @param a Array a
- * @return Minimum value
- */
- public static double getMinimum(Array a) {
- IndexIterator iter = a.getIndexIterator();
- double min = 1.7976931348623157E+308D;
- while (iter.hasNext()) {
- double val = iter.getDoubleNext();
- if (!Double.isNaN(val)) {
- if (val < min) {
- min = val;
- }
- }
- }
- if (min == 1.7976931348623157E+308D) {
- return Double.NaN;
- } else {
- return min;
- }
- }
-
- /**
- * Get maximum value
- *
- * @param a Array a
- * @return Maximum value
- */
- public static double getMaximum(Array a) {
- IndexIterator iter = a.getIndexIterator();
- double max = -1.797693134862316E+307D;
- while (iter.hasNext()) {
- double val = iter.getDoubleNext();
- if (!Double.isNaN(val)) {
- if (val > max) {
- max = val;
- }
- }
- }
- if (max == -1.797693134862316E+307D) {
- return Double.NaN;
- } else {
- return max;
- }
- }
-
- /**
- * Get minimum value
- *
- * @param a Array a
- * @param missingv Missing value
- * @return Minimum value
- */
- public static double getMinimum(Array a, double missingv) {
- IndexIterator iter = a.getIndexIterator();
- double min = 1.7976931348623157E+308D;
- while (iter.hasNext()) {
- double val = iter.getDoubleNext();
- if (!MIMath.doubleEquals(val, missingv)) {
- if (val < min) {
- min = val;
- }
- }
- }
- return min;
- }
-
- /**
- * Get maximum value
- *
- * @param a Array a
- * @param missingv Missing value
- * @return Maximum value
- */
- public static double getMaximum(Array a, double missingv) {
- IndexIterator iter = a.getIndexIterator();
- double max = -1.797693134862316E+307D;
- while (iter.hasNext()) {
- double val = iter.getDoubleNext();
- if (!MIMath.doubleEquals(val, missingv)) {
- if (val > max) {
- max = val;
- }
- }
- }
- return max;
- }
-
- /**
- * Compute minimum value of an array
- *
- * @param a Array a
- * @return Minimum value
- */
- public static double min(Array a) {
- double min = 1.7976931348623157E+308D;
- double v;
- IndexIterator ii = a.getIndexIterator();
- while (ii.hasNext()) {
- v = ii.getDoubleNext();
- if (!Double.isNaN(v)) {
- if (v < min) {
- min = v;
- }
- }
- }
- if (min == 1.7976931348623157E+308D) {
- return Double.NaN;
- } else {
- return min;
- }
- }
-
- /**
- * Compute minimum value of an array along an axis (dimension)
- *
- * @param a Array a
- * @param axis Axis
- * @return Minimum value array
- * @throws org.meteoinfo.ndarray.InvalidRangeException
- */
- public static Array min(Array a, int axis) throws InvalidRangeException {
- int[] dataShape = a.getShape();
- int[] shape = new int[dataShape.length - 1];
- int idx;
- for (int i = 0; i < dataShape.length; i++) {
- idx = i;
- if (idx == axis) {
- continue;
- } else if (idx > axis) {
- idx -= 1;
- }
- shape[idx] = dataShape[i];
- }
- Array r = Array.factory(DataType.DOUBLE, shape);
- double s;
- Index indexr = r.getIndex();
- int[] current;
- for (int i = 0; i < r.getSize(); i++) {
- current = indexr.getCurrentCounter();
- List ranges = new ArrayList<>();
- for (int j = 0; j < dataShape.length; j++) {
- if (j == axis) {
- ranges.add(new Range(0, dataShape[j] - 1, 1));
- } else {
- idx = j;
- if (idx > axis) {
- idx -= 1;
- }
- ranges.add(new Range(current[idx], current[idx], 1));
- }
- }
- s = min(a, ranges);
- r.setDouble(i, s);
- indexr.incr();
- }
-
- return r;
- }
-
- /**
- * Compute minimum value of an array
- *
- * @param a Array a
- * @param ranges Range list
- * @return Minimum value
- * @throws org.meteoinfo.ndarray.InvalidRangeException
- */
- public static double min(Array a, List ranges) throws InvalidRangeException {
- double min = 1.7976931348623157E+308D;
- double v;
- IndexIterator ii = a.getRangeIterator(ranges);
- while (ii.hasNext()) {
- v = ii.getDoubleNext();
- if (!Double.isNaN(v)) {
- if (v < min) {
- min = v;
- }
- }
- }
- if (min == 1.7976931348623157E+308D) {
- return Double.NaN;
- } else {
- return min;
- }
- }
-
- /**
- * Compute maximum value of an array
- *
- * @param a Array a
- * @return Maximum value
- */
- public static double max(Array a) {
- double max = -1.797693134862316E+307D;
- double v;
- IndexIterator ii = a.getIndexIterator();
- while (ii.hasNext()) {
- v = ii.getDoubleNext();
- if (!Double.isNaN(v)) {
- if (v > max) {
- max = v;
- }
- }
- }
- if (max == -1.797693134862316E+307D) {
- return Double.NaN;
- } else {
- return max;
- }
- }
-
- /**
- * Compute maximum value of an array along an axis (dimension)
- *
- * @param a Array a
- * @param axis Axis
- * @return Maximum value array
- * @throws org.meteoinfo.ndarray.InvalidRangeException
- */
- public static Array max(Array a, int axis) throws InvalidRangeException {
- int[] dataShape = a.getShape();
- int[] shape = new int[dataShape.length - 1];
- int idx;
- for (int i = 0; i < dataShape.length; i++) {
- idx = i;
- if (idx == axis) {
- continue;
- } else if (idx > axis) {
- idx -= 1;
- }
- shape[idx] = dataShape[i];
- }
- Array r = Array.factory(DataType.DOUBLE, shape);
- double s;
- Index indexr = r.getIndex();
- int[] current;
- for (int i = 0; i < r.getSize(); i++) {
- current = indexr.getCurrentCounter();
- List ranges = new ArrayList<>();
- for (int j = 0; j < dataShape.length; j++) {
- if (j == axis) {
- ranges.add(new Range(0, dataShape[j] - 1, 1));
- } else {
- idx = j;
- if (idx > axis) {
- idx -= 1;
- }
- ranges.add(new Range(current[idx], current[idx], 1));
- }
- }
- s = max(a, ranges);
- r.setDouble(i, s);
- indexr.incr();
- }
-
- return r;
- }
-
- /**
- * Compute maximum value of an array
- *
- * @param a Array a
- * @param ranges Range list
- * @return Maximum value
- * @throws org.meteoinfo.ndarray.InvalidRangeException
- */
- public static double max(Array a, List ranges) throws InvalidRangeException {
- double max = -1.797693134862316E+307D;
- double v;
- IndexIterator ii = a.getRangeIterator(ranges);
- while (ii.hasNext()) {
- v = ii.getDoubleNext();
- if (!Double.isNaN(v)) {
- if (v > max) {
- max = v;
- }
- }
- }
- if (max == -1.797693134862316E+307D) {
- return Double.NaN;
- } else {
- return max;
- }
- }
-
- /**
- * Compute sum value of an array along an axis (dimension)
- *
- * @param a Array a
- * @param axis Axis
- * @return Sum value array
- * @throws org.meteoinfo.ndarray.InvalidRangeException
- */
- public static Array sum(Array a, int axis) throws InvalidRangeException {
- int[] dataShape = a.getShape();
- int[] shape = new int[dataShape.length - 1];
- int idx;
- for (int i = 0; i < dataShape.length; i++) {
- idx = i;
- if (idx == axis) {
- continue;
- } else if (idx > axis) {
- idx -= 1;
- }
- shape[idx] = dataShape[i];
- }
- Array r = Array.factory(DataType.DOUBLE, shape);
- double s;
- Index indexr = r.getIndex();
- int[] current;
- for (int i = 0; i < r.getSize(); i++) {
- current = indexr.getCurrentCounter();
- List ranges = new ArrayList<>();
- for (int j = 0; j < dataShape.length; j++) {
- if (j == axis) {
- ranges.add(new Range(0, dataShape[j] - 1, 1));
- } else {
- idx = j;
- if (idx > axis) {
- idx -= 1;
- }
- ranges.add(new Range(current[idx], current[idx], 1));
- }
- }
- s = sum(a, ranges);
- r.setDouble(i, s);
- indexr.incr();
- }
-
- return r;
- }
-
- /**
- * Compute sum value of an array
- *
- * @param a Array a
- * @param ranges Range list
- * @return Sum value
- * @throws org.meteoinfo.ndarray.InvalidRangeException
- */
- public static double sum(Array a, List ranges) throws InvalidRangeException {
- double s = 0.0, v;
- int n = 0;
- IndexIterator ii = a.getRangeIterator(ranges);
- while (ii.hasNext()) {
- v = ii.getDoubleNext();
- if (!Double.isNaN(v)) {
- s += v;
- n += 1;
- }
- }
- if (n == 0) {
- s = Double.NaN;
- }
- return s;
- }
-
- /**
- * Compute the sum arry from a list of arrays
- *
- * @param alist list of arrays
- * @return Sum array
- */
- public static Array sum(List alist) {
- Array r = Array.factory(DataType.DOUBLE, alist.get(0).getShape());
- double sum, v;
- int n;
- for (int i = 0; i < r.getSize(); i++) {
- sum = 0.0;
- n = 0;
- for (Array a : alist) {
- v = a.getDouble(i);
- if (!Double.isNaN(v)) {
- sum += v;
- n += 1;
- }
- }
- if (n == 0) {
- sum = Double.NaN;
- }
- r.setDouble(i, sum);
- }
-
- return r;
- }
-
- /**
- * Summarize array
- *
- * @param a Array a
- * @return Summarize value
- */
- public static double sum(Array a) {
- double sum = 0.0D;
- double v;
- int n = 0;
- IndexIterator iterA = a.getIndexIterator();
- while (iterA.hasNext()) {
- v = iterA.getDoubleNext();
- if (!Double.isNaN(v)) {
- sum += v;
- n += 1;
- }
- }
- if (n == 0) {
- return Double.NaN;
- } else {
- return sum;
- }
- }
-
- /**
- * Summarize array skip missing value
- *
- * @param a Array a
- * @param missingValue Missing value
- * @return Summarize value
- */
- public static double sum(Array a, double missingValue) {
- double sum = 0.0D;
- IndexIterator iterA = a.getIndexIterator();
- while (iterA.hasNext()) {
- double val = iterA.getDoubleNext();
- if ((val != missingValue) && (!Double.isNaN(val))) {
- sum += val;
- }
- }
- return sum;
- }
-
- /**
- * Return the cumulative sum of the elements along a given axis.
- *
- * @param a Array a
- * @param axis Axis
- * @return Sum value array
- * @throws org.meteoinfo.ndarray.InvalidRangeException
- */
- public static Array cumsum(Array a, int axis) throws InvalidRangeException {
- int[] dataShape = a.getShape();
- int[] shape = new int[dataShape.length - 1];
- int idx;
- for (int i = 0; i < dataShape.length; i++) {
- idx = i;
- if (idx == axis) {
- continue;
- } else if (idx > axis) {
- idx -= 1;
- }
- shape[idx] = dataShape[i];
- }
- Array r = Array.factory(a.getDataType(), shape);
- Array rr = Array.factory(a.getDataType(), dataShape);
- List s;
- Index indexr = r.getIndex();
- Index indexrr = rr.getIndex();
- int[] current, currentrr = indexrr.getCurrentCounter();
- for (int i = 0; i < r.getSize(); i++) {
- current = indexr.getCurrentCounter();
- List ranges = new ArrayList<>();
- for (int j = 0; j < dataShape.length; j++) {
- if (j == axis) {
- ranges.add(new Range(0, dataShape[j] - 1, 1));
- } else {
- idx = j;
- if (idx > axis) {
- idx -= 1;
- }
- ranges.add(new Range(current[idx], current[idx], 1));
- currentrr[j] = current[idx];
- }
- }
- s = cumsum(a, ranges);
- for (int j = 0; j < s.size(); j++) {
- currentrr[axis] = j;
- rr.setDouble(indexrr.set(currentrr), s.get(j));
- }
- indexr.incr();
- }
- r = null;
-
- return rr;
- }
-
- /**
- * Compute cumulative sum value of an array
- *
- * @param a Array a
- * @param ranges Range list
- * @return Sum value
- * @throws org.meteoinfo.ndarray.InvalidRangeException
- */
- public static List cumsum(Array a, List ranges) throws InvalidRangeException {
- double s = 0.0, v;
- IndexIterator ii = a.getRangeIterator(ranges);
- List r = new ArrayList<>();
- while (ii.hasNext()) {
- v = ii.getDoubleNext();
- s += v;
- r.add(s);
- }
-
- return r;
- }
-
- /**
- * Produce array
- *
- * @param a Array a
- * @return Produce value
- */
- public static double prodDouble(Array a) {
- double prod = 1.0D;
- double v;
- IndexIterator iterA = a.getIndexIterator();
- while (iterA.hasNext()) {
- v = iterA.getDoubleNext();
- if (!Double.isNaN(v)) {
- prod *= v;
- }
- }
- return prod;
- }
-
- /**
- * Average array
- *
- * @param a Array a
- * @return Average value
- */
- public static double aveDouble(Array a) {
- double sum = 0.0D;
- double v;
- int n = 0;
- IndexIterator iterA = a.getIndexIterator();
- while (iterA.hasNext()) {
- v = iterA.getDoubleNext();
- if (!Double.isNaN(v)) {
- sum += v;
- n += 1;
- }
- }
- if (n == 0) {
- return Double.NaN;
- } else {
- return sum / n;
- }
- }
-
- /**
- * Average array skip missing value
- *
- * @param a Array a
- * @param missingValue Missing value
- * @return Average value
- */
- public static double aveDouble(Array a, double missingValue) {
- double sum = 0.0D;
- int n = 0;
- IndexIterator iterA = a.getIndexIterator();
- while (iterA.hasNext()) {
- double val = iterA.getDoubleNext();
- if ((val != missingValue) && (!Double.isNaN(val))) {
- sum += val;
- n += 1;
- }
- }
- return sum / n;
- }
-
- /**
- * Get the index of the minimum value into the flattened array.
- *
- * @param a Array a
- * @return Minimum value index
- * @throws org.meteoinfo.ndarray.InvalidRangeException
- */
- public static int argMin(Array a) throws InvalidRangeException {
- double min = Double.MAX_VALUE, v;
- int idx = 0;
- IndexIterator iterator = a.getIndexIterator();
- int i = 0;
- while (iterator.hasNext()) {
- v = iterator.getDoubleNext();
- if (!Double.isNaN(v)) {
- if (min > v) {
- min = v;
- idx = i;
- }
- }
- i += 1;
- }
- return idx;
- }
-
- /**
- * Get the indices of the minimum values along an axis.
- *
- * @param a Array a
- * @param axis Axis
- * @return Indices
- * @throws org.meteoinfo.ndarray.InvalidRangeException
- */
- public static Array argMin(Array a, int axis) throws InvalidRangeException {
- int[] dataShape = a.getShape();
- int[] shape = new int[dataShape.length - 1];
- int idx;
- for (int i = 0; i < dataShape.length; i++) {
- idx = i;
- if (idx == axis) {
- continue;
- } else if (idx > axis) {
- idx -= 1;
- }
- shape[idx] = dataShape[i];
- }
- Array r = Array.factory(DataType.INT, shape);
- Index indexr = r.getIndex();
- int[] current;
- for (int i = 0; i < r.getSize(); i++) {
- current = indexr.getCurrentCounter();
- List ranges = new ArrayList<>();
- for (int j = 0; j < dataShape.length; j++) {
- if (j == axis) {
- ranges.add(new Range(0, dataShape[j] - 1, 1));
- } else {
- idx = j;
- if (idx > axis) {
- idx -= 1;
- }
- ranges.add(new Range(current[idx], current[idx], 1));
- }
- }
- idx = argMin(a.section(ranges));
- r.setInt(i, idx);
- indexr.incr();
- }
-
- return r;
- }
-
- /**
- * Get the index of the maximum value into the flattened array.
- *
- * @param a Array a
- * @return Maximum value index
- * @throws org.meteoinfo.ndarray.InvalidRangeException
- */
- public static int argMax(Array a) throws InvalidRangeException {
- double max = Double.MIN_VALUE, v;
- int idx = 0;
- IndexIterator iterator = a.getIndexIterator();
- int i = 0;
- while (iterator.hasNext()) {
- v = iterator.getDoubleNext();
- if (!Double.isNaN(v)) {
- if (max < v) {
- max = v;
- idx = i;
- }
- }
- i += 1;
- }
- return idx;
- }
-
- /**
- * Get the indices of the maximum values along an axis.
- *
- * @param a Array a
- * @param axis Axis
- * @return Indices
- * @throws org.meteoinfo.ndarray.InvalidRangeException
- */
- public static Array argMax(Array a, int axis) throws InvalidRangeException {
- int[] dataShape = a.getShape();
- int[] shape = new int[dataShape.length - 1];
- int idx;
- for (int i = 0; i < dataShape.length; i++) {
- idx = i;
- if (idx == axis) {
- continue;
- } else if (idx > axis) {
- idx -= 1;
- }
- shape[idx] = dataShape[i];
- }
- Array r = Array.factory(DataType.INT, shape);
- Index indexr = r.getIndex();
- int[] current;
- for (int i = 0; i < r.getSize(); i++) {
- current = indexr.getCurrentCounter();
- List ranges = new ArrayList<>();
- for (int j = 0; j < dataShape.length; j++) {
- if (j == axis) {
- ranges.add(new Range(0, dataShape[j] - 1, 1));
- } else {
- idx = j;
- if (idx > axis) {
- idx -= 1;
- }
- ranges.add(new Range(current[idx], current[idx], 1));
- }
- }
- idx = argMax(a.section(ranges));
- r.setInt(i, idx);
- indexr.incr();
- }
-
- return r;
- }
-
- /**
- * Compute mean value of an array along an axis (dimension)
- *
- * @param a Array a
- * @param axis Axis
- * @return Mean value array
- * @throws org.meteoinfo.ndarray.InvalidRangeException
- */
- public static Array mean(Array a, int axis) throws InvalidRangeException {
- int[] dataShape = a.getShape();
- int[] shape = new int[dataShape.length - 1];
- int idx;
- for (int i = 0; i < dataShape.length; i++) {
- idx = i;
- if (idx == axis) {
- continue;
- } else if (idx > axis) {
- idx -= 1;
- }
- shape[idx] = dataShape[i];
- }
- Array r = Array.factory(DataType.DOUBLE, shape);
- double mean;
- Index indexr = r.getIndex();
- int[] current;
- for (int i = 0; i < r.getSize(); i++) {
- current = indexr.getCurrentCounter();
- List ranges = new ArrayList<>();
- for (int j = 0; j < dataShape.length; j++) {
- if (j == axis) {
- ranges.add(new Range(0, dataShape[j] - 1, 1));
- } else {
- idx = j;
- if (idx > axis) {
- idx -= 1;
- }
- ranges.add(new Range(current[idx], current[idx], 1));
- }
- }
- mean = mean(a, ranges);
- r.setDouble(i, mean);
- indexr.incr();
- }
-
- return r;
- }
-
- /**
- * Compute mean value of an array
- *
- * @param a Array a
- * @return Mean value
- */
- public static double mean(Array a) {
- double mean = 0.0, v;
- int n = 0;
- for (int i = 0; i < a.getSize(); i++) {
- v = a.getDouble(i);
- if (!Double.isNaN(v)) {
- mean += v;
- n += 1;
- }
- }
- if (n > 0) {
- mean = mean / n;
- } else {
- mean = Double.NaN;
- }
- return mean;
- }
-
- /**
- * Compute the arithmetic mean arry from a list of arrays
- *
- * @param alist list of arrays
- * @return Mean array
- */
- public static Array mean(List alist) {
- Array r = Array.factory(DataType.DOUBLE, alist.get(0).getShape());
- double sum, v;
- int n;
- for (int i = 0; i < r.getSize(); i++) {
- sum = 0.0;
- n = 0;
- for (Array a : alist) {
- v = a.getDouble(i);
- if (!Double.isNaN(v)) {
- sum += v;
- n += 1;
- }
- }
- if (n > 0) {
- sum = sum / n;
- } else {
- sum = Double.NaN;
- }
- r.setDouble(i, sum);
- }
-
- return r;
- }
-
- /**
- * Compute mean value of an array
- *
- * @param a Array a
- * @param ranges Range list
- * @return Mean value
- * @throws org.meteoinfo.ndarray.InvalidRangeException
- */
- public static double mean(Array a, List ranges) throws InvalidRangeException {
- double mean = 0.0, v;
- int n = 0;
- IndexIterator ii = a.getRangeIterator(ranges);
- while (ii.hasNext()) {
- v = ii.getDoubleNext();
- if (!Double.isNaN(v)) {
- mean += v;
- n += 1;
- }
- }
- if (n > 0) {
- mean = mean / n;
- } else {
- mean = Double.NaN;
- }
- return mean;
- }
-
- /**
- * Compute standard deviation value of an array along an axis (dimension)
- *
- * @param a Array a
- * @param axis Axis
- * @return Standard deviation value array
- * @throws org.meteoinfo.ndarray.InvalidRangeException
- */
- public static Array std(Array a, int axis) throws InvalidRangeException {
- int[] dataShape = a.getShape();
- int[] shape = new int[dataShape.length - 1];
- int idx;
- for (int i = 0; i < dataShape.length; i++) {
- idx = i;
- if (idx == axis) {
- continue;
- } else if (idx > axis) {
- idx -= 1;
- }
- shape[idx] = dataShape[i];
- }
- Array r = Array.factory(DataType.DOUBLE, shape);
- double mean;
- Index indexr = r.getIndex();
- int[] current;
- for (int i = 0; i < r.getSize(); i++) {
- current = indexr.getCurrentCounter();
- List ranges = new ArrayList<>();
- for (int j = 0; j < dataShape.length; j++) {
- if (j == axis) {
- ranges.add(new Range(0, dataShape[j] - 1, 1));
- } else {
- idx = j;
- if (idx > axis) {
- idx -= 1;
- }
- ranges.add(new Range(current[idx], current[idx], 1));
- }
- }
- mean = std(a, ranges);
- r.setDouble(i, mean);
- indexr.incr();
- }
-
- return r;
- }
-
- /**
- * Compute standard deviation value of an array
- *
- * @param a Array a
- * @param ranges Range list
- * @return Standard deviation value
- * @throws org.meteoinfo.ndarray.InvalidRangeException
- */
- public static double std(Array a, List ranges) throws InvalidRangeException {
- double mean = 0.0, v;
- int n = 0;
- IndexIterator ii = a.getRangeIterator(ranges);
- while (ii.hasNext()) {
- v = ii.getDoubleNext();
- if (!Double.isNaN(v)) {
- mean += v;
- n += 1;
- }
- }
- if (n > 0) {
- mean = mean / n;
- } else {
- mean = Double.NaN;
- }
-
- if (Double.isNaN(mean)) {
- return Double.NaN;
- }
-
- double sum = 0;
- ii = a.getRangeIterator(ranges);
- while (ii.hasNext()) {
- v = ii.getDoubleNext();
- if (!Double.isNaN(v)) {
- sum += Math.pow((v - mean), 2);
- }
- }
- sum = Math.sqrt(sum / n);
-
- return sum;
- }
-
- /**
- * Compute standard deviation value of an array
- *
- * @param a Array a
- * @return Standard deviation value
- * @throws org.meteoinfo.ndarray.InvalidRangeException
- */
- public static double std(Array a) throws InvalidRangeException {
- double mean = 0.0, v;
- int n = 0;
- IndexIterator ii = a.getIndexIterator();
- while (ii.hasNext()) {
- v = ii.getDoubleNext();
- if (!Double.isNaN(v)) {
- mean += v;
- n += 1;
- }
- }
- if (n > 0) {
- mean = mean / n;
- } else {
- mean = Double.NaN;
- return mean;
- }
-
- double sum = 0;
- ii = a.getIndexIterator();
- while (ii.hasNext()) {
- v = ii.getDoubleNext();
- if (!Double.isNaN(v)) {
- sum += Math.pow((v - mean), 2);
- }
- }
- sum = Math.sqrt(sum / n);
-
- return sum;
- }
-
- /**
- * Compute variance value of an array along an axis (dimension)
- *
- * @param a Array a
- * @param axis Axis
- * @return Variance value array
- * @throws org.meteoinfo.ndarray.InvalidRangeException
- */
- public static Array var(Array a, int axis) throws InvalidRangeException {
- int[] dataShape = a.getShape();
- int[] shape = new int[dataShape.length - 1];
- int idx;
- for (int i = 0; i < dataShape.length; i++) {
- idx = i;
- if (idx == axis) {
- continue;
- } else if (idx > axis) {
- idx -= 1;
- }
- shape[idx] = dataShape[i];
- }
- Array r = Array.factory(DataType.DOUBLE, shape);
- double mean;
- Index indexr = r.getIndex();
- int[] current;
- for (int i = 0; i < r.getSize(); i++) {
- current = indexr.getCurrentCounter();
- List ranges = new ArrayList<>();
- for (int j = 0; j < dataShape.length; j++) {
- if (j == axis) {
- ranges.add(new Range(0, dataShape[j] - 1, 1));
- } else {
- idx = j;
- if (idx > axis) {
- idx -= 1;
- }
- ranges.add(new Range(current[idx], current[idx], 1));
- }
- }
- mean = std(a, ranges);
- r.setDouble(i, mean);
- indexr.incr();
- }
-
- return r;
- }
-
- /**
- * Compute variance value of an array
- *
- * @param a Array a
- * @param ranges Range list
- * @return Variance value
- * @throws org.meteoinfo.ndarray.InvalidRangeException
- */
- public static double var(Array a, List ranges) throws InvalidRangeException {
- double mean = 0.0, v;
- int n = 0;
- IndexIterator ii = a.getRangeIterator(ranges);
- while (ii.hasNext()) {
- v = ii.getDoubleNext();
- if (!Double.isNaN(v)) {
- mean += v;
- n += 1;
- }
- }
- if (n > 0) {
- mean = mean / n;
- } else {
- mean = Double.NaN;
- }
-
- if (Double.isNaN(mean)) {
- return Double.NaN;
- }
-
- double sum = 0;
- ii = a.getRangeIterator(ranges);
- while (ii.hasNext()) {
- v = ii.getDoubleNext();
- if (!Double.isNaN(v)) {
- sum += Math.pow((v - mean), 2);
- }
- }
- sum = sum / n;
-
- return sum;
- }
-
- /**
- * Compute median value of an array along an axis (dimension)
- *
- * @param a Array a
- * @param axis Axis
- * @return Median value array
- * @throws org.meteoinfo.ndarray.InvalidRangeException
- */
- public static Array median(Array a, int axis) throws InvalidRangeException {
- int[] dataShape = a.getShape();
- int[] shape = new int[dataShape.length - 1];
- int idx;
- for (int i = 0; i < dataShape.length; i++) {
- idx = i;
- if (idx == axis) {
- continue;
- } else if (idx > axis) {
- idx -= 1;
- }
- shape[idx] = dataShape[i];
- }
- Array r = Array.factory(DataType.DOUBLE, shape);
- double mean;
- Index indexr = r.getIndex();
- int[] current;
- for (int i = 0; i < r.getSize(); i++) {
- current = indexr.getCurrentCounter();
- List ranges = new ArrayList<>();
- for (int j = 0; j < dataShape.length; j++) {
- if (j == axis) {
- ranges.add(new Range(0, dataShape[j] - 1, 1));
- } else {
- idx = j;
- if (idx > axis) {
- idx -= 1;
- }
- ranges.add(new Range(current[idx], current[idx], 1));
- }
- }
- mean = median(a, ranges);
- r.setDouble(i, mean);
- indexr.incr();
- }
-
- return r;
- }
-
- /**
- * Compute median value of an array
- *
- * @param a Array a
- * @param ranges Range list
- * @return Median value
- * @throws org.meteoinfo.ndarray.InvalidRangeException
- */
- public static double median(Array a, List ranges) throws InvalidRangeException {
- Array b = a.section(ranges);
- double median = Statistics.quantile(b, 2);
- return median;
- }
-
- /**
- * Compute median value of an array
- *
- * @param a Array a
- * @return Median value
- */
- public static double median(Array a) {
- return Statistics.quantile(a, 2);
- }
-
- /**
- * Element-wise maximum of array elements.
- *
- * @param x1 Array 1
- * @param x2 Array 2
- * @return The maximum of x1 and x2, element-wise.
- */
- public static Array maximum(Array x1, Array x2) {
- DataType dt = commonType(x1.getDataType(), x2.getDataType());
- Array r = Array.factory(dt, x1.getShape());
- for (int i = 0; i < r.getSize(); i++) {
- r.setObject(i, Math.max(x1.getDouble(i), x2.getDouble(i)));
- }
-
- return r;
- }
-
- /**
- * Element-wise maximum of array elements, ignores NaNs.
- *
- * @param x1 Array 1
- * @param x2 Array 2
- * @return The maximum of x1 and x2, element-wise.
- */
- public static Array fmax(Array x1, Array x2) {
- DataType dt = commonType(x1.getDataType(), x2.getDataType());
- Array r = Array.factory(dt, x1.getShape());
- for (int i = 0; i < r.getSize(); i++) {
- if (Double.isNaN(x1.getDouble(i))) {
- r.setObject(i, x2.getDouble(i));
- } else if (Double.isNaN(x2.getDouble(i))) {
- r.setObject(i, x1.getDouble(i));
- } else {
- r.setObject(i, Math.max(x1.getDouble(i), x2.getDouble(i)));
- }
- }
-
- return r;
- }
-
- /**
- * Element-wise minimum of array elements.
- *
- * @param x1 Array 1
- * @param x2 Array 2
- * @return The minimum of x1 and x2, element-wise.
- */
- public static Array minimum(Array x1, Array x2) {
- DataType dt = commonType(x1.getDataType(), x2.getDataType());
- Array r = Array.factory(dt, x1.getShape());
- for (int i = 0; i < r.getSize(); i++) {
- r.setObject(i, Math.min(x1.getDouble(i), x2.getDouble(i)));
- }
-
- return r;
- }
-
- /**
- * Element-wise minimum of array elements, ignores NaNs.
- *
- * @param x1 Array 1
- * @param x2 Array 2
- * @return The minimum of x1 and x2, element-wise.
- */
- public static Array fmin(Array x1, Array x2) {
- DataType dt = commonType(x1.getDataType(), x2.getDataType());
- Array r = Array.factory(dt, x1.getShape());
- for (int i = 0; i < r.getSize(); i++) {
- if (Double.isNaN(x1.getDouble(i))) {
- r.setObject(i, x2.getDouble(i));
- } else if (Double.isNaN(x2.getDouble(i))) {
- r.setObject(i, x1.getDouble(i));
- } else {
- r.setObject(i, Math.min(x1.getDouble(i), x2.getDouble(i)));
- }
- }
-
- return r;
- }
-
- /**
- * Moving average function
- *
- * @param x The data array
- * @param window Size of moving window
- * @param center Set the data in center moving window
- * @return Moving averaged array
- */
- public static Array rolling_mean(Array x, int window, boolean center) {
- int n = (int) x.getSize();
- Array r = Array.factory(DataType.DOUBLE, new int[]{n});
- double v, vv;
- int dn;
- if (center) {
- int halfn = (window - 1) / 2;
- int idx;
- for (int i = 0; i < n; i++) {
- v = 0;
- dn = 0;
- for (int j = 0; j < window; j++) {
- if (j < halfn) {
- idx = i - j;
- } else if (j == halfn) {
- idx = i;
- } else {
- idx = i + (j - halfn);
- }
- if (idx < 0 || idx >= n) {
- break;
- }
- vv = x.getDouble(idx);
- if (!Double.isNaN(vv)) {
- v += vv;
- dn += 1;
- }
- }
- if (dn > 0) {
- v = v / dn;
- } else {
- v = Double.NaN;
- }
- r.setDouble(i, v);
- }
- } else {
- for (int i = 0; i < n; i++) {
- v = 0;
- dn = 0;
- for (int j = 0; j < window; j++) {
- if (i - j < 0) {
- break;
- }
- vv = x.getDouble(i - j);
- if (!Double.isNaN(vv)) {
- v += vv;
- dn += 1;
- }
- }
- if (dn > 0) {
- v = v / dn;
- } else {
- v = Double.NaN;
- }
- r.setDouble(i, v);
- }
- }
-
- return r;
- }
-
- //
- //
- /**
- * Set missing value to NaN
- *
- * @param a Array a
- * @param missingv Missing value
- */
- public static void missingToNaN(Array a, Number missingv) {
- if (!a.getDataType().isNumeric()) {
- return;
- }
-
- IndexIterator iterA = a.getIndexIterator();
- switch (a.getDataType()) {
- case INT:
- case FLOAT:
- while (iterA.hasNext()) {
- float val = iterA.getFloatNext();
- if (val == missingv.floatValue()) {
- iterA.setFloatCurrent(Float.NaN);
- }
- }
- default:
- while (iterA.hasNext()) {
- double val = iterA.getDoubleNext();
- if (MIMath.doubleEquals(val, missingv.doubleValue())) {
- iterA.setDoubleCurrent(Double.NaN);
- }
- }
- }
- }
-
- /**
- * Set value
- *
- * @param a Array a
- * @param b Array b - 0/1 data
- * @param value Value
- */
- public static void setValue(Array a, Array b, Number value) {
- if (b.getDataType() == DataType.BOOLEAN) {
- for (int i = 0; i < a.getSize(); i++) {
- if (b.getBoolean(i)) {
- a.setObject(i, value);
- }
- }
- } else {
- for (int i = 0; i < a.getSize(); i++) {
- if (b.getInt(i) == 1) {
- a.setObject(i, value);
- }
- }
- }
- }
-
- /**
- * Set value
- *
- * @param a Array a
- * @param b Array b - 0/1 data
- * @param value Value array
- */
- public static void setValue(Array a, Array b, Array value) {
- if (b.getDataType() == DataType.BOOLEAN) {
- for (int i = 0; i < a.getSize(); i++) {
- if (b.getBoolean(i)) {
- a.setObject(i, value.getObject(i));
- }
- }
- } else {
- for (int i = 0; i < a.getSize(); i++) {
- if (b.getInt(i) == 1) {
- a.setObject(i, value.getObject(i));
- }
- }
- }
- }
-
- /**
- * As number list
- *
- * @param a Array a
- * @return Result number list
- */
- public static List asList(Array a) {
- IndexIterator iterA = a.getIndexIterator();
- List r = new ArrayList<>();
- switch (a.getDataType()) {
- case SHORT:
- case INT:
- while (iterA.hasNext()) {
- r.add(iterA.getIntNext());
- }
- break;
- case FLOAT:
- while (iterA.hasNext()) {
- r.add(iterA.getFloatNext());
- }
- break;
- case DOUBLE:
- while (iterA.hasNext()) {
- r.add(iterA.getDoubleNext());
- }
- break;
- case BOOLEAN:
- while (iterA.hasNext()) {
- r.add(iterA.getBooleanNext());
- }
- break;
- case OBJECT:
- while (iterA.hasNext()) {
- r.add(iterA.getObjectNext());
- }
- break;
- }
- return r;
- }
-
- /**
- * Get wind direction and wind speed from U/V
- *
- * @param u U component
- * @param v V component
- * @return Wind direction and wind speed
- */
- public static Array[] uv2ds(Array u, Array v) {
- Array windSpeed = ArrayMath.sqrt(ArrayMath.add(ArrayMath.mul(u, u), ArrayMath.mul(v, v)));
- Array windDir = Array.factory(windSpeed.getDataType(), windSpeed.getShape());
- double ws, wd, U, V;
- for (int i = 0; i < windSpeed.getSize(); i++) {
- U = u.getDouble(i);
- V = v.getDouble(i);
- if (Double.isNaN(U) || Double.isNaN(V)) {
- windDir.setDouble(i, Double.NaN);
- continue;
- }
- ws = windSpeed.getDouble(i);
- if (ws == 0) {
- wd = 0;
- } else {
- wd = Math.asin(U / ws) * 180 / Math.PI;
- if (U <= 0 && V < 0) {
- wd = 180.0 - wd;
- } else if (U > 0 && V < 0) {
- wd = 180.0 - wd;
- } else if (U < 0 && V > 0) {
- wd = 360.0 + wd;
- }
- wd += 180;
- if (wd >= 360) {
- wd -= 360;
- }
- }
- windDir.setDouble(i, wd);
- }
-
- return new Array[]{windDir, windSpeed};
- }
-
- /**
- * Get wind direction and wind speed from U/V
- *
- * @param u U component
- * @param v V component
- * @return Wind direction and wind speed
- */
- public static double[] uv2ds(double u, double v) {
- double ws = Math.sqrt(u * u + v * v);
- double wd;
- if (ws == 0) {
- wd = 0;
- } else {
- wd = Math.asin(u / ws) * 180 / Math.PI;
- if (u <= 0 && v < 0) {
- wd = 180.0 - wd;
- } else if (u > 0 && v < 0) {
- wd = 180.0 - wd;
- } else if (u < 0 && v > 0) {
- wd = 360.0 + wd;
- }
- wd += 180;
- if (wd >= 360) {
- wd -= 360;
- }
- }
-
- return new double[]{wd, ws};
- }
-
- /**
- * Get wind U/V components from wind direction and speed
- *
- * @param windDir Wind direction
- * @param windSpeed Wind speed
- * @return Wind U/V components
- */
- public static Array[] ds2uv(Array windDir, Array windSpeed) {
- Array U = Array.factory(DataType.DOUBLE, windDir.getShape());
- Array V = Array.factory(DataType.DOUBLE, windDir.getShape());
- double dir;
- for (int i = 0; i < U.getSize(); i++) {
- if (Double.isNaN(windDir.getDouble(i)) || Double.isNaN(windSpeed.getDouble(i))) {
- U.setDouble(i, Double.NaN);
- V.setDouble(i, Double.NaN);
- }
- dir = windDir.getDouble(i) + 180;
- if (dir > 360) {
- dir = dir - 360;
- }
- dir = dir * Math.PI / 180;
- U.setDouble(i, windSpeed.getDouble(i) * Math.sin(dir));
- V.setDouble(i, windSpeed.getDouble(i) * Math.cos(dir));
- }
-
- return new Array[]{U, V};
- }
-
- /**
- * Get wind U/V components from wind direction and speed
- *
- * @param windDir Wind direction
- * @param windSpeed Wind speed
- * @return Wind U/V components
- */
- public static double[] ds2uv(double windDir, double windSpeed) {
- double dir;
- dir = windDir + 180;
- if (dir > 360) {
- dir = dir - 360;
- }
- dir = dir * Math.PI / 180;
- double u = windSpeed * Math.sin(dir);
- double v = windSpeed * Math.cos(dir);
-
- return new double[]{u, v};
- }
-
- //
- //
- /**
- * In polygon function
- *
- * @param a Array a
- * @param x X dimension values
- * @param y Y dimension values
- * @param layer Polygon vector layer
- * @return Result array with cell values of 1 inside polygons and -1 outside
- * polygons
- */
- public static Array inPolygon(Array a, List x, List y, VectorLayer layer) {
- List polygons = (List) layer.getShapes();
- return ArrayMath.inPolygon(a, x, y, polygons);
- }
-
- /**
- * In polygon function
- *
- * @param a Array a
- * @param x X dimension values
- * @param y Y dimension values
- * @param ps Polygon shape
- * @return Result array with cell values of 1 inside polygons and -1 outside
- * polygons
- */
- public static Array inPolygon(Array a, List x, List y, PolygonShape ps) {
- List polygons = new ArrayList<>();
- polygons.add(ps);
- return ArrayMath.inPolygon(a, x, y, polygons);
- }
-
- /**
- * In polygon function
- *
- * @param a Array a
- * @param x X dimension values
- * @param y Y dimension values
- * @param polygons PolygonShape list
- * @return Result array with cell values of 1 inside polygons and -1 outside
- * polygons
- */
- public static Array inPolygon(Array a, List x, List y, List polygons) {
- if (a.getRank() == 2) {
- int xNum = x.size();
- int yNum = y.size();
-
- Array r = Array.factory(DataType.INT, a.getShape());
- for (int i = 0; i < yNum; i++) {
- for (int j = 0; j < xNum; j++) {
- if (GeoComputation.pointInPolygons(polygons, new PointD(x.get(j).doubleValue(), y.get(i).doubleValue()))) {
- r.setInt(i * xNum + j, 1);
- } else {
- r.setInt(i * xNum + j, -1);
- }
- }
- }
-
- return r;
- } else if (a.getRank() == 1) {
- int n = x.size();
- Array r = Array.factory(DataType.INT, a.getShape());
- for (int i = 0; i < n; i++) {
- if (GeoComputation.pointInPolygons(polygons, new PointD(x.get(i).doubleValue(), y.get(i).doubleValue()))) {
- r.setInt(i, 1);
- } else {
- r.setInt(i, -1);
- }
- }
-
- return r;
- }
-
- return null;
- }
-
- /**
- * In polygon function
- *
- * @param x X coordinates
- * @param y Y coordinates
- * @param polygons PolygonShape list
- * @return Result boolean array
- */
- public static Array inPolygon(Array x, Array y, List polygons) {
- Array r = Array.factory(DataType.BOOLEAN, x.getShape());
- for (int i = 0; i < r.getSize(); i++) {
- if (GeoComputation.pointInPolygons(polygons, new PointD(x.getDouble(i), y.getDouble(i)))) {
- r.setBoolean(i, true);
- } else {
- r.setBoolean(i, false);
- }
- }
-
- return r;
- }
-
- /**
- * In polygon function
- *
- * @param a Array a
- * @param x X dimension values
- * @param y Y dimension values
- * @param x_p X coordinate of the polygon
- * @param y_p Y coordinate of the polygon
- * @return Result array with cell values of 1 inside polygons and -1 outside
- * polygons
- */
- public static Array inPolygon(Array a, List x, List y, List x_p, List y_p) {
- PolygonShape ps = new PolygonShape();
- List points = new ArrayList<>();
- for (int i = 0; i < x_p.size(); i++) {
- points.add(new PointD(x_p.get(i).doubleValue(), y_p.get(i).doubleValue()));
- }
- ps.setPoints(points);
- List shapes = new ArrayList<>();
- shapes.add(ps);
-
- return inPolygon(a, x, y, shapes);
- }
-
- /**
- * In polygon function
- *
- * @param x X coordinates
- * @param y Y coordinates
- * @param x_p X coordinate of the polygon
- * @param y_p Y coordinate of the polygon
- * @return Result boolean array
- */
- public static Array inPolygon(Array x, Array y, Array x_p, Array y_p) {
- PolygonShape ps = new PolygonShape();
- List points = new ArrayList<>();
- for (int i = 0; i < x_p.getSize(); i++) {
- points.add(new PointD(x_p.getDouble(i), y_p.getDouble(i)));
- }
- ps.setPoints(points);
- List shapes = new ArrayList<>();
- shapes.add(ps);
-
- return inPolygon(x, y, shapes);
- }
-
- /**
- * Maskout function
- *
- * @param a Array a
- * @param x X dimension values
- * @param y Y dimension values
- * @param layer VectorLayer
- * @param missingValue Missing value
- * @return Result array with cell values of missing outside polygons
- */
- public static Array maskout(Array a, List x, List y, VectorLayer layer, Number missingValue) {
- List polygons = (List) layer.getShapes();
- return ArrayMath.maskout(a, x, y, polygons, missingValue);
- }
-
- /**
- * Maskout function
- *
- * @param a Array a
- * @param x X dimension values
- * @param y Y dimension values
- * @param polygon Polygon shape
- * @param missingValue Missing value
- * @return Result array with cell values of missing outside polygons
- */
- public static Array maskout(Array a, List x, List y, PolygonShape polygon, Number missingValue) {
- List polygons = new ArrayList<>();
- polygons.add(polygon);
- return ArrayMath.maskout(a, x, y, polygons, missingValue);
- }
-
- /**
- * Maskout function
- *
- * @param a Array a
- * @param x X Array
- * @param y Y Array
- * @param polygons Polygons for maskout
- * @return Result array with cell values of missing outside polygons
- */
- public static Array maskout(Array a, Array x, Array y, List polygons) {
- Array r = Array.factory(a.getDataType(), a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- if (GeoComputation.pointInPolygons(polygons, new PointD(x.getDouble(i), y.getDouble(i)))) {
- r.setObject(i, a.getObject(i));
- } else {
- r.setObject(i, Double.NaN);
- }
- }
- return r;
- }
-
- /**
- * Maskin function
- *
- * @param a Array a
- * @param x X Array
- * @param y Y Array
- * @param polygons Polygons for maskin
- * @return Result array with cell values of missing inside polygons
- */
- public static Array maskin(Array a, Array x, Array y, List polygons) {
- Array r = Array.factory(a.getDataType(), a.getShape());
- for (int i = 0; i < a.getSize(); i++) {
- if (GeoComputation.pointInPolygons(polygons, new PointD(x.getDouble(i), y.getDouble(i)))) {
- r.setObject(i, Double.NaN);
- } else {
- r.setObject(i, a.getObject(i));
- }
- }
- return r;
- }
-
- /**
- * Maskout function
- *
- * @param a Array a
- * @param x X Array
- * @param y Y Array
- * @param polygons Polygons for maskout
- * @return Result arrays removing cells outside polygons
- */
- public static Array[] maskout_Remove(Array a, Array x, Array y, List polygons) {
- List rdata = new ArrayList<>();
- List rxdata = new ArrayList<>();
- List rydata = new ArrayList<>();
- for (int i = 0; i < a.getSize(); i++) {
- if (GeoComputation.pointInPolygons(polygons, new PointD(x.getDouble(i), y.getDouble(i)))) {
- rdata.add(a.getObject(i));
- rxdata.add(x.getDouble(i));
- rydata.add(y.getDouble(i));
- }
- }
-
- int n = rdata.size();
- int[] shape = new int[1];
- shape[0] = n;
- Array r = Array.factory(a.getDataType(), shape);
- Array rx = Array.factory(x.getDataType(), shape);
- Array ry = Array.factory(y.getDataType(), shape);
- for (int i = 0; i < n; i++) {
- r.setObject(i, rdata.get(i));
- rx.setDouble(i, rxdata.get(i));
- ry.setDouble(i, rydata.get(i));
- }
-
- return new Array[]{r, rx, ry};
- }
-
- /**
- * Maskin function
- *
- * @param a Array a
- * @param x X Array
- * @param y Y Array
- * @param polygons Polygons for maskin
- * @return Result arrays removing cells inside polygons
- */
- public static Array[] maskin_Remove(Array a, Array x, Array y, List polygons) {
- List rdata = new ArrayList<>();
- List rxdata = new ArrayList<>();
- List rydata = new ArrayList<>();
- for (int i = 0; i < a.getSize(); i++) {
- if (!GeoComputation.pointInPolygons(polygons, new PointD(x.getDouble(i), y.getDouble(i)))) {
- rdata.add(a.getObject(i));
- rxdata.add(x.getDouble(i));
- rydata.add(y.getDouble(i));
- }
- }
-
- int n = rdata.size();
- int[] shape = new int[1];
- shape[0] = n;
- Array r = Array.factory(a.getDataType(), shape);
- Array rx = Array.factory(x.getDataType(), shape);
- Array ry = Array.factory(y.getDataType(), shape);
- for (int i = 0; i < n; i++) {
- r.setObject(i, rdata.get(i));
- rx.setDouble(i, rxdata.get(i));
- ry.setDouble(i, rydata.get(i));
- }
-
- return new Array[]{r, rx, ry};
- }
-
- /**
- * Maskout function
- *
- * @param a Array a
- * @param x X dimension values
- * @param y Y dimension values
- * @param polygons PolygonShape list
- * @return Result array with cell values of missing outside polygons
- */
- public static Array maskout(Array a, List x, List y, List polygons) {
- return maskout(a, x, y, polygons, Double.NaN);
- }
-
- /**
- * Maskout function
- *
- * @param a Array a
- * @param x X dimension values
- * @param y Y dimension values
- * @param polygons PolygonShape list
- * @param missingValue Missing value
- * @return Result array with cell values of missing outside polygons
- */
- public static Array maskout(Array a, List x, List y, List polygons, Number missingValue) {
- int xNum = x.size();
- int yNum = y.size();
-
- Array r = Array.factory(a.getDataType(), a.getShape());
- if (a.getRank() == 1) {
- for (int i = 0; i < xNum; i++) {
- if (GeoComputation.pointInPolygons(polygons, new PointD(x.get(i).doubleValue(), y.get(i).doubleValue()))) {
- r.setObject(i, a.getObject(i));
- } else {
- r.setObject(i, missingValue);
- }
- }
- } else if (a.getRank() == 2) {
- int idx;
- for (int i = 0; i < yNum; i++) {
- for (int j = 0; j < xNum; j++) {
- idx = i * xNum + j;
- if (GeoComputation.pointInPolygons(polygons, new PointD(x.get(j).doubleValue(), y.get(i).doubleValue()))) {
- r.setObject(idx, a.getObject(idx));
- } else {
- r.setObject(idx, missingValue);
- }
- }
- }
- }
-
- return r;
- }
-
- /**
- * Maskout function
- *
- * @param a Array a
- * @param m Array mask
- * @param missingValue Missing value
- * @return Result array
- */
- public static Array maskout(Array a, Array m, Number missingValue) {
- Array r = Array.factory(a.getDataType(), a.getShape());
- int n = (int) a.getSize();
- for (int i = 0; i < n; i++) {
- if (m.getDouble(i) < 0) {
- r.setObject(i, missingValue);
- } else {
- r.setObject(i, a.getObject(i));
- }
- }
-
- return r;
- }
-
- /**
- * Maskout function
- *
- * @param a Array a
- * @param m Array mask
- * @return Result array
- */
- public static Array maskout(Array a, Array m) {
- Array r = Array.factory(a.getDataType(), a.getShape());
- int n = (int) a.getSize();
- for (int i = 0; i < n; i++) {
- if (m.getDouble(i) < 0) {
- r.setObject(i, Double.NaN);
- } else {
- r.setObject(i, a.getObject(i));
- }
- }
-
- return r;
- }
-
- /**
- * Maskin function
- *
- * @param a Array a
- * @param m Array mask
- * @return Result array
- */
- public static Array maskin(Array a, Array m) {
- Array r = Array.factory(a.getDataType(), a.getShape());
- int n = (int) a.getSize();
- for (int i = 0; i < n; i++) {
- if (m.getDouble(i) < 0) {
- r.setObject(i, a.getObject(i));
- } else {
- r.setObject(i, Double.NaN);
- }
- }
-
- return r;
- }
-
- //
- //
- /**
- * Get correlation coefficient How well did the forecast values correspond
- * to the observed values? Range: -1 to 1. Perfect score: 1.
- *
- * @param xData X data array
- * @param yData Y data array
- * @return Correlation coefficent
- */
- public static float getR(List xData, List yData) {
- int n = xData.size();
- double x_sum = 0;
- double y_sum = 0;
- for (int i = 0; i < n; i++) {
- x_sum += xData.get(i).doubleValue();
- y_sum += yData.get(i).doubleValue();
- }
- double sx_sum = 0.0;
- double sy_sum = 0.0;
- double xy_sum = 0.0;
- for (int i = 0; i < n; i++) {
- sx_sum += xData.get(i).doubleValue() * xData.get(i).doubleValue();
- sy_sum += yData.get(i).doubleValue() * yData.get(i).doubleValue();
- xy_sum += xData.get(i).doubleValue() * yData.get(i).doubleValue();
- }
-
- double r = (n * xy_sum - x_sum * y_sum) / (Math.sqrt(n * sx_sum - x_sum * x_sum) * Math.sqrt(n * sy_sum - y_sum * y_sum));
- return (float) r;
- }
-
- /**
- * Get correlation coefficient How well did the forecast values correspond
- * to the observed values? Range: -1 to 1. Perfect score: 1.
- *
- * @param xData X data array
- * @param yData Y data array
- * @return Correlation coefficent
- */
- public static float getR(Array xData, Array yData) {
- int n = (int) xData.getSize();
- double x_sum = 0;
- double y_sum = 0;
- double sx_sum = 0.0;
- double sy_sum = 0.0;
- double xy_sum = 0.0;
- int nn = 0;
- double x, y;
- for (int i = 0; i < n; i++) {
- x = xData.getDouble(i);
- y = yData.getDouble(i);
- if (Double.isNaN(x) || Double.isNaN(y)) {
- continue;
- }
- x_sum += x;
- y_sum += y;
- sx_sum += x * x;
- sy_sum += y * y;
- xy_sum += x * y;
- nn += 1;
- }
-
- double r = (nn * xy_sum - x_sum * y_sum) / (Math.sqrt(nn * sx_sum - x_sum * x_sum) * Math.sqrt(nn * sy_sum - y_sum * y_sum));
- return (float) r;
- }
-
- /**
- * Determine the least square trend equation - linear fitting
- *
- * @param xData X data array
- * @param yData Y data array
- * @return Result array - y intercept and slope
- */
- public static double[] leastSquareTrend(List xData, List yData) {
- int n = xData.size();
- double sumX = 0.0;
- double sumY = 0.0;
- double sumSquareX = 0.0;
- double sumXY = 0.0;
- for (int i = 0; i < n; i++) {
- sumX += xData.get(i).doubleValue();
- sumY += yData.get(i).doubleValue();
- sumSquareX += xData.get(i).doubleValue() * xData.get(i).doubleValue();
- sumXY += xData.get(i).doubleValue() * yData.get(i).doubleValue();
- }
-
- double a = (sumSquareX * sumY - sumX * sumXY) / (n * sumSquareX - sumX * sumX);
- double b = (n * sumXY - sumX * sumY) / (n * sumSquareX - sumX * sumX);
-
- return new double[]{a, b};
- }
-
- /**
- * Linear regress
- *
- * @param xData X data array
- * @param yData Y data array
- * @return Result array - y intercept, slope and correlation coefficent
- */
- public static double[] lineRegress(List xData, List yData) {
- int n = xData.size();
- double x_sum = 0;
- double y_sum = 0;
- double sx_sum = 0.0;
- double sy_sum = 0.0;
- double xy_sum = 0.0;
- for (int i = 0; i < n; i++) {
- x_sum += xData.get(i).doubleValue();
- y_sum += yData.get(i).doubleValue();
- sx_sum += xData.get(i).doubleValue() * xData.get(i).doubleValue();
- sy_sum += yData.get(i).doubleValue() * yData.get(i).doubleValue();
- xy_sum += xData.get(i).doubleValue() * yData.get(i).doubleValue();
- }
-
- double r = (n * xy_sum - x_sum * y_sum) / (Math.sqrt(n * sx_sum - x_sum * x_sum) * Math.sqrt(n * sy_sum - y_sum * y_sum));
- double a = (sx_sum * y_sum - x_sum * xy_sum) / (n * sx_sum - x_sum * x_sum);
- double b = (n * xy_sum - x_sum * y_sum) / (n * sx_sum - x_sum * x_sum);
-
- return new double[]{a, b, r};
- }
-
- /**
- * Linear regress
- *
- * @param xData X data array
- * @param yData Y data array
- * @return Slope, intercept, correlation coefficent, two-sided p-value, the
- * standard error of the estimate for the slope, valid data number
- */
- public static double[] lineRegress(Array xData, Array yData) {
- double x_sum = 0;
- double y_sum = 0;
- double sx_sum = 0.0;
- double sy_sum = 0.0;
- double xy_sum = 0.0;
- int n = 0;
- List xi = new ArrayList<>();
- List yi = new ArrayList<>();
- for (int i = 0; i < xData.getSize(); i++) {
- if (Double.isNaN(xData.getDouble(i))) {
- continue;
- }
- if (Double.isNaN(yData.getDouble(i))) {
- continue;
- }
- xi.add(xData.getDouble(i));
- yi.add(yData.getDouble(i));
- x_sum += xData.getDouble(i);
- y_sum += yData.getDouble(i);
- sx_sum += xData.getDouble(i) * xData.getDouble(i);
- sy_sum += yData.getDouble(i) * yData.getDouble(i);
- xy_sum += xData.getDouble(i) * yData.getDouble(i);
- n += 1;
- }
-
- double r = (n * xy_sum - x_sum * y_sum) / (Math.sqrt(n * sx_sum - x_sum * x_sum) * Math.sqrt(n * sy_sum - y_sum * y_sum));
- double intercept = (sx_sum * y_sum - x_sum * xy_sum) / (n * sx_sum - x_sum * x_sum);
- double slope = (n * xy_sum - x_sum * y_sum) / (n * sx_sum - x_sum * x_sum);
- int df = n - 2; //degress of freedom
- double TINY = 1.0e-20;
- double t = r * Math.sqrt(df / ((1.0 - r + TINY) * (1.0 + r + TINY)));
- //two-sided p-value for a hypothesis test whose null hypothesis is that the slope is zero
- double p = studpval(t, df);
-
- // more statistical analysis
- double xbar = x_sum / n;
- double ybar = y_sum / n;
- double rss = 0.0; // residual sum of squares
- double ssr = 0.0; // regression sum of squares
- double fit;
- double xxbar = 0.0;
- for (int i = 0; i < n; i++) {
- fit = slope * xi.get(i) + intercept;
- rss += (fit - yi.get(i)) * (fit - yi.get(i));
- ssr += (fit - ybar) * (fit - ybar);
- xxbar += (xi.get(i) - xbar) * (xi.get(i) - xbar);
- }
- double svar = rss / df;
- double svar1 = svar / xxbar;
- double svar0 = svar / n + xbar * xbar * svar1;
- svar0 = Math.sqrt(svar0); //the standard error of the estimate for the intercept
- svar1 = Math.sqrt(svar1); //the standard error of the estimate for the slope
-
-// double xbar = x_sum / n;
-// double ybar = y_sum / n;
-// double bhat = 0.0;
-// double ssqx = 0.0;
-// for (int i = 0; i < n; i++) {
-// bhat = bhat + (yi.get(i) - ybar) * (xi.get(i) - xbar);
-// ssqx = ssqx + (xi.get(i) - xbar) * (xi.get(i) - xbar);
-// }
-// bhat = bhat / ssqx;
-// double ahat = ybar - bhat * xbar;
-// double sigmahat2 = 0.0;
-// double[] ri = new double[n];
-// for (int i = 0; i < n; i++) {
-// ri[i] = yi.get(i) - (ahat + bhat * xi.get(i));
-// sigmahat2 = sigmahat2 + ri[i] * ri[i];
-// }
-// sigmahat2 = sigmahat2 / (n * 1.0 - 2.0);
-// double seb = Math.sqrt(sigmahat2 / ssqx);
-// double sigmahat = Math.sqrt((seb * seb) * ssqx);
-// double sea = Math.sqrt(sigmahat * sigmahat * (1 / (n * 1.0) + xbar * xbar / ssqx));
-// double b0 = 0;
-// double Tb = (bhat - b0) / seb;
-// double a0 = 0;
-// double Ta = (ahat - a0) / sea;
-// p = studpval(Ta, n);
- return new double[]{slope, intercept, r, p, svar1, n};
- }
-
- private static double statcom(double mq, int mi, int mj, double mb) {
- double zz = 1;
- double mz = zz;
- int mk = mi;
- while (mk <= mj) {
- zz = zz * mq * mk / (mk - mb);
- mz = mz + zz;
- mk = mk + 2;
- }
- return mz;
- }
-
- private static double studpval(double mt, int mn) {
- mt = Math.abs(mt);
- double mw = mt / Math.sqrt(mn);
- double th = Math.atan2(mw, 1);
- if (mn == 1) {
- return 1.0 - th / (Math.PI / 2.0);
- }
- double sth = Math.sin(th);
- double cth = Math.cos(th);
- if (mn % 2 == 1) {
- return 1.0 - (th + sth * cth * statcom(cth * cth, 2, mn - 3, -1)) / (Math.PI / 2.0);
- } else {
- return 1.0 - sth * statcom(cth * cth, 1, mn - 3, -1);
- }
- }
-
- /**
- * Evaluate a polynomial at specific values. If p is of length N, this
- * function returns the value: p[0]*x**(N-1) + p[1]*x**(N-2) + ... +
- * p[N-2]*x + p[N-1]
- *
- * @param p array_like or poly1d object
- * @param x array_like or poly1d object
- * @return ndarray or poly1d
- */
- public static Array polyVal(List p, Array x) {
- int n = p.size();
- Array r = Array.factory(DataType.DOUBLE, x.getShape());
- for (int i = 0; i < x.getSize(); i++) {
- double val = x.getDouble(i);
- double rval = 0.0;
- for (int j = 0; j < n; j++) {
- rval += p.get(j).doubleValue() * Math.pow(val, n - j - 1);
- }
- r.setDouble(i, rval);
- }
-
- return r;
- }
-
- //
- //
- /**
- * Performs a centered difference operation on a grid data along one
- * dimension direction
- *
- * @param data The grid data
- * @param dimIdx Direction dimension index
- * @return Result grid data
- */
- public static Array cdiff(Array data, int dimIdx) {
- Array r = Array.factory(DataType.DOUBLE, data.getShape());
- Index index = data.getIndex();
- Index indexr = r.getIndex();
- int[] shape = data.getShape();
- int[] current, cc;
- double a, b;
- for (int i = 0; i < r.getSize(); i++) {
- current = indexr.getCurrentCounter();
- if (current[dimIdx] == 0 || current[dimIdx] == shape[dimIdx] - 1) {
- r.setDouble(indexr, Double.NaN);
- } else {
- cc = Arrays.copyOf(current, current.length);
- cc[dimIdx] = cc[dimIdx] - 1;
- index.set(cc);
- a = data.getDouble(index);
- cc[dimIdx] = cc[dimIdx] + 2;
- index.set(cc);
- b = data.getDouble(index);
- if (Double.isNaN(a) || Double.isNaN(b)) {
- r.setDouble(indexr, Double.NaN);
- } else {
- r.setDouble(indexr, a - b);
- }
- }
- indexr.incr();
- }
-
- return r;
- }
-
- /**
- * Performs a centered difference operation on a grid data in the x or y
- * direction
- *
- * @param data The grid data
- * @param isX If is x direction
- * @return Result grid data
- */
- public static Array cdiff_bak(Array data, boolean isX) {
- if (data.getRank() == 2) {
- int xnum = data.getShape()[1];
- int ynum = data.getShape()[0];
- Array r = Array.factory(DataType.DOUBLE, data.getShape());
- for (int i = 0; i < ynum; i++) {
- for (int j = 0; j < xnum; j++) {
- if (i == 0 || i == ynum - 1 || j == 0 || j == xnum - 1) {
- r.setDouble(i * xnum + j, Double.NaN);
- } else {
- double a, b;
- if (isX) {
- a = data.getDouble(i * xnum + j + 1);
- b = data.getDouble(i * xnum + j - 1);
- } else {
- a = data.getDouble((i + 1) * xnum + j);
- b = data.getDouble((i - 1) * xnum + j);
- }
- if (Double.isNaN(a) || Double.isNaN(b)) {
- r.setDouble(i * xnum + j, Double.NaN);
- } else {
- r.setDouble(i * xnum + j, a - b);
- }
- }
- }
- }
-
- return r;
- } else if (data.getRank() == 1) {
- int n = data.getShape()[0];
- Array r = Array.factory(DataType.DOUBLE, data.getShape());
- for (int i = 0; i < n; i++) {
- if (i == 0 || i == n - 1) {
- r.setDouble(i, Double.NaN);
- } else {
- double a, b;
- a = data.getDouble(i + 1);
- b = data.getDouble(i - 1);
- if (Double.isNaN(a) || Double.isNaN(b)) {
- r.setDouble(i, Double.NaN);
- } else {
- r.setDouble(i, a - b);
- }
- }
- }
-
- return r;
- } else {
- System.out.println("Data dimension number must be 1 or 2!");
- return null;
- }
- }
-
- /**
- * Calculates the vertical component of the curl (ie, vorticity)
- *
- * @param uData U component
- * @param vData V component
- * @param xx X dimension value
- * @param yy Y dimension value
- * @return Curl
- */
- public static Array hcurl(Array uData, Array vData, List xx, List yy) {
- int rank = uData.getRank();
- int[] shape = uData.getShape();
- Array lonData = Array.factory(DataType.DOUBLE, shape);
- Array latData = Array.factory(DataType.DOUBLE, shape);
- Index index = lonData.getIndex();
- int[] current;
- for (int i = 0; i < lonData.getSize(); i++) {
- current = index.getCurrentCounter();
- lonData.setDouble(index, xx.get(current[rank - 1]).doubleValue());
- latData.setDouble(index, yy.get(current[rank - 2]).doubleValue());
- index.incr();
- }
-
- Array dv = cdiff(vData, rank - 1);
- Array dx = mul(cdiff(lonData, rank - 1), Math.PI / 180);
- Array du = cdiff(mul(uData, cos(mul(latData, Math.PI / 180))), rank - 2);
- Array dy = mul(cdiff(latData, rank - 2), Math.PI / 180);
- Array gData = div(sub(div(dv, dx), div(du, dy)), mul(cos(mul(latData, Math.PI / 180)), 6.37e6));
-
- return gData;
- }
-
- /**
- * Calculates the horizontal divergence using finite differencing
- *
- * @param uData U component
- * @param vData V component
- * @param xx X dimension value
- * @param yy Y dimension value
- * @return Divergence
- */
- public static Array hdivg(Array uData, Array vData, List xx, List yy) {
- int rank = uData.getRank();
- int[] shape = uData.getShape();
- Array lonData = Array.factory(DataType.DOUBLE, shape);
- Array latData = Array.factory(DataType.DOUBLE, shape);
- Index index = lonData.getIndex();
- int[] current;
- for (int i = 0; i < lonData.getSize(); i++) {
- current = index.getCurrentCounter();
- lonData.setDouble(index, xx.get(current[rank - 1]).doubleValue());
- latData.setDouble(index, yy.get(current[rank - 2]).doubleValue());
- index.incr();
- }
-
- Array du = cdiff(uData, rank - 1);
- Array dx = mul(cdiff(lonData, rank - 1), Math.PI / 180);
- Array dv = cdiff(mul(vData, cos(mul(latData, Math.PI / 180))), rank - 2);
- Array dy = mul(cdiff(latData, rank - 2), Math.PI / 180);
- Array gData = div(add(div(du, dx), div(dv, dy)), mul(cos(mul(latData, Math.PI / 180)), 6.37e6));
-
- return gData;
- }
-
- /**
- * Take magnitude value from U/V grid data
- *
- * @param uData U grid data
- * @param vData V grid data
- * @return Magnitude grid data
- */
- public static Array magnitude(Array uData, Array vData) {
- int[] shape = uData.getShape();
- int xNum = shape[1];
- int yNum = shape[0];
- int idx;
-
- Array r = Array.factory(DataType.DOUBLE, shape);
- for (int i = 0; i < yNum; i++) {
- for (int j = 0; j < xNum; j++) {
- idx = i * xNum + j;
- if (Double.isNaN(uData.getDouble(idx)) || Double.isNaN(vData.getDouble(idx))) {
- r.setDouble(idx, Double.NaN);
- } else {
- r.setDouble(idx, Math.sqrt(Math.pow(uData.getDouble(idx), 2) + Math.pow(vData.getDouble(idx), 2)));
- }
- }
- }
-
- return r;
- }
-
- /**
- * Calculate fahrenheit temperature from celsius temperature
- *
- * @param tc Celsius temperature
- * @return Fahrenheit temperature
- */
- public static Array tc2tf(Array tc) {
- Array r = Array.factory(tc.getDataType(), tc.getShape());
- for (int i = 0; i < r.getSize(); i++) {
- r.setDouble(i, MeteoMath.tc2tf(tc.getDouble(i)));
- }
-
- return r;
- }
-
- /**
- * Calculate celsius temperature from fahrenheit temperature
- *
- * @param tf Fahrenheit temperature
- * @return Celsius temperature
- */
- public static Array tf2tc(Array tf) {
- Array r = Array.factory(tf.getDataType(), tf.getShape());
- for (int i = 0; i < r.getSize(); i++) {
- r.setDouble(i, MeteoMath.tf2tc(tf.getDouble(i)));
- }
-
- return r;
- }
-
- /**
- * Calculate relative humidity from specific humidity
- *
- * @param qair Specific humidity, dimensionless (e.g. kg/kg) ratio of water
- * mass / total air mass
- * @param temp Temperature - degree c
- * @param press Pressure - hPa (mb)
- * @return Relative humidity as percent (i.e. 80%)
- */
- public static Array qair2rh(Array qair, Array temp, double press) {
- Array r = Array.factory(DataType.DOUBLE, qair.getShape());
- double rh;
- for (int i = 0; i < r.getSize(); i++) {
- rh = MeteoMath.qair2rh(qair.getDouble(i), temp.getDouble(i), press);
- r.setDouble(i, rh);
- }
-
- return r;
- }
-
- /**
- * Calculate relative humidity
- *
- * @param qair Specific humidity, dimensionless (e.g. kg/kg) ratio of water
- * mass / total air mass
- * @param temp Temperature - degree c
- * @param press Pressure - hPa (mb)
- * @return Relative humidity as percent (i.e. 80%)
- */
- public static Array qair2rh(Array qair, Array temp, Array press) {
- Array r = Array.factory(DataType.DOUBLE, qair.getShape());
- double rh;
- for (int i = 0; i < r.getSize(); i++) {
- rh = MeteoMath.qair2rh(qair.getDouble(i), temp.getDouble(i), press.getDouble(i));
- r.setDouble(i, rh);
- }
-
- return r;
- }
-
- /**
- * Calculate height from pressure
- *
- * @param press Pressure - hPa
- * @return Height - m
- */
- public static Array press2Height(Array press) {
- Array r = Array.factory(DataType.DOUBLE, press.getShape());
- double rh;
- for (int i = 0; i < r.getSize(); i++) {
- rh = MeteoMath.press2Height(press.getDouble(i));
- r.setDouble(i, rh);
- }
-
- return r;
- }
-
- /**
- * Calculate pressure from height
- *
- * @param height Height - m
- * @return Pressure - hPa
- */
- public static Array height2Press(Array height) {
- Array r = Array.factory(DataType.DOUBLE, height.getShape());
- double rh;
- for (int i = 0; i < r.getSize(); i++) {
- rh = MeteoMath.height2Press(height.getDouble(i));
- r.setDouble(i, rh);
- }
-
- return r;
- }
- //
-}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/bak/ArrayUtil.java b/MeteoInfoLib/src/main/java/org/meteoinfo/bak/ArrayUtil.java
deleted file mode 100644
index c7a38c84..00000000
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/bak/ArrayUtil.java
+++ /dev/null
@@ -1,5546 +0,0 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.meteoinfo.bak;
-
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.UnsupportedEncodingException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Random;
-import java.util.Scanner;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import org.meteoinfo.data.mapdata.Field;
-import org.meteoinfo.geoprocess.GeoComputation;
-import org.meteoinfo.geoprocess.analysis.ResampleMethods;
-import org.meteoinfo.global.DataConvert;
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.global.MIMath;
-import org.meteoinfo.global.PointD;
-import org.meteoinfo.global.util.GlobalUtil;
-import org.meteoinfo.io.EndianDataOutputStream;
-import org.locationtech.jts.geom.Coordinate;
-import org.locationtech.jts.geom.Geometry;
-import org.locationtech.jts.geom.GeometryFactory;
-import org.meteoinfo.data.StationData;
-import org.meteoinfo.layer.VectorLayer;
-import org.meteoinfo.legend.LegendScheme;
-import org.meteoinfo.ndarray.Complex;
-import org.meteoinfo.math.ListIndexComparator;
-import org.meteoinfo.math.spatial.KDTree;
-import org.meteoinfo.math.spatial.KDTree.SearchResult;
-import org.meteoinfo.ndarray.util.BigDecimalUtil;
-import org.meteoinfo.projection.KnownCoordinateSystems;
-import org.meteoinfo.projection.info.ProjectionInfo;
-import org.meteoinfo.projection.ProjectionUtil;
-import org.meteoinfo.projection.Reproject;
-import org.meteoinfo.shape.PolygonShape;
-import org.meteoinfo.shape.ShapeTypes;
-import org.python.core.PyComplex;
-import org.meteoinfo.ndarray.Array;
-import org.meteoinfo.ndarray.DataType;
-import org.meteoinfo.ndarray.Index;
-import org.meteoinfo.ndarray.Index2D;
-import org.meteoinfo.ndarray.IndexIterator;
-import org.meteoinfo.ndarray.InvalidRangeException;
-import org.meteoinfo.ndarray.Range;
-
-/**
- *
- * @author yaqiang
- */
-public class ArrayUtil {
-
- //
- /**
- * Read ASCII data file to an array
- *
- * @param fileName File name
- * @param delimiter Delimiter
- * @param headerLines Headerline number
- * @param dataType Data type string
- * @param shape Shape
- * @param readFirstCol Read first column data or not
- * @return Result array
- * @throws UnsupportedEncodingException
- * @throws FileNotFoundException
- * @throws IOException
- */
- public static Array readASCIIFile(String fileName, String delimiter, int headerLines, String dataType,
- List shape, boolean readFirstCol) throws UnsupportedEncodingException, FileNotFoundException, IOException {
- BufferedReader sr = new BufferedReader(new InputStreamReader(new FileInputStream(fileName)));
- if (headerLines > 0) {
- for (int i = 0; i < headerLines; i++) {
- sr.readLine();
- }
- }
-
- DataType dt = DataType.DOUBLE;
- if (dataType != null) {
- if (dataType.contains("%")) {
- dataType = dataType.split("%")[1];
- }
- dt = ArrayUtil.toDataType(dataType);
- }
-
- int i;
- int[] ss = new int[shape.size()];
- for (i = 0; i < shape.size(); i++) {
- ss[i] = shape.get(i);
- }
- Array a = Array.factory(dt, ss);
-
- String[] dataArray;
- i = 0;
- String line = sr.readLine();
- int sCol = 0;
- if (!readFirstCol) {
- sCol = 1;
- }
- while (line != null) {
- line = line.trim();
- if (line.isEmpty()) {
- line = sr.readLine();
- continue;
- }
- dataArray = GlobalUtil.split(line, delimiter);
- for (int j = sCol; j < dataArray.length; j++) {
- a.setDouble(i, Double.parseDouble(dataArray[j]));
- i += 1;
- if (i >= a.getSize()) {
- break;
- }
- }
- if (i >= a.getSize()) {
- break;
- }
-
- line = sr.readLine();
- }
- sr.close();
-
- return a;
- }
-
- /**
- * Get row number of a ASCII file
- *
- * @param fileName File name
- * @return Row number
- * @throws FileNotFoundException
- */
- public static int numASCIIRow(String fileName) throws FileNotFoundException {
- File f = new File(fileName);
- int lineNumber;
- try (Scanner fileScanner = new Scanner(f)) {
- lineNumber = 0;
- while (fileScanner.hasNextLine()) {
- fileScanner.nextLine();
- lineNumber++;
- }
- }
-
- return lineNumber;
- }
-
- /**
- * Get row number of a ASCII file
- *
- * @param fileName File name
- * @param delimiter
- * @param headerLines
- * @return Row number
- * @throws FileNotFoundException
- */
- public static int numASCIICol(String fileName, String delimiter, int headerLines) throws FileNotFoundException, IOException {
- String[] dataArray;
- try (BufferedReader sr = new BufferedReader(new InputStreamReader(new FileInputStream(fileName)))) {
- if (headerLines > 0) {
- for (int i = 0; i < headerLines; i++) {
- sr.readLine();
- }
- }
- String line = sr.readLine().trim();
- dataArray = GlobalUtil.split(line, delimiter);
- }
-
- return dataArray.length;
- }
-
- /**
- * Save an array data to a binary file
- *
- * @param fn File path
- * @param a Array
- * @param byteOrder Byte order
- * @param append If append to existing file
- * @param sequential If write as sequential binary file - Fortran
- */
- public static void saveBinFile(String fn, Array a, String byteOrder, boolean append,
- boolean sequential) {
- try (DataOutputStream out = new DataOutputStream(new FileOutputStream(new File(fn), append))) {
- EndianDataOutputStream outs = new EndianDataOutputStream(out);
- ByteBuffer bb = a.getDataAsByteBuffer();
- int n = (int) a.getSize();
- ByteOrder bOrder = ByteOrder.LITTLE_ENDIAN;
- if (byteOrder.equalsIgnoreCase("big_endian")) {
- bOrder = ByteOrder.BIG_ENDIAN;
- }
-
- if (sequential) {
- if (bOrder == ByteOrder.BIG_ENDIAN) {
- outs.writeIntBE(n * 4);
- } else {
- outs.writeIntLE(n * 4);
- }
- }
-
- if (bOrder == ByteOrder.BIG_ENDIAN) {
- outs.write(bb.array());
- } else if (a.getDataType() == DataType.BYTE) {
- outs.write(bb.array());
- } else {
- ByteBuffer nbb = ByteBuffer.allocate(bb.array().length);
- nbb.order(bOrder);
- switch (a.getDataType()) {
- case INT:
- for (int i = 0; i < a.getSize(); i++) {
- nbb.putInt(i * 4, bb.getInt());
- //nbb.putInt(a.getInt(i));
- }
- break;
- case FLOAT:
- for (int i = 0; i < a.getSize(); i++) {
- nbb.putFloat(i * 4, bb.getFloat());
- }
- break;
- case DOUBLE:
- for (int i = 0; i < a.getSize(); i++) {
- nbb.putDouble(i * 8, bb.getDouble());
- }
- break;
- default:
- nbb.put(bb);
- }
- outs.write(nbb.array());
- }
-
- if (sequential) {
- if (bOrder == ByteOrder.BIG_ENDIAN) {
- outs.writeIntBE(n * 4);
- } else {
- outs.writeIntLE(n * 4);
- }
- }
-
- outs.close();
- } catch (FileNotFoundException ex) {
- Logger.getLogger(ArrayUtil.class.getName()).log(Level.SEVERE, null, ex);
- } catch (IOException ex) {
- Logger.getLogger(ArrayUtil.class.getName()).log(Level.SEVERE, null, ex);
- }
- }
-
- /**
- * Save an array data to a ASCII file
- *
- * @param fn File path
- * @param a Array
- * @param colNum Column number of each line
- * @param format String format
- * @param delimiter Delimiter
- * @throws java.io.IOException
- */
- public static void saveASCIIFile(String fn, Array a, int colNum,
- String format, String delimiter) throws IOException {
- BufferedWriter sw = new BufferedWriter(new FileWriter(new File(fn)));
- String line = "";
- int j = 0;
- for (int i = 0; i < a.getSize(); i++) {
- j += 1;
- if (format == null) {
- line = line + a.getObject(i).toString();
- } else {
- line = line + String.format(format, a.getObject(i));
- }
- if (j < colNum && i < a.getSize() - 1) {
- if (delimiter == null) {
- line = line + " ";
- } else {
- line = line + delimiter;
- }
- } else {
- sw.write(line);
- sw.newLine();
- line = "";
- j = 0;
- }
- }
- sw.flush();
- sw.close();
- }
-
- /**
- * Read array from a binary file
- *
- * @param fn Binary file name
- * @param dims Dimensions
- * @param dataType Data type string
- * @param skip Skip bytes
- * @param byteOrder Byte order
- * @return Result array
- */
- public static Array readBinFile(String fn, List dims, String dataType, int skip,
- String byteOrder) {
- DataType dt = DataType.DOUBLE;
- if (dataType != null) {
- if (dataType.contains("%")) {
- dataType = dataType.split("%")[1];
- }
- dt = ArrayUtil.toDataType(dataType);
- }
- DataType ndt = dt;
- if (dt == DataType.BYTE) {
- ndt = DataType.INT;
- }
-
- ByteOrder bOrder = ByteOrder.LITTLE_ENDIAN;
- if (byteOrder.equalsIgnoreCase("big_endian")) {
- bOrder = ByteOrder.BIG_ENDIAN;
- }
-
- int[] shape = new int[dims.size()];
- for (int i = 0; i < dims.size(); i++) {
- shape[i] = dims.get(i);
- }
- Array r = Array.factory(ndt, shape);
- IndexIterator iter = r.getIndexIterator();
- try {
- DataInputStream ins = new DataInputStream(new FileInputStream(fn));
- ins.skip(skip);
- byte[] bytes;
- byte[] db;
- int start = 0;
- switch (dt) {
- case BYTE:
- bytes = new byte[(int) r.getSize()];
- ins.read(bytes);
- for (int i = 0; i < r.getSize(); i++) {
- r.setInt(i, DataConvert.byte2Int(bytes[i]));
- }
- break;
- case SHORT:
- bytes = new byte[(int) r.getSize() * 2];
- db = new byte[2];
- ins.read(bytes);
- while (iter.hasNext()) {
- System.arraycopy(bytes, start, db, 0, 2);
- iter.setShortNext(DataConvert.bytes2Short(db, bOrder));
- start += 2;
- }
- break;
- case INT:
- bytes = new byte[(int) r.getSize() * 4];
- db = new byte[4];
- ins.read(bytes);
- while (iter.hasNext()) {
- System.arraycopy(bytes, start, db, 0, 4);
- iter.setIntNext(DataConvert.bytes2Int(db, bOrder));
- start += 4;
- }
- break;
- case FLOAT:
- bytes = new byte[(int) r.getSize() * 4];
- db = new byte[4];
- ins.read(bytes);
- while (iter.hasNext()) {
- System.arraycopy(bytes, start, db, 0, 4);
- iter.setFloatNext(DataConvert.bytes2Float(db, bOrder));
- start += 4;
- }
- break;
- case DOUBLE:
- bytes = new byte[(int) r.getSize() * 8];
- db = new byte[8];
- ins.read(bytes);
- while (iter.hasNext()) {
- System.arraycopy(bytes, start, db, 0, 8);
- iter.setDoubleNext(DataConvert.bytes2Double(db, bOrder));
- start += 8;
- }
- break;
- }
- ins.close();
- } catch (FileNotFoundException ex) {
- Logger.getLogger(ArrayUtil.class.getName()).log(Level.SEVERE, null, ex);
- } catch (IOException ex) {
- Logger.getLogger(ArrayUtil.class.getName()).log(Level.SEVERE, null, ex);
- }
-
- return r;
- }
-
- //
- //
-
- /**
- * Create an array
- *
- * @param data Object
- * @return Array
- */
- public static Array array(Object data) {
- if (data instanceof Number) {
- DataType dt = ArrayMath.getDataType(data);
- Array a = Array.factory(dt, new int[]{1});
- a.setObject(0, data);
- return a;
- } else if (data instanceof Array) {
- return (Array) data;
- } else if (data instanceof ArrayList) {
- return array((List) data);
- } else if (data.getClass().isArray()) {
- return Array.factory(data);
- } else {
- return null;
- }
- }
-
- /**
- * Create an array
- *
- * @param data Array like data
- * @return
- */
- public static Array array(ArrayList data) {
- return array((List) data);
- }
-
- /**
- * Create an array
- *
- * @param data Array like data
- * @return Array
- */
- public static Array array(List data) {
- Object d0 = data.get(0);
- if (d0 instanceof Number) {
- DataType dt = ArrayUtil.objectsToType(data);
- Array a = Array.factory(dt, new int[]{data.size()});
- for (int i = 0; i < data.size(); i++) {
- a.setObject(i, data.get(i));
- }
- return a;
- } else if (d0 instanceof String) {
- Array a = Array.factory(DataType.STRING, new int[]{data.size()});
- for (int i = 0; i < data.size(); i++) {
- a.setObject(i, data.get(i));
- }
- return a;
- } else if (d0 instanceof Boolean) {
- Array a = Array.factory(DataType.BOOLEAN, new int[]{data.size()});
- for (int i = 0; i < data.size(); i++) {
- a.setObject(i, data.get(i));
- }
- return a;
- } else if (d0 instanceof PyComplex) {
- Array a = Array.factory(DataType.OBJECT, new int[]{data.size()});
- PyComplex d;
- for (int i = 0; i < data.size(); i++) {
- d = (PyComplex) data.get(i);
- a.setObject(i, new Complex(d.real, d.imag));
- }
- return a;
- } else if (d0 instanceof List) {
- int ndim = data.size();
- int len = ((List) d0).size();
- DataType dt = ArrayUtil.objectsToType((List) d0);
- Array a = Array.factory(dt, new int[]{ndim, len});
- for (int i = 0; i < ndim; i++) {
- List d = (List) data.get(i);
- for (int j = 0; j < len; j++) {
- a.setObject(i * len + j, d.get(j));
- }
- }
- return a;
- } else {
- Array a = Array.factory(DataType.OBJECT, new int[]{data.size()});
- for (int i = 0; i < data.size(); i++) {
- a.setObject(i, data.get(i));
- }
- return a;
- }
- }
-
- /**
- * Array range
- *
- * @param start Start value
- * @param stop Stop value
- * @param step Step value
- * @return Array
- */
- public static Array arrayRange_bak(Number start, Number stop, final Number step) {
- if (stop == null) {
- stop = start;
- start = 0;
- }
- DataType dataType = ArrayUtil.objectsToType(new Object[]{
- start,
- stop,
- step});
- double startv = start.doubleValue();
- double stopv = stop.doubleValue();
- double stepv = step.doubleValue();
- List data = new ArrayList<>();
- if (dataType == DataType.FLOAT || dataType == DataType.DOUBLE) {
- while (startv < stopv) {
- data.add(startv);
- startv = BigDecimalUtil.add(startv, stepv);
- }
- } else {
- while (startv < stopv) {
- data.add(startv);
- startv += stepv;
- }
- }
- int length = data.size();
- Array a = Array.factory(dataType, new int[]{length});
- for (int i = 0; i < length; i++) {
- a.setObject(i, data.get(i));
- }
- return a;
- }
-
- /**
- * Array range
- *
- * @param start Start value
- * @param stop Stop value
- * @param step Step value
- * @return Array
- */
- public static Array arrayRange(Number start, Number stop, final Number step) {
- if (stop == null) {
- stop = start;
- start = 0;
- }
- DataType dataType = ArrayUtil.objectsToType(new Object[]{
- start,
- stop,
- step});
- double startv = start.doubleValue();
- double stopv = stop.doubleValue();
- double stepv = step.doubleValue();
- final int length = Math.max(0, (int) Math.ceil((stopv
- - startv) / stepv));
- Array a = Array.factory(dataType, new int[]{length});
- if (dataType == DataType.FLOAT || dataType == DataType.DOUBLE) {
- for (int i = 0; i < length; i++) {
- a.setObject(i, BigDecimalUtil.add(BigDecimalUtil.mul(i, stepv), startv));
- }
- } else {
- for (int i = 0; i < length; i++) {
- a.setObject(i, i * stepv + startv);
- }
- }
- return a;
- }
-
- /**
- * Array range
- *
- * @param start Start value
- * @param length Length
- * @param step Step value
- * @return Array
- */
- public static Array arrayRange1(Number start, final int length, final Number step) {
- DataType dataType = ArrayUtil.objectsToType(new Object[]{
- start,
- step});
- double startv = start.doubleValue();
- double stepv = step.doubleValue();
- Array a = Array.factory(dataType, new int[]{length});
- if (dataType == DataType.FLOAT || dataType == DataType.DOUBLE) {
- for (int i = 0; i < length; i++) {
- a.setObject(i, BigDecimalUtil.add(BigDecimalUtil.mul(i, stepv), startv));
- }
- } else {
- for (int i = 0; i < length; i++) {
- a.setObject(i, i * stepv + startv);
- }
- }
- return a;
- }
-
- /**
- * Array line space
- *
- * @param start Start value
- * @param stop Stop value
- * @param n Number value
- * @param endpoint If stop is included
- * @return Array
- */
- public static Array lineSpace(Number start, Number stop, final int n, boolean endpoint) {
- if (stop == null) {
- stop = start;
- start = 0;
- }
- double startv = start.doubleValue();
- double stopv = stop.doubleValue();
- int div = endpoint ? (n - 1) : n;
- double stepv = (stopv - startv) / div;
- Array a = Array.factory(DataType.DOUBLE, new int[]{n});
- double v = startv;
- for (int i = 0; i < n; i++) {
- a.setDouble(i, v);
- v += stepv;
- }
- if (endpoint) {
- if (a.getDouble(n - 1) != stopv) {
- a.setDouble(n - 1, stopv);
- }
- }
-
- return a;
- }
-
- /**
- * Array line space
- *
- * @param start Start value
- * @param stop Stop value
- * @param n Number value
- * @param endpoint If stop is included
- * @return Array
- */
- public static Array lineSpace_bak(Number start, Number stop, final int n, boolean endpoint) {
- if (stop == null) {
- stop = start;
- start = 0;
- }
- double startv = start.doubleValue();
- double stopv = stop.doubleValue();
- double stepv = (stopv - startv) / (n - 1);
- double endv = n * stepv + startv;
- int nn = n;
- if (endpoint) {
- if (endv < stopv) {
- nn += 1;
- }
- } else if (endv >= stopv) {
- nn -= 1;
- }
- Array a = Array.factory(DataType.FLOAT, new int[]{nn});
- for (int i = 0; i < nn; i++) {
- a.setObject(i, BigDecimalUtil.add(BigDecimalUtil.mul(i, stepv), startv));
- }
-
- return a;
- }
-
- /**
- * Get zero array
- *
- * @param n Number
- * @return Array
- */
- public static Array zeros(int n) {
- Array a = Array.factory(DataType.FLOAT, new int[]{n});
- for (int i = 0; i < n; i++) {
- a.setFloat(i, 0);
- }
-
- return a;
- }
-
- /**
- * Get zero array
- *
- * @param shape Shape
- * @param dtype Data type
- * @return Array Result array
- */
- public static Array zeros(List shape, String dtype) {
- DataType dt = toDataType(dtype);
- return zeros(shape, dt);
- }
-
- /**
- * Get zero array
- *
- * @param shape Shape
- * @param dtype Data type
- * @return Array Result array
- */
- public static Array zeros(List shape, DataType dtype) {
- int[] ashape = new int[shape.size()];
- for (int i = 0; i < shape.size(); i++) {
- ashape[i] = shape.get(i);
- }
- Array a = Array.factory(dtype, ashape);
-
- return a;
- }
-
- /**
- * Return a new array of given shape and type, filled with fill value.
- *
- * @param shape Shape
- * @param fillValue Fill value
- * @param dtype Data type
- * @return Array Result array
- */
- public static Array full(List shape, Object fillValue, DataType dtype) {
- int[] ashape = new int[shape.size()];
- for (int i = 0; i < shape.size(); i++) {
- ashape[i] = shape.get(i);
- }
- if (dtype == null) {
- dtype = ArrayMath.getDataType(fillValue);
- }
- Array a = Array.factory(dtype, ashape);
-
- for (int i = 0; i < a.getSize(); i++) {
- a.setObject(i, fillValue);
- }
-
- return a;
- }
-
- /**
- * Get ones array
- *
- * @param n Number
- * @return Array Result array
- */
- public static Array ones(int n) {
- Array a = Array.factory(DataType.FLOAT, new int[]{n});
- for (int i = 0; i < n; i++) {
- a.setFloat(i, 1);
- }
-
- return a;
- }
-
- /**
- * Get ones array
- *
- * @param shape Shape
- * @param dtype Data type
- * @return Array Result array
- */
- public static Array ones(List shape, String dtype) {
- DataType dt = toDataType(dtype);
- int[] ashape = new int[shape.size()];
- for (int i = 0; i < shape.size(); i++) {
- ashape[i] = shape.get(i);
- }
- Array a = Array.factory(dt, ashape);
- for (int i = 0; i < a.getSize(); i++) {
- a.setObject(i, 1);
- }
-
- return a;
- }
-
- /**
- * Return the identity array - a square array with ones on the main
- * diagonal.
- *
- * @param n Number of rows (and columns) in n x n output.
- * @param dtype Data type
- * @return Identity array
- */
- public static Array identity(int n, String dtype) {
- DataType dt = toDataType(dtype);
- int[] shape = new int[]{n, n};
- Array a = Array.factory(dt, shape);
- IndexIterator index = a.getIndexIterator();
- int[] current;
- while (index.hasNext()) {
- index.next();
- current = index.getCurrentCounter();
- if (current[0] == current[1]) {
- index.setObjectCurrent(1);
- } else {
- index.setObjectCurrent(0);
- }
- }
-
- return a;
- }
-
- /**
- * Return a 2-D array with ones on the diagonal and zeros elsewhere.
- *
- * @param n Number of rows in the output.
- * @param m Number of columns in the output.
- * @param k Index of the diagonal: 0 (the default) refers to the main
- * diagonal, a positive value refers to an upper diagonal, and a negative
- * value to a lower diagonal.
- * @param dtype Data type
- * @return Created array
- */
- public static Array eye(int n, int m, int k, String dtype) {
- DataType dt = toDataType(dtype);
- int[] shape = new int[]{n, m};
- Array a = Array.factory(dt, shape);
- IndexIterator index = a.getIndexIterator();
- int[] current;
- int i, j;
- while (index.hasNext()) {
- index.next();
- current = index.getCurrentCounter();
- i = current[0];
- j = current[1] - k;
- if (i == j) {
- index.setObjectCurrent(1);
- } else {
- index.setObjectCurrent(0);
- }
- }
-
- return a;
- }
-
- /**
- * Extract a diagonal or construct a diagonal array.
- *
- * @param a If a is a 2-D array, return a copy of its k-th diagonal. If a is
- * a 1-D array, return a 2-D array with a on the k-th diagonal.
- * @param k Diagonal in question.
- * @return Diagonal array
- */
- public static Array diag(Array a, int k) {
- if (a.getRank() == 2) {
- int m = a.getShape()[0];
- int n = a.getShape()[1];
- int len = Math.min(m, n) - Math.abs(k);
- Array r = Array.factory(a.getDataType(), new int[]{len});
- IndexIterator index = a.getIndexIterator();
- int[] current;
- int idx = 0, i, j;
- while (index.hasNext()) {
- index.next();
- current = index.getCurrentCounter();
- i = current[0];
- j = current[1] - k;
- if (i == j) {
- r.setObject(idx, index.getObjectCurrent());
- idx += 1;
- if (idx == len) {
- break;
- }
- }
- }
- return r;
- } else {
- int m = a.getShape()[0];
- Array r = Array.factory(a.getDataType(), new int[]{m, m});
- for (int i = 0; i < m; i++) {
- for (int j = 0; j < m; j++) {
- if (i == j - k) {
- r.setObject(i * m + j, a.getObject(i));
- } else {
- r.setObject(i * m + j, 0);
- }
- }
- }
- return r;
- }
- }
-
- /**
- * Repeat a value n times
- *
- * @param v The value
- * @param n N times
- * @return Repeated array
- */
- public static Array repeat(Number v, int n) {
- DataType dt = ArrayMath.getDataType(v);
- Array r = Array.factory(dt, new int[]{n});
- for (int i = 0; i < n; i++) {
- r.setObject(i, v);
- }
-
- return r;
- }
-
- /**
- * Repeat elements of an array.
- *
- * @param a The value
- * @param repeats The number of repetitions for each element
- * @return Repeated array
- */
- public static Array repeat(Array a, List repeats) {
- Array r;
- if (repeats.size() == 1) {
- int n = repeats.get(0);
- r = Array.factory(a.getDataType(), new int[]{(int) a.getSize() * n});
- for (int i = 0; i < a.getSize(); i++) {
- for (int j = 0; j < n; j++) {
- r.setObject(i * n + j, a.getObject(i));
- }
- }
- } else {
- int n = 0;
- for (int i = 0; i < repeats.size(); i++) {
- n += repeats.get(i);
- }
- r = Array.factory(a.getDataType(), new int[]{n});
- int idx = 0;
- for (int i = 0; i < a.getSize(); i++) {
- for (int j = 0; j < repeats.get(i); j++) {
- r.setObject(idx, a.getObject(i));
- idx += 1;
- }
- }
- }
-
- return r;
- }
-
- /**
- * Repeat elements of an array.
- *
- * @param a The value
- * @param repeats The number of repetitions for each element
- * @param axis The axis
- * @return Repeated array
- */
- public static Array repeat(Array a, List repeats, int axis) {
- Array r;
- if (repeats.size() == 1) {
- int n = repeats.get(0);
- int[] shape = a.getShape();
- shape[axis] = shape[axis] * n;
- r = Array.factory(a.getDataType(), shape);
- Index aindex = a.getIndex();
- Index index = r.getIndex();
- int[] current;
- for (int i = 0; i < r.getSize(); i++) {
- current = index.getCurrentCounter();
- current[axis] = current[axis] / n;
- aindex.set(current);
- r.setObject(index, a.getObject(aindex));
- index.incr();
- }
- } else {
- int n = 0;
- int[] rsum = new int[repeats.size()];
- for (int i = 0; i < repeats.size(); i++) {
- rsum[i] = n;
- n += repeats.get(i);
- }
- int[] shape = a.getShape();
- shape[axis] = n;
- r = Array.factory(a.getDataType(), shape);
- Index aindex = a.getIndex();
- Index index = r.getIndex();
- int[] current;
- int idx;
- for (int i = 0; i < a.getSize(); i++) {
- current = aindex.getCurrentCounter();
- idx = current[axis];
- for (int j = 0; j < repeats.get(idx); j++) {
- current[axis] = rsum[idx] + j;
- index.set(current);
- r.setObject(index, a.getObject(aindex));
- }
- aindex.incr();
- }
- }
-
- return r;
- }
-
- /**
- * Repeat a value n times
- *
- * @param v The value
- * @param n N times
- * @return Repeated array
- */
- public static Array tile(Number v, int n) {
- DataType dt = ArrayMath.getDataType(v);
- Array r = Array.factory(dt, new int[]{n});
- for (int i = 0; i < n; i++) {
- r.setObject(i, v);
- }
-
- return r;
- }
-
- /**
- * Repeat a value n times
- *
- * @param v The value
- * @param repeats The number of repetitions for each element
- * @return Repeated array
- */
- public static Array tile(Number v, List repeats) {
- int[] shape = new int[repeats.size()];
- for (int i = 0; i < repeats.size(); i++) {
- shape[i] = repeats.get(i);
- }
- DataType dt = ArrayMath.getDataType(v);
- Array r = Array.factory(dt, shape);
- for (int i = 0; i < r.getSize(); i++) {
- r.setObject(i, v);
- }
-
- return r;
- }
-
- /**
- * Repeat elements of an array.
- *
- * @param a The value
- * @param repeats The number of repetitions for each element
- * @return Repeated array
- */
- public static Array tile(Array a, List repeats) {
- if (a.getRank() > repeats.size()) {
- int n = a.getRank() - repeats.size();
- for (int i = 0; i < n; i++) {
- repeats.add(0, 1);
- }
- } else if (a.getRank() < repeats.size()) {
- int[] shape = a.getShape();
- int[] nshape = new int[repeats.size()];
- int n = repeats.size() - shape.length;
- for (int i = 0; i < nshape.length; i++) {
- if (i < n) {
- nshape[i] = 1;
- } else {
- nshape[i] = shape[i - n];
- }
- }
- a = a.reshape(nshape);
- }
- int[] ashape = a.getShape();
- int[] shape = a.getShape();
- for (int i = 0; i < shape.length; i++) {
- shape[i] = shape[i] * repeats.get(i);
- }
- Array r = Array.factory(a.getDataType(), shape);
- Index index = r.getIndex();
- Index aindex = a.getIndex();
- int[] current;
- int idx;
- for (int i = 0; i < r.getSize(); i++) {
- current = index.getCurrentCounter();
- for (int j = 0; j < repeats.size(); j++) {
- idx = current[j];
- idx = idx % ashape[j];
- current[j] = idx;
- }
- aindex.set(current);
- r.setObject(index, a.getObject(aindex));
- index.incr();
- }
-
- return r;
- }
-
- /**
- * Get random value
- *
- * @return Random value
- */
- public static double rand() {
- Random r = new Random();
- return r.nextDouble();
- }
-
- /**
- * Get random array - one dimension
- *
- * @param n Array length
- * @return Result array
- */
- public static Array rand(int n) {
- Array r = Array.factory(DataType.DOUBLE, new int[]{n});
- Random rd = new Random();
- for (int i = 0; i < r.getSize(); i++) {
- r.setDouble(i, rd.nextDouble());
- }
-
- return r;
- }
-
- /**
- * Get random array
- *
- * @param shape Shape
- * @return Array Result array
- */
- public static Array rand(List shape) {
- int[] ashape = new int[shape.size()];
- for (int i = 0; i < shape.size(); i++) {
- ashape[i] = shape.get(i);
- }
- Array a = Array.factory(DataType.DOUBLE, ashape);
- Random rd = new Random();
- for (int i = 0; i < a.getSize(); i++) {
- a.setDouble(i, rd.nextDouble());
- }
-
- return a;
- }
-
- private static DataType objectsToType(final Object[] objects) {
- if (objects.length == 0) {
- return DataType.INT;
- }
- short new_sz, sz = -1;
- DataType dataType = DataType.INT;
- for (final Object o : objects) {
- final DataType _type = ArrayMath.getDataType(o);
- new_sz = ArrayMath.typeToNBytes(_type);
- if (new_sz > sz) {
- dataType = _type;
- }
- }
- return dataType;
- }
-
- private static DataType objectsToType(final List objects) {
- if (objects.isEmpty()) {
- return DataType.INT;
- }
- short new_sz, sz = -1;
- DataType dataType = DataType.INT;
- for (final Object o : objects) {
- final DataType _type = ArrayMath.getDataType(o);
- new_sz = ArrayMath.typeToNBytes(_type);
- if (new_sz > sz) {
- dataType = _type;
- sz = new_sz;
- }
- }
- return dataType;
- }
-
- /**
- * Merge data type to one data type
- *
- * @param dt1 Data type 1
- * @param dt2 Data type 2
- * @return Merged data type
- */
- public static DataType mergeDataType(DataType dt1, DataType dt2) {
- if (dt1 == DataType.OBJECT || dt2 == DataType.OBJECT) {
- return DataType.OBJECT;
- } else if (dt1 == DataType.STRING || dt2 == DataType.STRING) {
- return DataType.STRING;
- } else if (dt1 == DataType.DOUBLE || dt2 == DataType.DOUBLE) {
- return DataType.DOUBLE;
- } else if (dt1 == DataType.FLOAT || dt2 == DataType.FLOAT) {
- return DataType.FLOAT;
- } else {
- return dt1;
- }
- }
-
- //
- //
- /**
- * Array to string
- *
- * @param a Array a
- * @return String
- */
- public static String convertToString(Array a) {
- StringBuilder sbuff = new StringBuilder();
- sbuff.append("array(");
- int ndim = a.getRank();
- if (ndim > 1) {
- sbuff.append("[");
- }
- int i = 0, n = 0;
- IndexIterator ii = a.getIndexIterator();
- int shapeIdx = ndim - 1;
- if (shapeIdx < 0) {
- sbuff.append("[");
- sbuff.append(ii.getObjectNext());
- sbuff.append("])");
- return sbuff.toString();
- }
-
- int len = a.getShape()[shapeIdx];
- Object data;
- String dstr;
- while (ii.hasNext()) {
- if (i == 0) {
- if (n > 0) {
- sbuff.append("\n ");
- }
- sbuff.append("[");
- }
- data = ii.getObjectNext();
- dstr = data.toString();
- if (a.getDataType() == DataType.BOOLEAN) {
- dstr = GlobalUtil.capitalize(dstr);
- }
- sbuff.append(dstr);
- i += 1;
- if (i == len) {
- sbuff.append("]");
- len = a.getShape()[shapeIdx];
- i = 0;
- } else {
- sbuff.append(", ");
- }
- n += 1;
- if (n > 200) {
- sbuff.append("...]");
- break;
- }
- }
- if (ndim > 1) {
- sbuff.append("]");
- }
- sbuff.append(")");
- return sbuff.toString();
- }
-
- /**
- * Array to string
- *
- * @param a Array a
- * @return String
- */
- public static String toString_old(Array a) {
- StringBuilder sbuff = new StringBuilder();
- sbuff.append("array(");
- int ndim = a.getRank();
- if (ndim > 1) {
- sbuff.append("[");
- }
- int i = 0;
- int shapeIdx = ndim - 1;
- int len = a.getShape()[shapeIdx];
- IndexIterator ii = a.getIndexIterator();
- while (ii.hasNext()) {
- if (i == 0) {
- sbuff.append("[");
- }
- Object data = ii.getObjectNext();
- sbuff.append(data);
- i += 1;
- if (i == len) {
- sbuff.append("]");
- len = a.getShape()[shapeIdx];
- i = 0;
- } else {
- sbuff.append(", ");
- }
- }
- if (ndim > 1) {
- sbuff.append("]");
- }
- return sbuff.toString();
- }
-
- /**
- * Get array list from StationData
- *
- * @param stdata StationData
- * @return Array list
- */
- public static List getArraysFromStationData(StationData stdata) {
- int n = stdata.getStNum();
- int[] shape = new int[1];
- shape[0] = n;
- Array lon = Array.factory(DataType.FLOAT, shape);
- Array lat = Array.factory(DataType.FLOAT, shape);
- Array value = Array.factory(DataType.FLOAT, shape);
- double v;
- for (int i = 0; i < n; i++) {
- lon.setFloat(i, (float) stdata.getX(i));
- lat.setFloat(i, (float) stdata.getY(i));
- v = stdata.getValue(i);
- if (v == stdata.missingValue) {
- v = Double.NaN;
- }
- value.setFloat(i, (float) v);
- }
-
- List r = new ArrayList<>();
- r.add(lon);
- r.add(lat);
- r.add(value);
- return r;
- }
-
- //
- //
- /**
- * Get data type string
- *
- * @param dt The data type
- * @return Data type string
- */
- public static String dataTypeString(DataType dt) {
- String str = "string";
- switch (dt) {
- case BYTE:
- str = "byte";
- break;
- case SHORT:
- str = "short";
- break;
- case INT:
- str = "int";
- break;
- case FLOAT:
- str = "float";
- break;
- case DOUBLE:
- str = "double";
- break;
- }
-
- return str;
- }
-
- /**
- * To data type - ucar.ma2
- *
- * @param dt Data type string
- * @return Data type
- */
- public static DataType toDataType(String dt) {
- if (dt.contains("%")) {
- dt = dt.split("%")[1];
- }
- switch (dt.toLowerCase()) {
- case "c":
- case "s":
- case "string":
- return DataType.STRING;
- case "b":
- case "byte":
- return DataType.BYTE;
- case "short":
- return DataType.SHORT;
- case "i":
- case "int":
- return DataType.INT;
- case "f":
- case "float":
- return DataType.FLOAT;
- case "d":
- case "double":
- return DataType.DOUBLE;
- case "bool":
- case "boolean":
- return DataType.BOOLEAN;
- default:
- return DataType.OBJECT;
- }
- }
-
- /**
- * Convert array to integer type
- *
- * @param a Array a
- * @return Result array
- */
- public static Array toInteger(Array a) {
- Array r = Array.factory(DataType.INT, a.getShape());
- if (a.getDataType().isNumeric()) {
- for (int i = 0; i < r.getSize(); i++) {
- r.setInt(i, a.getInt(i));
- }
- } else {
- if (a.getDataType() == DataType.BOOLEAN) {
- for (int i = 0; i < r.getSize(); i++) {
- r.setInt(i, a.getBoolean(i) ? 1 : 0);
- }
- } else {
- for (int i = 0; i < r.getSize(); i++) {
- r.setInt(i, Integer.valueOf(a.getObject(i).toString()));
- }
- }
- }
-
- return r;
- }
-
- /**
- * Convert array to float type
- *
- * @param a Array a
- * @return Result array
- */
- public static Array toFloat(Array a) {
- Array r = Array.factory(DataType.FLOAT, a.getShape());
- if (a.getDataType().isNumeric()) {
- for (int i = 0; i < r.getSize(); i++) {
- r.setFloat(i, a.getFloat(i));
- }
- } else {
- for (int i = 0; i < r.getSize(); i++) {
- r.setFloat(i, Float.valueOf(a.getObject(i).toString()));
- }
- }
-
- return r;
- }
-
- /**
- * Convert array to double type
- *
- * @param a Array a
- * @return Result array
- */
- public static Array toDouble(Array a) {
- Array r = Array.factory(DataType.DOUBLE, a.getShape());
- if (a.getDataType().isNumeric()) {
- for (int i = 0; i < r.getSize(); i++) {
- r.setDouble(i, a.getDouble(i));
- }
- } else {
- for (int i = 0; i < r.getSize(); i++) {
- r.setDouble(i, Double.valueOf(a.getObject(i).toString()));
- }
- }
-
- return r;
- }
-
- /**
- * Convert array to boolean type
- *
- * @param a Array a
- * @return Result array
- */
- public static Array toBoolean(Array a) {
- Array r = Array.factory(DataType.BOOLEAN, a.getShape());
- for (int i = 0; i < r.getSize(); i++) {
- r.setBoolean(i, a.getDouble(i) != 0);
- }
-
- return r;
- }
-
- /**
- * Concatenate arrays to one array along a axis
- *
- * @param arrays Array list
- * @param axis The axis
- * @return Concatenated array
- * @throws org.meteoinfo.ndarray.InvalidRangeException
- */
- public static Array concatenate(List arrays, Integer axis) throws InvalidRangeException {
- int ndim = arrays.get(0).getRank();
- if (axis == -1) {
- axis = ndim - 1;
- }
- int len = 0;
- int[] lens = new int[arrays.size()];
- int i = 0;
- List indexList = new ArrayList<>();
- for (Array a : arrays) {
- len += a.getShape()[axis];
- lens[i] = len;
- indexList.add(Index.factory(a.getShape()));
- i += 1;
- }
- int[] shape = arrays.get(0).getShape();
- shape[axis] = len;
- Array r = Array.factory(arrays.get(0).getDataType(), shape);
- int[] current;
- IndexIterator ii = r.getIndexIterator();
- Index index;
- int idx = 0;
- while (ii.hasNext()) {
- ii.next();
- current = ii.getCurrentCounter();
- for (i = 0; i < lens.length; i++) {
- if (current[axis] < lens[i]) {
- idx = i;
- break;
- }
- }
- if (idx > 0) {
- current[axis] = current[axis] - lens[idx - 1];
- }
- index = indexList.get(idx);
- index.set(current);
- ii.setObjectCurrent(arrays.get(idx).getObject(index));
- }
-
- return r;
- }
-
- /**
- * Concatenate two arrays to one array along a axis
- *
- * @param a Array a
- * @param b Array b
- * @param axis The axis
- * @return Concatenated array
- * @throws org.meteoinfo.ndarray.InvalidRangeException
- */
- public static Array concatenate(Array a, Array b, Integer axis) throws InvalidRangeException {
- int n = a.getRank();
- int[] shape = a.getShape();
- if (axis == -1) {
- axis = n - 1;
- }
- int nn = shape[axis];
- int[] bshape = b.getShape();
- int[] nshape = new int[n];
- for (int i = 0; i < n; i++) {
- if (i == axis) {
- nshape[i] = shape[i] + bshape[i];
- } else {
- nshape[i] = shape[i];
- }
- }
- Array r = Array.factory(a.getDataType(), nshape);
- Index indexr = r.getIndex();
- Index indexa = a.getIndex();
- Index indexb = b.getIndex();
- int[] current;
- for (int i = 0; i < r.getSize(); i++) {
- current = indexr.getCurrentCounter();
- if (current[axis] < nn) {
- indexa.set(current);
- r.setObject(indexr, a.getObject(indexa));
- } else {
- current[axis] = current[axis - nn];
- indexb.set(current);
- r.setObject(indexr, b.getObject(indexb));
- }
- indexr.incr();
- }
-
- return r;
- }
-
- /**
- * Sort array along an axis
- *
- * @param a Array a
- * @param axis The axis
- * @return Sorted array
- * @throws InvalidRangeException
- */
- public static Array sort(Array a, Integer axis) throws InvalidRangeException {
- int n = a.getRank();
- int[] shape = a.getShape();
- if (axis == null) {
- int[] nshape = new int[1];
- nshape[0] = (int) a.getSize();
- Array r = Array.factory(a.getDataType(), nshape);
- List tlist = new ArrayList();
- IndexIterator ii = a.getIndexIterator();
- while (ii.hasNext()) {
- tlist.add(ii.getObjectNext());
- }
- Collections.sort(tlist);
- for (int i = 0; i < r.getSize(); i++) {
- r.setObject(i, tlist.get(i));
- }
-
- return r;
- } else {
- if (axis == -1) {
- axis = n - 1;
- }
- int nn = shape[axis];
- Array r = Array.factory(a.getDataType(), shape);
- Index indexr = r.getIndex();
- int[] current;
- List ranges = new ArrayList<>();
- for (int i = 0; i < n; i++) {
- if (i == axis) {
- ranges.add(new Range(0, 0, 1));
- } else {
- ranges.add(new Range(0, shape[i] - 1, 1));
- }
- }
- IndexIterator rii = r.sectionNoReduce(ranges).getIndexIterator();
- while (rii.hasNext()) {
- rii.next();
- current = rii.getCurrentCounter();
- ranges = new ArrayList<>();
- for (int j = 0; j < n; j++) {
- if (j == axis) {
- ranges.add(new Range(0, shape[j] - 1, 1));
- } else {
- ranges.add(new Range(current[j], current[j], 1));
- }
- }
- List tlist = new ArrayList();
- IndexIterator ii = a.getRangeIterator(ranges);
- while (ii.hasNext()) {
- tlist.add(ii.getObjectNext());
- }
- Collections.sort(tlist);
- for (int j = 0; j < nn; j++) {
- indexr.set(current);
- r.setObject(indexr, tlist.get(j));
- current[axis] = current[axis] + 1;
- }
- }
-
- return r;
- }
- }
-
- /**
- * Get sorted array index along an axis
- *
- * @param a Array a
- * @param axis The axis
- * @return Index of sorted array
- * @throws InvalidRangeException
- */
- public static Array argSort(Array a, Integer axis) throws InvalidRangeException {
- int n = a.getRank();
- int[] shape = a.getShape();
- Object v;
- if (axis == null) {
- int[] nshape = new int[1];
- nshape[0] = (int) a.getSize();
- Array r = Array.factory(DataType.INT, nshape);
- List stlist = new ArrayList();
- IndexIterator ii = a.getIndexIterator();
- while (ii.hasNext()) {
- v = ii.getObjectNext();
- stlist.add(v);
- }
- //Collections.sort(stlist);
- ListIndexComparator comparator = new ListIndexComparator(stlist);
- Integer[] indexes = comparator.createIndexArray();
- Arrays.sort(indexes, comparator);
- for (int i = 0; i < r.getSize(); i++) {
- r.setInt(i, indexes[i]);
- }
-
- return r;
- } else {
- if (axis == -1) {
- axis = n - 1;
- }
- int nn = shape[axis];
- Array r = Array.factory(DataType.INT, shape);
- Index indexr = r.getIndex();
- int[] current;
- List ranges = new ArrayList<>();
- for (int i = 0; i < n; i++) {
- if (i == axis) {
- ranges.add(new Range(0, 0, 1));
- } else {
- ranges.add(new Range(0, shape[i] - 1, 1));
- }
- }
- IndexIterator rii = r.sectionNoReduce(ranges).getIndexIterator();
- while (rii.hasNext()) {
- rii.next();
- current = rii.getCurrentCounter();
- ranges = new ArrayList<>();
- for (int j = 0; j < n; j++) {
- if (j == axis) {
- ranges.add(new Range(0, shape[j] - 1, 1));
- } else {
- ranges.add(new Range(current[j], current[j], 1));
- }
- }
- List stlist = new ArrayList();
- IndexIterator ii = a.getRangeIterator(ranges);
- while (ii.hasNext()) {
- v = ii.getObjectNext();
- stlist.add(v);
- }
- //Collections.sort(stlist);
- ListIndexComparator comparator = new ListIndexComparator(stlist);
- Integer[] indexes = comparator.createIndexArray();
- Arrays.sort(indexes, comparator);
- for (int j = 0; j < nn; j++) {
- indexr.set(current);
- r.setObject(indexr, indexes[j]);
- current[axis] = current[axis] + 1;
- }
- }
-
- return r;
- }
- }
-
- /**
- * Convert array to N-Dimension double Java array
- *
- * @param a Array a
- * @param dtype Data type string
- * @return N-D Java array
- */
- public static Object copyToNDJavaArray(Array a, String dtype) {
- if (dtype == null) {
- return copyToNDJavaArray(a);
- }
-
- switch (dtype.toLowerCase()) {
- case "double":
- return copyToNDJavaArray_Double(a);
- case "long":
- return copyToNDJavaArray_Long(a);
- default:
- return copyToNDJavaArray(a);
- }
- }
-
- /**
- * Convert array to N-Dimension double Java array
- *
- * @param a Array a
- * @return N-D Java array
- */
- public static Object copyToNDJavaArray(Array a) {
- Object javaArray;
- try {
- javaArray = java.lang.reflect.Array.newInstance(Double.TYPE, a.getShape());
- } catch (IllegalArgumentException | NegativeArraySizeException e) {
- throw new IllegalArgumentException(e);
- }
- IndexIterator iter = a.getIndexIterator();
- reflectArrayCopyOut(javaArray, a, iter);
-
- return javaArray;
- }
-
- /**
- * Convert array to N-Dimension double Java array
- *
- * @param a Array a
- * @return N-D Java array
- */
- public static Object copyToNDJavaArray_Long(Array a) {
- Object javaArray;
- try {
- javaArray = java.lang.reflect.Array.newInstance(Long.TYPE, a.getShape());
- } catch (IllegalArgumentException | NegativeArraySizeException e) {
- throw new IllegalArgumentException(e);
- }
- IndexIterator iter = a.getIndexIterator();
- reflectArrayCopyOut(javaArray, a, iter);
-
- return javaArray;
- }
-
- /**
- * Convert array to N-Dimension double Java array
- *
- * @param a Array a
- * @return N-D Java array
- */
- public static Object copyToNDJavaArray_Double(Array a) {
- Object javaArray;
- try {
- javaArray = java.lang.reflect.Array.newInstance(Double.TYPE, a.getShape());
- } catch (IllegalArgumentException | NegativeArraySizeException e) {
- throw new IllegalArgumentException(e);
- }
- IndexIterator iter = a.getIndexIterator();
- reflectArrayCopyOut(javaArray, a, iter);
-
- return javaArray;
- }
-
- private static void reflectArrayCopyOut(Object jArray, Array aa, IndexIterator aaIter) {
- Class cType = jArray.getClass().getComponentType();
-
- if (!cType.isArray()) {
- if (cType == long.class) {
- copyTo1DJavaArray_Long(aaIter, jArray);
- } else {
- copyTo1DJavaArray(aaIter, jArray);
- }
- } else {
- for (int i = 0; i < java.lang.reflect.Array.getLength(jArray); i++) {
- reflectArrayCopyOut(java.lang.reflect.Array.get(jArray, i), aa, aaIter);
- }
- }
- }
-
- protected static void copyTo1DJavaArray(IndexIterator iter, Object javaArray) {
- double[] ja = (double[]) javaArray;
- for (int i = 0; i < ja.length; i++) {
- ja[i] = iter.getDoubleNext();
- }
- }
-
- protected static void copyTo1DJavaArray_Long(IndexIterator iter, Object javaArray) {
- long[] ja = (long[]) javaArray;
- for (int i = 0; i < ja.length; i++) {
- ja[i] = iter.getLongNext();
- }
- }
-
- /**
- * Return a new array with sub-arrays along an axis deleted
- *
- * @param a Input array
- * @param idx Index
- * @param axis The axis
- * @return
- */
- public static Array delete(Array a, int idx, int axis) {
- int[] shape = a.getShape();
- int n = shape.length;
- int[] nshape = new int[n];
- for (int i = 0; i < n; i++) {
- if (i == axis) {
- nshape[i] = shape[i] - 1;
- } else {
- nshape[i] = shape[i];
- }
- }
- Array r = Array.factory(a.getDataType(), nshape);
- IndexIterator ii = a.getIndexIterator();
- int[] current;
- int i = 0;
- while (ii.hasNext()) {
- ii.next();
- current = ii.getCurrentCounter();
- if (current[axis] != idx) {
- r.setObject(i, ii.getObjectCurrent());
- i += 1;
- }
- }
-
- return r;
- }
-
- /**
- * Return a new array with sub-arrays along an axis deleted
- *
- * @param a Input array
- * @param idx Index
- * @param axis The axis
- * @return
- */
- public static Array delete(Array a, List idx, int axis) {
- int[] shape = a.getShape();
- int n = shape.length;
- int[] nshape = new int[n];
- for (int i = 0; i < n; i++) {
- if (i == axis) {
- nshape[i] = shape[i] - idx.size();
- } else {
- nshape[i] = shape[i];
- }
- }
- Array r = Array.factory(a.getDataType(), nshape);
- IndexIterator ii = a.getIndexIterator();
- int[] current;
- int i = 0;
- while (ii.hasNext()) {
- ii.next();
- current = ii.getCurrentCounter();
- if (!idx.contains(current[axis])) {
- r.setObject(i, ii.getObjectCurrent());
- i += 1;
- }
- }
-
- return r;
- }
-
- //
- //
- /**
- * Histogram x/y array
- *
- * @param a Data array
- * @param nbins bin number
- * @return X/Y arrays
- */
- public static List histogram(Array a, int nbins) {
- double min = ArrayMath.getMinimum(a);
- double max = ArrayMath.getMaximum(a);
- double interval = BigDecimalUtil.div(BigDecimalUtil.sub(max, min), nbins);
- double[] bins = new double[nbins + 1];
- for (int i = 0; i < nbins + 1; i++) {
- bins[i] = min;
- min = BigDecimalUtil.add(min, interval);
- }
- Array ba = Array.factory(DataType.DOUBLE, new int[]{bins.length}, bins);
- return histogram(a, ba);
- }
-
- /**
- * Histogram x/y array
- *
- * @param a Data array
- * @param bins bin edges
- * @return X/Y arrays
- */
- public static List histogram(Array a, Array bins) {
- int n = (int) bins.getSize();
- Array hist = Array.factory(DataType.INT, new int[]{n - 1});
- double v;
- for (int i = 0; i < a.getSize(); i++) {
- v = a.getDouble(i);
- for (int j = 0; j < n - 1; j++) {
- if (j == n - 2) {
- if (v >= bins.getDouble(j) && v <= bins.getDouble(j + 1)) {
- hist.setInt(j, hist.getInt(j) + 1);
- break;
- }
- } else if (v >= bins.getDouble(j) && v < bins.getDouble(j + 1)) {
- hist.setInt(j, hist.getInt(j) + 1);
- break;
- }
- }
- }
-
- List r = new ArrayList<>();
- r.add(hist);
- r.add(bins);
-
- return r;
- }
-
- /**
- * Histogram x/y array
- *
- * @param a Data array
- * @param bins bin edges
- * @return X/Y arrays
- */
- public static List histogram(Array a, double[] bins) {
- int n = bins.length;
- double delta = bins[1] - bins[0];
- int[] count = new int[n + 1];
- double v;
- for (int i = 0; i < a.getSize(); i++) {
- v = a.getDouble(i);
- if (v < bins[0]) {
- count[0] += 1;
- } else if (v > bins[n - 1]) {
- count[n] += 1;
- } else {
- for (int j = 0; j < n - 1; j++) {
- if (v > bins[j] && v < bins[j + 1]) {
- count[j + 1] += 1;
- break;
- }
- }
- }
- }
-
- Array x = Array.factory(DataType.DOUBLE, new int[]{count.length + 1});
- Array y = Array.factory(DataType.INT, new int[]{count.length});
- for (int i = 0; i < count.length; i++) {
- y.setInt(i, count[i]);
- if (i == 0) {
- x.setDouble(0, bins[0] - delta);
- x.setDouble(1, bins[0]);
- } else if (i == count.length - 1) {
- x.setDouble(i + 1, bins[i - 1] + delta);
- } else {
- x.setDouble(i + 1, bins[i]);
- }
- }
- List r = new ArrayList<>();
- r.add(y);
- r.add(x);
-
- return r;
- }
-
- //
- //
- /**
- * Broadcast array to a new shape
- *
- * @param a Array a
- * @param shape Shape
- * @return Result array
- */
- public static Array broadcast(Array a, int[] shape) {
- int[] bshape = a.getShape();
- if (bshape.length > shape.length) {
- return null;
- }
-
- if (bshape.length < shape.length) {
- int miss = shape.length - a.getRank();
- bshape = new int[shape.length];
- for (int i = 0; i < shape.length; i++) {
- if (i < miss) {
- bshape[i] = 1;
- } else {
- bshape[i] = a.getShape()[i - miss];
- }
- }
- a = a.reshape(bshape);
- }
-
- //Check
- boolean pass = true;
- for (int i = 0; i < shape.length; i++) {
- if (shape[i] != bshape[i] && bshape[i] != 1) {
- pass = false;
- break;
- }
- }
- if (!pass) {
- return null;
- }
-
- //Broadcast
- Index aindex = a.getIndex();
- Array r = Array.factory(a.getDataType(), shape);
- Index index = r.getIndex();
- int[] current;
- for (int i = 0; i < r.getSize(); i++) {
- current = index.getCurrentCounter();
- for (int j = 0; j < shape.length; j++) {
- if (bshape[j] == 1) {
- aindex.setDim(j, 0);
- } else {
- aindex.setDim(j, current[j]);
- }
- }
- r.setObject(index, a.getObject(aindex));
- index.incr();
- }
-
- return r;
- }
-
- /**
- * Broadcast array to a new shape
- *
- * @param a Array a
- * @param shape Shape
- * @return Result array
- */
- public static Array broadcast(Array a, List shape) {
- int[] nshape = new int[shape.size()];
- for (int i = 0; i < shape.size(); i++) {
- nshape[i] = shape.get(i);
- }
- return broadcast(a, nshape);
- }
-
- /**
- * Mesh grid
- *
- * @param x X array - vector
- * @param y Y array - vector
- * @return Result arrays - matrix
- */
- public static Array[] meshgrid(Array x, Array y) {
- int xn = (int) x.getSize();
- int yn = (int) y.getSize();
- int[] shape = new int[]{yn, xn};
- Array rx = Array.factory(x.getDataType(), shape);
- Array ry = Array.factory(y.getDataType(), shape);
- for (int i = 0; i < yn; i++) {
- for (int j = 0; j < xn; j++) {
- rx.setObject(i * xn + j, x.getObject(j));
- ry.setObject(i * xn + j, y.getObject(i));
- }
- }
-
- return new Array[]{rx, ry};
- }
-
- /**
- * Mesh grid
- *
- * @param xs X arrays
- * @return Result arrays - matrix
- */
- public static Array[] meshgrid(Array... xs) {
- int n = xs.length;
- int[] shape = new int[n];
- int i = 0;
- Array x;
- for (i = 0; i < n; i++) {
- x = xs[i];
- shape[n - i - 1] = (int) x.getSize();
- }
-
- Array[] rs = new Array[n];
- Array r;
- int idx;
- for (int s = 0; s < n; s++) {
- x = xs[s];
- r = Array.factory(xs[s].getDataType(), shape);
- Index index = r.getIndex();
- for (i = 0; i < r.getSize(); i++) {
- idx = index.getCurrentCounter()[n - s - 1];
- r.setObject(index, x.getObject(idx));
- index.incr();
- }
- rs[s] = r;
- }
-
- return rs;
- }
-
- /**
- * Create mesh polygon layer
- *
- * @param x_s scatter X array
- * @param y_s scatter Y array
- * @param a scatter value array
- * @param ls Legend scheme
- * @param lonlim Longiutde limitation - to avoid the polygon cross -180/180
- * @return Mesh polygon layer
- */
- public static VectorLayer meshLayer(Array x_s, Array y_s, Array a, LegendScheme ls, double lonlim) {
- VectorLayer layer = new VectorLayer(ShapeTypes.Polygon);
- String fieldName = "Data";
- Field aDC = new Field(fieldName, org.meteoinfo.ndarray.DataType.DOUBLE);
- layer.editAddField(aDC);
-
- int[] shape = x_s.getShape();
- int colNum = shape[1];
- int rowNum = shape[0];
- double x1, x2, x3, x4;
- for (int i = 0; i < rowNum - 1; i++) {
- for (int j = 0; j < colNum - 1; j++) {
- x1 = x_s.getDouble(i * colNum + j);
- x2 = x_s.getDouble(i * colNum + j + 1);
- x3 = x_s.getDouble((i + 1) * colNum + j);
- x4 = x_s.getDouble((i + 1) * colNum + j + 1);
- if (lonlim > 0) {
- if (Math.abs(x2 - x4) > lonlim || Math.abs(x1 - x4) > lonlim
- || Math.abs(x3 - x4) > lonlim || Math.abs(x1 - x2) > lonlim
- || Math.abs(x2 - x3) > lonlim) {
- continue;
- }
- }
-
- PolygonShape ps = new PolygonShape();
- List points = new ArrayList<>();
- points.add(new PointD(x1, y_s.getDouble(i * colNum + j)));
- points.add(new PointD(x3, y_s.getDouble((i + 1) * colNum + j)));
- points.add(new PointD(x4, y_s.getDouble((i + 1) * colNum + j + 1)));
- points.add(new PointD(x2, y_s.getDouble(i * colNum + j + 1)));
- points.add((PointD) points.get(0).clone());
- ps.setPoints(points);
- ps.lowValue = a.getDouble(i * colNum + j);
- ps.highValue = ps.lowValue;
- int shapeNum = layer.getShapeNum();
- try {
- if (layer.editInsertShape(ps, shapeNum)) {
- layer.editCellValue(fieldName, shapeNum, ps.lowValue);
- }
- } catch (Exception ex) {
-
- }
- }
- }
- layer.setLayerName("Mesh_Layer");
- ls.setFieldName(fieldName);
- layer.setLegendScheme(ls.convertTo(ShapeTypes.Polygon));
-
- return layer;
- }
-
- /**
- * Create mesh polygon layer
- *
- * @param x_s scatter X array
- * @param y_s scatter Y array
- * @param a scatter value array
- * @param ls Legend scheme
- * @return Mesh polygon layer
- */
- public static VectorLayer meshLayer(Array x_s, Array y_s, Array a, LegendScheme ls) {
- VectorLayer layer = new VectorLayer(ShapeTypes.Polygon);
- String fieldName = "Data";
- Field aDC = new Field(fieldName, org.meteoinfo.ndarray.DataType.DOUBLE);
- layer.editAddField(aDC);
-
- int[] shape = x_s.getShape();
- int colNum = shape[1];
- int rowNum = shape[0];
- double x1, x2, x3, x4;
- for (int i = 0; i < rowNum - 1; i++) {
- for (int j = 0; j < colNum - 1; j++) {
- x1 = x_s.getDouble(i * colNum + j);
- x2 = x_s.getDouble(i * colNum + j + 1);
- x3 = x_s.getDouble((i + 1) * colNum + j);
- x4 = x_s.getDouble((i + 1) * colNum + j + 1);
- PolygonShape ps = new PolygonShape();
- List points = new ArrayList<>();
- points.add(new PointD(x1, y_s.getDouble(i * colNum + j)));
- points.add(new PointD(x3, y_s.getDouble((i + 1) * colNum + j)));
- points.add(new PointD(x4, y_s.getDouble((i + 1) * colNum + j + 1)));
- points.add(new PointD(x2, y_s.getDouble(i * colNum + j + 1)));
- points.add((PointD) points.get(0).clone());
- ps.setPoints(points);
- ps.lowValue = a.getDouble(i * colNum + j);
- ps.highValue = ps.lowValue;
- int shapeNum = layer.getShapeNum();
- try {
- if (layer.editInsertShape(ps, shapeNum)) {
- layer.editCellValue(fieldName, shapeNum, ps.lowValue);
- }
- } catch (Exception ex) {
-
- }
- }
- }
- layer.setLayerName("Mesh_Layer");
- ls.setFieldName(fieldName);
- layer.setLegendScheme(ls.convertTo(ShapeTypes.Polygon));
-
- return layer;
- }
-
- /**
- * Smooth with 5 points
- *
- * @param a Array
- * @param rowNum Row number
- * @param colNum Column number
- * @param unDefData Missing value
- * @return Result array
- */
- public static Array smooth5(Array a, int rowNum, int colNum, double unDefData) {
- Array r = Array.factory(a.getDataType(), a.getShape());
- double s = 0.5;
- if (Double.isNaN(unDefData)) {
- for (int i = 0; i < rowNum; i++) {
- for (int j = 0; j < colNum; j++) {
- if (i == 0 || i == rowNum - 1 || j == 0 || j == colNum - 1) {
- r.setDouble(i * colNum + j, a.getDouble(i * colNum + j));
- } else {
- if (Double.isNaN(a.getDouble(i * colNum + j)) || Double.isNaN(a.getDouble((i + 1) * colNum + j)) || Double.isNaN(a.getDouble((i - 1) * colNum + j))
- || Double.isNaN(a.getDouble(i * colNum + j + 1)) || Double.isNaN(a.getDouble(i * colNum + j - 1))) {
- r.setDouble(i * colNum + j, a.getDouble(i * colNum + j));
- continue;
- }
- r.setDouble(i * colNum + j, a.getDouble(i * colNum + j) + s / 4 * (a.getDouble((i + 1) * colNum + j) + a.getDouble((i - 1) * colNum + j) + a.getDouble(i * colNum + j + 1)
- + a.getDouble(i * colNum + j - 1) - 4 * a.getDouble(i * colNum + j)));
- }
- }
- }
- } else {
- for (int i = 0; i < rowNum; i++) {
- for (int j = 0; j < colNum; j++) {
- if (i == 0 || i == rowNum - 1 || j == 0 || j == colNum - 1) {
- r.setDouble(i * colNum + j, a.getDouble(i * colNum + j));
- } else {
- if (a.getDouble(i * colNum + j) == unDefData || a.getDouble((i + 1) * colNum + j) == unDefData || a.getDouble((i - 1) * colNum + j)
- == unDefData || a.getDouble(i * colNum + j + 1) == unDefData || a.getDouble(i * colNum + j - 1) == unDefData) {
- r.setDouble(i * colNum + j, a.getDouble(i * colNum + j));
- continue;
- }
- r.setDouble(i * colNum + j, a.getDouble(i * colNum + j) + s / 4 * (a.getDouble((i + 1) * colNum + j) + a.getDouble((i - 1) * colNum + j) + a.getDouble(i * colNum + j + 1)
- + a.getDouble(i * colNum + j - 1) - 4 * a.getDouble(i * colNum + j)));
- }
- }
- }
- }
-
- return r;
- }
-
- /**
- * Smooth with 5 points
- *
- * @param a Array
- * @return Result array
- */
- public static Array smooth5(Array a) {
- int[] shape = a.getShape();
- int colNum = shape[1];
- int rowNum = shape[0];
- Array r = Array.factory(a.getDataType(), shape);
- Index2D index = new Index2D(shape);
- double v, w;
- double sum, wsum;
- for (int i = 0; i < rowNum; i++) {
- for (int j = 0; j < colNum; j++) {
- sum = 0;
- wsum = 0;
- for (int ii = i - 1; ii <= i + 1; ii++) {
- if (ii < 0 || ii >= rowNum) {
- continue;
- }
- for (int jj = j - 1; jj <= j + 1; jj++) {
- if (jj < 0 || jj >= colNum) {
- continue;
- }
- if ((ii == i - 1 || ii == i + 1) && jj != j) {
- continue;
- }
- v = a.getDouble(index.set(ii, jj));
- if (!Double.isNaN(v)) {
- if (ii == i && jj == j) {
- w = 1;
- } else {
- w = 0.5;
- }
- sum += v * w;
- wsum += w;
- }
- }
- }
- index.set(i, j);
- if (wsum > 0) {
- r.setDouble(index, sum / wsum);
- } else {
- r.setDouble(index, Double.NaN);
- }
- }
- }
-
- return r;
- }
-
- /**
- * Smooth with 9 points
- *
- * @param a Array
- * @return Result array
- */
- public static Array smooth9(Array a) {
- int[] shape = a.getShape();
- int colNum = shape[1];
- int rowNum = shape[0];
- Array r = Array.factory(a.getDataType(), shape);
- Index2D index = new Index2D(shape);
- double v, w;
- double sum, wsum;
- for (int i = 0; i < rowNum; i++) {
- for (int j = 0; j < colNum; j++) {
- sum = 0;
- wsum = 0;
- for (int ii = i - 1; ii <= i + 1; ii++) {
- if (ii < 0 || ii >= rowNum) {
- continue;
- }
- for (int jj = j - 1; jj <= j + 1; jj++) {
- if (jj < 0 || jj >= colNum) {
- continue;
- }
- v = a.getDouble(index.set(ii, jj));
- if (!Double.isNaN(v)) {
- if (ii == i && jj == j) {
- w = 1;
- } else {
- if (ii == i || jj == j) {
- w = 0.5;
- } else {
- w = 0.3;
- }
- }
- sum += v * w;
- wsum += w;
- }
- }
- }
- index.set(i, j);
- if (wsum > 0) {
- r.setDouble(index, sum / wsum);
- } else {
- r.setDouble(index, Double.NaN);
- }
- }
- }
-
- return r;
- }
-
- /**
- * Interpolation with IDW radius method
- *
- * @param x_s scatter X array
- * @param y_s scatter Y array
- * @param a scatter value array
- * @param X grid X array
- * @param Y grid Y array
- * @param neededPointNum needed at least point number
- * @param radius search radius
- * @return interpolated grid data
- */
- public static Array interpolation_IDW_Radius(List x_s, List y_s, Array a,
- List X, List Y, int neededPointNum, double radius) {
- int rowNum, colNum, pNum;
- colNum = X.size();
- rowNum = Y.size();
- pNum = x_s.size();
- Array r = Array.factory(DataType.DOUBLE, new int[]{rowNum, colNum});
- int i, j;
- double w, gx, gy, v;
- boolean match;
-
- //Construct K-D tree
- int n = 0;
- KDTree.Euclidean kdTree = new KDTree.Euclidean<>(2);
- for (i = 0; i < pNum; i++) {
- if (!Double.isNaN(a.getDouble(i))) {
- kdTree.addPoint(new double[]{x_s.get(i).doubleValue(), y_s.get(i).doubleValue()}, a.getDouble(i));
- n += 1;
- }
- }
-
- //---- Do interpolation
- for (i = 0; i < rowNum; i++) {
- gy = Y.get(i).doubleValue();
- for (j = 0; j < colNum; j++) {
- gx = X.get(j).doubleValue();
- List> srs = kdTree.ballSearch_distance(new double[]{gx, gy}, radius * radius);
- if (srs == null || srs.size() < neededPointNum) {
- r.setDouble(i * colNum + j, Double.NaN);
- } else {
- double v_sum = 0.0;
- double weight_sum = 0.0;
- match = false;
- for (SearchResult sr : srs) {
- v = (double) sr.payload;
- if (sr.distance == 0) {
- r.setDouble(i * colNum + j, v);
- match = true;
- break;
- } else {
- w = 1. / sr.distance;
- weight_sum += w;
- v_sum += v * w;
- }
- }
- if (!match) {
- r.setDouble(i * colNum + j, v_sum / weight_sum);
- }
- }
- }
- }
-
- return r;
- }
-
- /**
- * Interpolation with IDW radius method
- *
- * @param x_s scatter X array
- * @param y_s scatter Y array
- * @param a scatter value array
- * @param X grid X array
- * @param Y grid Y array
- * @param NeededPointNum needed at least point number
- * @param radius search radius
- * @return interpolated grid data
- */
- public static Array interpolation_IDW_Radius_bak(List x_s, List y_s, Array a,
- List X, List Y, int NeededPointNum, double radius) {
- int rowNum, colNum, pNum;
- colNum = X.size();
- rowNum = Y.size();
- pNum = x_s.size();
- //double[][] GCoords = new double[rowNum][colNum];
- Array r = Array.factory(DataType.DOUBLE, new int[]{rowNum, colNum});
- int i, j, p, vNum;
- double w, SV, SW;
- boolean ifPointGrid;
- double x, y, v;
-
- //---- Do interpolation
- for (i = 0; i < rowNum; i++) {
- for (j = 0; j < colNum; j++) {
- r.setDouble(i * colNum + j, Double.NaN);
- ifPointGrid = false;
- SV = 0;
- SW = 0;
- vNum = 0;
- for (p = 0; p < pNum; p++) {
- v = a.getDouble(p);
- if (Double.isNaN(v)) {
- continue;
- }
- x = x_s.get(p).doubleValue();
- y = y_s.get(p).doubleValue();
- if (x < X.get(j).doubleValue() - radius || x > X.get(j).doubleValue() + radius || y < Y.get(i).doubleValue() - radius
- || y > Y.get(i).doubleValue() + radius) {
- continue;
- }
-
- if (Math.pow(X.get(j).doubleValue() - x, 2) + Math.pow(Y.get(i).doubleValue() - y, 2) == 0) {
- r.setDouble(i * colNum + j, v);
- ifPointGrid = true;
- break;
- } else if (Math.sqrt(Math.pow(X.get(j).doubleValue() - x, 2)
- + Math.pow(Y.get(i).doubleValue() - y, 2)) <= radius) {
- w = 1 / (Math.pow(X.get(j).doubleValue() - x, 2) + Math.pow(Y.get(i).doubleValue() - y, 2));
- SW = SW + w;
- SV = SV + v * w;
- vNum += 1;
- }
- }
-
- if (!ifPointGrid) {
- if (vNum >= NeededPointNum) {
- r.setDouble(i * colNum + j, SV / SW);
- }
- }
- }
- }
-
- //---- Smooth with 5 points
- r = smooth5(r, rowNum, colNum, Double.NaN);
-
- return r;
- }
-
- /**
- * Interpolation with IDW neighbor method
- *
- * @param x_s scatter X array
- * @param y_s scatter Y array
- * @param a scatter value array
- * @param X grid X array
- * @param Y grid Y array
- * @param points Number of points used for interpolation
- * @return interpolated grid data
- */
- public static Array interpolation_IDW_Neighbor(List x_s, List y_s, Array a,
- List X, List Y, Integer points) {
- int colNum = X.size();
- int rowNum = Y.size();
- int pNum = x_s.size();
- Array r = Array.factory(DataType.DOUBLE, new int[]{rowNum, colNum});
- int i, j;
- double w, v, gx, gy;
- boolean match;
-
- //Construct K-D tree
- int n = 0;
- KDTree.Euclidean kdTree = new KDTree.Euclidean<>(2);
- for (i = 0; i < pNum; i++) {
- if (!Double.isNaN(a.getDouble(i))) {
- kdTree.addPoint(new double[]{x_s.get(i).doubleValue(), y_s.get(i).doubleValue()}, a.getDouble(i));
- n += 1;
- }
- }
- if (points == null) {
- points = n;
- }
-
- //---- Do interpolation with IDW method
- for (i = 0; i < rowNum; i++) {
- gy = Y.get(i).doubleValue();
- for (j = 0; j < colNum; j++) {
- gx = X.get(j).doubleValue();
- List> srs = kdTree.nearestNeighbours(new double[]{gx, gy}, points);
- double v_sum = 0.0;
- double weight_sum = 0.0;
- match = false;
- for (SearchResult sr : srs) {
- v = (double) sr.payload;
- if (sr.distance == 0) {
- r.setDouble(i * colNum + j, v);
- match = true;
- break;
- } else {
- w = 1. / sr.distance;
- weight_sum += w;
- v_sum += v * w;
- }
- }
- if (!match) {
- r.setDouble(i * colNum + j, v_sum / weight_sum);
- }
- }
- }
-
- return r;
- }
-
- /**
- * Interpolation with IDW neighbor method
- *
- * @param x_s scatter X array
- * @param y_s scatter Y array
- * @param a scatter value array
- * @param X grid X array
- * @param Y grid Y array
- * @param NumberOfNearestNeighbors
- * @return interpolated grid data
- */
- public static Array interpolation_IDW_Neighbor_bak(List x_s, List y_s, Array a,
- List X, List Y, int NumberOfNearestNeighbors) {
- int rowNum, colNum, pNum;
- colNum = X.size();
- rowNum = Y.size();
- pNum = x_s.size();
- Array r = Array.factory(DataType.DOUBLE, new int[]{rowNum, colNum});
- int i, j, p, l, aP;
- double w, SV, SW, aMin;
- int points;
- points = NumberOfNearestNeighbors;
- double[] AllWeights = new double[pNum];
- double[][] NW = new double[2][points];
- int NWIdx;
- double x, y, v;
-
- //---- Do interpolation with IDW method
- for (i = 0; i < rowNum; i++) {
- for (j = 0; j < colNum; j++) {
- r.setDouble(i * colNum + j, Double.NaN);
- SV = 0;
- SW = 0;
- NWIdx = 0;
- for (p = 0; p < pNum; p++) {
- v = a.getDouble(p);
- if (Double.isNaN(v)) {
- AllWeights[p] = -1;
- continue;
- }
- x = x_s.get(p).doubleValue();
- y = y_s.get(p).doubleValue();
- if (X.get(j).doubleValue() == x && Y.get(i).doubleValue() == y) {
- r.setDouble(i * colNum + j, v);
- break;
- } else {
- w = 1 / (Math.pow(X.get(j).doubleValue() - x, 2) + Math.pow(Y.get(i).doubleValue() - y, 2));
- AllWeights[p] = w;
- if (NWIdx < points) {
- NW[0][NWIdx] = w;
- NW[1][NWIdx] = p;
- }
- NWIdx += 1;
- }
- }
-
- aMin = NW[0][0];
- aP = 0;
- for (l = 1; l < points; l++) {
- if (NW[0][l] < aMin) {
- aMin = NW[0][l];
- aP = l;
- }
- }
-
- if (Double.isNaN(r.getDouble(i * colNum + j))) {
- for (p = 0; p < pNum; p++) {
- w = AllWeights[p];
- if (w == -1) {
- continue;
- }
-
- if (w > aMin) {
- NW[0][aP] = w;
- NW[1][aP] = p;
- aMin = NW[0][0];
- aP = 0;
- for (l = 1; l < points; l++) {
- if (NW[0][l] < aMin) {
- aMin = NW[0][l];
- aP = l;
- }
- }
- }
- }
- for (p = 0; p < points; p++) {
- SV += NW[0][p] * a.getDouble((int) NW[1][p]);
- SW += NW[0][p];
- }
- r.setDouble(i * colNum + j, SV / SW);
- }
- }
- }
-
- //---- Smooth with 5 points
- r = smooth5(r, rowNum, colNum, Double.NaN);
-
- return r;
- }
-
- /**
- * Interpolate with nearest method
- *
- * @param x_s scatter X array
- * @param y_s scatter Y array
- * @param a scatter value array
- * @param X x coordinate
- * @param Y y coordinate
- * @param radius Radius
- * @return grid data
- */
- public static Array interpolation_Nearest(List x_s, List y_s, Array a, List X, List Y,
- double radius) {
- int rowNum, colNum, pNum;
- colNum = X.size();
- rowNum = Y.size();
- pNum = x_s.size();
- Array rdata = Array.factory(DataType.DOUBLE, new int[]{rowNum, colNum});
- double gx, gy;
-
- //Construct K-D tree
- KDTree.Euclidean kdTree = new KDTree.Euclidean<>(2);
- for (int i = 0; i < pNum; i++) {
- if (!Double.isNaN(a.getDouble(i))) {
- kdTree.addPoint(new double[]{x_s.get(i).doubleValue(), y_s.get(i).doubleValue()}, a.getDouble(i));
- }
- }
-
- //Loop
- if (radius == Double.POSITIVE_INFINITY) {
- for (int i = 0; i < rowNum; i++) {
- gy = Y.get(i).doubleValue();
- for (int j = 0; j < colNum; j++) {
- gx = X.get(j).doubleValue();
- SearchResult r = kdTree.nearestNeighbours(new double[]{gx, gy}, 1).get(0);
- rdata.setDouble(i * colNum + j, ((double) r.payload));
- }
- }
- } else {
- for (int i = 0; i < rowNum; i++) {
- gy = Y.get(i).doubleValue();
- for (int j = 0; j < colNum; j++) {
- gx = X.get(j).doubleValue();
- SearchResult r = kdTree.nearestNeighbours(new double[]{gx, gy}, 1).get(0);
- if (Math.sqrt(r.distance) <= radius) {
- rdata.setDouble(i * colNum + j, ((double) r.payload));
- } else {
- rdata.setDouble(i * colNum + j, Double.NaN);
- }
- }
- }
- }
-
- return rdata;
- }
-
- /**
- * Extend the grid to half cell, so the grid points are the centers of the
- * cells
- *
- * @param x Input x coordinate
- * @param y Input y coordinate
- * @return Result x and y coordinates
- */
- public static Array[] extendHalfCell(Array x, Array y) {
- double dX = x.getDouble(1) - x.getDouble(0);
- double dY = y.getDouble(1) - y.getDouble(0);
- int nx = (int) x.getSize() + 1;
- int ny = (int) y.getSize() + 1;
- Array rx = Array.factory(DataType.DOUBLE, new int[]{nx});
- Array ry = Array.factory(DataType.DOUBLE, new int[]{ny});
- for (int i = 0; i < rx.getSize(); i++) {
- if (i == rx.getSize() - 1) {
- rx.setDouble(i, x.getDouble(i - 1) + dX * 0.5);
- } else {
- rx.setDouble(i, x.getDouble(i) - dX * 0.5);
- }
- }
-
- for (int i = 0; i < ry.getSize(); i++) {
- if (i == ry.getSize() - 1) {
- ry.setDouble(i, y.getDouble(i - 1) + dY * 0.5);
- } else {
- ry.setDouble(i, y.getDouble(i) - dY * 0.5);
- }
- }
-
- return new Array[]{rx, ry};
- }
-
- /**
- * Interpolate with inside method - The grid cell value is the average value
- * of the inside points or fill value if no inside point.
- *
- * @param x_s scatter X array
- * @param y_s scatter Y array
- * @param a scatter value array
- * @param X x coordinate
- * @param Y y coordinate
- * @param centerPoint the points locate at center or border or grid
- * @return grid data
- */
- public static Array interpolation_Inside(List x_s, List y_s, Array a,
- List X, List Y, boolean centerPoint) {
- int rowNum, colNum, pNum;
- colNum = X.size();
- rowNum = Y.size();
- pNum = x_s.size();
- Array r = Array.factory(DataType.DOUBLE, new int[]{rowNum, colNum});
- double dX = X.get(1).doubleValue() - X.get(0).doubleValue();
- double dY = Y.get(1).doubleValue() - Y.get(0).doubleValue();
- int[][] pNums = new int[rowNum][colNum];
- double x, y, v, sx, sy, ex, ey;
- if (centerPoint) {
- sx = X.get(0).doubleValue() - dX * 0.5;
- sy = Y.get(0).doubleValue() - dY * 0.5;
- ex = X.get(colNum - 1).doubleValue() + dX * 0.5;
- ey = Y.get(rowNum - 1).doubleValue() + dY * 0.5;
- } else {
- sx = X.get(0).doubleValue();
- sy = Y.get(0).doubleValue();
- ex = X.get(colNum - 1).doubleValue();
- ey = Y.get(rowNum - 1).doubleValue();
- }
-
- for (int i = 0; i < rowNum; i++) {
- for (int j = 0; j < colNum; j++) {
- pNums[i][j] = 0;
- r.setDouble(i * colNum + j, 0.0);
- }
- }
-
- for (int p = 0; p < pNum; p++) {
- v = a.getDouble(p);
- if (Double.isNaN(v)) {
- continue;
- }
-
- x = x_s.get(p).doubleValue();
- y = y_s.get(p).doubleValue();
- if (x < sx || x > ex) {
- continue;
- }
- if (y < sy || y > ey) {
- continue;
- }
-
- int j = (int) ((x - sx) / dX);
- int i = (int) ((y - sy) / dY);
- pNums[i][j] += 1;
- r.setDouble(i * colNum + j, r.getDouble(i * colNum + j) + v);
- }
-
- for (int i = 0; i < rowNum; i++) {
- for (int j = 0; j < colNum; j++) {
- if (pNums[i][j] == 0) {
- r.setDouble(i * colNum + j, Double.NaN);
- } else {
- r.setDouble(i * colNum + j, r.getDouble(i * colNum + j) / pNums[i][j]);
- }
- }
- }
-
- return r;
- }
-
- /**
- * Interpolate with inside method - The grid cell value is the average value
- * of the inside points or fill value if no inside point.
- *
- * @param x_s scatter X array
- * @param y_s scatter Y array
- * @param a scatter value array
- * @param X x coordinate
- * @param Y y coordinate
- * @param centerPoint If the grid point is center or border
- * @return grid data
- */
- public static Array interpolation_Inside(Array x_s, Array y_s, Array a, Array X, Array Y,
- boolean centerPoint) {
- int rowNum, colNum, pNum;
- colNum = (int) X.getSize();
- rowNum = (int) Y.getSize();
- pNum = (int) x_s.getSize();
- Array r = Array.factory(DataType.DOUBLE, new int[]{rowNum, colNum});
- double dX = X.getDouble(1) - X.getDouble(0);
- double dY = Y.getDouble(1) - Y.getDouble(0);
- int[][] pNums = new int[rowNum][colNum];
- double x, y, v, sx, sy, ex, ey;
- if (centerPoint) {
- sx = X.getDouble(0) - dX * 0.5;
- sy = Y.getDouble(0) - dY * 0.5;
- ex = X.getDouble(colNum - 1) + dX * 0.5;
- ey = Y.getDouble(rowNum - 1) + dY * 0.5;
- } else {
- sx = X.getDouble(0);
- sy = Y.getDouble(0);
- ex = X.getDouble(colNum - 1);
- ey = Y.getDouble(rowNum - 1);
- }
-
- for (int i = 0; i < rowNum; i++) {
- for (int j = 0; j < colNum; j++) {
- pNums[i][j] = 0;
- r.setDouble(i * colNum + j, 0.0);
- }
- }
-
- for (int p = 0; p < pNum; p++) {
- v = a.getDouble(p);
- if (Double.isNaN(v)) {
- continue;
- }
-
- x = x_s.getDouble(p);
- y = y_s.getDouble(p);
- if (x < sx || x > ex) {
- continue;
- }
- if (y < sy || y > ey) {
- continue;
- }
-
- int j = (int) ((x - sx) / dX);
- int i = (int) ((y - sy) / dY);
- pNums[i][j] += 1;
- r.setDouble(i * colNum + j, r.getDouble(i * colNum + j) + v);
- }
-
- for (int i = 0; i < rowNum; i++) {
- for (int j = 0; j < colNum; j++) {
- if (pNums[i][j] == 0) {
- r.setDouble(i * colNum + j, Double.NaN);
- } else {
- r.setDouble(i * colNum + j, r.getDouble(i * colNum + j) / pNums[i][j]);
- }
- }
- }
-
- return r;
- }
-
- /**
- * Interpolate with inside method - The grid cell value is the maximum value
- * of the inside points or fill value if no inside point.
- *
- * @param x_s scatter X array
- * @param y_s scatter Y array
- * @param a scatter value array
- * @param X x coordinate
- * @param Y y coordinate
- * @param centerPoint points locate at center or border of grid
- * @return grid data
- */
- public static Array interpolation_Inside_Max(List x_s, List y_s, Array a,
- List X, List Y, boolean centerPoint) {
- int rowNum, colNum, pNum;
- colNum = X.size();
- rowNum = Y.size();
- pNum = x_s.size();
- Array r = Array.factory(DataType.DOUBLE, new int[]{rowNum, colNum});
- double dX = X.get(1).doubleValue() - X.get(0).doubleValue();
- double dY = Y.get(1).doubleValue() - Y.get(0).doubleValue();
- int[][] pNums = new int[rowNum][colNum];
- double x, y, v, sx, sy, ex, ey;
- double min = Double.NEGATIVE_INFINITY;
- if (centerPoint) {
- sx = X.get(0).doubleValue() - dX * 0.5;
- sy = Y.get(0).doubleValue() - dY * 0.5;
- ex = X.get(colNum - 1).doubleValue() + dX * 0.5;
- ey = Y.get(rowNum - 1).doubleValue() + dY * 0.5;
- } else {
- sx = X.get(0).doubleValue();
- sy = Y.get(0).doubleValue();
- ex = X.get(colNum - 1).doubleValue();
- ey = Y.get(rowNum - 1).doubleValue();
- }
-
- for (int i = 0; i < rowNum; i++) {
- for (int j = 0; j < colNum; j++) {
- pNums[i][j] = 0;
- r.setDouble(i * colNum + j, min);
- }
- }
-
- for (int p = 0; p < pNum; p++) {
- v = a.getDouble(p);
- if (Double.isNaN(v)) {
- continue;
- }
-
- x = x_s.get(p).doubleValue();
- y = y_s.get(p).doubleValue();
- if (x < sx || x > ex) {
- continue;
- }
- if (y < sy || y > ey) {
- continue;
- }
-
- int j = (int) ((x - sx) / dX);
- int i = (int) ((y - sy) / dY);
- pNums[i][j] += 1;
- r.setDouble(i * colNum + j, Math.max(r.getDouble(i * colNum + j), v));
- }
-
- for (int i = 0; i < rowNum; i++) {
- for (int j = 0; j < colNum; j++) {
- if (pNums[i][j] == 0 || Double.isInfinite(r.getDouble(i * colNum + j))) {
- r.setDouble(i * colNum + j, Double.NaN);
- }
- }
- }
-
- return r;
- }
-
- /**
- * Interpolate with inside method - The grid cell value is the minimum value
- * of the inside points or fill value if no inside point.
- *
- * @param x_s scatter X array
- * @param y_s scatter Y array
- * @param a scatter value array
- * @param X x coordinate
- * @param Y y coordinate
- * @param centerPoint points locate at center or border of grid
- * @return grid data
- */
- public static Array interpolation_Inside_Min(List x_s, List y_s, Array a,
- List X, List Y, boolean centerPoint) {
- int rowNum, colNum, pNum;
- colNum = X.size();
- rowNum = Y.size();
- pNum = x_s.size();
- Array r = Array.factory(DataType.DOUBLE, new int[]{rowNum, colNum});
- double dX = X.get(1).doubleValue() - X.get(0).doubleValue();
- double dY = Y.get(1).doubleValue() - Y.get(0).doubleValue();
- int[][] pNums = new int[rowNum][colNum];
- double x, y, v, sx, sy, ex, ey;
- double max = Double.MAX_VALUE;
- if (centerPoint) {
- sx = X.get(0).doubleValue() - dX * 0.5;
- sy = Y.get(0).doubleValue() - dY * 0.5;
- ex = X.get(colNum - 1).doubleValue() + dX * 0.5;
- ey = Y.get(rowNum - 1).doubleValue() + dY * 0.5;
- } else {
- sx = X.get(0).doubleValue();
- sy = Y.get(0).doubleValue();
- ex = X.get(colNum - 1).doubleValue();
- ey = Y.get(rowNum - 1).doubleValue();
- }
-
- for (int i = 0; i < rowNum; i++) {
- for (int j = 0; j < colNum; j++) {
- pNums[i][j] = 0;
- r.setDouble(i * colNum + j, max);
- }
- }
-
- for (int p = 0; p < pNum; p++) {
- v = a.getDouble(p);
- if (Double.isNaN(v)) {
- continue;
- }
-
- x = x_s.get(p).doubleValue();
- y = y_s.get(p).doubleValue();
- if (x < sx || x > ex) {
- continue;
- }
- if (y < sy || y > ey) {
- continue;
- }
-
- int j = (int) ((x - sx) / dX);
- int i = (int) ((y - sy) / dY);
- pNums[i][j] += 1;
- r.setDouble(i * colNum + j, Math.min(r.getDouble(i * colNum + j), v));
- }
-
- for (int i = 0; i < rowNum; i++) {
- for (int j = 0; j < colNum; j++) {
- if (pNums[i][j] == 0 || r.getDouble(i * colNum + j) == Double.MAX_VALUE) {
- r.setDouble(i * colNum + j, Double.NaN);
- }
- }
- }
-
- return r;
- }
-
- /**
- * Interpolate with inside method - The grid cell value is the count number
- * of the inside points or fill value if no inside point.
- *
- * @param x_s scatter X array
- * @param y_s scatter Y array
- * @param X x coordinate
- * @param Y y coordinate
- * @param pointDensity If return point density value
- * @param centerPoint points locate at center or border of grid
- * @return grid data
- */
- public static Object interpolation_Inside_Count(List x_s, List y_s,
- List X, List Y, boolean pointDensity, boolean centerPoint) {
- int rowNum, colNum, pNum;
- colNum = X.size();
- rowNum = Y.size();
- pNum = x_s.size();
- Array r = Array.factory(DataType.INT, new int[]{rowNum, colNum});
- double dX = X.get(1).doubleValue() - X.get(0).doubleValue();
- double dY = Y.get(1).doubleValue() - Y.get(0).doubleValue();
- int[][] pNums = new int[rowNum][colNum];
- double x, y, sx, sy, ex, ey;
- if (centerPoint) {
- sx = X.get(0).doubleValue() - dX * 0.5;
- sy = Y.get(0).doubleValue() - dY * 0.5;
- ex = X.get(colNum - 1).doubleValue() + dX * 0.5;
- ey = Y.get(rowNum - 1).doubleValue() + dY * 0.5;
- } else {
- sx = X.get(0).doubleValue();
- sy = Y.get(0).doubleValue();
- ex = X.get(colNum - 1).doubleValue();
- ey = Y.get(rowNum - 1).doubleValue();
- }
-
- for (int i = 0; i < rowNum; i++) {
- for (int j = 0; j < colNum; j++) {
- pNums[i][j] = 0;
- //r.setInt(i * colNum + j, 0);
- }
- }
-
- for (int p = 0; p < pNum; p++) {
- x = x_s.get(p).doubleValue();
- y = y_s.get(p).doubleValue();
- if (x < sx || x > ex) {
- continue;
- }
- if (y < sy || y > ey) {
- continue;
- }
-
- int j = (int) ((x - sx) / dX);
- int i = (int) ((y - sy) / dY);
- pNums[i][j] += 1;
- //r.setInt(i * colNum + j, r.getInt(i * colNum + j) + 1);
- }
-
- for (int i = 0; i < rowNum; i++) {
- for (int j = 0; j < colNum; j++) {
- r.setInt(i * colNum + j, pNums[i][j]);
- }
- }
-
- if (pointDensity) {
- Array pds = Array.factory(DataType.INT, new int[]{pNum});
- for (int p = 0; p < pNum; p++) {
- x = x_s.get(p).doubleValue();
- y = y_s.get(p).doubleValue();
- if (x < sx || x > ex) {
- continue;
- }
- if (y < sy || y > ey) {
- continue;
- }
-
- int j = (int) ((x - sx) / dX);
- int i = (int) ((y - sy) / dY);
- pds.setInt(p, pNums[i][j]);
- }
- return new Array[]{r, pds};
- }
-
- return r;
- }
-
- private static List getPointsIJ(List x_s, List y_s, List X, List Y) {
- int rowNum, colNum, pNum;
- colNum = X.size();
- rowNum = Y.size();
- pNum = x_s.size();
- double dX = X.get(1).doubleValue() - X.get(0).doubleValue();
- double dY = Y.get(1).doubleValue() - Y.get(0).doubleValue();
- List pIndices = new ArrayList<>();
- double x, y;
- int i, j;
- for (int p = 0; p < pNum; p++) {
- x = x_s.get(p).doubleValue();
- y = y_s.get(p).doubleValue();
- if (x < X.get(0).doubleValue() || x > X.get(colNum - 1).doubleValue()) {
- continue;
- }
- if (y < Y.get(0).doubleValue() || y > Y.get(rowNum - 1).doubleValue()) {
- continue;
- }
-
- j = (int) ((x - X.get(0).doubleValue()) / dX);
- i = (int) ((y - Y.get(0).doubleValue()) / dY);
- pIndices.add(new int[]{i, j});
- }
-
- return pIndices;
- }
-
- private static List getPointsIdx(List pIJ, int ii, int jj, int radius) {
- List pIdx = new ArrayList<>();
- int[] ij;
- int i, j;
- for (int p = 0; p < pIJ.size(); p++) {
- ij = pIJ.get(p);
- i = ij[0];
- j = ij[1];
- if (Math.abs(i - ii) <= radius && Math.abs(j - jj) <= radius) {
- pIdx.add(p);
- }
- }
-
- return pIdx;
- }
-
- /**
- * Interpolate with surface method
- *
- * @param x_s scatter X array
- * @param y_s scatter Y array
- * @param a scatter value array
- * @param X x coordinate
- * @param Y y coordinate
- * @param unDefData undefine value
- * @return grid data
- */
- public static Array interpolation_Surface_1(Array x_s, Array y_s, Array a, Array X, Array Y,
- double unDefData) {
- int rowNum, colNum, xn, yn;
- int[] shape = x_s.getShape();
- colNum = shape[1];
- rowNum = shape[0];
- xn = (int) X.getSize();
- yn = (int) Y.getSize();
- Array r = Array.factory(DataType.DOUBLE, new int[]{yn, xn});
- double x, y;
-
- PolygonShape[][] polygons = new PolygonShape[rowNum - 1][colNum - 1];
- PolygonShape ps;
- for (int i = 0; i < rowNum - 1; i++) {
- for (int j = 0; j < colNum - 1; j++) {
- ps = new PolygonShape();
- List points = new ArrayList<>();
- points.add(new PointD(x_s.getDouble(i * colNum + j), y_s.getDouble(i * colNum + j)));
- points.add(new PointD(x_s.getDouble((i + 1) * colNum + j), y_s.getDouble((i + 1) * colNum + j)));
- points.add(new PointD(x_s.getDouble((i + 1) * colNum + j + 1), y_s.getDouble((i + 1) * colNum + j + 1)));
- points.add(new PointD(x_s.getDouble(i * colNum + j + 1), y_s.getDouble(i * colNum + j + 1)));
- points.add((PointD) points.get(0).clone());
- ps.setPoints(points);
- polygons[i][j] = ps;
- }
- }
-
- for (int i = 0; i < yn; i++) {
- for (int j = 0; j < xn; j++) {
- r.setDouble(i * xn + j, unDefData);
- }
- }
-
- double v;
- for (int i = 0; i < rowNum - 1; i++) {
- for (int j = 0; j < colNum - 1; j++) {
- ps = polygons[i][j];
- v = a.getDouble(i * colNum + j);
- for (int ii = 0; ii < yn; ii++) {
- y = Y.getDouble(ii);
- for (int jj = 0; jj < xn; jj++) {
- x = X.getDouble(jj);
- if (Double.isNaN(r.getDouble(ii * xn + jj)) || r.getDouble(ii * xn + jj) == unDefData) {
- if (GeoComputation.pointInPolygon(ps, x, y)) {
- r.setDouble(ii * xn + jj, v);
- }
- }
- }
- }
- }
- }
-
- return r;
- }
-
- /**
- * Interpolate with surface method
- *
- * @param x_s scatter X array
- * @param y_s scatter Y array
- * @param a scatter value array
- * @param X x coordinate
- * @param Y y coordinate
- * @return grid data
- */
- public static Array interpolation_Surface(Array x_s, Array y_s, Array a, Array X, Array Y) {
- int rowNum, colNum, xn, yn;
- int[] shape = x_s.getShape();
- colNum = shape[1];
- rowNum = shape[0];
- xn = (int) X.getSize();
- yn = (int) Y.getSize();
- Array r = Array.factory(DataType.DOUBLE, new int[]{yn, xn});
- for (int i = 0; i < r.getSize(); i++) {
- r.setDouble(i, Double.NaN);
- }
-
- double x, y;
- double v, xll, xtl, xtr, xlr, yll, ytl, ytr, ylr;
- double dX = X.getDouble(1) - X.getDouble(0);
- double dY = Y.getDouble(1) - Y.getDouble(0);
- int minxi, maxxi, minyi, maxyi;
- for (int i = 0; i < rowNum - 1; i++) {
- for (int j = 0; j < colNum - 1; j++) {
- v = a.getDouble(i * colNum + j);
- if (Double.isNaN(v)) {
- continue;
- }
- xll = x_s.getDouble(i * colNum + j);
- xtl = x_s.getDouble((i + 1) * colNum + j);
- xtr = x_s.getDouble((i + 1) * colNum + j + 1);
- xlr = x_s.getDouble(i * colNum + j + 1);
- yll = y_s.getDouble(i * colNum + j);
- ytl = y_s.getDouble((i + 1) * colNum + j);
- ytr = y_s.getDouble((i + 1) * colNum + j + 1);
- ylr = y_s.getDouble(i * colNum + j + 1);
- if (Double.isNaN(xll) || Double.isNaN(xtl) || Double.isNaN(xtr) || Double.isNaN(xlr)
- || Double.isNaN(yll) || Double.isNaN(ytl) || Double.isNaN(ytr) || Double.isNaN(ylr)) {
- continue;
- }
- PolygonShape ps = new PolygonShape();
- List points = new ArrayList<>();
- points.add(new PointD(xll, yll));
- points.add(new PointD(xtl, ytl));
- points.add(new PointD(xtr, ytr));
- points.add(new PointD(xlr, ylr));
- points.add((PointD) points.get(0).clone());
- ps.setPoints(points);
- minxi = (int) ((ps.getExtent().minX - X.getDouble(0)) / dX);
- maxxi = (int) ((ps.getExtent().maxX - X.getDouble(0)) / dX);
- minyi = (int) ((ps.getExtent().minY - Y.getDouble(0)) / dY);
- maxyi = (int) ((ps.getExtent().maxY - Y.getDouble(0)) / dY);
- maxxi += 1;
- maxyi += 1;
- if (maxxi < 0 || minxi >= xn) {
- continue;
- }
- if (maxyi < 0 || minyi >= yn) {
- continue;
- }
- if (minxi < 0) {
- minxi = 0;
- }
- if (maxxi >= xn) {
- maxxi = xn - 1;
- }
- if (maxyi >= yn) {
- maxyi = yn - 1;
- }
- for (int m = minyi; m <= maxyi; m++) {
- y = Y.getDouble(m);
- for (int n = minxi; n <= maxxi; n++) {
- x = X.getDouble(n);
- if (GeoComputation.pointInPolygon(ps, x, y)) {
- r.setDouble(m * xn + n, v);
- }
- }
- }
- }
- }
-
- return r;
- }
-
- /**
- * Interpolate with surface method
- *
- * @param x_s scatter X array
- * @param y_s scatter Y array
- * @param a scatter value array
- * @param X x coordinate
- * @param Y y coordinate
- * @return grid data
- */
- public static Array interpolation_Surface_bak(Array x_s, Array y_s, Array a, Array X, Array Y) {
- int rowNum, colNum, xn, yn;
- int[] shape = x_s.getShape();
- colNum = shape[1];
- rowNum = shape[0];
- xn = (int) X.getSize();
- yn = (int) Y.getSize();
- Array r = Array.factory(DataType.DOUBLE, new int[]{yn, xn});
- double x, y;
- boolean isIn;
-
- PolygonShape[][] polygons = new PolygonShape[rowNum - 1][colNum - 1];
- for (int i = 0; i < rowNum - 1; i++) {
- for (int j = 0; j < colNum - 1; j++) {
- PolygonShape ps = new PolygonShape();
- List points = new ArrayList<>();
- points.add(new PointD(x_s.getDouble(i * colNum + j), y_s.getDouble(i * colNum + j)));
- points.add(new PointD(x_s.getDouble((i + 1) * colNum + j), y_s.getDouble((i + 1) * colNum + j)));
- points.add(new PointD(x_s.getDouble((i + 1) * colNum + j + 1), y_s.getDouble((i + 1) * colNum + j + 1)));
- points.add(new PointD(x_s.getDouble(i * colNum + j + 1), y_s.getDouble(i * colNum + j + 1)));
- points.add((PointD) points.get(0).clone());
- ps.setPoints(points);
- polygons[i][j] = ps;
- }
- }
-
- for (int i = 0; i < yn; i++) {
- y = Y.getDouble(i);
- for (int j = 0; j < xn; j++) {
- x = X.getDouble(j);
- isIn = false;
- for (int ii = 0; ii < rowNum - 1; ii++) {
- for (int jj = 0; jj < colNum - 1; jj++) {
- if (GeoComputation.pointInPolygon(polygons[ii][jj], x, y)) {
- r.setDouble(i * xn + j, a.getDouble(ii * colNum + jj));
- isIn = true;
- break;
- }
- }
- if (isIn) {
- break;
- }
- }
- if (!isIn) {
- r.setDouble(i * xn + j, Double.NaN);
- }
- }
- }
-
- return r;
- }
-
- /**
- * Cressman analysis
- *
- * @param x_s scatter X array
- * @param y_s scatter Y array
- * @param v_s scatter value array
- * @param X x array
- * @param Y y array
- * @param radList radii list
- * @return result grid data
- */
- public static Array cressman(List x_s, List y_s, Array v_s, List X, List Y,
- List radList) {
- int xNum = X.size();
- int yNum = Y.size();
- int pNum = x_s.size();
- //double[][] gridData = new double[yNum][xNum];
- Array r = Array.factory(DataType.DOUBLE, new int[]{yNum, xNum});
- int irad = radList.size();
- int i, j;
-
- //Loop through each stn report and convert stn lat/lon to grid coordinates
- double xMin = X.get(0).doubleValue();
- double xMax = X.get(xNum - 1).doubleValue();
- double yMin = Y.get(0).doubleValue();
- double yMax = Y.get(yNum - 1).doubleValue();
- double xDelt = X.get(1).doubleValue() - X.get(0).doubleValue();
- double yDelt = Y.get(1).doubleValue() - Y.get(0).doubleValue();
- double x, y;
- double sum;
- int stNum = 0;
- double[][] stationData = new double[pNum][3];
- for (i = 0; i < pNum; i++) {
- x = x_s.get(i).doubleValue();
- y = y_s.get(i).doubleValue();
- stationData[i][0] = (x - xMin) / xDelt;
- stationData[i][1] = (y - yMin) / yDelt;
- stationData[i][2] = v_s.getDouble(i);
- if (!Double.isNaN(stationData[i][2])) {
- //total += stationData[i][2];
- stNum += 1;
- }
- }
- //total = total / stNum;
-
- double HITOP = -999900000000000000000.0;
- double HIBOT = 999900000000000000000.0;
- double[][] TOP = new double[yNum][xNum];
- double[][] BOT = new double[yNum][xNum];
- for (i = 0; i < yNum; i++) {
- for (j = 0; j < xNum; j++) {
- TOP[i][j] = HITOP;
- BOT[i][j] = HIBOT;
- }
- }
-
- //Initial grid values are average of station reports within the first radius
- double val, sx, sy, sxi, syi;
- double rad;
- if (radList.size() > 0) {
- rad = radList.get(0).doubleValue();
- } else {
- rad = 4;
- }
- for (i = 0; i < yNum; i++) {
- y = Y.get(i).doubleValue();
- yMin = y - rad;
- yMax = y + rad;
- for (j = 0; j < xNum; j++) {
- x = X.get(j).doubleValue();
- xMin = x - rad;
- xMax = x + rad;
- stNum = 0;
- sum = 0;
- for (int s = 0; s < pNum; s++) {
- val = stationData[s][2];
- sx = x_s.get(s).doubleValue();
- sy = y_s.get(s).doubleValue();
- sxi = stationData[s][0];
- syi = stationData[s][1];
- if (Double.isNaN(val) || sx < xMin || sx > xMax || sy < yMin || sy > yMax) {
- continue;
- }
-
- double dis = Math.sqrt(Math.pow(sx - x, 2) + Math.pow(sy - y, 2));
- if (dis > rad) {
- continue;
- }
-
- sum += val;
- stNum += 1;
- if (TOP[i][j] < val) {
- TOP[i][j] = val;
- }
- if (BOT[i][j] > val) {
- BOT[i][j] = val;
- }
- }
- if (stNum == 0) {
- r.setDouble(i * xNum + j, Double.NaN);
- } else {
- r.setDouble(i * xNum + j, sum / stNum);
- }
- }
- }
-
- //Perform the objective analysis
- for (int p = 0; p < irad; p++) {
- rad = radList.get(p).doubleValue();
- for (i = 0; i < yNum; i++) {
- y = Y.get(i).doubleValue();
- yMin = y - rad;
- yMax = y + rad;
- for (j = 0; j < xNum; j++) {
- if (Double.isNaN(r.getDouble(i * xNum + j))) {
- continue;
- }
-
- x = X.get(j).doubleValue();
- xMin = x - rad;
- xMax = x + rad;
- sum = 0;
- double wSum = 0;
- for (int s = 0; s < pNum; s++) {
- val = stationData[s][2];
- sx = x_s.get(s).doubleValue();
- sy = y_s.get(s).doubleValue();
- sxi = stationData[s][0];
- syi = stationData[s][1];
- if (Double.isNaN(val) || sx < xMin || sx > xMax || sy < yMin || sy > yMax) {
- continue;
- }
-
- double dis = Math.sqrt(Math.pow(sx - x, 2) + Math.pow(sy - y, 2));
- if (dis > rad) {
- continue;
- }
-
- int i1 = (int) syi;
- int j1 = (int) sxi;
- int i2 = i1 + 1;
- int j2 = j1 + 1;
- double a = r.getDouble(i1 * xNum + j1);
- double b = r.getDouble(i1 * xNum + j2);
- double c = r.getDouble(i2 * xNum + j1);
- double d = r.getDouble(i2 * xNum + j2);
- List dList = new ArrayList<>();
- if (!Double.isNaN(a)) {
- dList.add(a);
- }
- if (!Double.isNaN(b)) {
- dList.add(b);
- }
- if (!Double.isNaN(c)) {
- dList.add(c);
- }
- if (Double.isNaN(d)) {
- dList.add(d);
- }
-
- double calVal;
- if (dList.isEmpty()) {
- continue;
- } else if (dList.size() == 1) {
- calVal = dList.get(0);
- } else if (dList.size() <= 3) {
- double aSum = 0;
- for (double dd : dList) {
- aSum += dd;
- }
- calVal = aSum / dList.size();
- } else {
- double x1val = a + (c - a) * (syi - i1);
- double x2val = b + (d - b) * (syi - i1);
- calVal = x1val + (x2val - x1val) * (sxi - j1);
- }
- double eVal = val - calVal;
- double w = (rad * rad - dis * dis) / (rad * rad + dis * dis);
- sum += eVal * w;
- wSum += w;
- }
-// if (wSum < 0.000001) {
-// r.setDouble(i * xNum + j, Double.NaN);
-// } else {
-// double aData = r.getDouble(i * xNum + j) + sum / wSum;
-// r.setDouble(i * xNum + j, Math.max(BOT[i][j], Math.min(TOP[i][j], aData)));
-// }
- if (wSum >= 0.000001) {
- double aData = r.getDouble(i * xNum + j) + sum / wSum;
- r.setDouble(i * xNum + j, Math.max(BOT[i][j], Math.min(TOP[i][j], aData)));
- }
- }
- }
- }
-
- //Return
- return r;
- }
-
- /**
- * Cressman analysis
- *
- * @param x_s scatter X array
- * @param y_s scatter Y array
- * @param v_s scatter value array
- * @param X x array
- * @param Y y array
- * @param radList radii list
- * @return result grid data
- */
- public static Array cressman_bak(List x_s, List y_s, Array v_s, List X, List Y,
- List radList) {
- int xNum = X.size();
- int yNum = Y.size();
- int pNum = x_s.size();
- //double[][] gridData = new double[yNum][xNum];
- Array r = Array.factory(DataType.DOUBLE, new int[]{yNum, xNum});
- int irad = radList.size();
- int i, j;
-
- //Loop through each stn report and convert stn lat/lon to grid coordinates
- double xMin = X.get(0).doubleValue();
- double xMax;
- double yMin = Y.get(0).doubleValue();
- double yMax;
- double xDelt = X.get(1).doubleValue() - X.get(0).doubleValue();
- double yDelt = Y.get(1).doubleValue() - Y.get(0).doubleValue();
- double x, y;
- double sum;
- int stNum = 0;
- double[][] stationData = new double[pNum][3];
- for (i = 0; i < pNum; i++) {
- x = x_s.get(i).doubleValue();
- y = y_s.get(i).doubleValue();
- stationData[i][0] = (x - xMin) / xDelt;
- stationData[i][1] = (y - yMin) / yDelt;
- stationData[i][2] = v_s.getDouble(i);
- if (!Double.isNaN(stationData[i][2])) {
- //total += stationData[i][2];
- stNum += 1;
- }
- }
- //total = total / stNum;
-
- double HITOP = -999900000000000000000.0;
- double HIBOT = 999900000000000000000.0;
- double[][] TOP = new double[yNum][xNum];
- double[][] BOT = new double[yNum][xNum];
- for (i = 0; i < yNum; i++) {
- for (j = 0; j < xNum; j++) {
- TOP[i][j] = HITOP;
- BOT[i][j] = HIBOT;
- }
- }
-
- //Initial grid values are average of station reports within the first radius
- double rad;
- if (radList.size() > 0) {
- rad = radList.get(0).doubleValue();
- } else {
- rad = 4;
- }
- for (i = 0; i < yNum; i++) {
- y = (double) i;
- yMin = y - rad;
- yMax = y + rad;
- for (j = 0; j < xNum; j++) {
- x = (double) j;
- xMin = x - rad;
- xMax = x + rad;
- stNum = 0;
- sum = 0;
- for (int s = 0; s < pNum; s++) {
- double val = stationData[s][2];
- double sx = stationData[s][0];
- double sy = stationData[s][1];
- if (sx < 0 || sx >= xNum - 1 || sy < 0 || sy >= yNum - 1) {
- continue;
- }
-
- if (Double.isNaN(val) || sx < xMin || sx > xMax || sy < yMin || sy > yMax) {
- continue;
- }
-
- double dis = Math.sqrt(Math.pow(sx - x, 2) + Math.pow(sy - y, 2));
- if (dis > rad) {
- continue;
- }
-
- sum += val;
- stNum += 1;
- if (TOP[i][j] < val) {
- TOP[i][j] = val;
- }
- if (BOT[i][j] > val) {
- BOT[i][j] = val;
- }
- }
- if (stNum == 0) {
- r.setDouble(i * xNum + j, Double.NaN);
- } else {
- r.setDouble(i * xNum + j, sum / stNum);
- }
- }
- }
-
- //Perform the objective analysis
- for (int p = 0; p < irad; p++) {
- rad = radList.get(p).doubleValue();
- for (i = 0; i < yNum; i++) {
- y = (double) i;
- yMin = y - rad;
- yMax = y + rad;
- for (j = 0; j < xNum; j++) {
- if (Double.isNaN(r.getDouble(i * xNum + j))) {
- continue;
- }
-
- x = (double) j;
- xMin = x - rad;
- xMax = x + rad;
- sum = 0;
- double wSum = 0;
- for (int s = 0; s < pNum; s++) {
- double val = stationData[s][2];
- double sx = stationData[s][0];
- double sy = stationData[s][1];
- if (sx < 0 || sx >= xNum - 1 || sy < 0 || sy >= yNum - 1) {
- continue;
- }
-
- if (Double.isNaN(val) || sx < xMin || sx > xMax || sy < yMin || sy > yMax) {
- continue;
- }
-
- double dis = Math.sqrt(Math.pow(sx - x, 2) + Math.pow(sy - y, 2));
- if (dis > rad) {
- continue;
- }
-
- int i1 = (int) sy;
- int j1 = (int) sx;
- int i2 = i1 + 1;
- int j2 = j1 + 1;
- double a = r.getDouble(i1 * xNum + j1);
- double b = r.getDouble(i1 * xNum + j2);
- double c = r.getDouble(i2 * xNum + j1);
- double d = r.getDouble(i2 * xNum + j2);
- List dList = new ArrayList<>();
- if (!Double.isNaN(a)) {
- dList.add(a);
- }
- if (!Double.isNaN(b)) {
- dList.add(b);
- }
- if (!Double.isNaN(c)) {
- dList.add(c);
- }
- if (Double.isNaN(d)) {
- dList.add(d);
- }
-
- double calVal;
- if (dList.isEmpty()) {
- continue;
- } else if (dList.size() == 1) {
- calVal = dList.get(0);
- } else if (dList.size() <= 3) {
- double aSum = 0;
- for (double dd : dList) {
- aSum += dd;
- }
- calVal = aSum / dList.size();
- } else {
- double x1val = a + (c - a) * (sy - i1);
- double x2val = b + (d - b) * (sy - i1);
- calVal = x1val + (x2val - x1val) * (sx - j1);
- }
- double eVal = val - calVal;
- double w = (rad * rad - dis * dis) / (rad * rad + dis * dis);
- sum += eVal * w;
- wSum += w;
- }
- if (wSum < 0.000001) {
- r.setDouble(i * xNum + j, Double.NaN);
- } else {
- double aData = r.getDouble(i * xNum + j) + sum / wSum;
- r.setDouble(i * xNum + j, Math.max(BOT[i][j], Math.min(TOP[i][j], aData)));
- }
-// if (wSum >= 0.000001) {
-// double aData = r.getDouble(i * xNum + j) + sum / wSum;
-// r.setDouble(i * xNum + j, Math.max(BOT[i][j], Math.min(TOP[i][j], aData)));
-// }
- }
- }
- }
-
- //Return
- return r;
- }
-
- /**
- * Interpolates from a rectilinear grid to another rectilinear grid using
- * bilinear interpolation.
- *
- * @param a The sample array
- * @param X X coordinate of the sample array
- * @param Y Y coordinate of the sample array
- * @param newX X coordinate of the query points
- * @param newY Y coordinate of the query points
- * @return Resampled array
- */
- public static Array linint2(Array a, Array X, Array Y, Array newX, Array newY) {
- int xn = (int) newX.getSize();
- int yn = (int) newY.getSize();
- int[] shape = a.getShape();
- int n = shape.length;
- shape[n - 1] = xn;
- shape[n - 2] = yn;
- double x, y, v;
- Array r = Array.factory(DataType.DOUBLE, shape);
-
- Index index = r.getIndex();
- int[] counter;
- int yi, xi;
- for (int k = 0; k < r.getSize(); k++) {
- counter = index.getCurrentCounter();
- yi = counter[n - 2];
- xi = counter[n - 1];
- y = newY.getDouble(yi);
- x = newX.getDouble(xi);
- v = bilinear(a, index, X, Y, x, y);
- r.setDouble(index, v);
- index.incr();
- }
-
- return r;
- }
-
- /**
- * Resample grid array with bilinear method
- *
- * @param a The sample array
- * @param X X coordinate of the sample array
- * @param Y Y coordinate of the sample array
- * @param newX X coordinate of the query points
- * @param newY Y coordinate of the query points
- * @return Resampled array
- */
- public static Array resample_Bilinear(Array a, List X, List Y, List newX, List newY) {
- int i, j;
- int xn = newX.size();
- int yn = newY.size();
- double x, y, v;
- Array r = Array.factory(DataType.DOUBLE, new int[]{yn, xn});
-
- for (i = 0; i < yn; i++) {
- y = newY.get(i).doubleValue();
- for (j = 0; j < xn; j++) {
- x = newX.get(j).doubleValue();
- if (x < X.get(0).doubleValue() || x > X.get(X.size() - 1).doubleValue()) {
- r.setDouble(i * xn + j, Double.NaN);
- } else if (y < Y.get(0).doubleValue() || y > Y.get(Y.size() - 1).doubleValue()) {
- r.setDouble(i * xn + j, Double.NaN);
- } else {
- v = toStation(a, X, Y, x, y);
- r.setDouble(i * xn + j, v);
- }
- }
- }
-
- return r;
- }
-
- /**
- * Resample grid array with bilinear method
- *
- * @param a The sample array
- * @param X X coordinate of the sample array
- * @param Y Y coordinate of the sample array
- * @param newX X coordinate of the query points
- * @param newY Y coordinate of the query points
- * @return Resampled array
- */
- public static Array resample_Bilinear(Array a, Array X, Array Y, Array newX, Array newY) {
- int i;
- int n = (int) newX.getSize();
- double x, y, v;
- Array r = Array.factory(DataType.DOUBLE, newX.getShape());
-
- for (i = 0; i < n; i++) {
- x = newX.getDouble(i);
- y = newY.getDouble(i);
- if (x < X.getDouble(0) || x > X.getDouble((int) X.getSize() - 1)) {
- r.setDouble(i, Double.NaN);
- } else if (y < Y.getDouble(0) || y > Y.getDouble((int) Y.getSize() - 1)) {
- r.setDouble(i, Double.NaN);
- } else {
- v = toStation(a, X, Y, x, y);
- r.setDouble(i, v);
- }
- }
-
- return r;
- }
-
- /**
- * Resample grid array with neighbor method
- *
- * @param a The sample array
- * @param X X coordinate of the sample array
- * @param Y Y coordinate of the sample array
- * @param newX X coordinate of the query points
- * @param newY Y coordinate of the query points
- * @return Resampled array
- */
- public static Array resample_Neighbor(Array a, Array X, Array Y, Array newX, Array newY) {
- int i;
- int n = (int) newX.getSize();
- double x, y, v;
- Array r = Array.factory(DataType.DOUBLE, newX.getShape());
-
- for (i = 0; i < n; i++) {
- x = newX.getDouble(i);
- y = newY.getDouble(i);
- if (x < X.getDouble(0) || x > X.getDouble((int) X.getSize() - 1)) {
- r.setDouble(i, Double.NaN);
- } else if (y < Y.getDouble(0) || y > Y.getDouble((int) Y.getSize() - 1)) {
- r.setDouble(i, Double.NaN);
- } else {
- v = toStation_Neighbor(a, X, Y, x, y);
- r.setDouble(i, v);
- }
- }
-
- return r;
- }
-
- /**
- * Interpolate array data
- *
- * @param a Array
- * @param X X coordinates
- * @param Y Y coordinates
- * @return Result array data
- */
- public Array interpolate(Array a, List X, List Y) {
- int nxNum = X.size() * 2 - 1;
- int nyNum = Y.size() * 2 - 1;
- List newX = new ArrayList<>();
- List newY = new ArrayList<>();
- int i;
-
- for (i = 0; i < nxNum; i++) {
- if (i % 2 == 0) {
- newX.add(X.get(i / 2).doubleValue());
- } else {
- newX.add((X.get((i - 1) / 2).doubleValue() + X.get((i - 1) / 2 + 1).doubleValue()) / 2);
- }
- }
- for (i = 0; i < nyNum; i++) {
- if (i % 2 == 0) {
- newY.add(Y.get(i / 2).doubleValue());
- } else {
- newY.add((Y.get((i - 1) / 2).doubleValue() + Y.get((i - 1) / 2 + 1).doubleValue()) / 2);
- }
- }
-
- return resample_Bilinear(a, X, Y, newX, newY);
- }
-
- /**
- * Multidimensional interpolation on regular grids.
- *
- * @param points The points defining the regular grid in n dimensions.
- * @param values The data on the regular grid in n dimensions.
- * @param xi The coordinates to sample the gridded data at
- * @return Interpolation value
- */
- public static double interpn_s(List> points, Array values, List xi) {
- Object[] r = findIndices(points, xi);
- boolean outBounds = (boolean) r[2];
- if (outBounds) {
- return Double.NaN;
- } else {
- double v, weight;
- Index index = values.getIndex();
- int[] indices = (int[]) r[0];
- double[] distances = (double[]) r[1];
- v = 0;
- List ii = new ArrayList<>();
- iterIndex(ii, index, indices, 0);
- int n = indices.length;
- for (Index idx : ii) {
- weight = 1;
- for (int i = 0; i < n; i++) {
- weight *= idx.getCurrentCounter()[i] == indices[i] ? 1 - distances[i] : distances[i];
- }
- v += values.getDouble(idx) * weight;
- }
-
- return v;
- }
- }
-
- /**
- * Multidimensional interpolation on regular grids.
- *
- * @param points The points defining the regular grid in n dimensions.
- * @param values The data on the regular grid in n dimensions.
- * @param xi The coordinates to sample the gridded data at
- * @return Interpolation value
- */
- public static double interpn_s(List points, Array values, Array xi) {
- Object[] r = findIndices(points, xi);
- boolean outBounds = (boolean) r[2];
- if (outBounds) {
- return Double.NaN;
- } else {
- double v, weight;
- Index index = values.getIndex();
- int[] indices = (int[]) r[0];
- double[] distances = (double[]) r[1];
- v = 0;
- List ii = new ArrayList<>();
- iterIndex(ii, index, indices, 0);
- int n = indices.length;
- for (Index idx : ii) {
- weight = 1;
- for (int i = 0; i < n; i++) {
- weight *= idx.getCurrentCounter()[i] == indices[i] ? 1 - distances[i] : distances[i];
- }
- v += values.getDouble(idx) * weight;
- }
-
- return v;
- }
- }
-
- /**
- * Multidimensional interpolation on regular grids.
- *
- * @param points The points defining the regular grid in n dimensions.
- * @param values The data on the regular grid in n dimensions.
- * @param xi The coordinates to sample the gridded data at - 2D
- * @return Interpolation value
- */
- public static Array interpn(List points, Array values, List xi) {
- int n = xi.size();
- Array r = Array.factory(DataType.DOUBLE, new int[]{n});
- for (int i = 0; i < n; i++) {
- Array x = xi.get(i);
- r.setDouble(i, interpn_s(points, values, x));
- }
-
- return r;
- }
-
- /**
- * Multidimensional interpolation on regular grids.
- *
- * @param points The points defining the regular grid in n dimensions.
- * @param values The data on the regular grid in n dimensions.
- * @param xi The coordinates to sample the gridded data at - 2D
- * @return Interpolation value
- * @throws org.meteoinfo.ndarray.InvalidRangeException
- */
- public static Object interpn(List points, Array values, Array xi) throws InvalidRangeException {
- if (xi.getRank() == 1) {
- return interpn_s(points, values, xi);
- }
-
- int n = xi.getShape()[0];
- int m = xi.getShape()[1];
- Array r = Array.factory(DataType.DOUBLE, new int[]{n});
- for (int i = 0; i < n; i++) {
- Array x = xi.section(new int[]{i, 0}, new int[]{1, m});
- r.setDouble(i, interpn_s(points, values, x));
- }
-
- return r;
- }
-
- private static void iterIndex(List ii, Index index, int[] indices, int idx) {
- int n = indices.length;
- if (idx < n - 1) {
- index.setDim(idx, indices[idx]);
- iterIndex(ii, index, indices, idx + 1);
- index.setDim(idx, indices[idx] + 1);
- iterIndex(ii, index, indices, idx + 1);
- } else {
- index.setDim(idx, indices[idx]);
- ii.add((Index) index.clone());
- //System.out.println(index);
- index.setDim(idx, indices[idx] + 1);
- ii.add((Index) index.clone());
- //System.out.println(index);
- }
- }
-
- /**
- * Find indices
- *
- * @param points The points defining the regular grid in n dimensions.
- * @param xi The coordinates to sample the gridded data at
- * @return Indices
- */
- public static Object[] findIndices(List> points, List xi) {
- int n = points.size();
- int[] indices = new int[n];
- double[] distances = new double[n];
- boolean outBounds = false;
- double x;
- List a;
- for (int i = 0; i < n; i++) {
- x = xi.get(i).doubleValue();
- a = points.get(i);
- int idx = searchSorted(a, x);
- if (idx < 0) {
- outBounds = true;
- idx = 0;
- }
- indices[i] = idx;
- distances[i] = (x - a.get(idx).doubleValue()) / (a.get(idx + 1).doubleValue() - a.get(idx).doubleValue());
- }
-
- return new Object[]{indices, distances, outBounds};
- }
-
- /**
- * Find indices
- *
- * @param points The points defining the regular grid in n dimensions.
- * @param xi The coordinates to sample the gridded data at
- * @return Indices
- */
- public static Object[] findIndices(List points, Array xi) {
- int n = points.size();
- int[] indices = new int[n];
- double[] distances = new double[n];
- boolean outBounds = false;
- double x;
- Array a;
- for (int i = 0; i < n; i++) {
- x = xi.getDouble(i);
- a = points.get(i);
- int idx = searchSorted(a, x);
- if (idx < 0) {
- outBounds = true;
- idx = 0;
- }
- indices[i] = idx;
- distances[i] = (x - a.getDouble(idx)) / (a.getDouble(idx + 1) - a.getDouble(idx));
- }
-
- return new Object[]{indices, distances, outBounds};
- }
-
- /**
- * Search sorted list index
- *
- * @param a Sorted list
- * @param v value
- * @return Index
- */
- public static int searchSorted(List a, double v) {
- int idx = -1;
- int n = a.size();
- if (a.get(1).doubleValue() > a.get(0).doubleValue()) {
- if (v < a.get(0).doubleValue()) {
- return idx;
- }
-
- if (v > a.get(n - 1).doubleValue()) {
- return idx;
- }
-
- for (int i = 1; i < n; i++) {
- if (v < a.get(i).doubleValue()) {
- idx = i - 1;
- break;
- }
- }
- } else {
- if (v > a.get(0).doubleValue()) {
- return idx;
- }
-
- if (v < a.get(n - 1).doubleValue()) {
- return idx;
- }
-
- for (int i = 1; i < n; i++) {
- if (v > a.get(i).doubleValue()) {
- idx = i - 1;
- break;
- }
- }
- }
-
- return idx;
- }
-
- /**
- * Search sorted list index
- *
- * @param a Sorted list
- * @param v value
- * @return Index
- */
- public static int searchSorted(Array a, double v) {
- int idx = -1;
- int n = (int) a.getSize();
- if (a.getDouble(1) > a.getDouble(0)) {
- if (v < a.getDouble(0)) {
- return idx;
- }
-
- if (v > a.getDouble(n - 1)) {
- return idx;
- }
-
- for (int i = 1; i < n; i++) {
- if (v < a.getDouble(i)) {
- idx = i - 1;
- break;
- }
- }
- } else {
- if (v > a.getDouble(0)) {
- return idx;
- }
-
- if (v < a.getDouble(n - 1)) {
- return idx;
- }
-
- for (int i = 1; i < n; i++) {
- if (v > a.getDouble(i)) {
- idx = i - 1;
- break;
- }
- }
- }
-
- return idx;
- }
-
-// /**
-// * Search sorted list index
-// *
-// * @param a Sorted list
-// * @param v value
-// * @return Index
-// */
-// public static int searchSorted(Array a, double v) {
-// if (v < a.getDouble(0) || v > a.getDouble((int)a.getSize() - 1)) {
-// return -1;
-// }
-//
-// int idx = Arrays.binarySearch((double[])a.get1DJavaArray(double.class), v);
-// if (idx < 0) {
-// idx = -idx - 1;
-// }
-// return idx;
-// }
- /**
- * Interpolates data with any shape over a specified axis.
- *
- * @param x Desired interpolated value
- * @param xp The x-coordinates of the data points.
- * @param a The data to be interpolated.
- * @param axis The axis to interpolate over.
- * @return Interpolated data
- * @throws InvalidRangeException
- */
- public static Array interpolate_1d(double x, Array xp, Array a, int axis) throws InvalidRangeException {
- int[] dataShape = xp.getShape();
- int[] shape = new int[dataShape.length - 1];
- for (int i = 0; i < dataShape.length; i++) {
- if (i < axis) {
- shape[i] = dataShape[i];
- } else if (i > axis) {
- shape[i - 1] = dataShape[i];
- }
- }
-
- Array r = Array.factory(a.getDataType(), shape);
- Index indexr = r.getIndex();
- Index indexa = a.getIndex();
- int[] current, dcurrent = new int[dataShape.length];
- int idx;
- Array tArray;
- double belowp, abovep, belowa, abovea;
- for (int i = 0; i < r.getSize(); i++) {
- current = indexr.getCurrentCounter();
- List ranges = new ArrayList<>();
- for (int j = 0; j < dataShape.length; j++) {
- if (j == axis) {
- ranges.add(new Range(0, dataShape[j] - 1, 1));
- } else {
- idx = j;
- if (idx > axis) {
- idx -= 1;
- }
- ranges.add(new Range(current[idx], current[idx], 1));
- dcurrent[j] = current[idx];
- }
- }
- tArray = ArrayMath.section(xp, ranges);
- idx = searchSorted(tArray, x);
- if (idx < 0) {
- r.setDouble(i, Double.NaN);
- } else if (idx == dataShape[axis] - 1) {
- dcurrent[axis] = idx;
- r.setObject(i, a.getObject(indexa.set(dcurrent)));
- } else {
- dcurrent[axis] = idx;
- indexa.set(dcurrent);
- belowp = xp.getDouble(indexa);
- belowa = a.getDouble(indexa);
- dcurrent[axis] = idx + 1;
- indexa.set(dcurrent);
- abovep = xp.getDouble(indexa);
- abovea = a.getDouble(indexa);
- r.setDouble(i, (x - belowp) / (abovep - belowp) * (abovea - belowa) + belowa);
- }
- indexr.incr();
- }
-
- return r;
- }
-
- /**
- * Interpolates data with any shape over a specified axis.
- *
- * @param xa Desired interpolated values
- * @param xp The x-coordinates of the data points.
- * @param a The data to be interpolated.
- * @param axis The axis to interpolate over.
- * @return Interpolated data
- * @throws InvalidRangeException
- */
- public static Array interpolate_1d(Array xa, Array xp, Array a, int axis) throws InvalidRangeException {
- int[] dataShape = xp.getShape();
- int[] shape = new int[dataShape.length];
- int[] tshape = new int[shape.length - 1];
- for (int i = 0; i < dataShape.length; i++) {
- if (i == axis) {
- shape[i] = xa.getShape()[0];
- } else {
- shape[i] = dataShape[i];
- if (i < axis) {
- tshape[i] = dataShape[i];
- } else {
- tshape[i - 1] = dataShape[i];
- }
- }
- }
-
- Array r = Array.factory(a.getDataType(), shape);
- Array rr = Array.factory(DataType.BYTE, tshape);
- Index indexrr = rr.getIndex();
- Index indexr = r.getIndex();
- Index indexa = a.getIndex();
- int[] currentrr, currenta = new int[dataShape.length], currentr = new int[shape.length];
- int idx;
- Array tArray;
- double belowp, abovep, belowa, abovea, x;
- for (int i = 0; i < rr.getSize(); i++) {
- currentrr = indexrr.getCurrentCounter();
- List ranges = new ArrayList<>();
- for (int j = 0; j < dataShape.length; j++) {
- if (j == axis) {
- ranges.add(new Range(0, dataShape[j] - 1, 1));
- } else {
- idx = j;
- if (idx > axis) {
- idx -= 1;
- }
- ranges.add(new Range(currentrr[idx], currentrr[idx], 1));
- currenta[j] = currentrr[idx];
- currentr[j] = currentrr[idx];
- }
- }
- tArray = ArrayMath.section(xp, ranges);
- for (int j = 0; j < xa.getSize(); j++) {
- x = xa.getDouble(j);
- idx = searchSorted(tArray, x);
- currentr[axis] = j;
- indexr.set(currentr);
- if (idx < 0) {
- r.setDouble(indexr, Double.NaN);
- } else if (idx == dataShape[axis] - 1) {
- currenta[axis] = idx;
- r.setObject(indexr, a.getObject(indexa.set(currenta)));
- } else {
- currenta[axis] = idx;
- indexa.set(currenta);
- belowp = xp.getDouble(indexa);
- belowa = a.getDouble(indexa);
- currenta[axis] = idx + 1;
- indexa.set(currenta);
- abovep = xp.getDouble(indexa);
- abovea = a.getDouble(indexa);
- r.setDouble(indexr, (x - belowp) / (abovep - belowp) * (abovea - belowa) + belowa);
- }
- }
- indexrr.incr();
- }
-
- return r;
- }
-
- //
- //
- /**
- * Reproject
- *
- * @param x X array
- * @param y Y array
- * @param toProj To projection
- * @return Result arrays
- */
- public static Array[] reproject(Array x, Array y, ProjectionInfo toProj) {
- ProjectionInfo fromProj = KnownCoordinateSystems.geographic.world.WGS1984;
- return reproject(x, y, fromProj, toProj);
- }
-
- /**
- * Reproject
- *
- * @param x X array
- * @param y Y array
- * @param fromProj From projection
- * @param toProj To projection
- * @return Result arrays
- */
- public static Array[] reproject(Array x, Array y, ProjectionInfo fromProj, ProjectionInfo toProj) {
- Array rx = Array.factory(DataType.DOUBLE, x.getShape());
- Array ry = Array.factory(DataType.DOUBLE, x.getShape());
- int n = (int) x.getSize();
- double[][] points = new double[n][];
- for (int i = 0; i < n; i++) {
- points[i] = new double[]{x.getDouble(i), y.getDouble(i)};
- }
- Reproject.reprojectPoints(points, fromProj, toProj, 0, points.length);
- for (int i = 0; i < n; i++) {
- rx.setDouble(i, points[i][0]);
- ry.setDouble(i, points[i][1]);
- }
-
- return new Array[]{rx, ry};
- }
-
- /**
- * Interpolate data to a station point
- *
- * @param data Data array
- * @param xArray X array
- * @param yArray Y array
- * @param x X coordinate of the station
- * @param y Y coordinate of the station
- * @param missingValue Missing value
- * @return Interpolated value
- */
- public static double toStation(Array data, List xArray, List yArray, double x, double y,
- double missingValue) {
- double iValue = Double.NaN;
- int nx = xArray.size();
- int ny = yArray.size();
- if (x < xArray.get(0).doubleValue() || x > xArray.get(nx - 1).doubleValue()
- || y < yArray.get(0).doubleValue() || y > yArray.get(ny - 1).doubleValue()) {
- return iValue;
- }
-
- //Get x/y index
- int xIdx = 0, yIdx = 0;
- int i;
- boolean isIn = false;
- for (i = 1; i < nx; i++) {
- if (x < xArray.get(i).doubleValue()) {
- xIdx = i - 1;
- isIn = true;
- break;
- }
- }
- if (!isIn) {
- xIdx = nx - 2;
- }
- isIn = false;
- for (i = 1; i < ny; i++) {
- if (y < yArray.get(i).doubleValue()) {
- yIdx = i - 1;
- isIn = true;
- break;
- }
- }
- if (!isIn) {
- yIdx = ny - 2;
- }
-
- int i1 = yIdx;
- int j1 = xIdx;
- int i2 = i1 + 1;
- int j2 = j1 + 1;
- Index index = data.getIndex();
- double a = data.getDouble(index.set(i1, j1));
- double b = data.getDouble(index.set(i1, j2));
- double c = data.getDouble(index.set(i2, j1));
- double d = data.getDouble(index.set(i2, j2));
- List dList = new ArrayList<>();
- if (!Double.isNaN(a) && !MIMath.doubleEquals(a, missingValue)) {
- dList.add(a);
- }
- if (!Double.isNaN(b) && !MIMath.doubleEquals(b, missingValue)) {
- dList.add(b);
- }
- if (!Double.isNaN(c) && !MIMath.doubleEquals(c, missingValue)) {
- dList.add(c);
- }
- if (!Double.isNaN(d) && !MIMath.doubleEquals(d, missingValue)) {
- dList.add(d);
- }
-
- if (dList.isEmpty()) {
- return iValue;
- } else if (dList.size() == 1) {
- iValue = dList.get(0);
- } else if (dList.size() <= 3) {
- double aSum = 0;
- for (double dd : dList) {
- aSum += dd;
- }
- iValue = aSum / dList.size();
- } else {
- double dx = xArray.get(xIdx + 1).doubleValue() - xArray.get(xIdx).doubleValue();
- double dy = yArray.get(yIdx + 1).doubleValue() - yArray.get(yIdx).doubleValue();
- double x1val = a + (c - a) * (y - yArray.get(i1).doubleValue()) / dy;
- double x2val = b + (d - b) * (y - yArray.get(i1).doubleValue()) / dy;
- iValue = x1val + (x2val - x1val) * (x - xArray.get(j1).doubleValue()) / dx;
- }
-
- return iValue;
- }
-
- /**
- * Interpolate data to a station point
- *
- * @param data Data array
- * @param xArray X array
- * @param yArray Y array
- * @param x X coordinate of the station
- * @param y Y coordinate of the station
- * @return Interpolated value
- */
- public static double toStation(Array data, List xArray, List yArray, double x, double y) {
- double iValue = Double.NaN;
- int nx = xArray.size();
- int ny = yArray.size();
- if (x < xArray.get(0).doubleValue() || x > xArray.get(nx - 1).doubleValue()
- || y < yArray.get(0).doubleValue() || y > yArray.get(ny - 1).doubleValue()) {
- return iValue;
- }
-
- //Get x/y index
- int xIdx = 0, yIdx = 0;
- int i;
- boolean isIn = false;
- for (i = 1; i < nx; i++) {
- if (x < xArray.get(i).doubleValue()) {
- xIdx = i - 1;
- isIn = true;
- break;
- }
- }
- if (!isIn) {
- xIdx = nx - 2;
- }
- isIn = false;
- for (i = 1; i < ny; i++) {
- if (y < yArray.get(i).doubleValue()) {
- yIdx = i - 1;
- isIn = true;
- break;
- }
- }
- if (!isIn) {
- yIdx = ny - 2;
- }
-
- int i1 = yIdx;
- int j1 = xIdx;
- int i2 = i1 + 1;
- int j2 = j1 + 1;
- Index index = data.getIndex();
- double a = data.getDouble(index.set(i1, j1));
- double b = data.getDouble(index.set(i1, j2));
- double c = data.getDouble(index.set(i2, j1));
- double d = data.getDouble(index.set(i2, j2));
- List dList = new ArrayList<>();
- if (!Double.isNaN(a)) {
- dList.add(a);
- }
- if (!Double.isNaN(b)) {
- dList.add(b);
- }
- if (!Double.isNaN(c)) {
- dList.add(c);
- }
- if (!Double.isNaN(d)) {
- dList.add(d);
- }
-
- if (dList.isEmpty()) {
- return iValue;
- } else if (dList.size() == 1) {
- iValue = dList.get(0);
- } else if (dList.size() <= 3) {
- double aSum = 0;
- for (double dd : dList) {
- aSum += dd;
- }
- iValue = aSum / dList.size();
- } else {
- double dx = xArray.get(xIdx + 1).doubleValue() - xArray.get(xIdx).doubleValue();
- double dy = yArray.get(yIdx + 1).doubleValue() - yArray.get(yIdx).doubleValue();
- double x1val = a + (c - a) * (y - yArray.get(i1).doubleValue()) / dy;
- double x2val = b + (d - b) * (y - yArray.get(i1).doubleValue()) / dy;
- iValue = x1val + (x2val - x1val) * (x - xArray.get(j1).doubleValue()) / dx;
- }
-
- return iValue;
- }
-
- /**
- * Get value index in a dimension array
- *
- * @param dim Dimension array
- * @param v The value
- * @return value index
- */
- public static int getDimIndex(Array dim, double v) {
- int n = (int) dim.getSize();
- if (v < dim.getDouble(0) || v > dim.getDouble(n - 1)) {
- return -1;
- }
-
- int idx = n - 1;
- for (int i = 1; i < n; i++) {
- if (v < dim.getDouble(i)) {
- idx = i - 1;
- break;
- }
- }
- return idx;
- }
-
- private static int[] gridIndex(Array xdim, Array ydim, double x, double y) {
- int xn = (int) xdim.getSize();
- int yn = (int) ydim.getSize();
- int xIdx = getDimIndex(xdim, x);
- if (xIdx < 0) {
- return null;
- }
-
- int yIdx = getDimIndex(ydim, y);
- if (yIdx < 0) {
- return null;
- }
-
- if (xIdx == xn - 1) {
- xIdx = xn - 2;
- }
- if (yIdx == yn - 1) {
- yIdx = yn - 2;
- }
- int i1 = yIdx;
- int j1 = xIdx;
- int i2 = i1 + 1;
- int j2 = j1 + 1;
-
- return new int[]{i1, j1, i2, j2};
- }
-
- private static double bilinear(Array data, Index dindex, Array xdim, Array ydim, double x, double y) {
- double iValue = Double.NaN;
- int[] xyIdx = gridIndex(xdim, ydim, x, y);
- if (xyIdx == null) {
- return iValue;
- }
-
- int i1 = xyIdx[0];
- int j1 = xyIdx[1];
- int i2 = xyIdx[2];
- int j2 = xyIdx[3];
- Index index = Index.factory(data.getShape());
- int n = index.getRank();
- for (int i = 0; i < n - 2; i++) {
- index.setDim(i, dindex.getCurrentCounter()[i]);
- }
- index.setDim(n - 2, i1);
- index.setDim(n - 1, j1);
- double a = data.getDouble(index);
- index.setDim(n - 1, j2);
- double b = data.getDouble(index);
- index.setDim(n - 2, i2);
- index.setDim(n - 1, j1);
- double c = data.getDouble(index);
- index.setDim(n - 2, i2);
- index.setDim(n - 1, j2);
- double d = data.getDouble(index);
- List dList = new ArrayList<>();
- if (!Double.isNaN(a)) {
- dList.add(a);
- }
- if (!Double.isNaN(b)) {
- dList.add(b);
- }
- if (!Double.isNaN(c)) {
- dList.add(c);
- }
- if (!Double.isNaN(d)) {
- dList.add(d);
- }
-
- if (dList.isEmpty()) {
- return iValue;
- } else if (dList.size() == 1) {
- iValue = dList.get(0);
- } else if (dList.size() <= 3) {
- double aSum = 0;
- for (double dd : dList) {
- aSum += dd;
- }
- iValue = aSum / dList.size();
- } else {
- double dx = xdim.getDouble(j1 + 1) - xdim.getDouble(j1);
- double dy = ydim.getDouble(i1 + 1) - ydim.getDouble(i1);
- double x1val = a + (c - a) * (y - ydim.getDouble(i1)) / dy;
- double x2val = b + (d - b) * (y - ydim.getDouble(i1)) / dy;
- iValue = x1val + (x2val - x1val) * (x - xdim.getDouble(j1)) / dx;
- }
-
- return iValue;
- }
-
- /**
- * Interpolate data to a station point
- *
- * @param data Data array
- * @param xArray X array
- * @param yArray Y array
- * @param x X coordinate of the station
- * @param y Y coordinate of the station
- * @return Interpolated value
- */
- public static double toStation(Array data, Array xArray, Array yArray, double x, double y) {
- double iValue = Double.NaN;
- int nx = (int) xArray.getSize();
- int ny = (int) yArray.getSize();
- if (x < xArray.getDouble(0) || x > xArray.getDouble(nx - 1)
- || y < yArray.getDouble(0) || y > yArray.getDouble(ny - 1)) {
- return iValue;
- }
-
- //Get x/y index
- int xIdx = 0, yIdx = 0;
- int i;
- boolean isIn = false;
- for (i = 1; i < nx; i++) {
- if (x < xArray.getDouble(i)) {
- xIdx = i - 1;
- isIn = true;
- break;
- }
- }
- if (!isIn) {
- xIdx = nx - 2;
- }
- isIn = false;
- for (i = 1; i < ny; i++) {
- if (y < yArray.getDouble(i)) {
- yIdx = i - 1;
- isIn = true;
- break;
- }
- }
- if (!isIn) {
- yIdx = ny - 2;
- }
-
- int i1 = yIdx;
- int j1 = xIdx;
- int i2 = i1 + 1;
- int j2 = j1 + 1;
- Index index = data.getIndex();
- double a = data.getDouble(index.set(i1, j1));
- double b = data.getDouble(index.set(i1, j2));
- double c = data.getDouble(index.set(i2, j1));
- double d = data.getDouble(index.set(i2, j2));
- List dList = new ArrayList<>();
- if (!Double.isNaN(a)) {
- dList.add(a);
- }
- if (!Double.isNaN(b)) {
- dList.add(b);
- }
- if (!Double.isNaN(c)) {
- dList.add(c);
- }
- if (!Double.isNaN(d)) {
- dList.add(d);
- }
-
- if (dList.isEmpty()) {
- return iValue;
- } else if (dList.size() == 1) {
- iValue = dList.get(0);
- } else if (dList.size() <= 3) {
- double aSum = 0;
- for (double dd : dList) {
- aSum += dd;
- }
- iValue = aSum / dList.size();
- } else {
- double dx = xArray.getDouble(xIdx + 1) - xArray.getDouble(xIdx);
- double dy = yArray.getDouble(yIdx + 1) - yArray.getDouble(yIdx);
- double x1val = a + (c - a) * (y - yArray.getDouble(i1)) / dy;
- double x2val = b + (d - b) * (y - yArray.getDouble(i1)) / dy;
- iValue = x1val + (x2val - x1val) * (x - xArray.getDouble(j1)) / dx;
- }
-
- return iValue;
- }
-
- /**
- * Interpolate data to a station point
- *
- * @param data Data array
- * @param xArray X array
- * @param yArray Y array
- * @param x X coordinate of the station
- * @param y Y coordinate of the station
- * @param missingValue Missing value
- * @return Interpolated value
- */
- public static double toStation_Neighbor(Array data, List xArray, List yArray, double x, double y,
- double missingValue) {
- double iValue = Double.NaN;
- int nx = xArray.size();
- int ny = yArray.size();
- if (x < xArray.get(0).doubleValue() || x > xArray.get(nx - 1).doubleValue()
- || y < yArray.get(0).doubleValue() || y > yArray.get(ny - 1).doubleValue()) {
- return iValue;
- }
-
- //Get x/y index
- int xIdx = 0, yIdx = 0;
- int i;
- boolean isIn = false;
- for (i = 1; i < nx; i++) {
- if (x < xArray.get(i).doubleValue()) {
- xIdx = i - 1;
- isIn = true;
- break;
- }
- }
- if (!isIn) {
- xIdx = nx - 2;
- }
- isIn = false;
- for (i = 1; i < ny; i++) {
- if (y < yArray.get(i).doubleValue()) {
- yIdx = i - 1;
- isIn = true;
- break;
- }
- }
- if (!isIn) {
- yIdx = ny - 2;
- }
-
- int i1 = yIdx;
- int j1 = xIdx;
- int i2 = i1 + 1;
- int j2 = j1 + 1;
- Index index = data.getIndex();
- double a = data.getDouble(index.set(i1, j1));
- double b = data.getDouble(index.set(i1, j2));
- double c = data.getDouble(index.set(i2, j1));
- double d = data.getDouble(index.set(i2, j2));
-
- if (Math.abs(x - xArray.get(j1).doubleValue()) < Math.abs(xArray.get(j2).doubleValue() - x)) {
- if (Math.abs(y - yArray.get(i1).doubleValue()) < Math.abs(yArray.get(i2).doubleValue() - y)) {
- iValue = a;
- } else {
- iValue = c;
- }
- } else if (Math.abs(y - yArray.get(i1).doubleValue()) < Math.abs(yArray.get(i2).doubleValue() - y)) {
- iValue = b;
- } else {
- iValue = d;
- }
-
- return iValue;
- }
-
- /**
- * Interpolate data to a station point
- *
- * @param data Data array
- * @param xArray X array
- * @param yArray Y array
- * @param x X coordinate of the station
- * @param y Y coordinate of the station
- * @return Interpolated value
- */
- public static double toStation_Neighbor(Array data, List xArray, List yArray, double x, double y) {
- //ouble iValue = Double.NaN;
- int nx = xArray.size();
- int ny = yArray.size();
- if (x < xArray.get(0).doubleValue() || x > xArray.get(nx - 1).doubleValue()
- || y < yArray.get(0).doubleValue() || y > yArray.get(ny - 1).doubleValue()) {
- return Double.NaN;
- }
-
- //Get x/y index
- int xIdx = 0, yIdx = 0;
- int i;
- boolean isIn = false;
- for (i = 1; i < nx; i++) {
- if (x < xArray.get(i).doubleValue()) {
- xIdx = i - 1;
- isIn = true;
- break;
- }
- }
- if (!isIn) {
- xIdx = nx - 2;
- }
- isIn = false;
- for (i = 1; i < ny; i++) {
- if (y < yArray.get(i).doubleValue()) {
- yIdx = i - 1;
- isIn = true;
- break;
- }
- }
- if (!isIn) {
- yIdx = ny - 2;
- }
-
- int i1 = yIdx;
- int j1 = xIdx;
- int i2 = i1 + 1;
- int j2 = j1 + 1;
- Index index = data.getIndex();
- double a = data.getDouble(index.set(i1, j1));
- double b = data.getDouble(index.set(i1, j2));
- double c = data.getDouble(index.set(i2, j1));
- double d = data.getDouble(index.set(i2, j2));
-
- double iValue;
- if (Math.abs(x - xArray.get(j1).doubleValue()) < Math.abs(xArray.get(j2).doubleValue() - x)) {
- if (Math.abs(y - yArray.get(i1).doubleValue()) < Math.abs(yArray.get(i2).doubleValue() - y)) {
- iValue = a;
- } else {
- iValue = c;
- }
- } else if (Math.abs(y - yArray.get(i1).doubleValue()) < Math.abs(yArray.get(i2).doubleValue() - y)) {
- iValue = b;
- } else {
- iValue = d;
- }
-
- return iValue;
- }
-
- /**
- * Interpolate data to a station point
- *
- * @param data Data array
- * @param xArray X array
- * @param yArray Y array
- * @param x X coordinate of the station
- * @param y Y coordinate of the station
- * @return Interpolated value
- */
- public static double toStation_Neighbor(Array data, Array xArray, Array yArray, double x, double y) {
- //ouble iValue = Double.NaN;
- int nx = (int) xArray.getSize();
- int ny = (int) yArray.getSize();
- if (x < xArray.getDouble(0) || x > xArray.getDouble(nx - 1)
- || y < yArray.getDouble(0) || y > yArray.getDouble(ny - 1)) {
- return Double.NaN;
- }
-
- //Get x/y index
- int xIdx = 0, yIdx = 0;
- int i;
- boolean isIn = false;
- for (i = 1; i < nx; i++) {
- if (x < xArray.getDouble(i)) {
- xIdx = i - 1;
- isIn = true;
- break;
- }
- }
- if (!isIn) {
- xIdx = nx - 2;
- }
- isIn = false;
- for (i = 1; i < ny; i++) {
- if (y < yArray.getDouble(i)) {
- yIdx = i - 1;
- isIn = true;
- break;
- }
- }
- if (!isIn) {
- yIdx = ny - 2;
- }
-
- int i1 = yIdx;
- int j1 = xIdx;
- int i2 = i1 + 1;
- int j2 = j1 + 1;
- Index index = data.getIndex();
- double a = data.getDouble(index.set(i1, j1));
- double b = data.getDouble(index.set(i1, j2));
- double c = data.getDouble(index.set(i2, j1));
- double d = data.getDouble(index.set(i2, j2));
-
- double iValue;
- if (Math.abs(x - xArray.getDouble(j1)) < Math.abs(xArray.getDouble(j2) - x)) {
- if (Math.abs(y - yArray.getDouble(i1)) < Math.abs(yArray.getDouble(i2) - y)) {
- iValue = a;
- } else {
- iValue = c;
- }
- } else if (Math.abs(y - yArray.getDouble(i1)) < Math.abs(yArray.getDouble(i2) - y)) {
- iValue = b;
- } else {
- iValue = d;
- }
-
- return iValue;
- }
-
- /**
- * Project grid data
- *
- * @param data Data array
- * @param xx X array
- * @param yy Y array
- * @param fromProj From projection
- * @param toProj To projection
- * @return Porjected grid data
- * @throws org.meteoinfo.ndarray.InvalidRangeException
- */
- public static Object[] reproject_back(Array data, List xx, List yy, ProjectionInfo fromProj, ProjectionInfo toProj) throws InvalidRangeException {
- Extent aExtent;
- int xnum = xx.size();
- int ynum = yy.size();
- double xdelta = xx.get(1).doubleValue() - xx.get(0).doubleValue();
- double ydelta = yy.get(1).doubleValue() - yy.get(0).doubleValue();
- aExtent = ProjectionUtil.getProjectionExtent(fromProj, toProj, xx, yy);
-
- double xDelt = (aExtent.maxX - aExtent.minX) / (xnum - 1);
- double yDelt = (aExtent.maxY - aExtent.minY) / (ynum - 1);
- Array rx = Array.factory(DataType.DOUBLE, new int[]{xnum});
- Array ry = Array.factory(DataType.DOUBLE, new int[]{ynum});
- int i, j, xIdx, yIdx;
- for (i = 0; i < xnum; i++) {
- rx.setDouble(i, aExtent.minX + i * xDelt);
- }
-
- for (i = 0; i < ynum; i++) {
- ry.setDouble(i, aExtent.minY + i * yDelt);
- }
-
- double x, y;
- Array r = Array.factory(data.getDataType(), data.getShape());
- double[][] points = new double[1][];
- Object fill_value = Double.NaN;
- switch (data.getDataType()) {
- case INT:
- fill_value = Integer.MIN_VALUE;
- break;
- case FLOAT:
- fill_value = Float.NaN;
- break;
- }
- for (i = 0; i < ynum; i++) {
- for (j = 0; j < xnum; j++) {
- points[0] = new double[]{rx.getDouble(j), ry.getDouble(i)};
- try {
- Reproject.reprojectPoints(points, toProj, fromProj, 0, 1);
- x = points[0][0];
- y = points[0][1];
-
- if (x < xx.get(0).doubleValue() || x > xx.get(xx.size() - 1).doubleValue()) {
- r.setObject(i * xnum + j, fill_value);
- } else if (y < yy.get(0).doubleValue() || y > yy.get(yy.size() - 1).doubleValue()) {
- r.setObject(i * xnum + j, fill_value);
- } else {
- xIdx = (int) ((x - xx.get(0).doubleValue()) / xdelta);
- yIdx = (int) ((y - yy.get(0).doubleValue()) / ydelta);
- r.setObject(i * xnum + j, data.getObject(yIdx * xnum + xIdx));
- }
- } catch (Exception e) {
- r.setObject(i * xnum + j, fill_value);
- j++;
- }
- }
- }
-
- return new Object[]{r, rx, ry};
- }
-
- /**
- * Project grid data
- *
- * @param data Data array
- * @param xx X array
- * @param yy Y array
- * @param fromProj From projection
- * @param toProj To projection
- * @param method Resample method
- * @return Porjected grid data
- * @throws org.meteoinfo.ndarray.InvalidRangeException
- */
- public static Object[] reproject(Array data, List xx, List yy, ProjectionInfo fromProj,
- ProjectionInfo toProj, ResampleMethods method) throws InvalidRangeException {
- Extent aExtent;
- int xnum = xx.size();
- int ynum = yy.size();
- aExtent = ProjectionUtil.getProjectionExtent(fromProj, toProj, xx, yy);
-
- double xDelt = (aExtent.maxX - aExtent.minX) / (xnum - 1);
- double yDelt = (aExtent.maxY - aExtent.minY) / (ynum - 1);
- int i;
- Array rx = Array.factory(DataType.DOUBLE, new int[]{xnum});
- Array ry = Array.factory(DataType.DOUBLE, new int[]{ynum});
- for (i = 0; i < xnum; i++) {
- rx.setDouble(i, aExtent.minX + i * xDelt);
- }
-
- for (i = 0; i < ynum; i++) {
- ry.setDouble(i, aExtent.minY + i * yDelt);
- }
-
- Array[] rr = ArrayUtil.meshgrid(rx, ry);
-
- Array r = ArrayUtil.reproject(data, xx, yy, rr[0], rr[1], fromProj, toProj, method);
-
- return new Object[]{r, rx, ry};
- }
-
- /**
- * Project grid data
- *
- * @param data Data array
- * @param xx X array
- * @param yy Y array
- * @param fromProj From projection
- * @param toProj To projection
- * @return Porjected grid data
- * @throws org.meteoinfo.ndarray.InvalidRangeException
- */
- public static Object[] reproject(Array data, List xx, List yy, ProjectionInfo fromProj,
- ProjectionInfo toProj) throws InvalidRangeException {
- return reproject(data, xx, yy, fromProj, toProj, ResampleMethods.NearestNeighbor);
- }
-
- /**
- * Reproject
- *
- * @param data Data array
- * @param x X array
- * @param y Y array
- * @param rx Result x array
- * @param ry Result y array
- * @param fromProj From projection
- * @param toProj To projection
- * @param fill_value Fill value
- * @param resampleMethod Resample method
- * @return Result arrays
- * @throws org.meteoinfo.ndarray.InvalidRangeException
- */
- public static Array reproject(Array data, List x, List y, Array rx, Array ry,
- ProjectionInfo fromProj, ProjectionInfo toProj, double fill_value, ResampleMethods resampleMethod) throws InvalidRangeException {
- int n = (int) rx.getSize();
- int[] dshape = data.getShape();
- int[] shape;
- if (rx.getRank() == 1) {
- shape = new int[1];
- shape[0] = rx.getShape()[0];
- } else {
- shape = new int[data.getRank()];
- for (int i = 0; i < shape.length; i++) {
- if (i == shape.length - 2) {
- shape[i] = rx.getShape()[0];
- } else if (i == shape.length - 1) {
- shape[i] = rx.getShape()[1];
- } else {
- shape[i] = data.getShape()[i];
- }
- }
- }
- Array r = Array.factory(data.getDataType(), shape);
-
- double[][] points = new double[n][];
- for (int i = 0; i < n; i++) {
- points[i] = new double[]{rx.getDouble(i), ry.getDouble(i)};
- }
- if (!fromProj.equals(toProj)) {
- Reproject.reprojectPoints(points, toProj, fromProj, 0, points.length);
- }
- double xx, yy;
- if (resampleMethod == ResampleMethods.Bilinear) {
- if (shape.length <= 2) {
- for (int i = 0; i < n; i++) {
- xx = points[i][0];
- yy = points[i][1];
- if (Double.isNaN(xx) || Double.isNaN(yy)) {
- r.setObject(i, Double.NaN);
- } else {
- r.setObject(i, toStation(data, x, y, xx, yy, fill_value));
- }
- }
- } else {
- Index indexr = r.getIndex();
- int[] current, cc = null;
- boolean isNew;
- Array ndata = null;
- int k;
- for (int i = 0; i < r.getSize(); i++) {
- current = indexr.getCurrentCounter();
- isNew = true;
- if (i > 0) {
- for (int j = 0; j < shape.length - 2; j++) {
- if (cc[j] != current[j]) {
- isNew = false;
- break;
- }
- }
- }
- cc = Arrays.copyOf(current, current.length);
- if (isNew) {
- List ranges = new ArrayList<>();
- for (int j = 0; j < shape.length - 2; j++) {
- ranges.add(new Range(current[j], current[j], 1));
- }
- ranges.add(new Range(0, dshape[dshape.length - 2] - 1, 1));
- ranges.add(new Range(0, dshape[dshape.length - 1] - 1, 1));
- ndata = data.section(ranges).reduce();
- }
- k = current[shape.length - 2] * shape[shape.length - 1] + current[shape.length - 1];
- xx = points[k][0];
- yy = points[k][1];
- if (Double.isNaN(xx) || Double.isNaN(yy)) {
- r.setObject(i, Double.NaN);
- } else {
- r.setObject(i, toStation(ndata, x, y, xx, yy, fill_value));
- }
- indexr.incr();
- }
- }
- } else if (shape.length <= 2) {
- for (int i = 0; i < n; i++) {
- xx = points[i][0];
- yy = points[i][1];
- if (Double.isNaN(xx) || Double.isNaN(yy)) {
- r.setObject(i, Double.NaN);
- } else {
- r.setObject(i, toStation_Neighbor(data, x, y, xx, yy, fill_value));
- }
- }
- } else {
- Index indexr = r.getIndex();
- int[] current, cc = null;
- boolean isNew;
- Array ndata = null;
- int k;
- for (int i = 0; i < r.getSize(); i++) {
- current = indexr.getCurrentCounter();
- isNew = true;
- if (i > 0) {
- for (int j = 0; j < shape.length - 2; j++) {
- if (cc[j] != current[j]) {
- isNew = false;
- break;
- }
- }
- }
- cc = Arrays.copyOf(current, current.length);
- if (isNew) {
- List ranges = new ArrayList<>();
- for (int j = 0; j < shape.length - 2; j++) {
- ranges.add(new Range(current[j], current[j], 1));
- }
- ranges.add(new Range(0, dshape[dshape.length - 2] - 1, 1));
- ranges.add(new Range(0, dshape[dshape.length - 1] - 1, 1));
- ndata = data.section(ranges).reduce();
- }
- k = current[shape.length - 2] * shape[shape.length - 1] + current[shape.length - 1];
- xx = points[k][0];
- yy = points[k][1];
- if (Double.isNaN(xx) || Double.isNaN(yy)) {
- r.setObject(i, Double.NaN);
- } else {
- r.setObject(i, toStation_Neighbor(ndata, x, y, xx, yy, fill_value));
- }
- indexr.incr();
- }
- }
-
- return r;
- }
-
- /**
- * Reproject
- *
- * @param data Data array
- * @param x X array
- * @param y Y array
- * @param rx Result x array
- * @param ry Result y array
- * @param fromProj From projection
- * @param toProj To projection
- * @param resampleMethod Resample method
- * @return Result arrays
- * @throws org.meteoinfo.ndarray.InvalidRangeException
- */
- public static Array reproject(Array data, List x, List y, Array rx, Array ry,
- ProjectionInfo fromProj, ProjectionInfo toProj, ResampleMethods resampleMethod) throws InvalidRangeException {
- int n = (int) rx.getSize();
- int[] dshape = data.getShape();
- int[] shape;
- if (rx.getRank() == 1) {
- shape = new int[1];
- shape[0] = rx.getShape()[0];
- } else {
- shape = new int[data.getRank()];
- for (int i = 0; i < shape.length; i++) {
- if (i == shape.length - 2) {
- shape[i] = rx.getShape()[0];
- } else if (i == shape.length - 1) {
- shape[i] = rx.getShape()[1];
- } else {
- shape[i] = data.getShape()[i];
- }
- }
- }
- Array r = Array.factory(data.getDataType(), shape);
-
- double[][] points = new double[n][];
- for (int i = 0; i < n; i++) {
- points[i] = new double[]{rx.getDouble(i), ry.getDouble(i)};
- }
- if (!fromProj.equals(toProj)) {
- Reproject.reprojectPoints(points, toProj, fromProj, 0, points.length);
- }
- double xx, yy;
- if (resampleMethod == ResampleMethods.Bilinear) {
- if (shape.length <= 2) {
- for (int i = 0; i < n; i++) {
- xx = points[i][0];
- yy = points[i][1];
- r.setObject(i, toStation(data, x, y, xx, yy));
- }
- } else {
- Index indexr = r.getIndex();
- int[] current, cc = null;
- boolean isNew;
- Array ndata = null;
- int k;
- for (int i = 0; i < r.getSize(); i++) {
- current = indexr.getCurrentCounter();
- isNew = true;
- if (i > 0) {
- for (int j = 0; j < shape.length - 2; j++) {
- if (cc[j] != current[j]) {
- isNew = false;
- break;
- }
- }
- }
- cc = Arrays.copyOf(current, current.length);
- if (isNew) {
- List ranges = new ArrayList<>();
- for (int j = 0; j < shape.length - 2; j++) {
- ranges.add(new Range(current[j], current[j], 1));
- }
- ranges.add(new Range(0, dshape[dshape.length - 2] - 1, 1));
- ranges.add(new Range(0, dshape[dshape.length - 1] - 1, 1));
- ndata = data.section(ranges).reduce();
- }
- k = current[shape.length - 2] * shape[shape.length - 1] + current[shape.length - 1];
- xx = points[k][0];
- yy = points[k][1];
- r.setObject(i, toStation(ndata, x, y, xx, yy));
- indexr.incr();
- }
- }
- } else if (shape.length == 2) {
- for (int i = 0; i < n; i++) {
- xx = points[i][0];
- yy = points[i][1];
- r.setObject(i, toStation_Neighbor(data, x, y, xx, yy));
- }
- } else {
- Index indexr = r.getIndex();
- int[] current, cc = null;
- boolean isNew;
- Array ndata = null;
- int k;
- for (int i = 0; i < r.getSize(); i++) {
- current = indexr.getCurrentCounter();
- isNew = true;
- if (i > 0) {
- for (int j = 0; j < shape.length - 2; j++) {
- if (cc[j] != current[j]) {
- isNew = false;
- break;
- }
- }
- }
- cc = Arrays.copyOf(current, current.length);
- if (isNew) {
- List ranges = new ArrayList<>();
- for (int j = 0; j < shape.length - 2; j++) {
- ranges.add(new Range(current[j], current[j], 1));
- }
- ranges.add(new Range(0, dshape[dshape.length - 2] - 1, 1));
- ranges.add(new Range(0, dshape[dshape.length - 1] - 1, 1));
- ndata = data.section(ranges).reduce();
- }
- k = current[shape.length - 2] * shape[shape.length - 1] + current[shape.length - 1];
- xx = points[k][0];
- yy = points[k][1];
- r.setObject(i, toStation_Neighbor(ndata, x, y, xx, yy));
- indexr.incr();
- }
- }
-
- return r;
- }
-
- /**
- * Reproject
- *
- * @param data Data array
- * @param x X array
- * @param y Y array
- * @param rx Result x array
- * @param ry Result y array
- * @param fromProj From projection
- * @param toProj To projection
- * @param fill_value Fill value
- * @param resampleMethod Resample method
- * @return Result arrays
- */
- public static Array reproject(Array data, List x, List y, List rx, List ry,
- ProjectionInfo fromProj, ProjectionInfo toProj, double fill_value, ResampleMethods resampleMethod) {
- int n = rx.size() * ry.size();
- int[] shape = new int[]{ry.size(), rx.size()};
- Array r = Array.factory(data.getDataType(), shape);
-
- double[][] points = new double[n][];
- for (int i = 0; i < ry.size(); i++) {
- for (int j = 0; j < rx.size(); j++) {
- points[i * rx.size() + j] = new double[]{rx.get(j).doubleValue(), ry.get(i).doubleValue()};
- }
- }
- if (!fromProj.equals(toProj)) {
- Reproject.reprojectPoints(points, toProj, fromProj, 0, points.length);
- }
- double xx, yy;
- if (resampleMethod == ResampleMethods.Bilinear) {
- for (int i = 0; i < n; i++) {
- xx = points[i][0];
- yy = points[i][1];
- r.setObject(i, toStation(data, x, y, xx, yy, fill_value));
- }
- } else {
- for (int i = 0; i < n; i++) {
- xx = points[i][0];
- yy = points[i][1];
- r.setObject(i, toStation_Neighbor(data, x, y, xx, yy, fill_value));
- }
- }
-
- return r;
- }
-
- /**
- * Computes the smallest convex Polygon that contains all the
- * points
- *
- * @param x X array
- * @param y Y array
- * @return PolygonShape
- */
- public static PolygonShape convexHull(Array x, Array y) {
- int n = (int) x.getSize();
- Geometry[] geos = new Geometry[n];
- GeometryFactory factory = new GeometryFactory();
- for (int i = 0; i < n; i++) {
- Coordinate c = new Coordinate(x.getDouble(i), y.getDouble(i));
- geos[i] = factory.createPoint(c);
- }
- Geometry gs = factory.createGeometryCollection(geos);
- Geometry ch = gs.convexHull();
- return new PolygonShape(ch);
- }
-
- //
- //
- //
-}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/Chart.java b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/Chart.java
index 46d418b2..1b99e49c 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/Chart.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/Chart.java
@@ -1,902 +1,902 @@
-/* This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.chart;
-
-import java.awt.BasicStroke;
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.Graphics2D;
-import java.awt.Rectangle;
-import java.awt.RenderingHints;
-import java.awt.Stroke;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Rectangle2D;
-import java.util.ArrayList;
-import java.util.List;
-import org.meteoinfo.chart.plot.MapPlot;
-import org.meteoinfo.chart.plot.Plot;
-import org.meteoinfo.drawing.Draw;
-import org.meteoinfo.global.PointF;
-
-/**
- *
- * @author Yaqiang Wang
- * yaqiang.wang@gmail.com
- */
-public class Chart {
-
- //
- private List plots;
- private int currentPlot;
- private int rowNum;
- private int columnNum;
- private ChartText title;
- private ChartText subTitle;
- private List texts;
- private ChartLegend legend;
- private Color background;
- //private boolean drawBackground;
- private boolean drawLegend;
- private Rectangle2D plotArea;
- private boolean antiAlias;
- private boolean symbolAntialias;
- private ChartPanel parent;
-
- //
- //
- /**
- * Constructor
- */
- public Chart() {
- this.drawLegend = false;
- this.background = Color.white;
- //this.drawBackground = true;
- this.antiAlias = false;
- this.symbolAntialias = true;
- this.rowNum = 1;
- this.columnNum = 1;
- this.plots = new ArrayList<>();
- this.currentPlot = -1;
- this.texts = new ArrayList<>();
- }
-
- /**
- * Constructor
- *
- * @param parent ChartPanel parent
- */
- public Chart(ChartPanel parent) {
- this();
- this.parent = parent;
- }
-
- /**
- * Constructor
- *
- * @param plot Plot
- * @param parent ChartPanel
- */
- public Chart(Plot plot, ChartPanel parent) {
- this(parent);
- this.plots.add(plot);
- }
-
- /**
- * Constructor
- *
- * @param plot Plot
- */
- public Chart(Plot plot) {
- this(plot, null);
- }
-
- /**
- * Constructor
- *
- * @param title Title
- * @param plot Plot
- * @param parent ChartPanel
- */
- public Chart(String title, Plot plot, ChartPanel parent) {
- this(plot, parent);
- if (title == null) {
- this.title = null;
- } else {
- this.title = new ChartText(title);
- }
- }
-
- /**
- * Constructor
- *
- * @param title Title
- * @param plot Plot
- */
- public Chart(String title, Plot plot) {
- this(title, plot, null);
- }
-
- //
- //
- /**
- * Set ChartPanel parent
- *
- * @param value ChartPanel
- */
- public void setParent(ChartPanel value) {
- this.parent = value;
- for (Plot plot : this.plots) {
- if (plot instanceof MapPlot) {
- ((MapPlot) plot).setParent(value);
- }
- }
- }
-
- /**
- * Get plot
- *
- * @return Plot
- */
- public List getPlots() {
- return plots;
- }
-
- /**
- * Get current plot
- *
- * @return Current plot
- */
- public Plot getCurrentPlot() {
- if (this.plots.isEmpty()) {
- return null;
- }
-
- if (this.currentPlot < 0 || this.currentPlot >= this.plots.size()) {
- this.currentPlot = this.plots.size() - 1;
- }
- return this.plots.get(this.currentPlot);
- }
-
- /**
- * Set current plot
- *
- * @param value Current plot
- */
- public void setCurrentPlot(Plot value) {
- if (this.plots.isEmpty()) {
- this.addPlot(value);
- //this.currentPlot = 0;
- } else if (this.currentPlot == -1) {
- this.plots.add(value);
- } else {
- if (this.currentPlot >= this.plots.size()) {
- this.currentPlot = this.plots.size() - 1;
- }
- Plot plot = this.plots.get(this.currentPlot);
- value.isSubPlot = plot.isSubPlot;
- value.columnIndex = plot.columnIndex;
- value.rowIndex = plot.rowIndex;
- this.plots.set(this.currentPlot, value);
- }
- }
-
- /**
- * Set current plot index
- *
- * @param value Current plot index
- */
- public void setCurrentPlot(int value) {
- this.currentPlot = value;
- }
-
- /**
- * Get the first plot
- *
- * @return Plot
- */
- public Plot getPlot() {
- if (this.plots.isEmpty()) {
- return null;
- }
-
- return this.plots.get(0);
- }
-
- /**
- * Get row number of sub plots
- *
- * @return Row number of sub plots
- */
- public int getRowNum() {
- return this.rowNum;
- }
-
- /**
- * Set row number of sub plots
- *
- * @param value Row number of sub plots
- */
- public void setRowNum(int value) {
- this.rowNum = value;
- }
-
- /**
- * Get column number of sub plots
- *
- * @return Column number of sub plots
- */
- public int getColumnNum() {
- return this.columnNum;
- }
-
- /**
- * Set column number of sub plots
- *
- * @param value Column number of sub plots
- */
- public void setColumnNum(int value) {
- this.columnNum = value;
- }
-
- /**
- * Get title
- *
- * @return Title
- */
- public ChartText getTitle() {
- return title;
- }
-
- /**
- * Set title
- *
- * @param value Title
- */
- public void setTitle(ChartText value) {
- title = value;
- }
-
- /**
- * Get sub title
- *
- * @return Sub title
- */
- public ChartText getSubTitle() {
- return subTitle;
- }
-
- /**
- * Set sub title
- *
- * @param value Sub title
- */
- public void setSubTitle(ChartText value) {
- subTitle = value;
- }
-
- /**
- * Get background
- *
- * @return Background
- */
- public Color getBackground() {
- return this.background;
- }
-
- /**
- * Set background
- *
- * @param value Background
- */
- public void setBackground(Color value) {
- this.background = value;
- }
-
-// /**
-// * Get if draw background
-// *
-// * @return Boolean
-// */
-// public boolean isDrawBackground() {
-// return this.drawBackground;
-// }
-
-// /**
-// * Set if draw background
-// *
-// * @param value Boolean
-// */
-// public void setDrawBackground(boolean value) {
-// this.drawBackground = value;
-// }
-
- /**
- * Get chart legend
- *
- * @return Chart legend
- */
- public ChartLegend getLegend() {
- return this.legend;
- }
-
- /**
- * Get if draw legend
- *
- * @return If draw legend
- */
- public boolean isDrawLegend() {
- return this.drawLegend;
- }
-
- /**
- * Set if draw legend
- *
- * @param value Boolean
- */
- public void setDrawLegend(boolean value) {
- this.drawLegend = value;
- }
-
- /**
- * Get plot area
- *
- * @return Plot area
- */
- public Rectangle2D getPlotArea() {
- return this.plotArea;
- }
-
- /**
- * Get if is anti-alias
- *
- * @return Boolean
- */
- public boolean isAntiAlias() {
- return this.antiAlias;
- }
-
- /**
- * Set if is anti-alias
- *
- * @param value Boolean
- */
- public void setAntiAlias(boolean value) {
- this.antiAlias = value;
- }
-
- /**
- * Get symbol antialias
- * @return Boolean
- */
- public boolean isSymbolAntialias() {
- return this.symbolAntialias;
- }
-
- /**
- * Set symbol antialias
- * @param value Boolean
- */
- public void setSymbolAntialias(boolean value) {
- this.symbolAntialias = value;
- }
-
- //
- //
- /**
- * Draw plot
- *
- * @param g Graphics2D
- * @param area Drawing area
- */
- public void draw(Graphics2D g, Rectangle2D area) {
- g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
- if (antiAlias) {
- g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
- //g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
- g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
- g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
- g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
- //g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
- g.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
- } else {
- g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
- //g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
- g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_DEFAULT);
- g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_OFF);
- g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_DEFAULT);
- //g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
- g.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT);
- }
-
- AffineTransform oldMatrix = g.getTransform();
- Rectangle oldRegion = g.getClipBounds();
- g.setClip(area);
- g.translate(area.getX(), area.getY());
-
- //Draw background
- if (this.background != null) {
- g.setColor(background);
- g.fill(new Rectangle2D.Double(0, 0, area.getWidth(), area.getHeight()));
- }
-
- //Draw title
- float y = 5;
- if (title != null) {
- g.setColor(title.getColor());
- g.setFont(title.getFont());
- float x = (float) area.getWidth() / 2;
- //y -= this.title.getHeight(g) - 5;
- //FontMetrics metrics = g.getFontMetrics(title.getFont());
- //x -= metrics.stringWidth(title.getText()) / 2;
- //y += metrics.getHeight();
- int i = 0;
- for (String text : title.getTexts()) {
- Dimension dim = Draw.getStringDimension(text, g);
- if (i == 0) {
- y += dim.getHeight();
- }
- Draw.drawString(g, text, x - dim.width / 2, y);
- g.setFont(title.getFont());
- y += dim.height + title.getLineSpace();
- i += 1;
- }
- y += 5;
- }
-
- //Draw plot
- plotArea = this.getPlotArea(g, area);
- //plotArea = area;
- if (plotArea.getWidth() < 20 || plotArea.getHeight() < 20) {
- g.setTransform(oldMatrix);
- g.setClip(oldRegion);
- return;
- }
-
- if (this.plots.size() > 0) {
- //double zoom = this.getPositionAreaZoom(g, plotArea);
- //Margin tightInset = this.getPlotsTightInset(g, plotArea);
- Margin shrink = this.getPlotsShrink(g, plotArea);
- for (int i = 0; i < this.plots.size(); i++) {
- Plot plot = this.plots.get(i);
- plot.setSymbolAntialias(this.symbolAntialias);
- if (plot.isOuterPosActive()){
- if (plot.isSubPlot || plot.isSameShrink()) {
- plot.setPlotShrink(shrink);
- } else {
- //plot.setPlotShrink(this.getPlotShrink(g, area, plot));
- plot.setPlotShrink(this.getPlotShrink(g, plotArea, plot));
- }
- }
- if (plot instanceof MapPlot) {
- ((MapPlot) plot).setAntialias(this.antiAlias);
- }
- plot.draw(g, plotArea);
- }
- }
-
- //Draw text
- drawText(g, area);
-
- //Draw legend
- if (this.drawLegend) {
- Dimension dim = this.legend.getLegendDimension(g, new Dimension((int) area.getWidth(), (int) area.getHeight()));
- float x = 0;
- switch (this.legend.getPosition()) {
- case UPPER_CENTER_OUTSIDE:
- x = (float) area.getWidth() / 2 - dim.width / 2;
- y += 5;
- break;
- case LOWER_CENTER_OUTSIDE:
- x = (float) area.getWidth() / 2 - dim.width / 2;
- y += plotArea.getHeight() + 5;
- break;
- case LEFT_OUTSIDE:
- x = 10;
- y = (float) area.getHeight() / 2 - dim.height / 2;
- break;
- case RIGHT_OUTSIDE:
- x = (float) plotArea.getWidth() + 10;
- y = (float) area.getHeight() / 2 - dim.height / 2;
- break;
- }
- this.legend.draw(g, new PointF(x, y));
- }
-
- g.setTransform(oldMatrix);
- g.setClip(oldRegion);
- }
-
- void drawText(Graphics2D g, Rectangle2D area) {
- float x, y;
- for (ChartText text : this.texts) {
- x = (float) (area.getWidth() * text.getX());
- y = (float) (area.getHeight() * (1 - text.getY()));
- Dimension dim = Draw.getStringDimension(text.getText(), g);
- Rectangle.Double rect = new Rectangle.Double(x, y, dim.getWidth(), dim.getHeight());
- if (text.isFill()) {
- g.setColor(text.getBackground());
- g.fill(rect);
- }
- if (text.isDrawNeatline()) {
- g.setColor(text.getNeatlineColor());
- Stroke oldStroke = g.getStroke();
- g.setStroke(new BasicStroke(text.getNeatlineSize()));
- g.draw(rect);
- g.setStroke(oldStroke);
- }
- g.setFont(text.getFont());
- g.setColor(text.getColor());
- Draw.drawString(g, text.getText(), x, y);
- }
- }
-
- private Rectangle2D getPlotArea(Graphics2D g, Rectangle2D area) {
- Rectangle2D pArea = new Rectangle2D.Double();
- int edge = 0;
- int top = edge;
- int left = edge;
- int right = edge;
- int bottom = edge;
- if (this.title != null) {
- top += this.title.getTrueDimension(g).height + 12;
- }
- pArea.setRect(left, top, area.getWidth() - left - right, area.getHeight() - top - bottom);
-
- return pArea;
- }
-
- private Rectangle2D getPlotArea_bak(Graphics2D g, Rectangle2D area) {
- Rectangle2D pArea = new Rectangle2D.Double();
- int edge = 2;
- int top = edge;
- int left = edge;
- int right = edge;
- int bottom = edge;
- if (this.title != null) {
- top += this.title.getTrueDimension(g).height + 10;
- }
- if (this.drawLegend) {
- Dimension dim = this.legend.getLegendDimension(g, new Dimension((int) area.getWidth(), (int) area.getHeight()));
- switch (this.legend.getPosition()) {
- case UPPER_CENTER_OUTSIDE:
- top += dim.height + 10;
- break;
- case LOWER_CENTER_OUTSIDE:
- bottom += dim.height + 10;
- break;
- case LEFT_OUTSIDE:
- left += dim.width + 10;
- break;
- case RIGHT_OUTSIDE:
- right += dim.width + 10;
- break;
- }
- }
- pArea.setRect(left, top, area.getWidth() - left - right, area.getHeight() - top - bottom);
-
- return pArea;
- }
-
- private Margin getPlotShrink(Graphics2D g, Rectangle2D area, Plot plot) {
- Margin shrink;
- if (plot.isSubPlot) {
- double rowHeight = area.getHeight() / this.rowNum;
- double colWidth = area.getWidth() / this.columnNum;
- double x = area.getX() + plot.columnIndex * colWidth;
- double y = area.getY() + plot.rowIndex * rowHeight;
- Rectangle2D subPlotArea = new Rectangle2D.Double(x, y, colWidth, rowHeight);
- plot.setOuterPositionArea(subPlotArea);
- plot.updatePosition(area, subPlotArea);
- Rectangle2D positionArea = plot.getPositionArea(area);
- plot.setPositionArea(positionArea);
- Margin tightInset = plot.getTightInset(g, positionArea);
- plot.setTightInset(tightInset);
- shrink = plot.getPlotShrink();
- } else {
- plot.setOuterPositionArea(area);
- Rectangle2D positionArea = plot.getPositionArea(area);
- plot.setPositionArea(positionArea);
- Margin tightInset = plot.getTightInset(g, positionArea);
- plot.setTightInset(tightInset);
- shrink = plot.getPlotShrink();
- //shrink = tightInset;
- }
-
- return shrink;
- }
-
- private Margin getPlotsShrink(Graphics2D g, Rectangle2D area) {
- Margin pshrink = null, shrink;
- for (int i = 0; i < this.plots.size(); i++) {
- Plot plot = this.plots.get(i);
- plot.setOuterPositionArea(plot.getOuterPositionArea(area));
- Rectangle2D positionArea = plot.getPositionArea(area);
- plot.setPositionArea(positionArea);
- Margin tightInset = plot.getTightInset(g, positionArea);
- plot.setTightInset(tightInset);
- shrink = plot.getPlotShrink();
- if (i == 0) {
- pshrink = shrink;
- } else if (pshrink != null) {
- pshrink = pshrink.extend(shrink);
- }
- }
-
- return pshrink;
- }
-
- private Margin getPlotsShrink_bak(Graphics2D g, Rectangle2D area) {
- Margin pshrink = null, shrink;
- for (int i = 0; i < this.plots.size(); i++) {
- Plot plot = this.plots.get(i);
- if (plot.isSubPlot) {
- double rowHeight = area.getHeight() / this.rowNum;
- double colWidth = area.getWidth() / this.columnNum;
- double x = area.getX() + plot.columnIndex * colWidth;
- double y = area.getY() + plot.rowIndex * rowHeight;
- Rectangle2D subPlotArea = new Rectangle2D.Double(x, y, colWidth, rowHeight);
- plot.setOuterPositionArea(subPlotArea);
- plot.updatePosition(area, subPlotArea);
- Rectangle2D positionArea = plot.getPositionArea(area);
- plot.setPositionArea(positionArea);
- Margin tightInset = plot.getTightInset(g, positionArea);
- plot.setTightInset(tightInset);
- shrink = plot.getPlotShrink();
- } else {
- plot.setOuterPositionArea(area);
- Rectangle2D positionArea = plot.getPositionArea(area);
- plot.setPositionArea(positionArea);
- Margin tightInset = plot.getTightInset(g, positionArea);
- plot.setTightInset(tightInset);
- shrink = plot.getPlotShrink();
- }
- if (i == 0) {
- pshrink = shrink;
- } else if (pshrink != null) {
- pshrink = pshrink.extend(shrink);
- }
- }
-
- return pshrink;
- }
-
- private Margin getPlotsTightInset(Graphics2D g, Rectangle2D area) {
- int i = 0;
- Margin pti = null, tightInset;
- for (Plot plot : this.plots) {
- if (plot.isSubPlot) {
- double rowHeight = area.getHeight() / this.rowNum;
- double colWidth = area.getWidth() / this.columnNum;
- double x = area.getX() + plot.columnIndex * colWidth;
- double y = area.getY() + plot.rowIndex * rowHeight;
- Rectangle2D subPlotArea = new Rectangle2D.Double(x, y, colWidth, rowHeight);
- plot.setOuterPositionArea(subPlotArea);
- plot.updatePosition(area, subPlotArea);
- Rectangle2D positionArea = plot.getPositionArea();
- plot.setPositionArea(positionArea);
- tightInset = plot.getTightInset(g, positionArea);
- } else {
- plot.setOuterPositionArea(area);
- Rectangle2D positionArea = plot.getPositionArea();
- plot.setPositionArea(positionArea);
- tightInset = plot.getTightInset(g, positionArea);
- }
- if (i == 0) {
- pti = tightInset;
- } else if (pti != null) {
- pti = pti.extend(tightInset);
- }
- i += 1;
- }
-
- return pti;
- }
-
- private double getPositionAreaZoom(Graphics2D g, Rectangle2D area) {
- double zoom = 1.0;
- for (Plot plot : this.plots) {
- if (plot.isSubPlot) {
- double rowHeight = area.getHeight() / this.rowNum;
- double colWidth = area.getWidth() / this.columnNum;
- double x = area.getX() + plot.columnIndex * colWidth;
- double y = area.getY() + plot.rowIndex * rowHeight;
- Rectangle2D subPlotArea = new Rectangle2D.Double(x, y, colWidth, rowHeight);
- plot.setOuterPositionArea(subPlotArea);
- plot.updatePosition(area, subPlotArea);
- Rectangle2D positionArea = plot.getPositionArea();
- plot.setPositionArea(positionArea);
- Margin tightInset = plot.getTightInset(g, positionArea);
- plot.setTightInset(tightInset);
- double zoom1 = plot.updatePostionAreaZoom();
- if (zoom1 < zoom) {
- zoom = zoom1;
- }
- } else {
- plot.setOuterPositionArea(area);
- Rectangle2D positionArea = plot.getPositionArea();
- plot.setPositionArea(positionArea);
- Margin tightInset = plot.getTightInset(g, positionArea);
- plot.setTightInset(tightInset);
- double zoom1 = plot.updatePostionAreaZoom();
- if (zoom1 < zoom) {
- zoom = zoom1;
- }
- }
- }
-
- return zoom;
- }
-
- private Rectangle2D getSubPlotArea(Graphics2D g, Plot plot, Rectangle2D area) {
- if (plot.isSubPlot) {
- double rowHeight = area.getHeight() / this.rowNum;
- double colWidth = area.getWidth() / this.columnNum;
- double x = area.getX() + plot.columnIndex * colWidth;
- double y = area.getY() + plot.rowIndex * rowHeight;
- Rectangle2D subPlotArea = new Rectangle2D.Double(x, y, colWidth, rowHeight);
- plot.setOuterPositionArea(subPlotArea);
- plot.updatePosition(area, subPlotArea);
- Rectangle2D positionArea = plot.getPositionArea();
- plot.setPositionArea(positionArea);
- Margin tightInset = plot.getTightInset(g, positionArea);
- plot.setTightInset(tightInset);
- double zoom = plot.updatePostionAreaZoom();
- plot.setPositionAreaZoom(zoom);
- return subPlotArea;
- } else {
- plot.setOuterPositionArea(area);
- Rectangle2D positionArea = plot.getPositionArea();
- plot.setPositionArea(positionArea);
- Margin tightInset = plot.getTightInset(g, positionArea);
- plot.setTightInset(tightInset);
- double zoom = plot.updatePostionAreaZoom();
- plot.setPositionAreaZoom(zoom);
- //return tightInset.getArea(positionArea);
- return area;
- }
- }
-
- /**
- * Get graph area
- *
- * @return Get graph area
- */
- public Rectangle2D getGraphArea() {
- Rectangle2D rect = this.plots.get(0).getPositionArea();
- double left = rect.getX() + this.plotArea.getX();
- double top = rect.getY() + this.plotArea.getY();
- return new Rectangle2D.Double(left, top, rect.getWidth(), rect.getHeight());
- }
-
- /**
- * Find a plot by point
- *
- * @param x X
- * @param y Y
- * @return Plot
- */
- public Plot findPlot(int x, int y) {
- for (Plot plot : this.plots) {
- Rectangle2D area = plot.getPositionArea();
- if (area.contains(x, y)) {
- return plot;
- }
- }
-
- return null;
- }
-
- /**
- * Clear plots
- */
- public void clearPlots() {
- this.plots.clear();
- }
-
- /**
- * Clear texts
- */
- public void clearTexts() {
- this.texts.clear();
- }
-
- /**
- * Remove a plot
- *
- * @param plot The plot
- */
- public void removePlot(Plot plot) {
- this.plots.remove(plot);
- }
-
- /**
- * Add a plot
- *
- * @param plot Plot
- */
- public void addPlot(Plot plot) {
- if (plot instanceof MapPlot) {
- ((MapPlot) plot).setParent(parent);
- }
- this.plots.add(plot);
- }
-
- /**
- * Set plot
- *
- * @param plot Plot
- */
- public void setPlot(Plot plot) {
- if (plot instanceof MapPlot) {
- ((MapPlot) plot).setParent(parent);
- }
- this.plots.clear();
- this.plots.add(plot);
- }
-
- /**
- * Get plot by plot index
- *
- * @param plotIdx Plot index - begin with 1
- * @return Plot index
- */
- public Plot getPlot(int plotIdx) {
- for (Plot plot : this.plots) {
- int pIdx = plot.rowIndex * this.columnNum + plot.columnIndex + 1;
- if (pIdx == plotIdx) {
- return plot;
- }
- }
-
- if (plotIdx > 0 && plotIdx <= this.plots.size())
- return this.plots.get(plotIdx - 1);
- else
- return null;
- }
-
- /**
- * Get plot index
- * @param plot The plot
- * @return Plot index
- */
- public int getPlotIndex(Plot plot){
- return this.plots.indexOf(plot);
- }
-
- /**
- * Check if has web map layer
- *
- * @return Boolean
- */
- public boolean hasWebMap() {
- for (Plot plot : this.plots) {
- if (plot instanceof MapPlot) {
- MapPlot mp = (MapPlot) plot;
- if (mp.hasWebMapLayer()) {
- return true;
- }
- }
- }
-
- return false;
- }
-
- /**
- * Add text
- *
- * @param text Text
- */
- public void addText(ChartText text) {
- this.texts.add(text);
- }
- //
-
-}
+/* This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ */
+package org.meteoinfo.chart;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.Stroke;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.util.ArrayList;
+import java.util.List;
+import org.meteoinfo.chart.plot.MapPlot;
+import org.meteoinfo.chart.plot.Plot;
+import org.meteoinfo.common.PointF;
+import org.meteoinfo.drawing.Draw;
+
+/**
+ *
+ * @author Yaqiang Wang
+ * yaqiang.wang@gmail.com
+ */
+public class Chart {
+
+ //
+ private List plots;
+ private int currentPlot;
+ private int rowNum;
+ private int columnNum;
+ private ChartText title;
+ private ChartText subTitle;
+ private List texts;
+ private ChartLegend legend;
+ private Color background;
+ //private boolean drawBackground;
+ private boolean drawLegend;
+ private Rectangle2D plotArea;
+ private boolean antiAlias;
+ private boolean symbolAntialias;
+ private ChartPanel parent;
+
+ //
+ //
+ /**
+ * Constructor
+ */
+ public Chart() {
+ this.drawLegend = false;
+ this.background = Color.white;
+ //this.drawBackground = true;
+ this.antiAlias = false;
+ this.symbolAntialias = true;
+ this.rowNum = 1;
+ this.columnNum = 1;
+ this.plots = new ArrayList<>();
+ this.currentPlot = -1;
+ this.texts = new ArrayList<>();
+ }
+
+ /**
+ * Constructor
+ *
+ * @param parent ChartPanel parent
+ */
+ public Chart(ChartPanel parent) {
+ this();
+ this.parent = parent;
+ }
+
+ /**
+ * Constructor
+ *
+ * @param plot Plot
+ * @param parent ChartPanel
+ */
+ public Chart(Plot plot, ChartPanel parent) {
+ this(parent);
+ this.plots.add(plot);
+ }
+
+ /**
+ * Constructor
+ *
+ * @param plot Plot
+ */
+ public Chart(Plot plot) {
+ this(plot, null);
+ }
+
+ /**
+ * Constructor
+ *
+ * @param title Title
+ * @param plot Plot
+ * @param parent ChartPanel
+ */
+ public Chart(String title, Plot plot, ChartPanel parent) {
+ this(plot, parent);
+ if (title == null) {
+ this.title = null;
+ } else {
+ this.title = new ChartText(title);
+ }
+ }
+
+ /**
+ * Constructor
+ *
+ * @param title Title
+ * @param plot Plot
+ */
+ public Chart(String title, Plot plot) {
+ this(title, plot, null);
+ }
+
+ //
+ //
+ /**
+ * Set ChartPanel parent
+ *
+ * @param value ChartPanel
+ */
+ public void setParent(ChartPanel value) {
+ this.parent = value;
+ for (Plot plot : this.plots) {
+ if (plot instanceof MapPlot) {
+ ((MapPlot) plot).setParent(value);
+ }
+ }
+ }
+
+ /**
+ * Get plot
+ *
+ * @return Plot
+ */
+ public List getPlots() {
+ return plots;
+ }
+
+ /**
+ * Get current plot
+ *
+ * @return Current plot
+ */
+ public Plot getCurrentPlot() {
+ if (this.plots.isEmpty()) {
+ return null;
+ }
+
+ if (this.currentPlot < 0 || this.currentPlot >= this.plots.size()) {
+ this.currentPlot = this.plots.size() - 1;
+ }
+ return this.plots.get(this.currentPlot);
+ }
+
+ /**
+ * Set current plot
+ *
+ * @param value Current plot
+ */
+ public void setCurrentPlot(Plot value) {
+ if (this.plots.isEmpty()) {
+ this.addPlot(value);
+ //this.currentPlot = 0;
+ } else if (this.currentPlot == -1) {
+ this.plots.add(value);
+ } else {
+ if (this.currentPlot >= this.plots.size()) {
+ this.currentPlot = this.plots.size() - 1;
+ }
+ Plot plot = this.plots.get(this.currentPlot);
+ value.isSubPlot = plot.isSubPlot;
+ value.columnIndex = plot.columnIndex;
+ value.rowIndex = plot.rowIndex;
+ this.plots.set(this.currentPlot, value);
+ }
+ }
+
+ /**
+ * Set current plot index
+ *
+ * @param value Current plot index
+ */
+ public void setCurrentPlot(int value) {
+ this.currentPlot = value;
+ }
+
+ /**
+ * Get the first plot
+ *
+ * @return Plot
+ */
+ public Plot getPlot() {
+ if (this.plots.isEmpty()) {
+ return null;
+ }
+
+ return this.plots.get(0);
+ }
+
+ /**
+ * Get row number of sub plots
+ *
+ * @return Row number of sub plots
+ */
+ public int getRowNum() {
+ return this.rowNum;
+ }
+
+ /**
+ * Set row number of sub plots
+ *
+ * @param value Row number of sub plots
+ */
+ public void setRowNum(int value) {
+ this.rowNum = value;
+ }
+
+ /**
+ * Get column number of sub plots
+ *
+ * @return Column number of sub plots
+ */
+ public int getColumnNum() {
+ return this.columnNum;
+ }
+
+ /**
+ * Set column number of sub plots
+ *
+ * @param value Column number of sub plots
+ */
+ public void setColumnNum(int value) {
+ this.columnNum = value;
+ }
+
+ /**
+ * Get title
+ *
+ * @return Title
+ */
+ public ChartText getTitle() {
+ return title;
+ }
+
+ /**
+ * Set title
+ *
+ * @param value Title
+ */
+ public void setTitle(ChartText value) {
+ title = value;
+ }
+
+ /**
+ * Get sub title
+ *
+ * @return Sub title
+ */
+ public ChartText getSubTitle() {
+ return subTitle;
+ }
+
+ /**
+ * Set sub title
+ *
+ * @param value Sub title
+ */
+ public void setSubTitle(ChartText value) {
+ subTitle = value;
+ }
+
+ /**
+ * Get background
+ *
+ * @return Background
+ */
+ public Color getBackground() {
+ return this.background;
+ }
+
+ /**
+ * Set background
+ *
+ * @param value Background
+ */
+ public void setBackground(Color value) {
+ this.background = value;
+ }
+
+// /**
+// * Get if draw background
+// *
+// * @return Boolean
+// */
+// public boolean isDrawBackground() {
+// return this.drawBackground;
+// }
+
+// /**
+// * Set if draw background
+// *
+// * @param value Boolean
+// */
+// public void setDrawBackground(boolean value) {
+// this.drawBackground = value;
+// }
+
+ /**
+ * Get chart legend
+ *
+ * @return Chart legend
+ */
+ public ChartLegend getLegend() {
+ return this.legend;
+ }
+
+ /**
+ * Get if draw legend
+ *
+ * @return If draw legend
+ */
+ public boolean isDrawLegend() {
+ return this.drawLegend;
+ }
+
+ /**
+ * Set if draw legend
+ *
+ * @param value Boolean
+ */
+ public void setDrawLegend(boolean value) {
+ this.drawLegend = value;
+ }
+
+ /**
+ * Get plot area
+ *
+ * @return Plot area
+ */
+ public Rectangle2D getPlotArea() {
+ return this.plotArea;
+ }
+
+ /**
+ * Get if is anti-alias
+ *
+ * @return Boolean
+ */
+ public boolean isAntiAlias() {
+ return this.antiAlias;
+ }
+
+ /**
+ * Set if is anti-alias
+ *
+ * @param value Boolean
+ */
+ public void setAntiAlias(boolean value) {
+ this.antiAlias = value;
+ }
+
+ /**
+ * Get symbol antialias
+ * @return Boolean
+ */
+ public boolean isSymbolAntialias() {
+ return this.symbolAntialias;
+ }
+
+ /**
+ * Set symbol antialias
+ * @param value Boolean
+ */
+ public void setSymbolAntialias(boolean value) {
+ this.symbolAntialias = value;
+ }
+
+ //
+ //
+ /**
+ * Draw plot
+ *
+ * @param g Graphics2D
+ * @param area Drawing area
+ */
+ public void draw(Graphics2D g, Rectangle2D area) {
+ g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
+ if (antiAlias) {
+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ //g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
+ g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
+ g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
+ g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
+ //g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
+ g.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
+ } else {
+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
+ //g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
+ g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_DEFAULT);
+ g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_OFF);
+ g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_DEFAULT);
+ //g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
+ g.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT);
+ }
+
+ AffineTransform oldMatrix = g.getTransform();
+ Rectangle oldRegion = g.getClipBounds();
+ g.setClip(area);
+ g.translate(area.getX(), area.getY());
+
+ //Draw background
+ if (this.background != null) {
+ g.setColor(background);
+ g.fill(new Rectangle2D.Double(0, 0, area.getWidth(), area.getHeight()));
+ }
+
+ //Draw title
+ float y = 5;
+ if (title != null) {
+ g.setColor(title.getColor());
+ g.setFont(title.getFont());
+ float x = (float) area.getWidth() / 2;
+ //y -= this.title.getHeight(g) - 5;
+ //FontMetrics metrics = g.getFontMetrics(title.getFont());
+ //x -= metrics.stringWidth(title.getText()) / 2;
+ //y += metrics.getHeight();
+ int i = 0;
+ for (String text : title.getTexts()) {
+ Dimension dim = Draw.getStringDimension(text, g);
+ if (i == 0) {
+ y += dim.getHeight();
+ }
+ Draw.drawString(g, text, x - dim.width / 2, y);
+ g.setFont(title.getFont());
+ y += dim.height + title.getLineSpace();
+ i += 1;
+ }
+ y += 5;
+ }
+
+ //Draw plot
+ plotArea = this.getPlotArea(g, area);
+ //plotArea = area;
+ if (plotArea.getWidth() < 20 || plotArea.getHeight() < 20) {
+ g.setTransform(oldMatrix);
+ g.setClip(oldRegion);
+ return;
+ }
+
+ if (this.plots.size() > 0) {
+ //double zoom = this.getPositionAreaZoom(g, plotArea);
+ //Margin tightInset = this.getPlotsTightInset(g, plotArea);
+ Margin shrink = this.getPlotsShrink(g, plotArea);
+ for (int i = 0; i < this.plots.size(); i++) {
+ Plot plot = this.plots.get(i);
+ plot.setSymbolAntialias(this.symbolAntialias);
+ if (plot.isOuterPosActive()){
+ if (plot.isSubPlot || plot.isSameShrink()) {
+ plot.setPlotShrink(shrink);
+ } else {
+ //plot.setPlotShrink(this.getPlotShrink(g, area, plot));
+ plot.setPlotShrink(this.getPlotShrink(g, plotArea, plot));
+ }
+ }
+ if (plot instanceof MapPlot) {
+ ((MapPlot) plot).setAntialias(this.antiAlias);
+ }
+ plot.draw(g, plotArea);
+ }
+ }
+
+ //Draw text
+ drawText(g, area);
+
+ //Draw legend
+ if (this.drawLegend) {
+ Dimension dim = this.legend.getLegendDimension(g, new Dimension((int) area.getWidth(), (int) area.getHeight()));
+ float x = 0;
+ switch (this.legend.getPosition()) {
+ case UPPER_CENTER_OUTSIDE:
+ x = (float) area.getWidth() / 2 - dim.width / 2;
+ y += 5;
+ break;
+ case LOWER_CENTER_OUTSIDE:
+ x = (float) area.getWidth() / 2 - dim.width / 2;
+ y += plotArea.getHeight() + 5;
+ break;
+ case LEFT_OUTSIDE:
+ x = 10;
+ y = (float) area.getHeight() / 2 - dim.height / 2;
+ break;
+ case RIGHT_OUTSIDE:
+ x = (float) plotArea.getWidth() + 10;
+ y = (float) area.getHeight() / 2 - dim.height / 2;
+ break;
+ }
+ this.legend.draw(g, new PointF(x, y));
+ }
+
+ g.setTransform(oldMatrix);
+ g.setClip(oldRegion);
+ }
+
+ void drawText(Graphics2D g, Rectangle2D area) {
+ float x, y;
+ for (ChartText text : this.texts) {
+ x = (float) (area.getWidth() * text.getX());
+ y = (float) (area.getHeight() * (1 - text.getY()));
+ Dimension dim = Draw.getStringDimension(text.getText(), g);
+ Rectangle.Double rect = new Rectangle.Double(x, y, dim.getWidth(), dim.getHeight());
+ if (text.isFill()) {
+ g.setColor(text.getBackground());
+ g.fill(rect);
+ }
+ if (text.isDrawNeatline()) {
+ g.setColor(text.getNeatlineColor());
+ Stroke oldStroke = g.getStroke();
+ g.setStroke(new BasicStroke(text.getNeatlineSize()));
+ g.draw(rect);
+ g.setStroke(oldStroke);
+ }
+ g.setFont(text.getFont());
+ g.setColor(text.getColor());
+ Draw.drawString(g, text.getText(), x, y);
+ }
+ }
+
+ private Rectangle2D getPlotArea(Graphics2D g, Rectangle2D area) {
+ Rectangle2D pArea = new Rectangle2D.Double();
+ int edge = 0;
+ int top = edge;
+ int left = edge;
+ int right = edge;
+ int bottom = edge;
+ if (this.title != null) {
+ top += this.title.getTrueDimension(g).height + 12;
+ }
+ pArea.setRect(left, top, area.getWidth() - left - right, area.getHeight() - top - bottom);
+
+ return pArea;
+ }
+
+ private Rectangle2D getPlotArea_bak(Graphics2D g, Rectangle2D area) {
+ Rectangle2D pArea = new Rectangle2D.Double();
+ int edge = 2;
+ int top = edge;
+ int left = edge;
+ int right = edge;
+ int bottom = edge;
+ if (this.title != null) {
+ top += this.title.getTrueDimension(g).height + 10;
+ }
+ if (this.drawLegend) {
+ Dimension dim = this.legend.getLegendDimension(g, new Dimension((int) area.getWidth(), (int) area.getHeight()));
+ switch (this.legend.getPosition()) {
+ case UPPER_CENTER_OUTSIDE:
+ top += dim.height + 10;
+ break;
+ case LOWER_CENTER_OUTSIDE:
+ bottom += dim.height + 10;
+ break;
+ case LEFT_OUTSIDE:
+ left += dim.width + 10;
+ break;
+ case RIGHT_OUTSIDE:
+ right += dim.width + 10;
+ break;
+ }
+ }
+ pArea.setRect(left, top, area.getWidth() - left - right, area.getHeight() - top - bottom);
+
+ return pArea;
+ }
+
+ private Margin getPlotShrink(Graphics2D g, Rectangle2D area, Plot plot) {
+ Margin shrink;
+ if (plot.isSubPlot) {
+ double rowHeight = area.getHeight() / this.rowNum;
+ double colWidth = area.getWidth() / this.columnNum;
+ double x = area.getX() + plot.columnIndex * colWidth;
+ double y = area.getY() + plot.rowIndex * rowHeight;
+ Rectangle2D subPlotArea = new Rectangle2D.Double(x, y, colWidth, rowHeight);
+ plot.setOuterPositionArea(subPlotArea);
+ plot.updatePosition(area, subPlotArea);
+ Rectangle2D positionArea = plot.getPositionArea(area);
+ plot.setPositionArea(positionArea);
+ Margin tightInset = plot.getTightInset(g, positionArea);
+ plot.setTightInset(tightInset);
+ shrink = plot.getPlotShrink();
+ } else {
+ plot.setOuterPositionArea(area);
+ Rectangle2D positionArea = plot.getPositionArea(area);
+ plot.setPositionArea(positionArea);
+ Margin tightInset = plot.getTightInset(g, positionArea);
+ plot.setTightInset(tightInset);
+ shrink = plot.getPlotShrink();
+ //shrink = tightInset;
+ }
+
+ return shrink;
+ }
+
+ private Margin getPlotsShrink(Graphics2D g, Rectangle2D area) {
+ Margin pshrink = null, shrink;
+ for (int i = 0; i < this.plots.size(); i++) {
+ Plot plot = this.plots.get(i);
+ plot.setOuterPositionArea(plot.getOuterPositionArea(area));
+ Rectangle2D positionArea = plot.getPositionArea(area);
+ plot.setPositionArea(positionArea);
+ Margin tightInset = plot.getTightInset(g, positionArea);
+ plot.setTightInset(tightInset);
+ shrink = plot.getPlotShrink();
+ if (i == 0) {
+ pshrink = shrink;
+ } else if (pshrink != null) {
+ pshrink = pshrink.extend(shrink);
+ }
+ }
+
+ return pshrink;
+ }
+
+ private Margin getPlotsShrink_bak(Graphics2D g, Rectangle2D area) {
+ Margin pshrink = null, shrink;
+ for (int i = 0; i < this.plots.size(); i++) {
+ Plot plot = this.plots.get(i);
+ if (plot.isSubPlot) {
+ double rowHeight = area.getHeight() / this.rowNum;
+ double colWidth = area.getWidth() / this.columnNum;
+ double x = area.getX() + plot.columnIndex * colWidth;
+ double y = area.getY() + plot.rowIndex * rowHeight;
+ Rectangle2D subPlotArea = new Rectangle2D.Double(x, y, colWidth, rowHeight);
+ plot.setOuterPositionArea(subPlotArea);
+ plot.updatePosition(area, subPlotArea);
+ Rectangle2D positionArea = plot.getPositionArea(area);
+ plot.setPositionArea(positionArea);
+ Margin tightInset = plot.getTightInset(g, positionArea);
+ plot.setTightInset(tightInset);
+ shrink = plot.getPlotShrink();
+ } else {
+ plot.setOuterPositionArea(area);
+ Rectangle2D positionArea = plot.getPositionArea(area);
+ plot.setPositionArea(positionArea);
+ Margin tightInset = plot.getTightInset(g, positionArea);
+ plot.setTightInset(tightInset);
+ shrink = plot.getPlotShrink();
+ }
+ if (i == 0) {
+ pshrink = shrink;
+ } else if (pshrink != null) {
+ pshrink = pshrink.extend(shrink);
+ }
+ }
+
+ return pshrink;
+ }
+
+ private Margin getPlotsTightInset(Graphics2D g, Rectangle2D area) {
+ int i = 0;
+ Margin pti = null, tightInset;
+ for (Plot plot : this.plots) {
+ if (plot.isSubPlot) {
+ double rowHeight = area.getHeight() / this.rowNum;
+ double colWidth = area.getWidth() / this.columnNum;
+ double x = area.getX() + plot.columnIndex * colWidth;
+ double y = area.getY() + plot.rowIndex * rowHeight;
+ Rectangle2D subPlotArea = new Rectangle2D.Double(x, y, colWidth, rowHeight);
+ plot.setOuterPositionArea(subPlotArea);
+ plot.updatePosition(area, subPlotArea);
+ Rectangle2D positionArea = plot.getPositionArea();
+ plot.setPositionArea(positionArea);
+ tightInset = plot.getTightInset(g, positionArea);
+ } else {
+ plot.setOuterPositionArea(area);
+ Rectangle2D positionArea = plot.getPositionArea();
+ plot.setPositionArea(positionArea);
+ tightInset = plot.getTightInset(g, positionArea);
+ }
+ if (i == 0) {
+ pti = tightInset;
+ } else if (pti != null) {
+ pti = pti.extend(tightInset);
+ }
+ i += 1;
+ }
+
+ return pti;
+ }
+
+ private double getPositionAreaZoom(Graphics2D g, Rectangle2D area) {
+ double zoom = 1.0;
+ for (Plot plot : this.plots) {
+ if (plot.isSubPlot) {
+ double rowHeight = area.getHeight() / this.rowNum;
+ double colWidth = area.getWidth() / this.columnNum;
+ double x = area.getX() + plot.columnIndex * colWidth;
+ double y = area.getY() + plot.rowIndex * rowHeight;
+ Rectangle2D subPlotArea = new Rectangle2D.Double(x, y, colWidth, rowHeight);
+ plot.setOuterPositionArea(subPlotArea);
+ plot.updatePosition(area, subPlotArea);
+ Rectangle2D positionArea = plot.getPositionArea();
+ plot.setPositionArea(positionArea);
+ Margin tightInset = plot.getTightInset(g, positionArea);
+ plot.setTightInset(tightInset);
+ double zoom1 = plot.updatePostionAreaZoom();
+ if (zoom1 < zoom) {
+ zoom = zoom1;
+ }
+ } else {
+ plot.setOuterPositionArea(area);
+ Rectangle2D positionArea = plot.getPositionArea();
+ plot.setPositionArea(positionArea);
+ Margin tightInset = plot.getTightInset(g, positionArea);
+ plot.setTightInset(tightInset);
+ double zoom1 = plot.updatePostionAreaZoom();
+ if (zoom1 < zoom) {
+ zoom = zoom1;
+ }
+ }
+ }
+
+ return zoom;
+ }
+
+ private Rectangle2D getSubPlotArea(Graphics2D g, Plot plot, Rectangle2D area) {
+ if (plot.isSubPlot) {
+ double rowHeight = area.getHeight() / this.rowNum;
+ double colWidth = area.getWidth() / this.columnNum;
+ double x = area.getX() + plot.columnIndex * colWidth;
+ double y = area.getY() + plot.rowIndex * rowHeight;
+ Rectangle2D subPlotArea = new Rectangle2D.Double(x, y, colWidth, rowHeight);
+ plot.setOuterPositionArea(subPlotArea);
+ plot.updatePosition(area, subPlotArea);
+ Rectangle2D positionArea = plot.getPositionArea();
+ plot.setPositionArea(positionArea);
+ Margin tightInset = plot.getTightInset(g, positionArea);
+ plot.setTightInset(tightInset);
+ double zoom = plot.updatePostionAreaZoom();
+ plot.setPositionAreaZoom(zoom);
+ return subPlotArea;
+ } else {
+ plot.setOuterPositionArea(area);
+ Rectangle2D positionArea = plot.getPositionArea();
+ plot.setPositionArea(positionArea);
+ Margin tightInset = plot.getTightInset(g, positionArea);
+ plot.setTightInset(tightInset);
+ double zoom = plot.updatePostionAreaZoom();
+ plot.setPositionAreaZoom(zoom);
+ //return tightInset.getArea(positionArea);
+ return area;
+ }
+ }
+
+ /**
+ * Get graph area
+ *
+ * @return Get graph area
+ */
+ public Rectangle2D getGraphArea() {
+ Rectangle2D rect = this.plots.get(0).getPositionArea();
+ double left = rect.getX() + this.plotArea.getX();
+ double top = rect.getY() + this.plotArea.getY();
+ return new Rectangle2D.Double(left, top, rect.getWidth(), rect.getHeight());
+ }
+
+ /**
+ * Find a plot by point
+ *
+ * @param x X
+ * @param y Y
+ * @return Plot
+ */
+ public Plot findPlot(int x, int y) {
+ for (Plot plot : this.plots) {
+ Rectangle2D area = plot.getPositionArea();
+ if (area.contains(x, y)) {
+ return plot;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Clear plots
+ */
+ public void clearPlots() {
+ this.plots.clear();
+ }
+
+ /**
+ * Clear texts
+ */
+ public void clearTexts() {
+ this.texts.clear();
+ }
+
+ /**
+ * Remove a plot
+ *
+ * @param plot The plot
+ */
+ public void removePlot(Plot plot) {
+ this.plots.remove(plot);
+ }
+
+ /**
+ * Add a plot
+ *
+ * @param plot Plot
+ */
+ public void addPlot(Plot plot) {
+ if (plot instanceof MapPlot) {
+ ((MapPlot) plot).setParent(parent);
+ }
+ this.plots.add(plot);
+ }
+
+ /**
+ * Set plot
+ *
+ * @param plot Plot
+ */
+ public void setPlot(Plot plot) {
+ if (plot instanceof MapPlot) {
+ ((MapPlot) plot).setParent(parent);
+ }
+ this.plots.clear();
+ this.plots.add(plot);
+ }
+
+ /**
+ * Get plot by plot index
+ *
+ * @param plotIdx Plot index - begin with 1
+ * @return Plot index
+ */
+ public Plot getPlot(int plotIdx) {
+ for (Plot plot : this.plots) {
+ int pIdx = plot.rowIndex * this.columnNum + plot.columnIndex + 1;
+ if (pIdx == plotIdx) {
+ return plot;
+ }
+ }
+
+ if (plotIdx > 0 && plotIdx <= this.plots.size())
+ return this.plots.get(plotIdx - 1);
+ else
+ return null;
+ }
+
+ /**
+ * Get plot index
+ * @param plot The plot
+ * @return Plot index
+ */
+ public int getPlotIndex(Plot plot){
+ return this.plots.indexOf(plot);
+ }
+
+ /**
+ * Check if has web map layer
+ *
+ * @return Boolean
+ */
+ public boolean hasWebMap() {
+ for (Plot plot : this.plots) {
+ if (plot instanceof MapPlot) {
+ MapPlot mp = (MapPlot) plot;
+ if (mp.hasWebMapLayer()) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Add text
+ *
+ * @param text Text
+ */
+ public void addText(ChartText text) {
+ this.texts.add(text);
+ }
+ //
+
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/ChartColorBar.java b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/ChartColorBar.java
index 3453e2a3..306f84ac 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/ChartColorBar.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/ChartColorBar.java
@@ -17,10 +17,10 @@ import java.util.ArrayList;
import java.util.List;
import org.meteoinfo.chart.plot.XAlign;
import org.meteoinfo.chart.plot.YAlign;
+import org.meteoinfo.common.PointD;
+import org.meteoinfo.common.PointF;
import org.meteoinfo.drawing.Draw;
import org.meteoinfo.global.DataConvert;
-import org.meteoinfo.global.PointD;
-import org.meteoinfo.global.PointF;
import org.meteoinfo.legend.ColorBreak;
import org.meteoinfo.legend.LegendScheme;
import org.meteoinfo.legend.LegendType;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/ChartElement.java b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/ChartElement.java
index bac04ca9..9c72883e 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/ChartElement.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/ChartElement.java
@@ -1,335 +1,336 @@
- /* Copyright 2012 Yaqiang Wang,
- * yaqiang.wang@gmail.com
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.chart;
-
-import org.meteoinfo.global.event.ILocationChangedListener;
-import org.meteoinfo.global.event.ISizeChangedListener;
-import org.meteoinfo.global.event.LocationChangedEvent;
-import org.meteoinfo.global.event.SizeChangedEvent;
-import org.meteoinfo.global.PointF;
-import java.awt.Color;
-import java.awt.Rectangle;
-import javax.swing.event.EventListenerList;
-import org.meteoinfo.layout.ResizeAbility;
-
-/**
- *
- * @author yaqiang
- */
-public abstract class ChartElement {
- //
-
- public void addLocationChangedListener(ILocationChangedListener listener) {
- this._listeners.add(ILocationChangedListener.class, listener);
- }
-
- public void removeLocationChangedListener(ILocationChangedListener listener) {
- this._listeners.remove(ILocationChangedListener.class, listener);
- }
-
- public void fireLocationChangedEvent() {
- fireLocationChangedEvent(new LocationChangedEvent(this));
- }
-
- private void fireLocationChangedEvent(LocationChangedEvent event) {
- Object[] listeners = _listeners.getListenerList();
- for (int i = 0; i < listeners.length; i = i + 2) {
- if (listeners[i] == ILocationChangedListener.class) {
- ((ILocationChangedListener) listeners[i + 1]).locationChangedEvent(event);
- }
- }
- }
-
- public void addSizeChangedListener(ISizeChangedListener listener) {
- this._listeners.add(ISizeChangedListener.class, listener);
- }
-
- public void removeSizeChangedListener(ISizeChangedListener listener) {
- this._listeners.remove(ISizeChangedListener.class, listener);
- }
-
- public void fireSizeChangedEvent() {
- fireSizeChangedEvent(new SizeChangedEvent(this));
- }
-
- private void fireSizeChangedEvent(SizeChangedEvent event) {
- Object[] listeners = _listeners.getListenerList();
- for (int i = 0; i < listeners.length; i = i + 2) {
- if (listeners[i] == ISizeChangedListener.class) {
- ((ISizeChangedListener) listeners[i + 1]).sizeChangedEvent(event);
- }
- }
- }
- //
- //
- private final EventListenerList _listeners = new EventListenerList();
- protected float x;
- protected float y;
- protected float width;
- protected float height;
- protected Color _foreColor;
- protected Color _backColor;
- private boolean _selected;
- private ResizeAbility _resizeAbility;
- private boolean _visible = true;
- private boolean drawBackColor = false;
- //
- //
-
- public ChartElement() {
- _foreColor = Color.black;
- _backColor = Color.white;
- _selected = false;
- _resizeAbility = ResizeAbility.None;
- }
- //
- //
-
- /**
- * Get if visible
- *
- * @return Boolean
- */
- public boolean isVisible() {
- return _visible;
- }
-
- /**
- * Set if visible
- *
- * @param istrue Boolean
- */
- public void setVisible(boolean istrue) {
- _visible = istrue;
- }
-
- /**
- * Get x
- *
- * @return x
- */
- public float getX() {
- return x;
- }
-
- /**
- * Set left
- *
- * @param left
- */
- public void setX(float left) {
- x = left;
- this.fireLocationChangedEvent();
- }
-
- /**
- * Get y
- *
- * @return Y
- */
- public float getY() {
- return y;
- }
-
- /**
- * Set y
- *
- * @param top Y
- */
- public void setY(float top) {
- y = top;
- this.fireLocationChangedEvent();
- }
-
- /**
- * Get width
- *
- * @return Width
- */
- public float getWidth() {
- return width;
- }
-
- /**
- * Set width
- *
- * @param width Width
- */
- public void setWidth(float width) {
- this.width = width;
- this.fireSizeChangedEvent();
- }
-
- /**
- * Get height
- *
- * @return Height
- */
- public float getHeight() {
- return height;
- }
-
- /**
- * Set height
- *
- * @param height Height
- */
- public void setHeight(float height) {
- this.height = height;
- this.fireSizeChangedEvent();
- }
-
- /**
- * Get right
- *
- * @return Right
- */
- public float getRight() {
- return x + width;
- }
-
- /**
- * Get bottom
- *
- * @return Bottom
- */
- public float getBottom() {
- return y + height;
- }
-
- /**
- * Get bounds rectangle
- *
- * @return Bounds rectangle
- */
- public Rectangle.Float getBounds() {
- return new Rectangle.Float(x, y, width, height);
- }
-
- /**
- * Get foreground color
- *
- * @return Foreground color
- */
- public Color getForeground() {
- return _foreColor;
- }
-
- /**
- * Set foreground color
- *
- * @param color Foreground color
- */
- public void setForeground(Color color) {
- _foreColor = color;
- }
-
- /**
- * Get background color
- *
- * @return Background color
- */
- public Color getBackground() {
- return _backColor;
- }
-
- /**
- * Set background color
- *
- * @param color Background color
- */
- public void setBackground(Color color) {
- _backColor = color;
- }
-
- /**
- * Get if is selected
- *
- * @return Boolean
- */
- public boolean isSelected() {
- return _selected;
- }
-
- /**
- * Set if is selected
- *
- * @param istrue Boolean
- */
- public void setSelected(boolean istrue) {
- _selected = istrue;
- }
-
- /**
- * Get resize ability
- *
- * @return Resize ability
- */
- public ResizeAbility getResizeAbility() {
- return _resizeAbility;
- }
-
- /**
- * Set resize ability
- *
- * @param ra Resize ability
- */
- public void setResizeAbility(ResizeAbility ra) {
- _resizeAbility = ra;
- }
-
- /**
- * Get is draw backcolor
- * @return Boolean
- */
- public boolean isDrawBackColor(){
- return drawBackColor;
- }
-
- /**
- * Set is draw backcolor
- * @param value Boolean
- */
- public void setDrawBackColor(boolean value){
- drawBackColor = value;
- }
- //
- //
-
- /**
- * Move update method
- */
- public abstract void moveUpdate();
-
- /**
- * Resize update method
- */
- public abstract void resizeUpdate();
-
- /**
- * Page to screen
- *
- * @param pageX Page X
- * @param pageY Page Y
- * @param pageLocation Page location
- * @param zoom Zoom
- * @return Screen point
- */
- public PointF pageToScreen(float pageX, float pageY, PointF pageLocation, float zoom) {
- float x = pageX * zoom + pageLocation.X;
- float y = pageY * zoom + pageLocation.Y;
- return (new PointF(x, y));
- }
- //
-}
+ /* Copyright 2012 Yaqiang Wang,
+ * yaqiang.wang@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ */
+package org.meteoinfo.chart;
+
+import org.meteoinfo.common.PointF;
+import org.meteoinfo.global.event.ILocationChangedListener;
+import org.meteoinfo.global.event.ISizeChangedListener;
+import org.meteoinfo.global.event.LocationChangedEvent;
+import org.meteoinfo.global.event.SizeChangedEvent;
+
+import java.awt.Color;
+import java.awt.Rectangle;
+import javax.swing.event.EventListenerList;
+import org.meteoinfo.layout.ResizeAbility;
+
+/**
+ *
+ * @author yaqiang
+ */
+public abstract class ChartElement {
+ //
+
+ public void addLocationChangedListener(ILocationChangedListener listener) {
+ this._listeners.add(ILocationChangedListener.class, listener);
+ }
+
+ public void removeLocationChangedListener(ILocationChangedListener listener) {
+ this._listeners.remove(ILocationChangedListener.class, listener);
+ }
+
+ public void fireLocationChangedEvent() {
+ fireLocationChangedEvent(new LocationChangedEvent(this));
+ }
+
+ private void fireLocationChangedEvent(LocationChangedEvent event) {
+ Object[] listeners = _listeners.getListenerList();
+ for (int i = 0; i < listeners.length; i = i + 2) {
+ if (listeners[i] == ILocationChangedListener.class) {
+ ((ILocationChangedListener) listeners[i + 1]).locationChangedEvent(event);
+ }
+ }
+ }
+
+ public void addSizeChangedListener(ISizeChangedListener listener) {
+ this._listeners.add(ISizeChangedListener.class, listener);
+ }
+
+ public void removeSizeChangedListener(ISizeChangedListener listener) {
+ this._listeners.remove(ISizeChangedListener.class, listener);
+ }
+
+ public void fireSizeChangedEvent() {
+ fireSizeChangedEvent(new SizeChangedEvent(this));
+ }
+
+ private void fireSizeChangedEvent(SizeChangedEvent event) {
+ Object[] listeners = _listeners.getListenerList();
+ for (int i = 0; i < listeners.length; i = i + 2) {
+ if (listeners[i] == ISizeChangedListener.class) {
+ ((ISizeChangedListener) listeners[i + 1]).sizeChangedEvent(event);
+ }
+ }
+ }
+ //
+ //
+ private final EventListenerList _listeners = new EventListenerList();
+ protected float x;
+ protected float y;
+ protected float width;
+ protected float height;
+ protected Color _foreColor;
+ protected Color _backColor;
+ private boolean _selected;
+ private ResizeAbility _resizeAbility;
+ private boolean _visible = true;
+ private boolean drawBackColor = false;
+ //
+ //
+
+ public ChartElement() {
+ _foreColor = Color.black;
+ _backColor = Color.white;
+ _selected = false;
+ _resizeAbility = ResizeAbility.None;
+ }
+ //
+ //
+
+ /**
+ * Get if visible
+ *
+ * @return Boolean
+ */
+ public boolean isVisible() {
+ return _visible;
+ }
+
+ /**
+ * Set if visible
+ *
+ * @param istrue Boolean
+ */
+ public void setVisible(boolean istrue) {
+ _visible = istrue;
+ }
+
+ /**
+ * Get x
+ *
+ * @return x
+ */
+ public float getX() {
+ return x;
+ }
+
+ /**
+ * Set left
+ *
+ * @param left
+ */
+ public void setX(float left) {
+ x = left;
+ this.fireLocationChangedEvent();
+ }
+
+ /**
+ * Get y
+ *
+ * @return Y
+ */
+ public float getY() {
+ return y;
+ }
+
+ /**
+ * Set y
+ *
+ * @param top Y
+ */
+ public void setY(float top) {
+ y = top;
+ this.fireLocationChangedEvent();
+ }
+
+ /**
+ * Get width
+ *
+ * @return Width
+ */
+ public float getWidth() {
+ return width;
+ }
+
+ /**
+ * Set width
+ *
+ * @param width Width
+ */
+ public void setWidth(float width) {
+ this.width = width;
+ this.fireSizeChangedEvent();
+ }
+
+ /**
+ * Get height
+ *
+ * @return Height
+ */
+ public float getHeight() {
+ return height;
+ }
+
+ /**
+ * Set height
+ *
+ * @param height Height
+ */
+ public void setHeight(float height) {
+ this.height = height;
+ this.fireSizeChangedEvent();
+ }
+
+ /**
+ * Get right
+ *
+ * @return Right
+ */
+ public float getRight() {
+ return x + width;
+ }
+
+ /**
+ * Get bottom
+ *
+ * @return Bottom
+ */
+ public float getBottom() {
+ return y + height;
+ }
+
+ /**
+ * Get bounds rectangle
+ *
+ * @return Bounds rectangle
+ */
+ public Rectangle.Float getBounds() {
+ return new Rectangle.Float(x, y, width, height);
+ }
+
+ /**
+ * Get foreground color
+ *
+ * @return Foreground color
+ */
+ public Color getForeground() {
+ return _foreColor;
+ }
+
+ /**
+ * Set foreground color
+ *
+ * @param color Foreground color
+ */
+ public void setForeground(Color color) {
+ _foreColor = color;
+ }
+
+ /**
+ * Get background color
+ *
+ * @return Background color
+ */
+ public Color getBackground() {
+ return _backColor;
+ }
+
+ /**
+ * Set background color
+ *
+ * @param color Background color
+ */
+ public void setBackground(Color color) {
+ _backColor = color;
+ }
+
+ /**
+ * Get if is selected
+ *
+ * @return Boolean
+ */
+ public boolean isSelected() {
+ return _selected;
+ }
+
+ /**
+ * Set if is selected
+ *
+ * @param istrue Boolean
+ */
+ public void setSelected(boolean istrue) {
+ _selected = istrue;
+ }
+
+ /**
+ * Get resize ability
+ *
+ * @return Resize ability
+ */
+ public ResizeAbility getResizeAbility() {
+ return _resizeAbility;
+ }
+
+ /**
+ * Set resize ability
+ *
+ * @param ra Resize ability
+ */
+ public void setResizeAbility(ResizeAbility ra) {
+ _resizeAbility = ra;
+ }
+
+ /**
+ * Get is draw backcolor
+ * @return Boolean
+ */
+ public boolean isDrawBackColor(){
+ return drawBackColor;
+ }
+
+ /**
+ * Set is draw backcolor
+ * @param value Boolean
+ */
+ public void setDrawBackColor(boolean value){
+ drawBackColor = value;
+ }
+ //
+ //
+
+ /**
+ * Move update method
+ */
+ public abstract void moveUpdate();
+
+ /**
+ * Resize update method
+ */
+ public abstract void resizeUpdate();
+
+ /**
+ * Page to screen
+ *
+ * @param pageX Page X
+ * @param pageY Page Y
+ * @param pageLocation Page location
+ * @param zoom Zoom
+ * @return Screen point
+ */
+ public PointF pageToScreen(float pageX, float pageY, PointF pageLocation, float zoom) {
+ float x = pageX * zoom + pageLocation.X;
+ float y = pageY * zoom + pageLocation.Y;
+ return (new PointF(x, y));
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/ChartLegend.java b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/ChartLegend.java
index 0053c6bf..0e66c9f5 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/ChartLegend.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/ChartLegend.java
@@ -1,1441 +1,1441 @@
-/* Copyright 2012 Yaqiang Wang,
- * yaqiang.wang@gmail.com
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.chart;
-
-import org.meteoinfo.drawing.Draw;
-import org.meteoinfo.global.PointF;
-import org.meteoinfo.legend.ColorBreak;
-import org.meteoinfo.legend.LegendScheme;
-import org.meteoinfo.legend.PointBreak;
-import org.meteoinfo.legend.PolygonBreak;
-import org.meteoinfo.legend.PolylineBreak;
-import com.l2fprod.common.beans.BaseBeanInfo;
-import com.l2fprod.common.beans.ExtendedPropertyDescriptor;
-import com.l2fprod.common.beans.editor.ComboBoxPropertyEditor;
-import java.awt.BasicStroke;
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.Font;
-import java.awt.FontMetrics;
-import java.awt.Graphics2D;
-import java.awt.Rectangle;
-import java.awt.geom.AffineTransform;
-import java.util.List;
-import org.meteoinfo.chart.plot.PlotOrientation;
-import org.meteoinfo.chart.plot.XAlign;
-import org.meteoinfo.chart.plot.YAlign;
-import org.meteoinfo.global.DataConvert;
-import org.meteoinfo.legend.LegendType;
-
-/**
- *
- * @author Yaqiang Wang
- */
-public class ChartLegend {
- //
-
- //private final XY1DPlot plot;
- protected LegendScheme legendScheme;
- private LegendPosition position;
- protected float shrink;
- protected int aspect;
- private boolean colorBar;
- protected float x;
- protected float y;
- protected PlotOrientation orientation;
- protected Color background;
- protected boolean drawBackground;
- protected int width;
- protected int height;
- protected int legendWidth;
- protected int legendHeight;
- protected ChartText label;
- protected String labelLocation;
- protected Font tickLabelFont;
- protected Color tickLabelColor;
- protected float tickLabelAngle;
- protected boolean drawNeatLine;
- protected Color neatLineColor;
- protected float neatLineSize;
- private float breakSpace;
- private float topSpace;
- private float leftSpace;
- protected double _vBarWidth;
- protected double _hBarHeight;
- private int rowColNum = 1;
- private boolean autoRowColNum = true;
- private Dimension symbolDimension;
- protected boolean extendRect;
- protected boolean autoExtendFrac;
- protected float xshift;
- protected float yshift;
- //
- //
-
- /**
- * Constructor
- *
- * @param ls LegendScheme
- */
- public ChartLegend(LegendScheme ls) {
- //this.plot = plot;
- this.legendScheme = ls;
- this.colorBar = false;
- this.position = LegendPosition.LOWER_CENTER_OUTSIDE;
- this.orientation = PlotOrientation.HORIZONTAL;
- this.shrink = 1.0f;
- this.aspect = 20;
- this.background = Color.white;
- this.drawBackground = false;
- drawNeatLine = true;
- neatLineColor = Color.black;
- neatLineSize = 1;
- breakSpace = 3;
- topSpace = 5;
- leftSpace = 5;
- _vBarWidth = 10;
- _hBarHeight = 10;
- this.labelLocation = "out";
- tickLabelFont = new Font("Arial", Font.PLAIN, 14);
- this.tickLabelColor = Color.black;
- this.tickLabelAngle = 0;
- this.symbolDimension = new Dimension(16, 10);
- this.extendRect = true;
- this.autoExtendFrac = false;
- this.xshift = 0;
- this.yshift = 0;
- }
-
- //
- //
- //
- //
- /**
- * Get legend scheme
- *
- * @return Legend scheme
- */
- public LegendScheme getLegendScheme() {
- return this.legendScheme;
- }
-
- /**
- * Set legend scheme
- *
- * @param value Legend scheme
- */
- public void setLegendScheme(LegendScheme value) {
- this.legendScheme = value;
- }
-
- /**
- * Get if is color bar
- *
- * @return Boolean
- */
- public boolean isColorbar() {
- return this.colorBar;
- }
-
- /**
- * Set if is color bar
- *
- * @param value Boolean
- */
- public void setColorbar(boolean value) {
- this.colorBar = value;
- }
-
- /**
- * Get legend position
- *
- * @return Legend position
- */
- public LegendPosition getPosition() {
- return this.position;
- }
-
- /**
- * Set legend position
- *
- * @param value Legend position
- */
- public void setPosition(LegendPosition value) {
- this.position = value;
- }
-
- /**
- * Get shrink
- *
- * @return Shrink
- */
- public float getShrink() {
- return this.shrink;
- }
-
- /**
- * Set shrink
- *
- * @param value Shrink
- */
- public void setShrink(float value) {
- this.shrink = value;
- }
-
- /**
- * Get aspect
- *
- * @return Aspect
- */
- public int getAspect() {
- return this.aspect;
- }
-
- /**
- * Set aspect
- *
- * @param value Aspect
- */
- public void setAspect(int value) {
- this.aspect = value;
- }
-
- /**
- * Get X
- *
- * @return X value
- */
- public float getX() {
- return this.x;
- }
-
- /**
- * Set X
- *
- * @param value X value
- */
- public void setX(float value) {
- x = value;
- }
-
- /**
- * Get Y
- *
- * @return Y value
- */
- public float getY() {
- return this.y;
- }
-
- /**
- * Set Y
- *
- * @param value Y value
- */
- public void setY(float value) {
- y = value;
- }
-
- /**
- * Get width
- *
- * @return Width
- */
- public int getWidth() {
- return this.width;
- }
-
- /**
- * Set width
- *
- * @param value Width
- */
- public void setWidth(int value) {
- this.width = value;
- }
-
- /**
- * Get height
- *
- * @return Height
- */
- public int getHeight() {
- return this.height;
- }
-
- /**
- * Set height
- *
- * @param value Height
- */
- public void setHeight(int value) {
- this.height = value;
- }
-
- /**
- * Get legend width
- *
- * @return Legend width
- */
- public int getLegendWidth() {
- return this.legendWidth;
- }
-
- /**
- * Set legend width
- *
- * @param value Legend width
- */
- public void setLegendWidth(int value) {
- this.legendWidth = value;
- }
-
- /**
- * Get legend height
- *
- * @return Legend height
- */
- public int getLegendHeight() {
- return this.legendHeight;
- }
-
- /**
- * Set legend height
- *
- * @param value Legend height
- */
- public void setLegendHeight(int value) {
- this.legendHeight = value;
- }
-
- /**
- * Get plot orientation
- *
- * @return Plot orientation
- */
- public PlotOrientation getPlotOrientation() {
- return this.orientation;
- }
-
- /**
- * Set plot orientation
- *
- * @param value Plot orientation
- */
- public void setPlotOrientation(PlotOrientation value) {
- this.orientation = value;
- }
-
- /**
- * Get background
- *
- * @return Background
- */
- public Color getBackground() {
- return this.background;
- }
-
- /**
- * Set background
- *
- * @param value Background
- */
- public void setBackground(Color value) {
- this.background = value;
- }
-
- /**
- * Get if draw background
- *
- * @return Boolean
- */
- public boolean isDrawBackground() {
- return this.drawBackground;
- }
-
- /**
- * Set if draw background
- *
- * @param value Boolean
- */
- public void setDrawBackground(boolean value) {
- this.drawBackground = value;
- }
-
- /**
- * Get if draw neat line
- *
- * @return If draw neat line
- */
- public boolean isDrawNeatLine() {
- return drawNeatLine;
- }
-
- /**
- * Set if draw neat line
- *
- * @param istrue If draw neat line
- */
- public void setDrawNeatLine(boolean istrue) {
- drawNeatLine = istrue;
- }
-
- /**
- * Get neat line color
- *
- * @return Neat line color
- */
- public Color getNeatLineColor() {
- return neatLineColor;
- }
-
- /**
- * Set neat line color
- *
- * @param color Neat line color
- */
- public void setNeatLineColor(Color color) {
- neatLineColor = color;
- }
-
- /**
- * Get neat line size
- *
- * @return Neat line size
- */
- public float getNeatLineSize() {
- return neatLineSize;
- }
-
- /**
- * Set neat line size
- *
- * @param size Neat line size
- */
- public void setNeatLineSize(float size) {
- neatLineSize = size;
- }
-
- /**
- * Get break space
- * @return Break space
- */
- public float getBreakSpace() {
- return this.breakSpace;
- }
-
- /**
- * Set break space
- * @param value Break space
- */
- public void setBreakSpace(float value) {
- this.breakSpace = value;
- }
-
- /**
- * Get label
- *
- * @return Label
- */
- public ChartText getLabel() {
- return this.label;
- }
-
- /**
- * Set label
- *
- * @param value Label
- */
- public void setLabel(ChartText value) {
- this.label = value;
- }
-
- /**
- * Get label font
- *
- * @return Label font
- */
- public Font getLabelFont() {
- return this.label.getFont();
- }
-
- /**
- * Set label font
- *
- * @param value Label font
- */
- public void setLabelFont(Font value) {
- this.label.setFont(value);
- }
-
- /**
- * Get label color
- *
- * @return Label color
- */
- public Color getLabelColor() {
- return this.label.getColor();
- }
-
- /**
- * Set label color
- *
- * @param value Label color
- */
- public void setLabelColor(Color value) {
- this.label.setColor(value);
- }
-
- /**
- * Get label location (in, out, top, bottom, left, right)
- *
- * @return Label location
- */
- public String getLabelLocation() {
- return this.labelLocation;
- }
-
- /**
- * Set label location
- *
- * @param value Label location
- */
- public void setLabelLocation(String value) {
- this.labelLocation = value;
- }
-
- /**
- * Get Tick label font
- *
- * @return The Tick label font
- */
- public Font getTickLabelFont() {
- return tickLabelFont;
- }
-
- /**
- * Set Tick label font
- *
- * @param font The Tick label font
- */
- public void setTickLabelFont(Font font) {
- tickLabelFont = font;
- }
-
- /**
- * Get tick label color
- *
- * @return Tick label color
- */
- public Color getTickLabelColor() {
- return this.tickLabelColor;
- }
-
- /**
- * Set tick label color
- *
- * @param value Tick label color
- */
- public void setTickLabelColor(Color value) {
- this.tickLabelColor = value;
- }
-
- /**
- * Get tick lable angle
- *
- * @return Tick label angle
- */
- public float getTickLabelAngle() {
- return this.tickLabelAngle;
- }
-
- /**
- * Set tick label angle
- *
- * @param value Tick label angle
- */
- public void setTickLabelAngle(float value) {
- this.tickLabelAngle = value;
- }
-
- /**
- * Get column number
- *
- * @return Column number
- */
- public int getColumnNumber() {
- return rowColNum;
- }
-
- /**
- * Set column number
- *
- * @param value Column number
- */
- public void setColumnNumber(int value) {
- rowColNum = value;
- }
-
- /**
- * Get if automatic set row/col number
- *
- * @return Boolean
- */
- public boolean isAutoRowColNum() {
- return this.autoRowColNum;
- }
-
- /**
- * Set if automatic set row/col number
- *
- * @param value Boolean
- */
- public void setAutoRowColNum(boolean value) {
- this.autoRowColNum = value;
- }
-
- /**
- * Get symbol dimension
- *
- * @return Symbol dimension
- */
- public Dimension getSymbolDimension() {
- return this.symbolDimension;
- }
-
- /**
- * Set symbol dimension
- *
- * @param value Symbol dimension
- */
- public void setSymbolDimension(Dimension value) {
- this.symbolDimension = value;
- }
-
- /**
- * Set symbol width
- *
- * @param value Width
- */
- public void setSymbolWidth(int value) {
- this.symbolDimension.width = value;
- }
-
- /**
- * Set symbol height
- *
- * @param value height
- */
- public void setSymbolHeight(int value) {
- this.symbolDimension.height = value;
- }
-
- /**
- * Set symbol scale
- *
- * @param value Symble scale
- */
- public void setSymbolScale(float value) {
- double w = this.symbolDimension.getWidth() * value;
- double h = this.symbolDimension.getHeight() * value;
- this.symbolDimension.setSize(w, h);
- }
-
- /**
- * Get if extend rectangle - or triangle
- *
- * @return Boolean
- */
- public boolean isExtendRect() {
- return this.extendRect;
- }
-
- /**
- * Set if extend rectangle - or triangle
- *
- * @param value Boolean
- */
- public void setExtendRect(boolean value) {
- this.extendRect = value;
- }
-
- /**
- * Get if auto set extend fraction - extend has save width and height Only
- * valid for colorbar
- *
- * @return Boolean
- */
- public boolean isAutoExtendFrac() {
- return this.autoExtendFrac;
- }
-
- /**
- * Set if auto set extend fraction - extend has save width and height Only
- * valid for colorbar
- *
- * @param value
- */
- public void setAutoExtendFrac(boolean value) {
- this.autoExtendFrac = value;
- }
-
- /**
- * Set tick labels
- *
- * @param value Tick labels
- */
- public void setTickCaptions(List value) {
- for (int i = 0; i < this.legendScheme.getBreakNum(); i++) {
- if (i < value.size()) {
- this.legendScheme.getLegendBreaks().get(i).setCaption(value.get(i));
- } else {
- break;
- }
- }
- }
-
- /**
- * Get x shift - pixel unit
- *
- * @return X shift
- */
- public float getXShift() {
- return this.xshift;
- }
-
- /**
- * Set x shift
- *
- * @param value X shift
- */
- public void setXShift(float value) {
- this.xshift = value;
- }
-
- /**
- * Get y shift - pixel unit
- *
- * @return Y shift
- */
- public float getYShift() {
- return this.yshift;
- }
-
- /**
- * Set y shift
- *
- * @param value Y shift
- */
- public void setYShift(float value) {
- this.yshift = value;
- }
-
- //
- //
- /**
- * Draw legend
- *
- * @param g Graphics2D
- * @param point Start point
- */
- public void draw(Graphics2D g, PointF point) {
-
- AffineTransform oldMatrix = g.getTransform();
- g.translate(point.X + this.xshift, point.Y + this.yshift);
-
- //Draw background color
- if (this.drawBackground) {
- g.setColor(this.background);
- g.fill(new Rectangle.Float(0, 0, this.width, this.height));
- }
-
- //Draw legend
- g.setStroke(new BasicStroke(1));
- switch (this.orientation) {
- case HORIZONTAL:
- drawHorizontalLegend(g, legendScheme);
- break;
- case VERTICAL:
- this.drawVerticalLegend(g, legendScheme);
- break;
- }
-
- //Draw neatline
- if (drawNeatLine) {
- Rectangle.Float mapRect = new Rectangle.Float(0, 0, this.width, this.height);
- g.setColor(neatLineColor);
- g.setStroke(new BasicStroke(neatLineSize));
- g.draw(mapRect);
- }
-
- g.setTransform(oldMatrix);
- }
-
- private void drawVerticalLegend(Graphics2D g, LegendScheme aLS) {
- String caption;
- float breakHeight = this.getBreakHeight(g);
- float symbolHeight = this.symbolDimension.height;
- float symbolWidth = this.symbolDimension.width;
- float colWidth = symbolWidth + getMaxLabelWidth(g) + 10;
-
- //Set columns
- int[] rowNums = new int[rowColNum];
- int ave = aLS.getVisibleBreakNum() / rowColNum;
- if (ave * rowColNum < aLS.getBreakNum()) {
- ave += 1;
- }
- int num = 0;
- int i;
- for (i = 1; i < rowColNum; i++) {
- rowNums[i] = ave;
- num += ave;
- }
- rowNums[0] = aLS.getVisibleBreakNum() - num;
-
- //Draw title
- float y0 = 0;
- if (this.label != null) {
- float x0 = (float) (this.width / 2.);
- y0 += this.breakSpace * 2;
- this.label.draw(g, x0, y0);
- y0 += this.label.getDimension(g).height + this.breakSpace * 2;
- }
-
- //Draw legend
- float x, y;
- i = 0;
- for (int col = 0; col < rowColNum; col++) {
- x = symbolWidth / 2 + leftSpace + col * colWidth;
- y = y0 + breakHeight / 2 + breakSpace * 2;
- for (int row = 0; row < rowNums[col]; row++) {
- if (!aLS.getLegendBreaks().get(i).isDrawShape()) {
- continue;
- }
-
- //y += breakHeight + breakSpace;
- ColorBreak cb = aLS.getLegendBreaks().get(i);
- if (!cb.isDrawShape()) {
- continue;
- }
- caption = aLS.getLegendBreaks().get(i).getCaption();
- if (cb instanceof PointBreak) {
- PointBreak aPB = (PointBreak) cb.clone();
- ((PointBreak) aPB).setSize(((PointBreak) cb).getSize() * (symbolHeight / 10.f));
- Draw.drawPoint(new PointF(x, y), aPB, g);
- } else if (cb instanceof PolylineBreak) {
- PolylineBreak aPLB = (PolylineBreak) cb;
- Draw.drawPolylineSymbol_S(new PointF(x, y), symbolWidth, symbolHeight, aPLB, g);
- } else if (cb instanceof PolygonBreak) {
- Draw.drawPolygonSymbol(new PointF(x, y), symbolWidth, symbolHeight, (PolygonBreak) cb, g);
- } else {
- PolygonBreak pgb = new PolygonBreak();
- pgb.setColor(cb.getColor());
- pgb.setOutlineColor(Color.black);
- Draw.drawPolygonSymbol(new PointF(x, y), symbolWidth, symbolHeight, pgb, g);
- }
-
- PointF sP = new PointF(0, 0);
- sP.X = x + symbolWidth / 2;
- sP.Y = y;
- g.setColor(this.tickLabelColor);
- g.setFont(this.tickLabelFont);
- Draw.drawString(g, sP.X + 5, sP.Y, caption, XAlign.LEFT, YAlign.CENTER, true);
- y += breakHeight + breakSpace;
-
- i += 1;
- }
- }
- }
-
- private void drawHorizontalLegend(Graphics2D g, LegendScheme aLS) {
- String caption;
- float breakHeight = this.getBreakHeight(g);
- float symbolHeight = this.symbolDimension.height;
- float symbolWidth = this.symbolDimension.width;
-
- //Set columns
- int[] colNums = new int[rowColNum];
- int ave = aLS.getVisibleBreakNum() / rowColNum;
- if (ave * rowColNum < aLS.getBreakNum()) {
- ave += 1;
- }
- int num = 0;
- int i;
- for (i = 0; i < rowColNum - 1; i++) {
- colNums[i] = ave;
- num += ave;
- }
- colNums[rowColNum - 1] = aLS.getVisibleBreakNum() - num;
-
- //Draw legend
- float x, y;
- y = this.breakSpace + breakHeight / 2;
- i = 0;
- for (int row = 0; row < rowColNum; row++) {
- x = this.symbolDimension.width / 2 + 5;
- for (int col = 0; col < colNums[row]; col++) {
- if (i >= aLS.getBreakNum()) {
- break;
- }
-
- ColorBreak cb = aLS.getLegendBreaks().get(i);
- if (!cb.isDrawShape()) {
- continue;
- }
- caption = aLS.getLegendBreaks().get(i).getCaption();
- if (cb instanceof PointBreak) {
- PointBreak aPB = (PointBreak) cb;
- Draw.drawPoint(new PointF(x, y), aPB, g);
- } else if (cb instanceof PolylineBreak) {
- PolylineBreak aPLB = (PolylineBreak) cb;
- Draw.drawPolylineSymbol_S(new PointF(x, y), symbolWidth, symbolHeight, aPLB, g);
- } else if (cb instanceof PolygonBreak) {
- Draw.drawPolygonSymbol(new PointF(x, y), symbolWidth, symbolHeight, (PolygonBreak) cb, g);
- }
-
- PointF sP = new PointF(0, 0);
- sP.X = x + symbolWidth / 2;
- sP.Y = y;
- g.setColor(this.tickLabelColor);
- g.setFont(this.tickLabelFont);
- Draw.drawString(g, sP.X + 5, sP.Y, caption, XAlign.LEFT, YAlign.CENTER, true);
- Dimension dim = Draw.getStringDimension(caption, g);
- x += this.symbolDimension.width + dim.width + 15;
- i += 1;
- }
- y += breakHeight + this.breakSpace * 2;
- }
- }
-
- private int getMaxLabelWidth(Graphics2D g) {
- String caption;
- Dimension aSF;
- int bNum = legendScheme.getBreakNum();
- int labWidth = 0;
- g.setFont(this.tickLabelFont);
- for (int i = 0; i < bNum; i++) {
- caption = legendScheme.getLegendBreaks().get(i).getCaption();
- boolean isValid = true;
- if (isValid) {
- aSF = Draw.getStringDimension(caption, this.tickLabelAngle, g);
- int labwidth = aSF.width;
- if (labWidth < labwidth) {
- labWidth = labwidth;
- }
- }
- }
-
- return labWidth;
- }
-
- private int getBreakHeight(Graphics2D g) {
- g.setFont(tickLabelFont);
- Dimension dim = Draw.getStringDimension(this.legendScheme.getLegendBreak(0).getCaption(), g);
- return Math.max(dim.height, this.symbolDimension.height);
- }
-
- /**
- * Get legend dimension
- *
- * @param g Graphics2D
- * @param limitDim Limit dimension
- * @return Legend dimension
- */
- public Dimension getLegendDimension(Graphics2D g, Dimension limitDim) {
- if (legendScheme != null) {
- if (this.colorBar) {
- switch (this.orientation) {
- case VERTICAL:
- this.width = (int) (this.getTickWidth(g) + limitDim.height * this.shrink / this.aspect + 5);
- if (this.label != null) {
- g.setFont(this.label.getFont());
- this.width += (int) Draw.getStringDimension(label.getText(), g).height + 5;
- }
- break;
- default:
- g.setFont(this.tickLabelFont);
- this.height = (int) (Draw.getStringDimension("test", g).height + limitDim.width * this.shrink / this.aspect + 5);
- if (this.label != null) {
- g.setFont(this.label.getFont());
- Dimension dim = Draw.getStringDimension(label.getText(), g);
- switch (this.labelLocation) {
- case "top":
- case "right":
- this.width += dim.width + 10;
- break;
- default:
- this.height += (int) Draw.getStringDimension(label.getText(), g).height + 5;
- break;
- }
- }
- }
- } else {
- int breakHeight = getBreakHeight(g);
- int titleHeight = 0;
- int titleWidth = 0;
- if (this.label != null) {
- Dimension dim = this.label.getDimension(g);
- titleHeight = dim.height + (int) (this.breakSpace * 4);
- titleWidth = dim.width;
- }
- switch (this.orientation) {
- case VERTICAL:
- //Get column number
- if (this.autoRowColNum) {
- int tHeight = (int) (legendScheme.getBreakNum() * (breakHeight + breakSpace)
- + breakSpace * 2 + breakHeight / 2 + 5);
- rowColNum = 1;
- if (tHeight > limitDim.height * 10 / 8) {
- rowColNum = tHeight / (limitDim.height * 10 / 8) + 1;
- if (rowColNum == 1) {
- rowColNum = 2;
- } else {
- int n = legendScheme.getBreakNum() / rowColNum;
- int m = legendScheme.getBreakNum() % rowColNum;
- if (m != 0) {
- if (m <= n) {
- rowColNum += 1;
- } else {
- rowColNum += 2;
- }
- } else if (rowColNum * (limitDim.width * 8 / 10) < tHeight) {
- rowColNum += 1;
- }
- }
- }
- }
-
- //Get width
- int colWidth = this.symbolDimension.width + getMaxLabelWidth(g) + 15;
- this.width = colWidth * rowColNum;
-
- //Get height
- int[] rowNums = new int[rowColNum];
- int ave = legendScheme.getBreakNum() / rowColNum;
- if (ave * rowColNum < legendScheme.getBreakNum()) {
- ave += 1;
- }
- int num = 0;
- int i;
- for (i = 0; i < rowColNum - 1; i++) {
- rowNums[i] = ave;
- num += ave;
- }
- rowNums[rowColNum - 1] = legendScheme.getBreakNum() - num;
-
-// this.height = (int) (rowNums[0] * (breakHeight + _breakSpace)
-// + _breakSpace * 2 + breakHeight / 2 + 5);
- this.height = (int) (rowNums[0] * (breakHeight + breakSpace)
- + breakSpace * 3);
- break;
- case HORIZONTAL:
- //Get row number
- if (this.autoRowColNum) {
- int breakWidth = this.symbolDimension.width + this.getMaxLabelWidth(g) + 15;
- int tWidth = breakWidth * legendScheme.getBreakNum();
- rowColNum = 1;
- if (tWidth > limitDim.width * 8 / 10) {
- rowColNum = tWidth / (limitDim.width * 8 / 10);
- if (rowColNum == 1) {
- rowColNum = 2;
- } else {
- int n = legendScheme.getBreakNum() / rowColNum;
- int m = legendScheme.getBreakNum() % rowColNum;
- if (m != 0) {
- if (m <= n) {
- rowColNum += 1;
- } else {
- rowColNum += 2;
- }
- } else if (rowColNum * (limitDim.width * 8 / 10) < tWidth) {
- rowColNum += 1;
- }
- }
- }
- }
-
- //Get height
- this.height = (int) (breakHeight + this.breakSpace * 2) * this.rowColNum;
-
- //Get width
- //FontMetrics metrics = g.getFontMetrics(tickFont);
- ave = legendScheme.getBreakNum() / rowColNum;
- if (ave * rowColNum < legendScheme.getBreakNum()) {
- ave += 1;
- }
- num = 0;
- int maxWidth = 0;
- int tempWidth = 0;
- for (i = 0; i < legendScheme.getBreakNum(); i++) {
- if (num < ave) {
- //tempWidth += this.symbolDimension.width + 15
- // + metrics.stringWidth(legendScheme.getLegendBreaks().get(i).getCaption());
- tempWidth += this.symbolDimension.width + 15
- + Draw.getStringDimension(legendScheme.getLegendBreaks().get(i).getCaption(), g).width;
- num += 1;
- } else {
- if (maxWidth < tempWidth) {
- maxWidth = tempWidth;
- }
- //tempWidth = metrics.stringWidth(legendScheme.getLegendBreaks().get(i).getCaption()) + 15;
- tempWidth = Draw.getStringDimension(legendScheme.getLegendBreaks().get(i).getCaption(), g).width;
- num = 1;
- }
- }
- if (maxWidth < tempWidth) {
- maxWidth = tempWidth;
- }
- if (maxWidth > limitDim.width) {
- maxWidth = limitDim.width * 8 / 10;
- }
- this.width = maxWidth;
- break;
- }
- this.height += titleHeight;
- this.width = Math.max(this.width, titleWidth);
- }
- }
-
- return new Dimension(this.width, this.height);
- }
-
- protected int getTickWidth(Graphics2D g) {
- float rwidth = 0;
- String caption = "";
- int bNum = this.legendScheme.getBreakNum();
- //FontMetrics metrics = g.getFontMetrics(this.tickFont);
- g.setFont(this.tickLabelFont);
- if (this.legendScheme.getLegendBreaks().get(bNum - 1).isNoData()) {
- bNum -= 1;
- }
- for (int i = 0; i < bNum; i++) {
- switch (this.legendScheme.getShapeType()) {
- case Point:
- PointBreak aPB = (PointBreak) legendScheme.getLegendBreaks().get(i);
- if (legendScheme.getLegendType() == LegendType.GraduatedColor) {
- caption = DataConvert.removeTailingZeros(aPB.getEndValue().toString());
- } else {
- caption = aPB.getCaption();
- }
- break;
- case Polyline:
- PolylineBreak aPLB = (PolylineBreak) legendScheme.getLegendBreaks().get(i);
- if (legendScheme.getLegendType() == LegendType.GraduatedColor) {
- caption = DataConvert.removeTailingZeros(aPLB.getEndValue().toString());
- } else {
- caption = aPLB.getCaption();
- }
- break;
- case Polygon:
- PolygonBreak aPGB = (PolygonBreak) legendScheme.getLegendBreaks().get(i);
- if (legendScheme.getLegendType() == LegendType.GraduatedColor) {
- caption = DataConvert.removeTailingZeros(aPGB.getEndValue().toString());
- } else {
- caption = aPGB.getCaption();
- }
- break;
- case Image:
- ColorBreak aCB = legendScheme.getLegendBreaks().get(i);
- if (legendScheme.getLegendType() == LegendType.GraduatedColor) {
- caption = DataConvert.removeTailingZeros(aCB.getEndValue().toString());
- } else {
- caption = aCB.getCaption();
- }
- break;
- }
-
- boolean isValid = true;
- switch (legendScheme.getLegendType()) {
- case GraduatedColor:
- if (i == bNum - 1) {
- isValid = false;
- }
- break;
- }
- if (isValid) {
- //float labwidth = metrics.stringWidth(caption);
- float labwidth = (float) Draw.getStringDimension(caption, this.tickLabelAngle, g).getWidth();
- if (rwidth < labwidth) {
- rwidth = labwidth;
- }
- }
- }
-
- return (int) rwidth;
- }
-
- protected int getTickHeight(Graphics2D g) {
- float rheight = 0;
- String caption = "";
- int bNum = this.legendScheme.getBreakNum();
- //FontMetrics metrics = g.getFontMetrics(this.tickFont);
- g.setFont(this.tickLabelFont);
- if (this.legendScheme.getLegendBreaks().get(bNum - 1).isNoData()) {
- bNum -= 1;
- }
- for (int i = 0; i < bNum; i++) {
- switch (this.legendScheme.getShapeType()) {
- case Point:
- PointBreak aPB = (PointBreak) legendScheme.getLegendBreaks().get(i);
- if (legendScheme.getLegendType() == LegendType.GraduatedColor) {
- caption = DataConvert.removeTailingZeros(aPB.getEndValue().toString());
- } else {
- caption = aPB.getCaption();
- }
- break;
- case Polyline:
- PolylineBreak aPLB = (PolylineBreak) legendScheme.getLegendBreaks().get(i);
- if (legendScheme.getLegendType() == LegendType.GraduatedColor) {
- caption = DataConvert.removeTailingZeros(aPLB.getEndValue().toString());
- } else {
- caption = aPLB.getCaption();
- }
- break;
- case Polygon:
- PolygonBreak aPGB = (PolygonBreak) legendScheme.getLegendBreaks().get(i);
- if (legendScheme.getLegendType() == LegendType.GraduatedColor) {
- caption = DataConvert.removeTailingZeros(aPGB.getEndValue().toString());
- } else {
- caption = aPGB.getCaption();
- }
- break;
- case Image:
- ColorBreak aCB = legendScheme.getLegendBreaks().get(i);
- if (legendScheme.getLegendType() == LegendType.GraduatedColor) {
- caption = DataConvert.removeTailingZeros(aCB.getEndValue().toString());
- } else {
- caption = aCB.getCaption();
- }
- break;
- }
-
- boolean isValid = true;
- switch (legendScheme.getLegendType()) {
- case GraduatedColor:
- if (i == bNum - 1) {
- isValid = false;
- }
- break;
- }
- if (isValid) {
- float labheight = (float) Draw.getStringDimension(caption, 90 - Math.abs(this.tickLabelAngle), g).getWidth();
- if (rheight < labheight) {
- rheight = labheight;
- }
- }
- }
-
- return (int) rheight;
- }
-
- /**
- * Update tick gap
- *
- * @param g Graphics2D
- * @return Ticks gap
- */
- protected int getTickGap(Graphics2D g) {
- if (this.tickLabelAngle != 0) {
- return 1;
- }
-
- double len;
- int n = this.legendScheme.getBreakNum();
- int nn;
- if (this.orientation == PlotOrientation.HORIZONTAL) {
- len = this.width;
- int labLen = this.getTickWidth(g);
- nn = (int) ((len * 0.8) / labLen);
- } else {
- len = this.height;
- FontMetrics metrics = g.getFontMetrics(tickLabelFont);
- nn = (int) (len / metrics.getHeight());
- }
- if (nn == 0) {
- nn = 1;
- }
- return n / nn + 1;
- }
-
- //
- //
- public class LayoutLegendBean {
-
- LayoutLegendBean() {
- }
-
- //
- /**
- * Get if draw neat line
- *
- * @return If draw neat line
- */
- public boolean isDrawNeatLine() {
- return drawNeatLine;
- }
-
- /**
- * Set if draw neat line
- *
- * @param istrue If draw neat line
- */
- public void setDrawNeatLine(boolean istrue) {
- drawNeatLine = istrue;
- }
-
- /**
- * Get neat line color
- *
- * @return Neat line color
- */
- public Color getNeatLineColor() {
- return neatLineColor;
- }
-
- /**
- * Set neat line color
- *
- * @param color Neat line color
- */
- public void setNeatLineColor(Color color) {
- neatLineColor = color;
- }
-
- /**
- * Get neat line size
- *
- * @return Neat line size
- */
- public float getNeatLineSize() {
- return neatLineSize;
- }
-
- /**
- * Set neat line size
- *
- * @param size Neat line size
- */
- public void setNeatLineSize(float size) {
- neatLineSize = size;
- }
-
- /**
- * Get tick label font
- *
- * @return The tick label font
- */
- public Font getTickLabelFont() {
- return tickLabelFont;
- }
-
- /**
- * Set tick label font
- *
- * @param font The tick label font
- */
- public void setTickLabelFont(Font font) {
- tickLabelFont = font;
- }
-
- /**
- * Get column number
- *
- * @return Column number
- */
- public int getColumnNumber() {
- return rowColNum;
- }
-
- /**
- * Set column number
- *
- * @param value Column number
- */
- public void setColumnNumber(int value) {
- rowColNum = value;
- }
-
- /**
- * Get is draw background
- *
- * @return Boolean
- */
- public boolean isDrawBackground() {
- return drawBackground;
- }
-
- /**
- * Set is draw background
- *
- * @param value Boolean
- */
- public void setDrawBackground(boolean value) {
- drawBackground = value;
- }
-
- /**
- * Get background color
- *
- * @return Background color
- */
- public Color getBackground() {
- return background;
- }
-
- /**
- * Set background color
- *
- * @param c Background color
- */
- public void setBackground(Color c) {
- background = c;
- }
-
- //
- }
-
- public static class LayoutLegendBeanBeanInfo extends BaseBeanInfo {
-
- public LayoutLegendBeanBeanInfo() {
- super(LayoutLegendBean.class);
- ExtendedPropertyDescriptor e = addProperty("plotOrientation");
- e.setCategory("General").setDisplayName("Plot orientation");
- e.setPropertyEditorClass(PlotOrientationEditor.class);
- addProperty("tickFont").setCategory("General").setDisplayName("Tick Font");
- addProperty("drawBackground").setCategory("General").setDisplayName("Draw Background");
- addProperty("background").setCategory("General").setDisplayName("Background");
- addProperty("columnNumber").setCategory("General").setDisplayName("Column Number");
- addProperty("drawNeatLine").setCategory("Neat Line").setDisplayName("Draw Neat Line");
- addProperty("neatLineColor").setCategory("Neat Line").setDisplayName("Neat Line Color");
- addProperty("neatLineSize").setCategory("Neat Line").setDisplayName("Neat Line Size");
- }
- }
-
- public static class PlotOrientationEditor extends ComboBoxPropertyEditor {
-
- public PlotOrientationEditor() {
- super();
- PlotOrientation[] orientations = PlotOrientation.values();
- String[] types = new String[orientations.length];
- int i = 0;
- for (PlotOrientation type : orientations) {
- types[i] = type.toString();
- i += 1;
- }
- setAvailableValues(types);
- }
- }
-
- //
-}
+/* Copyright 2012 Yaqiang Wang,
+ * yaqiang.wang@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ */
+package org.meteoinfo.chart;
+
+import org.meteoinfo.common.PointF;
+import org.meteoinfo.drawing.Draw;
+import org.meteoinfo.legend.ColorBreak;
+import org.meteoinfo.legend.LegendScheme;
+import org.meteoinfo.legend.PointBreak;
+import org.meteoinfo.legend.PolygonBreak;
+import org.meteoinfo.legend.PolylineBreak;
+import com.l2fprod.common.beans.BaseBeanInfo;
+import com.l2fprod.common.beans.ExtendedPropertyDescriptor;
+import com.l2fprod.common.beans.editor.ComboBoxPropertyEditor;
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.geom.AffineTransform;
+import java.util.List;
+import org.meteoinfo.chart.plot.PlotOrientation;
+import org.meteoinfo.chart.plot.XAlign;
+import org.meteoinfo.chart.plot.YAlign;
+import org.meteoinfo.global.DataConvert;
+import org.meteoinfo.legend.LegendType;
+
+/**
+ *
+ * @author Yaqiang Wang
+ */
+public class ChartLegend {
+ //
+
+ //private final XY1DPlot plot;
+ protected LegendScheme legendScheme;
+ private LegendPosition position;
+ protected float shrink;
+ protected int aspect;
+ private boolean colorBar;
+ protected float x;
+ protected float y;
+ protected PlotOrientation orientation;
+ protected Color background;
+ protected boolean drawBackground;
+ protected int width;
+ protected int height;
+ protected int legendWidth;
+ protected int legendHeight;
+ protected ChartText label;
+ protected String labelLocation;
+ protected Font tickLabelFont;
+ protected Color tickLabelColor;
+ protected float tickLabelAngle;
+ protected boolean drawNeatLine;
+ protected Color neatLineColor;
+ protected float neatLineSize;
+ private float breakSpace;
+ private float topSpace;
+ private float leftSpace;
+ protected double _vBarWidth;
+ protected double _hBarHeight;
+ private int rowColNum = 1;
+ private boolean autoRowColNum = true;
+ private Dimension symbolDimension;
+ protected boolean extendRect;
+ protected boolean autoExtendFrac;
+ protected float xshift;
+ protected float yshift;
+ //
+ //
+
+ /**
+ * Constructor
+ *
+ * @param ls LegendScheme
+ */
+ public ChartLegend(LegendScheme ls) {
+ //this.plot = plot;
+ this.legendScheme = ls;
+ this.colorBar = false;
+ this.position = LegendPosition.LOWER_CENTER_OUTSIDE;
+ this.orientation = PlotOrientation.HORIZONTAL;
+ this.shrink = 1.0f;
+ this.aspect = 20;
+ this.background = Color.white;
+ this.drawBackground = false;
+ drawNeatLine = true;
+ neatLineColor = Color.black;
+ neatLineSize = 1;
+ breakSpace = 3;
+ topSpace = 5;
+ leftSpace = 5;
+ _vBarWidth = 10;
+ _hBarHeight = 10;
+ this.labelLocation = "out";
+ tickLabelFont = new Font("Arial", Font.PLAIN, 14);
+ this.tickLabelColor = Color.black;
+ this.tickLabelAngle = 0;
+ this.symbolDimension = new Dimension(16, 10);
+ this.extendRect = true;
+ this.autoExtendFrac = false;
+ this.xshift = 0;
+ this.yshift = 0;
+ }
+
+ //
+ //
+ //
+ //
+ /**
+ * Get legend scheme
+ *
+ * @return Legend scheme
+ */
+ public LegendScheme getLegendScheme() {
+ return this.legendScheme;
+ }
+
+ /**
+ * Set legend scheme
+ *
+ * @param value Legend scheme
+ */
+ public void setLegendScheme(LegendScheme value) {
+ this.legendScheme = value;
+ }
+
+ /**
+ * Get if is color bar
+ *
+ * @return Boolean
+ */
+ public boolean isColorbar() {
+ return this.colorBar;
+ }
+
+ /**
+ * Set if is color bar
+ *
+ * @param value Boolean
+ */
+ public void setColorbar(boolean value) {
+ this.colorBar = value;
+ }
+
+ /**
+ * Get legend position
+ *
+ * @return Legend position
+ */
+ public LegendPosition getPosition() {
+ return this.position;
+ }
+
+ /**
+ * Set legend position
+ *
+ * @param value Legend position
+ */
+ public void setPosition(LegendPosition value) {
+ this.position = value;
+ }
+
+ /**
+ * Get shrink
+ *
+ * @return Shrink
+ */
+ public float getShrink() {
+ return this.shrink;
+ }
+
+ /**
+ * Set shrink
+ *
+ * @param value Shrink
+ */
+ public void setShrink(float value) {
+ this.shrink = value;
+ }
+
+ /**
+ * Get aspect
+ *
+ * @return Aspect
+ */
+ public int getAspect() {
+ return this.aspect;
+ }
+
+ /**
+ * Set aspect
+ *
+ * @param value Aspect
+ */
+ public void setAspect(int value) {
+ this.aspect = value;
+ }
+
+ /**
+ * Get X
+ *
+ * @return X value
+ */
+ public float getX() {
+ return this.x;
+ }
+
+ /**
+ * Set X
+ *
+ * @param value X value
+ */
+ public void setX(float value) {
+ x = value;
+ }
+
+ /**
+ * Get Y
+ *
+ * @return Y value
+ */
+ public float getY() {
+ return this.y;
+ }
+
+ /**
+ * Set Y
+ *
+ * @param value Y value
+ */
+ public void setY(float value) {
+ y = value;
+ }
+
+ /**
+ * Get width
+ *
+ * @return Width
+ */
+ public int getWidth() {
+ return this.width;
+ }
+
+ /**
+ * Set width
+ *
+ * @param value Width
+ */
+ public void setWidth(int value) {
+ this.width = value;
+ }
+
+ /**
+ * Get height
+ *
+ * @return Height
+ */
+ public int getHeight() {
+ return this.height;
+ }
+
+ /**
+ * Set height
+ *
+ * @param value Height
+ */
+ public void setHeight(int value) {
+ this.height = value;
+ }
+
+ /**
+ * Get legend width
+ *
+ * @return Legend width
+ */
+ public int getLegendWidth() {
+ return this.legendWidth;
+ }
+
+ /**
+ * Set legend width
+ *
+ * @param value Legend width
+ */
+ public void setLegendWidth(int value) {
+ this.legendWidth = value;
+ }
+
+ /**
+ * Get legend height
+ *
+ * @return Legend height
+ */
+ public int getLegendHeight() {
+ return this.legendHeight;
+ }
+
+ /**
+ * Set legend height
+ *
+ * @param value Legend height
+ */
+ public void setLegendHeight(int value) {
+ this.legendHeight = value;
+ }
+
+ /**
+ * Get plot orientation
+ *
+ * @return Plot orientation
+ */
+ public PlotOrientation getPlotOrientation() {
+ return this.orientation;
+ }
+
+ /**
+ * Set plot orientation
+ *
+ * @param value Plot orientation
+ */
+ public void setPlotOrientation(PlotOrientation value) {
+ this.orientation = value;
+ }
+
+ /**
+ * Get background
+ *
+ * @return Background
+ */
+ public Color getBackground() {
+ return this.background;
+ }
+
+ /**
+ * Set background
+ *
+ * @param value Background
+ */
+ public void setBackground(Color value) {
+ this.background = value;
+ }
+
+ /**
+ * Get if draw background
+ *
+ * @return Boolean
+ */
+ public boolean isDrawBackground() {
+ return this.drawBackground;
+ }
+
+ /**
+ * Set if draw background
+ *
+ * @param value Boolean
+ */
+ public void setDrawBackground(boolean value) {
+ this.drawBackground = value;
+ }
+
+ /**
+ * Get if draw neat line
+ *
+ * @return If draw neat line
+ */
+ public boolean isDrawNeatLine() {
+ return drawNeatLine;
+ }
+
+ /**
+ * Set if draw neat line
+ *
+ * @param istrue If draw neat line
+ */
+ public void setDrawNeatLine(boolean istrue) {
+ drawNeatLine = istrue;
+ }
+
+ /**
+ * Get neat line color
+ *
+ * @return Neat line color
+ */
+ public Color getNeatLineColor() {
+ return neatLineColor;
+ }
+
+ /**
+ * Set neat line color
+ *
+ * @param color Neat line color
+ */
+ public void setNeatLineColor(Color color) {
+ neatLineColor = color;
+ }
+
+ /**
+ * Get neat line size
+ *
+ * @return Neat line size
+ */
+ public float getNeatLineSize() {
+ return neatLineSize;
+ }
+
+ /**
+ * Set neat line size
+ *
+ * @param size Neat line size
+ */
+ public void setNeatLineSize(float size) {
+ neatLineSize = size;
+ }
+
+ /**
+ * Get break space
+ * @return Break space
+ */
+ public float getBreakSpace() {
+ return this.breakSpace;
+ }
+
+ /**
+ * Set break space
+ * @param value Break space
+ */
+ public void setBreakSpace(float value) {
+ this.breakSpace = value;
+ }
+
+ /**
+ * Get label
+ *
+ * @return Label
+ */
+ public ChartText getLabel() {
+ return this.label;
+ }
+
+ /**
+ * Set label
+ *
+ * @param value Label
+ */
+ public void setLabel(ChartText value) {
+ this.label = value;
+ }
+
+ /**
+ * Get label font
+ *
+ * @return Label font
+ */
+ public Font getLabelFont() {
+ return this.label.getFont();
+ }
+
+ /**
+ * Set label font
+ *
+ * @param value Label font
+ */
+ public void setLabelFont(Font value) {
+ this.label.setFont(value);
+ }
+
+ /**
+ * Get label color
+ *
+ * @return Label color
+ */
+ public Color getLabelColor() {
+ return this.label.getColor();
+ }
+
+ /**
+ * Set label color
+ *
+ * @param value Label color
+ */
+ public void setLabelColor(Color value) {
+ this.label.setColor(value);
+ }
+
+ /**
+ * Get label location (in, out, top, bottom, left, right)
+ *
+ * @return Label location
+ */
+ public String getLabelLocation() {
+ return this.labelLocation;
+ }
+
+ /**
+ * Set label location
+ *
+ * @param value Label location
+ */
+ public void setLabelLocation(String value) {
+ this.labelLocation = value;
+ }
+
+ /**
+ * Get Tick label font
+ *
+ * @return The Tick label font
+ */
+ public Font getTickLabelFont() {
+ return tickLabelFont;
+ }
+
+ /**
+ * Set Tick label font
+ *
+ * @param font The Tick label font
+ */
+ public void setTickLabelFont(Font font) {
+ tickLabelFont = font;
+ }
+
+ /**
+ * Get tick label color
+ *
+ * @return Tick label color
+ */
+ public Color getTickLabelColor() {
+ return this.tickLabelColor;
+ }
+
+ /**
+ * Set tick label color
+ *
+ * @param value Tick label color
+ */
+ public void setTickLabelColor(Color value) {
+ this.tickLabelColor = value;
+ }
+
+ /**
+ * Get tick lable angle
+ *
+ * @return Tick label angle
+ */
+ public float getTickLabelAngle() {
+ return this.tickLabelAngle;
+ }
+
+ /**
+ * Set tick label angle
+ *
+ * @param value Tick label angle
+ */
+ public void setTickLabelAngle(float value) {
+ this.tickLabelAngle = value;
+ }
+
+ /**
+ * Get column number
+ *
+ * @return Column number
+ */
+ public int getColumnNumber() {
+ return rowColNum;
+ }
+
+ /**
+ * Set column number
+ *
+ * @param value Column number
+ */
+ public void setColumnNumber(int value) {
+ rowColNum = value;
+ }
+
+ /**
+ * Get if automatic set row/col number
+ *
+ * @return Boolean
+ */
+ public boolean isAutoRowColNum() {
+ return this.autoRowColNum;
+ }
+
+ /**
+ * Set if automatic set row/col number
+ *
+ * @param value Boolean
+ */
+ public void setAutoRowColNum(boolean value) {
+ this.autoRowColNum = value;
+ }
+
+ /**
+ * Get symbol dimension
+ *
+ * @return Symbol dimension
+ */
+ public Dimension getSymbolDimension() {
+ return this.symbolDimension;
+ }
+
+ /**
+ * Set symbol dimension
+ *
+ * @param value Symbol dimension
+ */
+ public void setSymbolDimension(Dimension value) {
+ this.symbolDimension = value;
+ }
+
+ /**
+ * Set symbol width
+ *
+ * @param value Width
+ */
+ public void setSymbolWidth(int value) {
+ this.symbolDimension.width = value;
+ }
+
+ /**
+ * Set symbol height
+ *
+ * @param value height
+ */
+ public void setSymbolHeight(int value) {
+ this.symbolDimension.height = value;
+ }
+
+ /**
+ * Set symbol scale
+ *
+ * @param value Symble scale
+ */
+ public void setSymbolScale(float value) {
+ double w = this.symbolDimension.getWidth() * value;
+ double h = this.symbolDimension.getHeight() * value;
+ this.symbolDimension.setSize(w, h);
+ }
+
+ /**
+ * Get if extend rectangle - or triangle
+ *
+ * @return Boolean
+ */
+ public boolean isExtendRect() {
+ return this.extendRect;
+ }
+
+ /**
+ * Set if extend rectangle - or triangle
+ *
+ * @param value Boolean
+ */
+ public void setExtendRect(boolean value) {
+ this.extendRect = value;
+ }
+
+ /**
+ * Get if auto set extend fraction - extend has save width and height Only
+ * valid for colorbar
+ *
+ * @return Boolean
+ */
+ public boolean isAutoExtendFrac() {
+ return this.autoExtendFrac;
+ }
+
+ /**
+ * Set if auto set extend fraction - extend has save width and height Only
+ * valid for colorbar
+ *
+ * @param value
+ */
+ public void setAutoExtendFrac(boolean value) {
+ this.autoExtendFrac = value;
+ }
+
+ /**
+ * Set tick labels
+ *
+ * @param value Tick labels
+ */
+ public void setTickCaptions(List value) {
+ for (int i = 0; i < this.legendScheme.getBreakNum(); i++) {
+ if (i < value.size()) {
+ this.legendScheme.getLegendBreaks().get(i).setCaption(value.get(i));
+ } else {
+ break;
+ }
+ }
+ }
+
+ /**
+ * Get x shift - pixel unit
+ *
+ * @return X shift
+ */
+ public float getXShift() {
+ return this.xshift;
+ }
+
+ /**
+ * Set x shift
+ *
+ * @param value X shift
+ */
+ public void setXShift(float value) {
+ this.xshift = value;
+ }
+
+ /**
+ * Get y shift - pixel unit
+ *
+ * @return Y shift
+ */
+ public float getYShift() {
+ return this.yshift;
+ }
+
+ /**
+ * Set y shift
+ *
+ * @param value Y shift
+ */
+ public void setYShift(float value) {
+ this.yshift = value;
+ }
+
+ //
+ //
+ /**
+ * Draw legend
+ *
+ * @param g Graphics2D
+ * @param point Start point
+ */
+ public void draw(Graphics2D g, PointF point) {
+
+ AffineTransform oldMatrix = g.getTransform();
+ g.translate(point.X + this.xshift, point.Y + this.yshift);
+
+ //Draw background color
+ if (this.drawBackground) {
+ g.setColor(this.background);
+ g.fill(new Rectangle.Float(0, 0, this.width, this.height));
+ }
+
+ //Draw legend
+ g.setStroke(new BasicStroke(1));
+ switch (this.orientation) {
+ case HORIZONTAL:
+ drawHorizontalLegend(g, legendScheme);
+ break;
+ case VERTICAL:
+ this.drawVerticalLegend(g, legendScheme);
+ break;
+ }
+
+ //Draw neatline
+ if (drawNeatLine) {
+ Rectangle.Float mapRect = new Rectangle.Float(0, 0, this.width, this.height);
+ g.setColor(neatLineColor);
+ g.setStroke(new BasicStroke(neatLineSize));
+ g.draw(mapRect);
+ }
+
+ g.setTransform(oldMatrix);
+ }
+
+ private void drawVerticalLegend(Graphics2D g, LegendScheme aLS) {
+ String caption;
+ float breakHeight = this.getBreakHeight(g);
+ float symbolHeight = this.symbolDimension.height;
+ float symbolWidth = this.symbolDimension.width;
+ float colWidth = symbolWidth + getMaxLabelWidth(g) + 10;
+
+ //Set columns
+ int[] rowNums = new int[rowColNum];
+ int ave = aLS.getVisibleBreakNum() / rowColNum;
+ if (ave * rowColNum < aLS.getBreakNum()) {
+ ave += 1;
+ }
+ int num = 0;
+ int i;
+ for (i = 1; i < rowColNum; i++) {
+ rowNums[i] = ave;
+ num += ave;
+ }
+ rowNums[0] = aLS.getVisibleBreakNum() - num;
+
+ //Draw title
+ float y0 = 0;
+ if (this.label != null) {
+ float x0 = (float) (this.width / 2.);
+ y0 += this.breakSpace * 2;
+ this.label.draw(g, x0, y0);
+ y0 += this.label.getDimension(g).height + this.breakSpace * 2;
+ }
+
+ //Draw legend
+ float x, y;
+ i = 0;
+ for (int col = 0; col < rowColNum; col++) {
+ x = symbolWidth / 2 + leftSpace + col * colWidth;
+ y = y0 + breakHeight / 2 + breakSpace * 2;
+ for (int row = 0; row < rowNums[col]; row++) {
+ if (!aLS.getLegendBreaks().get(i).isDrawShape()) {
+ continue;
+ }
+
+ //y += breakHeight + breakSpace;
+ ColorBreak cb = aLS.getLegendBreaks().get(i);
+ if (!cb.isDrawShape()) {
+ continue;
+ }
+ caption = aLS.getLegendBreaks().get(i).getCaption();
+ if (cb instanceof PointBreak) {
+ PointBreak aPB = (PointBreak) cb.clone();
+ ((PointBreak) aPB).setSize(((PointBreak) cb).getSize() * (symbolHeight / 10.f));
+ Draw.drawPoint(new PointF(x, y), aPB, g);
+ } else if (cb instanceof PolylineBreak) {
+ PolylineBreak aPLB = (PolylineBreak) cb;
+ Draw.drawPolylineSymbol_S(new PointF(x, y), symbolWidth, symbolHeight, aPLB, g);
+ } else if (cb instanceof PolygonBreak) {
+ Draw.drawPolygonSymbol(new PointF(x, y), symbolWidth, symbolHeight, (PolygonBreak) cb, g);
+ } else {
+ PolygonBreak pgb = new PolygonBreak();
+ pgb.setColor(cb.getColor());
+ pgb.setOutlineColor(Color.black);
+ Draw.drawPolygonSymbol(new PointF(x, y), symbolWidth, symbolHeight, pgb, g);
+ }
+
+ PointF sP = new PointF(0, 0);
+ sP.X = x + symbolWidth / 2;
+ sP.Y = y;
+ g.setColor(this.tickLabelColor);
+ g.setFont(this.tickLabelFont);
+ Draw.drawString(g, sP.X + 5, sP.Y, caption, XAlign.LEFT, YAlign.CENTER, true);
+ y += breakHeight + breakSpace;
+
+ i += 1;
+ }
+ }
+ }
+
+ private void drawHorizontalLegend(Graphics2D g, LegendScheme aLS) {
+ String caption;
+ float breakHeight = this.getBreakHeight(g);
+ float symbolHeight = this.symbolDimension.height;
+ float symbolWidth = this.symbolDimension.width;
+
+ //Set columns
+ int[] colNums = new int[rowColNum];
+ int ave = aLS.getVisibleBreakNum() / rowColNum;
+ if (ave * rowColNum < aLS.getBreakNum()) {
+ ave += 1;
+ }
+ int num = 0;
+ int i;
+ for (i = 0; i < rowColNum - 1; i++) {
+ colNums[i] = ave;
+ num += ave;
+ }
+ colNums[rowColNum - 1] = aLS.getVisibleBreakNum() - num;
+
+ //Draw legend
+ float x, y;
+ y = this.breakSpace + breakHeight / 2;
+ i = 0;
+ for (int row = 0; row < rowColNum; row++) {
+ x = this.symbolDimension.width / 2 + 5;
+ for (int col = 0; col < colNums[row]; col++) {
+ if (i >= aLS.getBreakNum()) {
+ break;
+ }
+
+ ColorBreak cb = aLS.getLegendBreaks().get(i);
+ if (!cb.isDrawShape()) {
+ continue;
+ }
+ caption = aLS.getLegendBreaks().get(i).getCaption();
+ if (cb instanceof PointBreak) {
+ PointBreak aPB = (PointBreak) cb;
+ Draw.drawPoint(new PointF(x, y), aPB, g);
+ } else if (cb instanceof PolylineBreak) {
+ PolylineBreak aPLB = (PolylineBreak) cb;
+ Draw.drawPolylineSymbol_S(new PointF(x, y), symbolWidth, symbolHeight, aPLB, g);
+ } else if (cb instanceof PolygonBreak) {
+ Draw.drawPolygonSymbol(new PointF(x, y), symbolWidth, symbolHeight, (PolygonBreak) cb, g);
+ }
+
+ PointF sP = new PointF(0, 0);
+ sP.X = x + symbolWidth / 2;
+ sP.Y = y;
+ g.setColor(this.tickLabelColor);
+ g.setFont(this.tickLabelFont);
+ Draw.drawString(g, sP.X + 5, sP.Y, caption, XAlign.LEFT, YAlign.CENTER, true);
+ Dimension dim = Draw.getStringDimension(caption, g);
+ x += this.symbolDimension.width + dim.width + 15;
+ i += 1;
+ }
+ y += breakHeight + this.breakSpace * 2;
+ }
+ }
+
+ private int getMaxLabelWidth(Graphics2D g) {
+ String caption;
+ Dimension aSF;
+ int bNum = legendScheme.getBreakNum();
+ int labWidth = 0;
+ g.setFont(this.tickLabelFont);
+ for (int i = 0; i < bNum; i++) {
+ caption = legendScheme.getLegendBreaks().get(i).getCaption();
+ boolean isValid = true;
+ if (isValid) {
+ aSF = Draw.getStringDimension(caption, this.tickLabelAngle, g);
+ int labwidth = aSF.width;
+ if (labWidth < labwidth) {
+ labWidth = labwidth;
+ }
+ }
+ }
+
+ return labWidth;
+ }
+
+ private int getBreakHeight(Graphics2D g) {
+ g.setFont(tickLabelFont);
+ Dimension dim = Draw.getStringDimension(this.legendScheme.getLegendBreak(0).getCaption(), g);
+ return Math.max(dim.height, this.symbolDimension.height);
+ }
+
+ /**
+ * Get legend dimension
+ *
+ * @param g Graphics2D
+ * @param limitDim Limit dimension
+ * @return Legend dimension
+ */
+ public Dimension getLegendDimension(Graphics2D g, Dimension limitDim) {
+ if (legendScheme != null) {
+ if (this.colorBar) {
+ switch (this.orientation) {
+ case VERTICAL:
+ this.width = (int) (this.getTickWidth(g) + limitDim.height * this.shrink / this.aspect + 5);
+ if (this.label != null) {
+ g.setFont(this.label.getFont());
+ this.width += (int) Draw.getStringDimension(label.getText(), g).height + 5;
+ }
+ break;
+ default:
+ g.setFont(this.tickLabelFont);
+ this.height = (int) (Draw.getStringDimension("test", g).height + limitDim.width * this.shrink / this.aspect + 5);
+ if (this.label != null) {
+ g.setFont(this.label.getFont());
+ Dimension dim = Draw.getStringDimension(label.getText(), g);
+ switch (this.labelLocation) {
+ case "top":
+ case "right":
+ this.width += dim.width + 10;
+ break;
+ default:
+ this.height += (int) Draw.getStringDimension(label.getText(), g).height + 5;
+ break;
+ }
+ }
+ }
+ } else {
+ int breakHeight = getBreakHeight(g);
+ int titleHeight = 0;
+ int titleWidth = 0;
+ if (this.label != null) {
+ Dimension dim = this.label.getDimension(g);
+ titleHeight = dim.height + (int) (this.breakSpace * 4);
+ titleWidth = dim.width;
+ }
+ switch (this.orientation) {
+ case VERTICAL:
+ //Get column number
+ if (this.autoRowColNum) {
+ int tHeight = (int) (legendScheme.getBreakNum() * (breakHeight + breakSpace)
+ + breakSpace * 2 + breakHeight / 2 + 5);
+ rowColNum = 1;
+ if (tHeight > limitDim.height * 10 / 8) {
+ rowColNum = tHeight / (limitDim.height * 10 / 8) + 1;
+ if (rowColNum == 1) {
+ rowColNum = 2;
+ } else {
+ int n = legendScheme.getBreakNum() / rowColNum;
+ int m = legendScheme.getBreakNum() % rowColNum;
+ if (m != 0) {
+ if (m <= n) {
+ rowColNum += 1;
+ } else {
+ rowColNum += 2;
+ }
+ } else if (rowColNum * (limitDim.width * 8 / 10) < tHeight) {
+ rowColNum += 1;
+ }
+ }
+ }
+ }
+
+ //Get width
+ int colWidth = this.symbolDimension.width + getMaxLabelWidth(g) + 15;
+ this.width = colWidth * rowColNum;
+
+ //Get height
+ int[] rowNums = new int[rowColNum];
+ int ave = legendScheme.getBreakNum() / rowColNum;
+ if (ave * rowColNum < legendScheme.getBreakNum()) {
+ ave += 1;
+ }
+ int num = 0;
+ int i;
+ for (i = 0; i < rowColNum - 1; i++) {
+ rowNums[i] = ave;
+ num += ave;
+ }
+ rowNums[rowColNum - 1] = legendScheme.getBreakNum() - num;
+
+// this.height = (int) (rowNums[0] * (breakHeight + _breakSpace)
+// + _breakSpace * 2 + breakHeight / 2 + 5);
+ this.height = (int) (rowNums[0] * (breakHeight + breakSpace)
+ + breakSpace * 3);
+ break;
+ case HORIZONTAL:
+ //Get row number
+ if (this.autoRowColNum) {
+ int breakWidth = this.symbolDimension.width + this.getMaxLabelWidth(g) + 15;
+ int tWidth = breakWidth * legendScheme.getBreakNum();
+ rowColNum = 1;
+ if (tWidth > limitDim.width * 8 / 10) {
+ rowColNum = tWidth / (limitDim.width * 8 / 10);
+ if (rowColNum == 1) {
+ rowColNum = 2;
+ } else {
+ int n = legendScheme.getBreakNum() / rowColNum;
+ int m = legendScheme.getBreakNum() % rowColNum;
+ if (m != 0) {
+ if (m <= n) {
+ rowColNum += 1;
+ } else {
+ rowColNum += 2;
+ }
+ } else if (rowColNum * (limitDim.width * 8 / 10) < tWidth) {
+ rowColNum += 1;
+ }
+ }
+ }
+ }
+
+ //Get height
+ this.height = (int) (breakHeight + this.breakSpace * 2) * this.rowColNum;
+
+ //Get width
+ //FontMetrics metrics = g.getFontMetrics(tickFont);
+ ave = legendScheme.getBreakNum() / rowColNum;
+ if (ave * rowColNum < legendScheme.getBreakNum()) {
+ ave += 1;
+ }
+ num = 0;
+ int maxWidth = 0;
+ int tempWidth = 0;
+ for (i = 0; i < legendScheme.getBreakNum(); i++) {
+ if (num < ave) {
+ //tempWidth += this.symbolDimension.width + 15
+ // + metrics.stringWidth(legendScheme.getLegendBreaks().get(i).getCaption());
+ tempWidth += this.symbolDimension.width + 15
+ + Draw.getStringDimension(legendScheme.getLegendBreaks().get(i).getCaption(), g).width;
+ num += 1;
+ } else {
+ if (maxWidth < tempWidth) {
+ maxWidth = tempWidth;
+ }
+ //tempWidth = metrics.stringWidth(legendScheme.getLegendBreaks().get(i).getCaption()) + 15;
+ tempWidth = Draw.getStringDimension(legendScheme.getLegendBreaks().get(i).getCaption(), g).width;
+ num = 1;
+ }
+ }
+ if (maxWidth < tempWidth) {
+ maxWidth = tempWidth;
+ }
+ if (maxWidth > limitDim.width) {
+ maxWidth = limitDim.width * 8 / 10;
+ }
+ this.width = maxWidth;
+ break;
+ }
+ this.height += titleHeight;
+ this.width = Math.max(this.width, titleWidth);
+ }
+ }
+
+ return new Dimension(this.width, this.height);
+ }
+
+ protected int getTickWidth(Graphics2D g) {
+ float rwidth = 0;
+ String caption = "";
+ int bNum = this.legendScheme.getBreakNum();
+ //FontMetrics metrics = g.getFontMetrics(this.tickFont);
+ g.setFont(this.tickLabelFont);
+ if (this.legendScheme.getLegendBreaks().get(bNum - 1).isNoData()) {
+ bNum -= 1;
+ }
+ for (int i = 0; i < bNum; i++) {
+ switch (this.legendScheme.getShapeType()) {
+ case Point:
+ PointBreak aPB = (PointBreak) legendScheme.getLegendBreaks().get(i);
+ if (legendScheme.getLegendType() == LegendType.GraduatedColor) {
+ caption = DataConvert.removeTailingZeros(aPB.getEndValue().toString());
+ } else {
+ caption = aPB.getCaption();
+ }
+ break;
+ case Polyline:
+ PolylineBreak aPLB = (PolylineBreak) legendScheme.getLegendBreaks().get(i);
+ if (legendScheme.getLegendType() == LegendType.GraduatedColor) {
+ caption = DataConvert.removeTailingZeros(aPLB.getEndValue().toString());
+ } else {
+ caption = aPLB.getCaption();
+ }
+ break;
+ case Polygon:
+ PolygonBreak aPGB = (PolygonBreak) legendScheme.getLegendBreaks().get(i);
+ if (legendScheme.getLegendType() == LegendType.GraduatedColor) {
+ caption = DataConvert.removeTailingZeros(aPGB.getEndValue().toString());
+ } else {
+ caption = aPGB.getCaption();
+ }
+ break;
+ case Image:
+ ColorBreak aCB = legendScheme.getLegendBreaks().get(i);
+ if (legendScheme.getLegendType() == LegendType.GraduatedColor) {
+ caption = DataConvert.removeTailingZeros(aCB.getEndValue().toString());
+ } else {
+ caption = aCB.getCaption();
+ }
+ break;
+ }
+
+ boolean isValid = true;
+ switch (legendScheme.getLegendType()) {
+ case GraduatedColor:
+ if (i == bNum - 1) {
+ isValid = false;
+ }
+ break;
+ }
+ if (isValid) {
+ //float labwidth = metrics.stringWidth(caption);
+ float labwidth = (float) Draw.getStringDimension(caption, this.tickLabelAngle, g).getWidth();
+ if (rwidth < labwidth) {
+ rwidth = labwidth;
+ }
+ }
+ }
+
+ return (int) rwidth;
+ }
+
+ protected int getTickHeight(Graphics2D g) {
+ float rheight = 0;
+ String caption = "";
+ int bNum = this.legendScheme.getBreakNum();
+ //FontMetrics metrics = g.getFontMetrics(this.tickFont);
+ g.setFont(this.tickLabelFont);
+ if (this.legendScheme.getLegendBreaks().get(bNum - 1).isNoData()) {
+ bNum -= 1;
+ }
+ for (int i = 0; i < bNum; i++) {
+ switch (this.legendScheme.getShapeType()) {
+ case Point:
+ PointBreak aPB = (PointBreak) legendScheme.getLegendBreaks().get(i);
+ if (legendScheme.getLegendType() == LegendType.GraduatedColor) {
+ caption = DataConvert.removeTailingZeros(aPB.getEndValue().toString());
+ } else {
+ caption = aPB.getCaption();
+ }
+ break;
+ case Polyline:
+ PolylineBreak aPLB = (PolylineBreak) legendScheme.getLegendBreaks().get(i);
+ if (legendScheme.getLegendType() == LegendType.GraduatedColor) {
+ caption = DataConvert.removeTailingZeros(aPLB.getEndValue().toString());
+ } else {
+ caption = aPLB.getCaption();
+ }
+ break;
+ case Polygon:
+ PolygonBreak aPGB = (PolygonBreak) legendScheme.getLegendBreaks().get(i);
+ if (legendScheme.getLegendType() == LegendType.GraduatedColor) {
+ caption = DataConvert.removeTailingZeros(aPGB.getEndValue().toString());
+ } else {
+ caption = aPGB.getCaption();
+ }
+ break;
+ case Image:
+ ColorBreak aCB = legendScheme.getLegendBreaks().get(i);
+ if (legendScheme.getLegendType() == LegendType.GraduatedColor) {
+ caption = DataConvert.removeTailingZeros(aCB.getEndValue().toString());
+ } else {
+ caption = aCB.getCaption();
+ }
+ break;
+ }
+
+ boolean isValid = true;
+ switch (legendScheme.getLegendType()) {
+ case GraduatedColor:
+ if (i == bNum - 1) {
+ isValid = false;
+ }
+ break;
+ }
+ if (isValid) {
+ float labheight = (float) Draw.getStringDimension(caption, 90 - Math.abs(this.tickLabelAngle), g).getWidth();
+ if (rheight < labheight) {
+ rheight = labheight;
+ }
+ }
+ }
+
+ return (int) rheight;
+ }
+
+ /**
+ * Update tick gap
+ *
+ * @param g Graphics2D
+ * @return Ticks gap
+ */
+ protected int getTickGap(Graphics2D g) {
+ if (this.tickLabelAngle != 0) {
+ return 1;
+ }
+
+ double len;
+ int n = this.legendScheme.getBreakNum();
+ int nn;
+ if (this.orientation == PlotOrientation.HORIZONTAL) {
+ len = this.width;
+ int labLen = this.getTickWidth(g);
+ nn = (int) ((len * 0.8) / labLen);
+ } else {
+ len = this.height;
+ FontMetrics metrics = g.getFontMetrics(tickLabelFont);
+ nn = (int) (len / metrics.getHeight());
+ }
+ if (nn == 0) {
+ nn = 1;
+ }
+ return n / nn + 1;
+ }
+
+ //
+ //
+ public class LayoutLegendBean {
+
+ LayoutLegendBean() {
+ }
+
+ //
+ /**
+ * Get if draw neat line
+ *
+ * @return If draw neat line
+ */
+ public boolean isDrawNeatLine() {
+ return drawNeatLine;
+ }
+
+ /**
+ * Set if draw neat line
+ *
+ * @param istrue If draw neat line
+ */
+ public void setDrawNeatLine(boolean istrue) {
+ drawNeatLine = istrue;
+ }
+
+ /**
+ * Get neat line color
+ *
+ * @return Neat line color
+ */
+ public Color getNeatLineColor() {
+ return neatLineColor;
+ }
+
+ /**
+ * Set neat line color
+ *
+ * @param color Neat line color
+ */
+ public void setNeatLineColor(Color color) {
+ neatLineColor = color;
+ }
+
+ /**
+ * Get neat line size
+ *
+ * @return Neat line size
+ */
+ public float getNeatLineSize() {
+ return neatLineSize;
+ }
+
+ /**
+ * Set neat line size
+ *
+ * @param size Neat line size
+ */
+ public void setNeatLineSize(float size) {
+ neatLineSize = size;
+ }
+
+ /**
+ * Get tick label font
+ *
+ * @return The tick label font
+ */
+ public Font getTickLabelFont() {
+ return tickLabelFont;
+ }
+
+ /**
+ * Set tick label font
+ *
+ * @param font The tick label font
+ */
+ public void setTickLabelFont(Font font) {
+ tickLabelFont = font;
+ }
+
+ /**
+ * Get column number
+ *
+ * @return Column number
+ */
+ public int getColumnNumber() {
+ return rowColNum;
+ }
+
+ /**
+ * Set column number
+ *
+ * @param value Column number
+ */
+ public void setColumnNumber(int value) {
+ rowColNum = value;
+ }
+
+ /**
+ * Get is draw background
+ *
+ * @return Boolean
+ */
+ public boolean isDrawBackground() {
+ return drawBackground;
+ }
+
+ /**
+ * Set is draw background
+ *
+ * @param value Boolean
+ */
+ public void setDrawBackground(boolean value) {
+ drawBackground = value;
+ }
+
+ /**
+ * Get background color
+ *
+ * @return Background color
+ */
+ public Color getBackground() {
+ return background;
+ }
+
+ /**
+ * Set background color
+ *
+ * @param c Background color
+ */
+ public void setBackground(Color c) {
+ background = c;
+ }
+
+ //
+ }
+
+ public static class LayoutLegendBeanBeanInfo extends BaseBeanInfo {
+
+ public LayoutLegendBeanBeanInfo() {
+ super(LayoutLegendBean.class);
+ ExtendedPropertyDescriptor e = addProperty("plotOrientation");
+ e.setCategory("General").setDisplayName("Plot orientation");
+ e.setPropertyEditorClass(PlotOrientationEditor.class);
+ addProperty("tickFont").setCategory("General").setDisplayName("Tick Font");
+ addProperty("drawBackground").setCategory("General").setDisplayName("Draw Background");
+ addProperty("background").setCategory("General").setDisplayName("Background");
+ addProperty("columnNumber").setCategory("General").setDisplayName("Column Number");
+ addProperty("drawNeatLine").setCategory("Neat Line").setDisplayName("Draw Neat Line");
+ addProperty("neatLineColor").setCategory("Neat Line").setDisplayName("Neat Line Color");
+ addProperty("neatLineSize").setCategory("Neat Line").setDisplayName("Neat Line Size");
+ }
+ }
+
+ public static class PlotOrientationEditor extends ComboBoxPropertyEditor {
+
+ public PlotOrientationEditor() {
+ super();
+ PlotOrientation[] orientations = PlotOrientation.values();
+ String[] types = new String[orientations.length];
+ int i = 0;
+ for (PlotOrientation type : orientations) {
+ types[i] = type.toString();
+ i += 1;
+ }
+ setAvailableValues(types);
+ }
+ }
+
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/ChartNorthArrow.java b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/ChartNorthArrow.java
index a2ebf0eb..a6e9813f 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/ChartNorthArrow.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/ChartNorthArrow.java
@@ -1,298 +1,298 @@
-/* Copyright 2012 Yaqiang Wang,
- * yaqiang.wang@gmail.com
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.chart;
-
-import com.l2fprod.common.beans.BaseBeanInfo;
-import org.meteoinfo.drawing.Draw;
-import org.meteoinfo.global.PointF;
-import java.awt.BasicStroke;
-import java.awt.Color;
-import java.awt.Graphics2D;
-import java.awt.Rectangle;
-import java.awt.RenderingHints;
-import java.awt.geom.AffineTransform;
-import org.meteoinfo.chart.plot.MapPlot;
-import org.meteoinfo.layout.NorthArrowType;
-
-/**
- *
- * @author Yaqiang Wang
- */
-public class ChartNorthArrow extends ChartElement {
-//
-
- private MapPlot mapPlot;
- private boolean _antiAlias;
- private float lineWidth;
- private boolean _drawNeatLine;
- private Color _neatLineColor;
- private float _neatLineSize;
- private NorthArrowType _northArrowType;
- private float _angle;
- //
- //
-
- /**
- * Constructor
- *
- * @param mapPlot The map plot
- */
- public ChartNorthArrow(MapPlot mapPlot) {
- super();
-
- this.setWidth(50);
- this.setHeight(50);
-
- this.mapPlot = mapPlot;
- this.lineWidth = 1;
- _antiAlias = true;
- _drawNeatLine = false;
- _neatLineColor = Color.black;
- _neatLineSize = 1;
- _northArrowType = NorthArrowType.NORTHARROW_1;
- _angle = 0;
- }
- //
- //
-
- /**
- * Get map plot
- *
- * @return The map plot
- */
- public MapPlot getMapPlot() {
- return this.mapPlot;
- }
-
- /**
- * Get line widht
- * @return Line width
- */
- public float getLineWidth() {
- return this.lineWidth;
- }
-
- /**
- * Set line width
- * @param value Line width
- */
- public void setLineWidth(float value) {
- this.lineWidth = value;
- }
-
- /**
- * Get if draw neat line
- *
- * @return If draw neat line
- */
- public boolean isDrawNeatLine() {
- return _drawNeatLine;
- }
-
- /**
- * Set if draw neat line
- *
- * @param istrue If draw neat line
- */
- public void setDrawNeatLine(boolean istrue) {
- _drawNeatLine = istrue;
- }
-
- /**
- * Get neat line color
- *
- * @return Neat line color
- */
- public Color getNeatLineColor() {
- return _neatLineColor;
- }
-
- /**
- * Set neat line color
- *
- * @param color Neat line color
- */
- public void setNeatLineColor(Color color) {
- _neatLineColor = color;
- }
-
- /**
- * Get neat line size
- *
- * @return Neat line size
- */
- public float getNeatLineSize() {
- return _neatLineSize;
- }
-
- /**
- * Set neat line size
- *
- * @param size Neat line size
- */
- public void setNeatLineSize(float size) {
- _neatLineSize = size;
- }
-
- /**
- * Get angle
- *
- * @return Angle
- */
- public float getAngle() {
- return _angle;
- }
-
- /**
- * Set angle
- *
- * @param angle The angle
- */
- public void setAngle(float angle) {
- _angle = angle;
- }
-
- //
- //
- /**
- * Draw text
- *
- * @param g Graphics2D
- * @param x X
- * @param y Y
- */
- public void draw(Graphics2D g, float x, float y) {
- AffineTransform oldMatrix = g.getTransform();
- g.translate(x, y);
- if (_angle != 0) {
- g.rotate(_angle);
- }
- if (_antiAlias) {
- g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
- } else {
- g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
- }
-
- //Draw background color
- if (this.isDrawBackColor()){
- g.setColor(this.getBackground());
- g.fill(new Rectangle.Float(0, 0, this.getWidth(), this.getHeight()));
- }
-
- drawNorthArrow(g);
-
- //Draw neatline
- if (_drawNeatLine) {
- Rectangle.Float mapRect = new Rectangle.Float(_neatLineSize - 1, _neatLineSize - 1,
- (this.getWidth() - _neatLineSize), (this.getHeight() - _neatLineSize));
- g.setColor(_neatLineColor);
- g.setStroke(new BasicStroke(_neatLineSize));
- g.draw(mapRect);
- }
-
- g.setTransform(oldMatrix);
- }
-
- /**
- * Paint graphics
- *
- * @param g Graphics
- * @param pageLocation Page location
- * @param zoom Zoom
- */
- public void paintGraphics(Graphics2D g, PointF pageLocation, float zoom) {
- AffineTransform oldMatrix = g.getTransform();
- PointF aP = pageToScreen(this.getX(), this.getY(), pageLocation, zoom);
- g.translate(aP.X, aP.Y);
- g.scale(zoom, zoom);
- if (_angle != 0) {
- g.rotate(_angle);
- }
- if (_antiAlias) {
- g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
- } else {
- g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
- }
-
- //Draw background color
- if (this.isDrawBackColor()){
- g.setColor(this.getBackground());
- g.fill(new Rectangle.Float(0, 0, this.getWidth() * zoom, this.getHeight() * zoom));
- }
-
- drawNorthArrow(g);
-
- //Draw neatline
- if (_drawNeatLine) {
- Rectangle.Float mapRect = new Rectangle.Float(_neatLineSize - 1, _neatLineSize - 1,
- (this.getWidth() - _neatLineSize) * zoom, (this.getHeight() - _neatLineSize) * zoom);
- g.setColor(_neatLineColor);
- g.setStroke(new BasicStroke(_neatLineSize));
- g.draw(mapRect);
- }
-
- g.setTransform(oldMatrix);
- }
-
- private void drawNorthArrow(Graphics2D g) {
- switch (_northArrowType) {
- case NORTHARROW_1:
- drawNorthArrow1(g);
- break;
- }
- }
-
- private void drawNorthArrow1(Graphics2D g) {
- g.setColor(this.getForeground());
- g.setStroke(new BasicStroke(this.lineWidth));
-
- //Draw N symbol
- PointF[] points = new PointF[4];
- float x = this.getWidth() / 2;
- float y = this.getHeight() / 6;
- float w = this.getWidth() / 6;
- float h = this.getHeight() / 4;
- points[0] = new PointF(x - w / 2, y + h / 2);
- points[1] = new PointF(x - w / 2, y - h / 2);
- points[2] = new PointF(x + w / 2, y + h / 2);
- points[3] = new PointF(x + w / 2, y - h / 2);
- Draw.drawPolyline(points, g);
-
- //Draw arrow
- w = this.getWidth() / 2;
- h = this.getHeight() * 2 / 3;
- points = new PointF[3];
- points[0] = new PointF(x - w / 2, this.getHeight());
- points[1] = new PointF(x, this.getHeight() - h / 2);
- points[2] = new PointF(x, this.getHeight() - h);
- Draw.fillPolygon(points, g, null);
- Draw.drawPolyline(points, g);
-
- points = new PointF[4];
- points[0] = new PointF(x + w / 2, this.getHeight());
- points[1] = new PointF(x, this.getHeight() - h / 2);
- points[2] = new PointF(x, this.getHeight() - h);
- points[3] = points[0];
- Draw.drawPolyline(points, g);
- }
-
- @Override
- public void moveUpdate() {
- }
-
- @Override
- public void resizeUpdate() {
- }
- //
-}
+/* Copyright 2012 Yaqiang Wang,
+ * yaqiang.wang@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ */
+package org.meteoinfo.chart;
+
+import org.meteoinfo.common.PointF;
+import org.meteoinfo.drawing.Draw;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.geom.AffineTransform;
+import org.meteoinfo.chart.plot.MapPlot;
+import org.meteoinfo.layout.NorthArrowType;
+
+/**
+ *
+ * @author Yaqiang Wang
+ */
+public class ChartNorthArrow extends ChartElement {
+//
+
+ private MapPlot mapPlot;
+ private boolean _antiAlias;
+ private float lineWidth;
+ private boolean _drawNeatLine;
+ private Color _neatLineColor;
+ private float _neatLineSize;
+ private NorthArrowType _northArrowType;
+ private float _angle;
+ //
+ //
+
+ /**
+ * Constructor
+ *
+ * @param mapPlot The map plot
+ */
+ public ChartNorthArrow(MapPlot mapPlot) {
+ super();
+
+ this.setWidth(50);
+ this.setHeight(50);
+
+ this.mapPlot = mapPlot;
+ this.lineWidth = 1;
+ _antiAlias = true;
+ _drawNeatLine = false;
+ _neatLineColor = Color.black;
+ _neatLineSize = 1;
+ _northArrowType = NorthArrowType.NORTHARROW_1;
+ _angle = 0;
+ }
+ //
+ //
+
+ /**
+ * Get map plot
+ *
+ * @return The map plot
+ */
+ public MapPlot getMapPlot() {
+ return this.mapPlot;
+ }
+
+ /**
+ * Get line widht
+ * @return Line width
+ */
+ public float getLineWidth() {
+ return this.lineWidth;
+ }
+
+ /**
+ * Set line width
+ * @param value Line width
+ */
+ public void setLineWidth(float value) {
+ this.lineWidth = value;
+ }
+
+ /**
+ * Get if draw neat line
+ *
+ * @return If draw neat line
+ */
+ public boolean isDrawNeatLine() {
+ return _drawNeatLine;
+ }
+
+ /**
+ * Set if draw neat line
+ *
+ * @param istrue If draw neat line
+ */
+ public void setDrawNeatLine(boolean istrue) {
+ _drawNeatLine = istrue;
+ }
+
+ /**
+ * Get neat line color
+ *
+ * @return Neat line color
+ */
+ public Color getNeatLineColor() {
+ return _neatLineColor;
+ }
+
+ /**
+ * Set neat line color
+ *
+ * @param color Neat line color
+ */
+ public void setNeatLineColor(Color color) {
+ _neatLineColor = color;
+ }
+
+ /**
+ * Get neat line size
+ *
+ * @return Neat line size
+ */
+ public float getNeatLineSize() {
+ return _neatLineSize;
+ }
+
+ /**
+ * Set neat line size
+ *
+ * @param size Neat line size
+ */
+ public void setNeatLineSize(float size) {
+ _neatLineSize = size;
+ }
+
+ /**
+ * Get angle
+ *
+ * @return Angle
+ */
+ public float getAngle() {
+ return _angle;
+ }
+
+ /**
+ * Set angle
+ *
+ * @param angle The angle
+ */
+ public void setAngle(float angle) {
+ _angle = angle;
+ }
+
+ //
+ //
+ /**
+ * Draw text
+ *
+ * @param g Graphics2D
+ * @param x X
+ * @param y Y
+ */
+ public void draw(Graphics2D g, float x, float y) {
+ AffineTransform oldMatrix = g.getTransform();
+ g.translate(x, y);
+ if (_angle != 0) {
+ g.rotate(_angle);
+ }
+ if (_antiAlias) {
+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ } else {
+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
+ }
+
+ //Draw background color
+ if (this.isDrawBackColor()){
+ g.setColor(this.getBackground());
+ g.fill(new Rectangle.Float(0, 0, this.getWidth(), this.getHeight()));
+ }
+
+ drawNorthArrow(g);
+
+ //Draw neatline
+ if (_drawNeatLine) {
+ Rectangle.Float mapRect = new Rectangle.Float(_neatLineSize - 1, _neatLineSize - 1,
+ (this.getWidth() - _neatLineSize), (this.getHeight() - _neatLineSize));
+ g.setColor(_neatLineColor);
+ g.setStroke(new BasicStroke(_neatLineSize));
+ g.draw(mapRect);
+ }
+
+ g.setTransform(oldMatrix);
+ }
+
+ /**
+ * Paint graphics
+ *
+ * @param g Graphics
+ * @param pageLocation Page location
+ * @param zoom Zoom
+ */
+ public void paintGraphics(Graphics2D g, PointF pageLocation, float zoom) {
+ AffineTransform oldMatrix = g.getTransform();
+ PointF aP = pageToScreen(this.getX(), this.getY(), pageLocation, zoom);
+ g.translate(aP.X, aP.Y);
+ g.scale(zoom, zoom);
+ if (_angle != 0) {
+ g.rotate(_angle);
+ }
+ if (_antiAlias) {
+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ } else {
+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
+ }
+
+ //Draw background color
+ if (this.isDrawBackColor()){
+ g.setColor(this.getBackground());
+ g.fill(new Rectangle.Float(0, 0, this.getWidth() * zoom, this.getHeight() * zoom));
+ }
+
+ drawNorthArrow(g);
+
+ //Draw neatline
+ if (_drawNeatLine) {
+ Rectangle.Float mapRect = new Rectangle.Float(_neatLineSize - 1, _neatLineSize - 1,
+ (this.getWidth() - _neatLineSize) * zoom, (this.getHeight() - _neatLineSize) * zoom);
+ g.setColor(_neatLineColor);
+ g.setStroke(new BasicStroke(_neatLineSize));
+ g.draw(mapRect);
+ }
+
+ g.setTransform(oldMatrix);
+ }
+
+ private void drawNorthArrow(Graphics2D g) {
+ switch (_northArrowType) {
+ case NORTHARROW_1:
+ drawNorthArrow1(g);
+ break;
+ }
+ }
+
+ private void drawNorthArrow1(Graphics2D g) {
+ g.setColor(this.getForeground());
+ g.setStroke(new BasicStroke(this.lineWidth));
+
+ //Draw N symbol
+ PointF[] points = new PointF[4];
+ float x = this.getWidth() / 2;
+ float y = this.getHeight() / 6;
+ float w = this.getWidth() / 6;
+ float h = this.getHeight() / 4;
+ points[0] = new PointF(x - w / 2, y + h / 2);
+ points[1] = new PointF(x - w / 2, y - h / 2);
+ points[2] = new PointF(x + w / 2, y + h / 2);
+ points[3] = new PointF(x + w / 2, y - h / 2);
+ Draw.drawPolyline(points, g);
+
+ //Draw arrow
+ w = this.getWidth() / 2;
+ h = this.getHeight() * 2 / 3;
+ points = new PointF[3];
+ points[0] = new PointF(x - w / 2, this.getHeight());
+ points[1] = new PointF(x, this.getHeight() - h / 2);
+ points[2] = new PointF(x, this.getHeight() - h);
+ Draw.fillPolygon(points, g, null);
+ Draw.drawPolyline(points, g);
+
+ points = new PointF[4];
+ points[0] = new PointF(x + w / 2, this.getHeight());
+ points[1] = new PointF(x, this.getHeight() - h / 2);
+ points[2] = new PointF(x, this.getHeight() - h);
+ points[3] = points[0];
+ Draw.drawPolyline(points, g);
+ }
+
+ @Override
+ public void moveUpdate() {
+ }
+
+ @Override
+ public void resizeUpdate() {
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/ChartPanel.java b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/ChartPanel.java
index 91344501..0be014f6 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/ChartPanel.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/ChartPanel.java
@@ -81,11 +81,11 @@ import org.meteoinfo.chart.plot.AbstractPlot2D;
import org.meteoinfo.chart.plot.Plot3D;
import org.meteoinfo.chart.plot.PlotType;
import org.meteoinfo.chart.plot3d.Projector;
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.GenericFileFilter;
+import org.meteoinfo.common.PointF;
import org.meteoinfo.ndarray.DataType;
import org.meteoinfo.data.mapdata.Field;
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.global.GenericFileFilter;
-import org.meteoinfo.global.PointF;
import org.meteoinfo.image.ImageUtil;
import org.meteoinfo.layer.LayerTypes;
import org.meteoinfo.layer.MapLayer;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/ChartScaleBar.java b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/ChartScaleBar.java
index a191471e..4e813f5d 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/ChartScaleBar.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/ChartScaleBar.java
@@ -1,457 +1,457 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.meteoinfo.chart;
-
-import java.awt.BasicStroke;
-import java.awt.Color;
-import java.awt.Font;
-import java.awt.FontMetrics;
-import java.awt.Graphics2D;
-import java.awt.Rectangle;
-import java.awt.RenderingHints;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Line2D;
-import org.meteoinfo.chart.plot.MapPlot;
-import org.meteoinfo.global.PointF;
-import org.meteoinfo.layout.ScaleBarType;
-import org.meteoinfo.layout.ScaleBarUnits;
-
-/**
- *
- * @author Yaqiang Wang
- */
-public class ChartScaleBar extends ChartElement {
- //
-
- private MapPlot mapPlot;
- private boolean _antiAlias;
- private float lineWidth;
- private Font _font;
- private ScaleBarType _scaleBarType;
- private ScaleBarUnits _unit;
- private String _unitText;
- private int _numBreaks;
- private boolean _drawNeatLine;
- private Color _neatLineColor;
- private float _neatLineSize;
- private boolean _drawScaleText;
- private float _yShiftScale = 2.0f;
- //
- //
-
- /**
- * Constructor
- *
- * @param mapPlot The map plot
- */
- public ChartScaleBar(MapPlot mapPlot) {
- super();
- //this.setElementType(ElementType.LayoutScaleBar);
- //this.setResizeAbility(ResizeAbility.ResizeAll);
-
- this.width = 200;
- this.height = 50;
- this.mapPlot = mapPlot;
- _antiAlias = true;
- _scaleBarType = ScaleBarType.SCALELINE_1;
- lineWidth = 1;
- _drawNeatLine = false;
- _neatLineColor = Color.black;
- _neatLineSize = 1;
- _font = new Font("Arial", Font.PLAIN, 12);
- _unit = ScaleBarUnits.KILOMETERS;
- _unitText = "km";
- _numBreaks = 4;
- _drawScaleText = false;
- }
- //
- //
-
- /**
- * Get map plot
- *
- * @return The map plot
- */
- public MapPlot getMapPlot() {
- return mapPlot;
- }
-
- /**
- * Get line widht
- * @return Line width
- */
- public float getLineWidth() {
- return this.lineWidth;
- }
-
- /**
- * Set line width
- * @param value Line width
- */
- public void setLineWidth(float value) {
- this.lineWidth = value;
- }
-
- /**
- * Get scale bar type
- *
- * @return Scale bar type
- */
- public ScaleBarType getScaleBarType() {
- return _scaleBarType;
- }
-
- /**
- * Set scale bar type
- *
- * @param type Scale bar type
- */
- public void setScaleBarType(ScaleBarType type) {
- _scaleBarType = type;
- }
-
- /**
- * Get if draw neat line
- *
- * @return If draw neat line
- */
- public boolean isDrawNeatLine() {
- return _drawNeatLine;
- }
-
- /**
- * Set if draw neat line
- *
- * @param istrue If draw neat line
- */
- public void setDrawNeatLine(boolean istrue) {
- _drawNeatLine = istrue;
- }
-
- /**
- * Get neat line color
- *
- * @return Neat line color
- */
- public Color getNeatLineColor() {
- return _neatLineColor;
- }
-
- /**
- * Set neat line color
- *
- * @param color Neat line color
- */
- public void setNeatLineColor(Color color) {
- _neatLineColor = color;
- }
-
- /**
- * Get neat line size
- *
- * @return Neat line size
- */
- public float getNeatLineSize() {
- return _neatLineSize;
- }
-
- /**
- * Set neat line size
- *
- * @param size Neat line size
- */
- public void setNeatLineSize(float size) {
- _neatLineSize = size;
- }
-
- /**
- * Get font
- *
- * @return The font
- */
- public Font getFont() {
- return _font;
- }
-
- /**
- * Set font
- *
- * @param font The font
- */
- public void setFont(Font font) {
- _font = font;
- }
-
- /**
- * Get break number
- *
- * @return The break number
- */
- public int getBreakNumber() {
- return _numBreaks;
- }
-
- /**
- * Set break number
- *
- * @param num Break number
- */
- public void setBreakNumber(int num) {
- _numBreaks = num;
- }
-
- /**
- * Get if draw scale text
- *
- * @return If draw scale text
- */
- public boolean isDrawScaleText() {
- return _drawScaleText;
- }
-
- /**
- * Set if draw scale text
- *
- * @param istrue If draw scale text
- */
- public void setDrawScaleText(boolean istrue) {
- _drawScaleText = istrue;
- }
- //
- //
- /**
- * Draw text
- *
- * @param g Graphics2D
- * @param x X
- * @param y Y
- */
- public void draw(Graphics2D g, float x, float y) {
- AffineTransform oldMatrix = g.getTransform();
- g.translate(x, y);
- if (_antiAlias) {
- g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
- } else {
- g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
- }
-
- //Draw background color
- if (this.isDrawBackColor()){
- g.setColor(this.getBackground());
- g.fill(new Rectangle.Float(0, 0, this.getWidth(), this.getHeight()));
- }
-
- drawScaleBar(g);
-
- //Draw neatline
- if (_drawNeatLine) {
- Rectangle.Float mapRect = new Rectangle.Float(_neatLineSize - 1, _neatLineSize - 1,
- (this.getWidth() - _neatLineSize), (this.getHeight() - _neatLineSize));
- g.setColor(_neatLineColor);
- g.setStroke(new BasicStroke(_neatLineSize));
- g.draw(mapRect);
- }
-
- g.setTransform(oldMatrix);
- }
-
- /**
- * Paint graphics
- *
- * @param g Graphics
- * @param pageLocation Page location
- * @param zoom Zoom
- */
- public void paintGraphics(Graphics2D g, PointF pageLocation) {
- AffineTransform oldMatrix = g.getTransform();
- PointF aP = pageToScreen(this.getX(), this.getY(), pageLocation, 1);
- g.translate(aP.X, aP.Y);
- if (_antiAlias) {
- g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
- } else {
- g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
- }
-
- //Draw background color
- if (this.isDrawBackColor()){
- g.setColor(this.getBackground());
- g.fill(new Rectangle.Float(0, 0, this.getWidth(), this.getHeight()));
- }
-
- drawScaleBar(g);
-
- //Draw neatline
- if (_drawNeatLine) {
- Rectangle.Float mapRect = new Rectangle.Float(_neatLineSize - 1, _neatLineSize - 1,
- (this.getWidth() - _neatLineSize), (this.getHeight() - _neatLineSize));
- g.setColor(_neatLineColor);
- g.setStroke(new BasicStroke(_neatLineSize));
- g.draw(mapRect);
- }
-
- g.setTransform(oldMatrix);
- }
-
- private void drawScaleBar(Graphics2D g) {
- //Calculates the width of one break in greographic units
- FontMetrics metrics = g.getFontMetrics(this._font);
- float unitLegnth = metrics.stringWidth(_unitText) * 2;
- float widthNoUnit = (this.getWidth() - unitLegnth);
- long geoBreakWidth = (long) (getGeoWidth(widthNoUnit / _numBreaks));
-
- //If the geobreakWidth is less than 1 we return and don't draw anything
- if (geoBreakWidth < 1) {
- return;
- }
-
- double n = Math.pow(10, String.valueOf(geoBreakWidth).length() - 1);
- geoBreakWidth = (long) (Math.floor(geoBreakWidth / n) * n);
-
- long breakWidth = (long) (getWidth(geoBreakWidth));
- FontMetrics metrics1 = g.getFontMetrics(_font);
- float fontHeight = metrics1.getHeight();
- float leftStart = metrics1.stringWidth(String.valueOf(Math.abs(geoBreakWidth))) / 2F;
-
- //Draw scale text
- double scale = geoBreakWidth * getConversionFactor(_unit) * 100 / (breakWidth / 96 * 2.539999918);
- if (_drawScaleText) {
- g.setFont(this._font);
- g.setColor(this.getForeground());
- g.drawString("1 : " + String.format("{0:0,0}", scale),
- leftStart - (metrics.stringWidth(String.valueOf(Math.abs(0))) / 2), fontHeight * 2.5F);
- }
-
- //Draw scale bar
- switch (_scaleBarType) {
- case SCALELINE_1:
- drawScaleLine1(g, breakWidth, geoBreakWidth);
- break;
- case SCALELINE_2:
- drawScaleLine2(g, breakWidth, geoBreakWidth);
- break;
- case ALTERNATING_BAR:
- drawAlternatingBar(g, breakWidth, geoBreakWidth);
- break;
- }
- }
-
- private double getConversionFactor(ScaleBarUnits unit) {
- switch (unit) {
- case KILOMETERS:
- return 1000;
- default:
- return 1;
- }
- }
-
- private double getGeoWidth(double width) {
- double geoWidth = width / mapPlot.getMapFrame().getMapView().getXScale() / getConversionFactor(_unit);
- if (mapPlot.getMapFrame().getMapView().getProjection().isLonLatMap()) {
- geoWidth = geoWidth * getLonDistScale();
- }
-
- return geoWidth;
- }
-
- private double getWidth(double geoWidth) {
- double width = geoWidth * mapPlot.getMapFrame().getMapView().getXScale() * getConversionFactor(_unit);
- if (mapPlot.getMapFrame().getMapView().getProjection().isLonLatMap()) {
- width = width / getLonDistScale();
- }
-
- return width;
- }
-
- private double getLonDistScale() {
- //Get meters of one longitude degree
- double pY = (mapPlot.getMapFrame().getMapView().getViewExtent().maxY + mapPlot.getMapFrame().getMapView().getViewExtent().minY) / 2;
- double ProjX = 0, ProjY = pY, pProjX = 1, pProjY = pY;
- double dx = Math.abs(ProjX - pProjX);
- double dy = Math.abs(ProjY - pProjY);
- double dist;
- double y = (ProjY + pProjY) / 2;
- double factor = Math.cos(y * Math.PI / 180);
- dx *= factor;
- dist = Math.sqrt(dx * dx + dy * dy);
- dist = dist * 111319.5;
-
- return dist;
- }
-
- private void drawScaleLine1(Graphics2D g, long breakWidth, long geoBreakWidth) {
- FontMetrics metrics = g.getFontMetrics(_font);
- float fontHeight = metrics.getHeight();
- float leftStart = metrics.stringWidth(String.valueOf(Math.abs(geoBreakWidth))) / 2F;
- int yShift = 10;
-
- g.setColor(this.getForeground());
- g.setStroke(new BasicStroke(this.lineWidth));
- g.draw(new Line2D.Float(leftStart, fontHeight * 1.6f + yShift, leftStart + (breakWidth * _numBreaks), fontHeight * 1.6f + yShift));
- g.setFont(this._font);
- for (int i = 0; i <= _numBreaks; i++) {
- g.draw(new Line2D.Float(leftStart, fontHeight * 1.1f + yShift, leftStart, fontHeight * 1.6f + yShift));
- g.drawString(String.valueOf(Math.abs(geoBreakWidth * i)),
- leftStart - (metrics.stringWidth(String.valueOf(Math.abs(geoBreakWidth * i))) / 2), yShift * _yShiftScale);
- leftStart = leftStart + breakWidth;
- }
- g.drawString(_unitText, leftStart - breakWidth + (fontHeight / 2), fontHeight * 1.1f + yShift * _yShiftScale);
- }
-
- private void drawScaleLine2(Graphics2D g, long breakWidth, long geoBreakWidth) {
- FontMetrics metrics = g.getFontMetrics(_font);
- float fontHeight = metrics.getHeight();
- float leftStart = metrics.stringWidth(String.valueOf(Math.abs(geoBreakWidth))) / 2F;
- int yShift = 5;
-
- g.setColor(this.getForeground());
- g.setStroke(new BasicStroke(this.lineWidth));
- g.draw(new Line2D.Float(leftStart, fontHeight * 1.6f + yShift, leftStart + (breakWidth * _numBreaks), fontHeight * 1.6f + yShift));
- g.setFont(this._font);
- for (int i = 0; i <= _numBreaks; i++) {
- g.draw(new Line2D.Float(leftStart, fontHeight * 1.1f + yShift, leftStart, fontHeight + (fontHeight * 1.1f) + yShift));
- g.drawString(String.valueOf(Math.abs(geoBreakWidth * i)),
- leftStart - (metrics.stringWidth(String.valueOf(Math.abs(geoBreakWidth * i))) / 2), yShift * _yShiftScale);
- leftStart = leftStart + breakWidth;
- }
- g.drawString(_unitText, leftStart - breakWidth + (fontHeight / 2), fontHeight * 1.1f + yShift * _yShiftScale);
- }
-
- private void drawAlternatingBar(Graphics2D g, long breakWidth, long geoBreakWidth) {
- FontMetrics metrics = g.getFontMetrics(_font);
- float fontHeight = metrics.getHeight();
- float leftStart = metrics.stringWidth(String.valueOf(Math.abs(geoBreakWidth))) / 2F;
- int yShift = 5;
- float rHeight = fontHeight / 2;
-
- boolean isFill = false;
- g.setStroke(new BasicStroke(this.lineWidth));
- g.setColor(this.getForeground());
- g.setFont(this._font);
- for (int i = 0; i <= _numBreaks; i++) {
- if (i < _numBreaks) {
- if (isFill) {
- g.fill(new Rectangle.Float(leftStart, fontHeight * 1.1f + yShift, breakWidth, rHeight));
- }
- g.draw(new Rectangle.Float(leftStart, fontHeight * 1.1f + yShift, breakWidth, rHeight));
- }
- g.drawString(String.valueOf(Math.abs(geoBreakWidth * i)),
- leftStart - (metrics.stringWidth(String.valueOf(Math.abs(geoBreakWidth * i))) / 2), yShift * _yShiftScale);
- leftStart = leftStart + breakWidth;
- isFill = !isFill;
- }
- g.setColor(this.getForeground());
- g.drawString(_unitText, leftStart - breakWidth + (fontHeight / 2), fontHeight * 1.1f + yShift * _yShiftScale);
- }
-
- @Override
- public void moveUpdate() {
- }
-
- @Override
- public void resizeUpdate() {
- }
- //
-}
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.meteoinfo.chart;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Line2D;
+import org.meteoinfo.chart.plot.MapPlot;
+import org.meteoinfo.common.PointF;
+import org.meteoinfo.layout.ScaleBarType;
+import org.meteoinfo.layout.ScaleBarUnits;
+
+/**
+ *
+ * @author Yaqiang Wang
+ */
+public class ChartScaleBar extends ChartElement {
+ //
+
+ private MapPlot mapPlot;
+ private boolean _antiAlias;
+ private float lineWidth;
+ private Font _font;
+ private ScaleBarType _scaleBarType;
+ private ScaleBarUnits _unit;
+ private String _unitText;
+ private int _numBreaks;
+ private boolean _drawNeatLine;
+ private Color _neatLineColor;
+ private float _neatLineSize;
+ private boolean _drawScaleText;
+ private float _yShiftScale = 2.0f;
+ //
+ //
+
+ /**
+ * Constructor
+ *
+ * @param mapPlot The map plot
+ */
+ public ChartScaleBar(MapPlot mapPlot) {
+ super();
+ //this.setElementType(ElementType.LayoutScaleBar);
+ //this.setResizeAbility(ResizeAbility.ResizeAll);
+
+ this.width = 200;
+ this.height = 50;
+ this.mapPlot = mapPlot;
+ _antiAlias = true;
+ _scaleBarType = ScaleBarType.SCALELINE_1;
+ lineWidth = 1;
+ _drawNeatLine = false;
+ _neatLineColor = Color.black;
+ _neatLineSize = 1;
+ _font = new Font("Arial", Font.PLAIN, 12);
+ _unit = ScaleBarUnits.KILOMETERS;
+ _unitText = "km";
+ _numBreaks = 4;
+ _drawScaleText = false;
+ }
+ //
+ //
+
+ /**
+ * Get map plot
+ *
+ * @return The map plot
+ */
+ public MapPlot getMapPlot() {
+ return mapPlot;
+ }
+
+ /**
+ * Get line widht
+ * @return Line width
+ */
+ public float getLineWidth() {
+ return this.lineWidth;
+ }
+
+ /**
+ * Set line width
+ * @param value Line width
+ */
+ public void setLineWidth(float value) {
+ this.lineWidth = value;
+ }
+
+ /**
+ * Get scale bar type
+ *
+ * @return Scale bar type
+ */
+ public ScaleBarType getScaleBarType() {
+ return _scaleBarType;
+ }
+
+ /**
+ * Set scale bar type
+ *
+ * @param type Scale bar type
+ */
+ public void setScaleBarType(ScaleBarType type) {
+ _scaleBarType = type;
+ }
+
+ /**
+ * Get if draw neat line
+ *
+ * @return If draw neat line
+ */
+ public boolean isDrawNeatLine() {
+ return _drawNeatLine;
+ }
+
+ /**
+ * Set if draw neat line
+ *
+ * @param istrue If draw neat line
+ */
+ public void setDrawNeatLine(boolean istrue) {
+ _drawNeatLine = istrue;
+ }
+
+ /**
+ * Get neat line color
+ *
+ * @return Neat line color
+ */
+ public Color getNeatLineColor() {
+ return _neatLineColor;
+ }
+
+ /**
+ * Set neat line color
+ *
+ * @param color Neat line color
+ */
+ public void setNeatLineColor(Color color) {
+ _neatLineColor = color;
+ }
+
+ /**
+ * Get neat line size
+ *
+ * @return Neat line size
+ */
+ public float getNeatLineSize() {
+ return _neatLineSize;
+ }
+
+ /**
+ * Set neat line size
+ *
+ * @param size Neat line size
+ */
+ public void setNeatLineSize(float size) {
+ _neatLineSize = size;
+ }
+
+ /**
+ * Get font
+ *
+ * @return The font
+ */
+ public Font getFont() {
+ return _font;
+ }
+
+ /**
+ * Set font
+ *
+ * @param font The font
+ */
+ public void setFont(Font font) {
+ _font = font;
+ }
+
+ /**
+ * Get break number
+ *
+ * @return The break number
+ */
+ public int getBreakNumber() {
+ return _numBreaks;
+ }
+
+ /**
+ * Set break number
+ *
+ * @param num Break number
+ */
+ public void setBreakNumber(int num) {
+ _numBreaks = num;
+ }
+
+ /**
+ * Get if draw scale text
+ *
+ * @return If draw scale text
+ */
+ public boolean isDrawScaleText() {
+ return _drawScaleText;
+ }
+
+ /**
+ * Set if draw scale text
+ *
+ * @param istrue If draw scale text
+ */
+ public void setDrawScaleText(boolean istrue) {
+ _drawScaleText = istrue;
+ }
+ //
+ //
+ /**
+ * Draw text
+ *
+ * @param g Graphics2D
+ * @param x X
+ * @param y Y
+ */
+ public void draw(Graphics2D g, float x, float y) {
+ AffineTransform oldMatrix = g.getTransform();
+ g.translate(x, y);
+ if (_antiAlias) {
+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ } else {
+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
+ }
+
+ //Draw background color
+ if (this.isDrawBackColor()){
+ g.setColor(this.getBackground());
+ g.fill(new Rectangle.Float(0, 0, this.getWidth(), this.getHeight()));
+ }
+
+ drawScaleBar(g);
+
+ //Draw neatline
+ if (_drawNeatLine) {
+ Rectangle.Float mapRect = new Rectangle.Float(_neatLineSize - 1, _neatLineSize - 1,
+ (this.getWidth() - _neatLineSize), (this.getHeight() - _neatLineSize));
+ g.setColor(_neatLineColor);
+ g.setStroke(new BasicStroke(_neatLineSize));
+ g.draw(mapRect);
+ }
+
+ g.setTransform(oldMatrix);
+ }
+
+ /**
+ * Paint graphics
+ *
+ * @param g Graphics
+ * @param pageLocation Page location
+ * @param zoom Zoom
+ */
+ public void paintGraphics(Graphics2D g, PointF pageLocation) {
+ AffineTransform oldMatrix = g.getTransform();
+ PointF aP = pageToScreen(this.getX(), this.getY(), pageLocation, 1);
+ g.translate(aP.X, aP.Y);
+ if (_antiAlias) {
+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ } else {
+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
+ }
+
+ //Draw background color
+ if (this.isDrawBackColor()){
+ g.setColor(this.getBackground());
+ g.fill(new Rectangle.Float(0, 0, this.getWidth(), this.getHeight()));
+ }
+
+ drawScaleBar(g);
+
+ //Draw neatline
+ if (_drawNeatLine) {
+ Rectangle.Float mapRect = new Rectangle.Float(_neatLineSize - 1, _neatLineSize - 1,
+ (this.getWidth() - _neatLineSize), (this.getHeight() - _neatLineSize));
+ g.setColor(_neatLineColor);
+ g.setStroke(new BasicStroke(_neatLineSize));
+ g.draw(mapRect);
+ }
+
+ g.setTransform(oldMatrix);
+ }
+
+ private void drawScaleBar(Graphics2D g) {
+ //Calculates the width of one break in greographic units
+ FontMetrics metrics = g.getFontMetrics(this._font);
+ float unitLegnth = metrics.stringWidth(_unitText) * 2;
+ float widthNoUnit = (this.getWidth() - unitLegnth);
+ long geoBreakWidth = (long) (getGeoWidth(widthNoUnit / _numBreaks));
+
+ //If the geobreakWidth is less than 1 we return and don't draw anything
+ if (geoBreakWidth < 1) {
+ return;
+ }
+
+ double n = Math.pow(10, String.valueOf(geoBreakWidth).length() - 1);
+ geoBreakWidth = (long) (Math.floor(geoBreakWidth / n) * n);
+
+ long breakWidth = (long) (getWidth(geoBreakWidth));
+ FontMetrics metrics1 = g.getFontMetrics(_font);
+ float fontHeight = metrics1.getHeight();
+ float leftStart = metrics1.stringWidth(String.valueOf(Math.abs(geoBreakWidth))) / 2F;
+
+ //Draw scale text
+ double scale = geoBreakWidth * getConversionFactor(_unit) * 100 / (breakWidth / 96 * 2.539999918);
+ if (_drawScaleText) {
+ g.setFont(this._font);
+ g.setColor(this.getForeground());
+ g.drawString("1 : " + String.format("{0:0,0}", scale),
+ leftStart - (metrics.stringWidth(String.valueOf(Math.abs(0))) / 2), fontHeight * 2.5F);
+ }
+
+ //Draw scale bar
+ switch (_scaleBarType) {
+ case SCALELINE_1:
+ drawScaleLine1(g, breakWidth, geoBreakWidth);
+ break;
+ case SCALELINE_2:
+ drawScaleLine2(g, breakWidth, geoBreakWidth);
+ break;
+ case ALTERNATING_BAR:
+ drawAlternatingBar(g, breakWidth, geoBreakWidth);
+ break;
+ }
+ }
+
+ private double getConversionFactor(ScaleBarUnits unit) {
+ switch (unit) {
+ case KILOMETERS:
+ return 1000;
+ default:
+ return 1;
+ }
+ }
+
+ private double getGeoWidth(double width) {
+ double geoWidth = width / mapPlot.getMapFrame().getMapView().getXScale() / getConversionFactor(_unit);
+ if (mapPlot.getMapFrame().getMapView().getProjection().isLonLatMap()) {
+ geoWidth = geoWidth * getLonDistScale();
+ }
+
+ return geoWidth;
+ }
+
+ private double getWidth(double geoWidth) {
+ double width = geoWidth * mapPlot.getMapFrame().getMapView().getXScale() * getConversionFactor(_unit);
+ if (mapPlot.getMapFrame().getMapView().getProjection().isLonLatMap()) {
+ width = width / getLonDistScale();
+ }
+
+ return width;
+ }
+
+ private double getLonDistScale() {
+ //Get meters of one longitude degree
+ double pY = (mapPlot.getMapFrame().getMapView().getViewExtent().maxY + mapPlot.getMapFrame().getMapView().getViewExtent().minY) / 2;
+ double ProjX = 0, ProjY = pY, pProjX = 1, pProjY = pY;
+ double dx = Math.abs(ProjX - pProjX);
+ double dy = Math.abs(ProjY - pProjY);
+ double dist;
+ double y = (ProjY + pProjY) / 2;
+ double factor = Math.cos(y * Math.PI / 180);
+ dx *= factor;
+ dist = Math.sqrt(dx * dx + dy * dy);
+ dist = dist * 111319.5;
+
+ return dist;
+ }
+
+ private void drawScaleLine1(Graphics2D g, long breakWidth, long geoBreakWidth) {
+ FontMetrics metrics = g.getFontMetrics(_font);
+ float fontHeight = metrics.getHeight();
+ float leftStart = metrics.stringWidth(String.valueOf(Math.abs(geoBreakWidth))) / 2F;
+ int yShift = 10;
+
+ g.setColor(this.getForeground());
+ g.setStroke(new BasicStroke(this.lineWidth));
+ g.draw(new Line2D.Float(leftStart, fontHeight * 1.6f + yShift, leftStart + (breakWidth * _numBreaks), fontHeight * 1.6f + yShift));
+ g.setFont(this._font);
+ for (int i = 0; i <= _numBreaks; i++) {
+ g.draw(new Line2D.Float(leftStart, fontHeight * 1.1f + yShift, leftStart, fontHeight * 1.6f + yShift));
+ g.drawString(String.valueOf(Math.abs(geoBreakWidth * i)),
+ leftStart - (metrics.stringWidth(String.valueOf(Math.abs(geoBreakWidth * i))) / 2), yShift * _yShiftScale);
+ leftStart = leftStart + breakWidth;
+ }
+ g.drawString(_unitText, leftStart - breakWidth + (fontHeight / 2), fontHeight * 1.1f + yShift * _yShiftScale);
+ }
+
+ private void drawScaleLine2(Graphics2D g, long breakWidth, long geoBreakWidth) {
+ FontMetrics metrics = g.getFontMetrics(_font);
+ float fontHeight = metrics.getHeight();
+ float leftStart = metrics.stringWidth(String.valueOf(Math.abs(geoBreakWidth))) / 2F;
+ int yShift = 5;
+
+ g.setColor(this.getForeground());
+ g.setStroke(new BasicStroke(this.lineWidth));
+ g.draw(new Line2D.Float(leftStart, fontHeight * 1.6f + yShift, leftStart + (breakWidth * _numBreaks), fontHeight * 1.6f + yShift));
+ g.setFont(this._font);
+ for (int i = 0; i <= _numBreaks; i++) {
+ g.draw(new Line2D.Float(leftStart, fontHeight * 1.1f + yShift, leftStart, fontHeight + (fontHeight * 1.1f) + yShift));
+ g.drawString(String.valueOf(Math.abs(geoBreakWidth * i)),
+ leftStart - (metrics.stringWidth(String.valueOf(Math.abs(geoBreakWidth * i))) / 2), yShift * _yShiftScale);
+ leftStart = leftStart + breakWidth;
+ }
+ g.drawString(_unitText, leftStart - breakWidth + (fontHeight / 2), fontHeight * 1.1f + yShift * _yShiftScale);
+ }
+
+ private void drawAlternatingBar(Graphics2D g, long breakWidth, long geoBreakWidth) {
+ FontMetrics metrics = g.getFontMetrics(_font);
+ float fontHeight = metrics.getHeight();
+ float leftStart = metrics.stringWidth(String.valueOf(Math.abs(geoBreakWidth))) / 2F;
+ int yShift = 5;
+ float rHeight = fontHeight / 2;
+
+ boolean isFill = false;
+ g.setStroke(new BasicStroke(this.lineWidth));
+ g.setColor(this.getForeground());
+ g.setFont(this._font);
+ for (int i = 0; i <= _numBreaks; i++) {
+ if (i < _numBreaks) {
+ if (isFill) {
+ g.fill(new Rectangle.Float(leftStart, fontHeight * 1.1f + yShift, breakWidth, rHeight));
+ }
+ g.draw(new Rectangle.Float(leftStart, fontHeight * 1.1f + yShift, breakWidth, rHeight));
+ }
+ g.drawString(String.valueOf(Math.abs(geoBreakWidth * i)),
+ leftStart - (metrics.stringWidth(String.valueOf(Math.abs(geoBreakWidth * i))) / 2), yShift * _yShiftScale);
+ leftStart = leftStart + breakWidth;
+ isFill = !isFill;
+ }
+ g.setColor(this.getForeground());
+ g.drawString(_unitText, leftStart - breakWidth + (fontHeight / 2), fontHeight * 1.1f + yShift * _yShiftScale);
+ }
+
+ @Override
+ public void moveUpdate() {
+ }
+
+ @Override
+ public void resizeUpdate() {
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/ChartText.java b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/ChartText.java
index 7aefc4be..716e9294 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/ChartText.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/ChartText.java
@@ -1,740 +1,740 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.meteoinfo.chart;
-
-import java.awt.BasicStroke;
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.Font;
-import java.awt.Graphics2D;
-import java.awt.Rectangle;
-import java.awt.Stroke;
-import java.awt.geom.AffineTransform;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import org.meteoinfo.chart.plot.XAlign;
-import org.meteoinfo.chart.plot.YAlign;
-import org.meteoinfo.drawing.Draw;
-import org.meteoinfo.global.Extent;
-import org.locationtech.jts.geom.Geometry;
-import org.locationtech.jts.geom.GeometryFactory;
-import org.meteoinfo.shape.Shape;
-import org.meteoinfo.shape.ShapeTypes;
-
-/**
- *
- * @author yaqiang
- */
-public class ChartText extends Shape {
-
- //
- protected double x;
- protected double y;
- private Font font;
- private List text;
- private Color color;
- private int lineSpace;
- private CoordinateType coordinates;
- private Color background;
- private boolean drawBackground;
- private boolean drawNeatline;
- private Color neatLineColor;
- private float neatLineSize;
- private float gap;
- protected float angle;
- private XAlign xAlign;
- private YAlign yAlign;
- private boolean useExternalFont;
- protected double xShift;
- protected double yShift;
-
- //
- //
- /**
- * Constructor
- */
- public ChartText() {
- font = new Font("Arial", Font.PLAIN, 14);
- color = Color.black;
- lineSpace = 5;
- coordinates = CoordinateType.DATA;
- this.background = Color.white;
- this.drawBackground = false;
- this.drawNeatline = false;
- this.neatLineColor = Color.black;
- this.neatLineSize = 1.0f;
- this.gap = 3.0f;
- this.angle = 0.0f;
- this.xAlign = XAlign.LEFT;
- this.yAlign = YAlign.BOTTOM;
- this.useExternalFont = false;
- this.xShift = 0;
- this.yShift = 0;
- }
-
- /**
- * Constructor
- *
- * @param text Text
- */
- public ChartText(String text) {
- this();
- this.text = new ArrayList<>();
- String[] lines = text.split("\n");
- this.text.addAll(Arrays.asList(lines));
- }
-
- /**
- * Constructor
- *
- * @param text Text
- */
- public ChartText(List text) {
- this();
- this.text = text;
- }
-
- /**
- * Constructor
- *
- * @param text Text
- * @param font Font
- */
- public ChartText(String text, Font font) {
- this();
- this.text = new ArrayList<>();
- String[] lines = text.split("\n");
- this.text.addAll(Arrays.asList(lines));
- this.font = font;
- }
-
- /**
- * Constructor
- *
- * @param text Text
- * @param font Font
- */
- public ChartText(List text, Font font) {
- this();
- this.text = text;
- this.font = font;
- }
- //
- //
-
- /**
- * Get text
- *
- * @return Text
- */
- public String getText() {
- return text.get(0);
- }
-
- /**
- * Set text
- *
- * @param value Text
- */
- public void setText(String value) {
- text = new ArrayList<>();
- String[] lines = value.split("\n");
- this.text.addAll(Arrays.asList(lines));
- }
-
- /**
- * Get texts
- *
- * @return Text list
- */
- public List getTexts() {
- return text;
- }
-
- /**
- * Set texts
- *
- * @param value Text list
- */
- public void setTexts(List value) {
- text = value;
- }
-
- /**
- * Get font
- *
- * @return Font
- */
- public Font getFont() {
- return font;
- }
-
- /**
- * Set font
- *
- * @param value Font
- */
- public void setFont(Font value) {
- font = value;
- }
-
- /**
- * Get title color
- *
- * @return Title color
- */
- public Color getColor() {
- return color;
- }
-
- /**
- * Set title color
- *
- * @param value Title color
- */
- public void setColor(Color value) {
- this.color = value;
- }
-
- /**
- * Get x
- *
- * @return X
- */
- public double getX() {
- return this.x;
- }
-
- /**
- * Set x
- *
- * @param value X
- */
- public void setX(double value) {
- this.x = value;
- }
-
- /**
- * Get y
- *
- * @return Y
- */
- public double getY() {
- return this.y;
- }
-
- /**
- * Set y
- *
- * @param value Y
- */
- public void setY(double value) {
- this.y = value;
- }
-
- /**
- * Get line space
- *
- * @return Line space
- */
- public int getLineSpace() {
- return this.lineSpace;
- }
-
- /**
- * Set line space
- *
- * @param value Line space
- */
- public void setLineSpace(int value) {
- this.lineSpace = value;
- }
-
- /**
- * Get coordinates
- *
- * @return Coordinates
- */
- public CoordinateType getCoordinates() {
- return this.coordinates;
- }
-
- /**
- * Set coordinates
- *
- * @param value Coordinates
- */
- public void setCoordinates(CoordinateType value) {
- this.coordinates = value;
- }
-
- /**
- * Set coordinates
- *
- * @param value Coordinates
- */
- public void setCoordinates(String value) {
- switch (value) {
- case "axes":
- this.coordinates = CoordinateType.AXES;
- break;
- case "figure":
- this.coordinates = CoordinateType.FIGURE;
- break;
- case "data":
- this.coordinates = CoordinateType.DATA;
- break;
- case "inches":
- this.coordinates = CoordinateType.INCHES;
- break;
- }
- }
-
- /**
- * Get background color
- *
- * @return Background color
- */
- public Color getBackground() {
- return this.background;
- }
-
- /**
- * Set background color
- *
- * @param value Background color
- */
- public void setBackground(Color value) {
- this.background = value;
- }
-
- /**
- * Get if is fill background
- *
- * @return Boolean
- */
- public boolean isFill() {
- return this.drawBackground;
- }
-
- /**
- * Set fill background or not
- *
- * @param value Boolean
- */
- public void setFill(boolean value) {
- this.drawBackground = value;
- }
-
- /**
- * Get draw neatline or not
- *
- * @return Boolean
- */
- public boolean isDrawNeatline() {
- return this.drawNeatline;
- }
-
- /**
- * Set draw neatline or not
- *
- * @param value Boolean
- */
- public void setDrawNeatline(boolean value) {
- this.drawNeatline = value;
- }
-
- /**
- * Get neatline color
- *
- * @return Neatline color
- */
- public Color getNeatlineColor() {
- return this.neatLineColor;
- }
-
- /**
- * Set neatline color
- *
- * @param value Neatline color
- */
- public void setNeatlineColor(Color value) {
- this.neatLineColor = value;
- }
-
- /**
- * Get neatline size
- *
- * @return Neatline size
- */
- public float getNeatlineSize() {
- return this.neatLineSize;
- }
-
- /**
- * Set neatline size
- *
- * @param value Neatline size
- */
- public void setNeatlineSize(float value) {
- this.neatLineSize = value;
- }
-
- /**
- * Get gap
- *
- * @return Gap
- */
- public float getGap() {
- return this.gap;
- }
-
- /**
- * Set gap
- *
- * @param value Gap
- */
- public void setGap(float value) {
- this.gap = value;
- }
-
- /**
- * Get angle
- *
- * @return Angle
- */
- public float getAngle() {
- return this.angle;
- }
-
- /**
- * Set angle
- *
- * @param value Angle
- */
- public void setAngle(float value) {
- this.angle = value;
- }
-
- /**
- * Get x align
- *
- * @return X align
- */
- public XAlign getXAlign() {
- return this.xAlign;
- }
-
- /**
- * Set x align
- *
- * @param value X align
- */
- public void setXAlign(XAlign value) {
- this.xAlign = value;
- }
-
- /**
- * Set x align
- *
- * @param value X align string
- */
- public void setXAlign(String value) {
- this.xAlign = XAlign.valueOf(value.toUpperCase());
- }
-
- /**
- * Get y align
- *
- * @return Y align
- */
- public YAlign getYAlign() {
- return this.yAlign;
- }
-
- /**
- * Set y align
- *
- * @param value Y align
- */
- public void setYAlign(YAlign value) {
- this.yAlign = value;
- }
-
- /**
- * Set y align
- *
- * @param value Y align string
- */
- public void setYAlign(String value) {
- this.yAlign = YAlign.valueOf(value.toUpperCase());
- }
-
- /**
- * Get if use external font - only for LaTeX string
- *
- * @return Boolean
- */
- public boolean isUseExternalFont() {
- return this.useExternalFont;
- }
-
- /**
- * Set if use external font - only for LaTeX string
- *
- * @param value Boolean
- */
- public void setUseExternalFont(boolean value) {
- this.useExternalFont = value;
- }
-
- /**
- * Get x shift
- * @return X shift
- */
- public double getXShift() {
- return this.xShift;
- }
-
- /**
- * Set x shift
- * @param value X shift
- */
- public void setXShift(double value) {
- this.xShift = value;
- }
-
- /**
- * Get y shift
- * @return Y shift
- */
- public double getYShift() {
- return this.yShift;
- }
-
- /**
- * Set y shift
- * @param value Y shift
- */
- public void setYShift(double value) {
- this.yShift = value;
- }
-
- //
- //
- /**
- * Add text in new line
- *
- * @param value The text string
- */
- public void addText(String value) {
- this.text.add(value);
- }
-
- @Override
- public ShapeTypes getShapeType() {
- return ShapeTypes.TEXT;
- }
-
- /**
- * Get text line number
- *
- * @return Text line number
- */
- public int getLineNum() {
- return this.text.size();
- }
-
- /**
- * Get text dimension with angle
- *
- * @param g Graphics2D
- * @return Dimension
- */
- public Dimension getTrueDimension(Graphics2D g) {
- Dimension dim = getDimension(g);
- if (this.angle != 0) {
- int width = dim.width;
- int height = dim.height;
- int temp;
- if (angle == 90 || angle == -90) {
- temp = width;
- width = height;
- height = temp;
- } else {
- width = (int) ((width * Math.cos(Math.toRadians(angle))) + (height * Math.sin(Math.toRadians(angle))));
- height = (int) ((width * Math.sin(Math.toRadians(angle))) + (height * Math.cos(Math.toRadians(angle))));
- }
- return new Dimension(width, height);
- } else {
- return dim;
- }
- }
-
- /**
- * Get text dimension
- *
- * @param g Graphics2D
- * @return Dimension
- */
- public Dimension getDimension(Graphics2D g) {
- g.setFont(font);
- int width = 0, height = 0;
- for (String line : this.text) {
- Dimension dim = Draw.getStringDimension(line, g);
- if (width < dim.width) {
- width = dim.width;
- }
- height += dim.height + this.lineSpace;
- }
- height -= this.lineSpace;
-
- return new Dimension(width, height);
- }
-
- /**
- * To geometry method
- *
- * @param factory GeometryFactory
- * @return Geometry
- */
- @Override
- public Geometry toGeometry(GeometryFactory factory) {
- return null;
- }
-
- /**
- * Set point
- *
- * @param x X
- * @param y Y
- */
- public void setPoint(double x, double y) {
- this.x = x;
- this.y = y;
- Extent aExtent = new Extent();
- aExtent.minX = x;
- aExtent.maxX = x;
- aExtent.minY = y;
- aExtent.maxY = y;
- this.setExtent(aExtent);
- }
-
- /**
- * To string
- *
- * @return String
- */
- @Override
- public String toString() {
- if (this.text.size() == 1) {
- return this.text.get(0);
- } else {
- String r = "";
- for (int i = 0; i < this.text.size(); i++) {
- if (i == 0) {
- r = this.text.get(i);
- } else {
- r = r + "\n" + this.text.get(i);
- }
- }
- return r;
- }
- }
-
- /**
- * Draw text
- *
- * @param g Graphics2D
- * @param x X
- * @param y Y
- */
- public void draw(Graphics2D g, float x, float y) {
- Dimension dim = this.getDimension(g);
- x += this.xShift;
- y += this.yShift;
-
- AffineTransform tempTrans = g.getTransform();
- if (this.angle != 0) {
- //AffineTransform myTrans = new AffineTransform();
- AffineTransform myTrans = (AffineTransform) tempTrans.clone();
- myTrans.translate(x, y);
- //myTrans.translate(tempTrans.getTranslateX() + x, tempTrans.getTranslateY() + y);
- myTrans.rotate(-angle * Math.PI / 180);
- g.setTransform(myTrans);
- x = 0;
- y = 0;
- }
-
- Rectangle.Double rect = new Rectangle.Double(x, y - dim.getHeight(), dim.getWidth(), dim.getHeight());
- rect.setRect(rect.x - gap, rect.y - gap, rect.width + gap * 2,
- rect.height + gap * 2);
- if (this.drawBackground) {
- g.setColor(this.background);
- g.fill(rect);
- }
- if (this.drawNeatline) {
- g.setColor(this.neatLineColor);
- Stroke oldStroke = g.getStroke();
- g.setStroke(new BasicStroke(neatLineSize));
- g.draw(rect);
- g.setStroke(oldStroke);
- }
-
- g.setColor(this.color);
- g.setFont(font);
- switch (this.yAlign) {
- case BOTTOM:
- y = y - dim.height;
- break;
- case CENTER:
- y = y - dim.height * 0.5f;
- break;
- }
-
- for (String str : this.text) {
- dim = Draw.getStringDimension(str, g);
- Draw.drawString(g, x, y, str, xAlign, YAlign.TOP, useExternalFont);
- y += dim.height;
- y += this.lineSpace;
- }
-
- if (this.angle != 0) {
- g.setTransform(tempTrans);
- }
- }
-
- /**
- * Clone
- *
- * @return Cloned object
- */
- @Override
- public Object clone() {
- ChartText ct = new ChartText();
- ct.angle = this.angle;
- ct.background = this.background;
- ct.color = this.color;
- ct.coordinates = this.coordinates;
- ct.drawBackground = this.drawBackground;
- ct.drawNeatline = this.drawNeatline;
- ct.font = this.font;
- ct.gap = this.gap;
- ct.lineSpace = this.lineSpace;
- ct.neatLineColor = this.neatLineColor;
- ct.neatLineSize = this.neatLineSize;
- ct.text = this.text;
- ct.useExternalFont = this.useExternalFont;
- ct.x = this.x;
- ct.xAlign = this.xAlign;
- ct.y = this.y;
- ct.yAlign = this.yAlign;
-
- return ct;
- }
- //
-}
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.meteoinfo.chart;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.Stroke;
+import java.awt.geom.AffineTransform;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import org.meteoinfo.chart.plot.XAlign;
+import org.meteoinfo.chart.plot.YAlign;
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.drawing.Draw;
+import org.locationtech.jts.geom.Geometry;
+import org.locationtech.jts.geom.GeometryFactory;
+import org.meteoinfo.shape.Shape;
+import org.meteoinfo.shape.ShapeTypes;
+
+/**
+ *
+ * @author yaqiang
+ */
+public class ChartText extends Shape {
+
+ //
+ protected double x;
+ protected double y;
+ private Font font;
+ private List text;
+ private Color color;
+ private int lineSpace;
+ private CoordinateType coordinates;
+ private Color background;
+ private boolean drawBackground;
+ private boolean drawNeatline;
+ private Color neatLineColor;
+ private float neatLineSize;
+ private float gap;
+ protected float angle;
+ private XAlign xAlign;
+ private YAlign yAlign;
+ private boolean useExternalFont;
+ protected double xShift;
+ protected double yShift;
+
+ //
+ //
+ /**
+ * Constructor
+ */
+ public ChartText() {
+ font = new Font("Arial", Font.PLAIN, 14);
+ color = Color.black;
+ lineSpace = 5;
+ coordinates = CoordinateType.DATA;
+ this.background = Color.white;
+ this.drawBackground = false;
+ this.drawNeatline = false;
+ this.neatLineColor = Color.black;
+ this.neatLineSize = 1.0f;
+ this.gap = 3.0f;
+ this.angle = 0.0f;
+ this.xAlign = XAlign.LEFT;
+ this.yAlign = YAlign.BOTTOM;
+ this.useExternalFont = false;
+ this.xShift = 0;
+ this.yShift = 0;
+ }
+
+ /**
+ * Constructor
+ *
+ * @param text Text
+ */
+ public ChartText(String text) {
+ this();
+ this.text = new ArrayList<>();
+ String[] lines = text.split("\n");
+ this.text.addAll(Arrays.asList(lines));
+ }
+
+ /**
+ * Constructor
+ *
+ * @param text Text
+ */
+ public ChartText(List text) {
+ this();
+ this.text = text;
+ }
+
+ /**
+ * Constructor
+ *
+ * @param text Text
+ * @param font Font
+ */
+ public ChartText(String text, Font font) {
+ this();
+ this.text = new ArrayList<>();
+ String[] lines = text.split("\n");
+ this.text.addAll(Arrays.asList(lines));
+ this.font = font;
+ }
+
+ /**
+ * Constructor
+ *
+ * @param text Text
+ * @param font Font
+ */
+ public ChartText(List text, Font font) {
+ this();
+ this.text = text;
+ this.font = font;
+ }
+ //
+ //
+
+ /**
+ * Get text
+ *
+ * @return Text
+ */
+ public String getText() {
+ return text.get(0);
+ }
+
+ /**
+ * Set text
+ *
+ * @param value Text
+ */
+ public void setText(String value) {
+ text = new ArrayList<>();
+ String[] lines = value.split("\n");
+ this.text.addAll(Arrays.asList(lines));
+ }
+
+ /**
+ * Get texts
+ *
+ * @return Text list
+ */
+ public List getTexts() {
+ return text;
+ }
+
+ /**
+ * Set texts
+ *
+ * @param value Text list
+ */
+ public void setTexts(List value) {
+ text = value;
+ }
+
+ /**
+ * Get font
+ *
+ * @return Font
+ */
+ public Font getFont() {
+ return font;
+ }
+
+ /**
+ * Set font
+ *
+ * @param value Font
+ */
+ public void setFont(Font value) {
+ font = value;
+ }
+
+ /**
+ * Get title color
+ *
+ * @return Title color
+ */
+ public Color getColor() {
+ return color;
+ }
+
+ /**
+ * Set title color
+ *
+ * @param value Title color
+ */
+ public void setColor(Color value) {
+ this.color = value;
+ }
+
+ /**
+ * Get x
+ *
+ * @return X
+ */
+ public double getX() {
+ return this.x;
+ }
+
+ /**
+ * Set x
+ *
+ * @param value X
+ */
+ public void setX(double value) {
+ this.x = value;
+ }
+
+ /**
+ * Get y
+ *
+ * @return Y
+ */
+ public double getY() {
+ return this.y;
+ }
+
+ /**
+ * Set y
+ *
+ * @param value Y
+ */
+ public void setY(double value) {
+ this.y = value;
+ }
+
+ /**
+ * Get line space
+ *
+ * @return Line space
+ */
+ public int getLineSpace() {
+ return this.lineSpace;
+ }
+
+ /**
+ * Set line space
+ *
+ * @param value Line space
+ */
+ public void setLineSpace(int value) {
+ this.lineSpace = value;
+ }
+
+ /**
+ * Get coordinates
+ *
+ * @return Coordinates
+ */
+ public CoordinateType getCoordinates() {
+ return this.coordinates;
+ }
+
+ /**
+ * Set coordinates
+ *
+ * @param value Coordinates
+ */
+ public void setCoordinates(CoordinateType value) {
+ this.coordinates = value;
+ }
+
+ /**
+ * Set coordinates
+ *
+ * @param value Coordinates
+ */
+ public void setCoordinates(String value) {
+ switch (value) {
+ case "axes":
+ this.coordinates = CoordinateType.AXES;
+ break;
+ case "figure":
+ this.coordinates = CoordinateType.FIGURE;
+ break;
+ case "data":
+ this.coordinates = CoordinateType.DATA;
+ break;
+ case "inches":
+ this.coordinates = CoordinateType.INCHES;
+ break;
+ }
+ }
+
+ /**
+ * Get background color
+ *
+ * @return Background color
+ */
+ public Color getBackground() {
+ return this.background;
+ }
+
+ /**
+ * Set background color
+ *
+ * @param value Background color
+ */
+ public void setBackground(Color value) {
+ this.background = value;
+ }
+
+ /**
+ * Get if is fill background
+ *
+ * @return Boolean
+ */
+ public boolean isFill() {
+ return this.drawBackground;
+ }
+
+ /**
+ * Set fill background or not
+ *
+ * @param value Boolean
+ */
+ public void setFill(boolean value) {
+ this.drawBackground = value;
+ }
+
+ /**
+ * Get draw neatline or not
+ *
+ * @return Boolean
+ */
+ public boolean isDrawNeatline() {
+ return this.drawNeatline;
+ }
+
+ /**
+ * Set draw neatline or not
+ *
+ * @param value Boolean
+ */
+ public void setDrawNeatline(boolean value) {
+ this.drawNeatline = value;
+ }
+
+ /**
+ * Get neatline color
+ *
+ * @return Neatline color
+ */
+ public Color getNeatlineColor() {
+ return this.neatLineColor;
+ }
+
+ /**
+ * Set neatline color
+ *
+ * @param value Neatline color
+ */
+ public void setNeatlineColor(Color value) {
+ this.neatLineColor = value;
+ }
+
+ /**
+ * Get neatline size
+ *
+ * @return Neatline size
+ */
+ public float getNeatlineSize() {
+ return this.neatLineSize;
+ }
+
+ /**
+ * Set neatline size
+ *
+ * @param value Neatline size
+ */
+ public void setNeatlineSize(float value) {
+ this.neatLineSize = value;
+ }
+
+ /**
+ * Get gap
+ *
+ * @return Gap
+ */
+ public float getGap() {
+ return this.gap;
+ }
+
+ /**
+ * Set gap
+ *
+ * @param value Gap
+ */
+ public void setGap(float value) {
+ this.gap = value;
+ }
+
+ /**
+ * Get angle
+ *
+ * @return Angle
+ */
+ public float getAngle() {
+ return this.angle;
+ }
+
+ /**
+ * Set angle
+ *
+ * @param value Angle
+ */
+ public void setAngle(float value) {
+ this.angle = value;
+ }
+
+ /**
+ * Get x align
+ *
+ * @return X align
+ */
+ public XAlign getXAlign() {
+ return this.xAlign;
+ }
+
+ /**
+ * Set x align
+ *
+ * @param value X align
+ */
+ public void setXAlign(XAlign value) {
+ this.xAlign = value;
+ }
+
+ /**
+ * Set x align
+ *
+ * @param value X align string
+ */
+ public void setXAlign(String value) {
+ this.xAlign = XAlign.valueOf(value.toUpperCase());
+ }
+
+ /**
+ * Get y align
+ *
+ * @return Y align
+ */
+ public YAlign getYAlign() {
+ return this.yAlign;
+ }
+
+ /**
+ * Set y align
+ *
+ * @param value Y align
+ */
+ public void setYAlign(YAlign value) {
+ this.yAlign = value;
+ }
+
+ /**
+ * Set y align
+ *
+ * @param value Y align string
+ */
+ public void setYAlign(String value) {
+ this.yAlign = YAlign.valueOf(value.toUpperCase());
+ }
+
+ /**
+ * Get if use external font - only for LaTeX string
+ *
+ * @return Boolean
+ */
+ public boolean isUseExternalFont() {
+ return this.useExternalFont;
+ }
+
+ /**
+ * Set if use external font - only for LaTeX string
+ *
+ * @param value Boolean
+ */
+ public void setUseExternalFont(boolean value) {
+ this.useExternalFont = value;
+ }
+
+ /**
+ * Get x shift
+ * @return X shift
+ */
+ public double getXShift() {
+ return this.xShift;
+ }
+
+ /**
+ * Set x shift
+ * @param value X shift
+ */
+ public void setXShift(double value) {
+ this.xShift = value;
+ }
+
+ /**
+ * Get y shift
+ * @return Y shift
+ */
+ public double getYShift() {
+ return this.yShift;
+ }
+
+ /**
+ * Set y shift
+ * @param value Y shift
+ */
+ public void setYShift(double value) {
+ this.yShift = value;
+ }
+
+ //
+ //
+ /**
+ * Add text in new line
+ *
+ * @param value The text string
+ */
+ public void addText(String value) {
+ this.text.add(value);
+ }
+
+ @Override
+ public ShapeTypes getShapeType() {
+ return ShapeTypes.TEXT;
+ }
+
+ /**
+ * Get text line number
+ *
+ * @return Text line number
+ */
+ public int getLineNum() {
+ return this.text.size();
+ }
+
+ /**
+ * Get text dimension with angle
+ *
+ * @param g Graphics2D
+ * @return Dimension
+ */
+ public Dimension getTrueDimension(Graphics2D g) {
+ Dimension dim = getDimension(g);
+ if (this.angle != 0) {
+ int width = dim.width;
+ int height = dim.height;
+ int temp;
+ if (angle == 90 || angle == -90) {
+ temp = width;
+ width = height;
+ height = temp;
+ } else {
+ width = (int) ((width * Math.cos(Math.toRadians(angle))) + (height * Math.sin(Math.toRadians(angle))));
+ height = (int) ((width * Math.sin(Math.toRadians(angle))) + (height * Math.cos(Math.toRadians(angle))));
+ }
+ return new Dimension(width, height);
+ } else {
+ return dim;
+ }
+ }
+
+ /**
+ * Get text dimension
+ *
+ * @param g Graphics2D
+ * @return Dimension
+ */
+ public Dimension getDimension(Graphics2D g) {
+ g.setFont(font);
+ int width = 0, height = 0;
+ for (String line : this.text) {
+ Dimension dim = Draw.getStringDimension(line, g);
+ if (width < dim.width) {
+ width = dim.width;
+ }
+ height += dim.height + this.lineSpace;
+ }
+ height -= this.lineSpace;
+
+ return new Dimension(width, height);
+ }
+
+ /**
+ * To geometry method
+ *
+ * @param factory GeometryFactory
+ * @return Geometry
+ */
+ @Override
+ public Geometry toGeometry(GeometryFactory factory) {
+ return null;
+ }
+
+ /**
+ * Set point
+ *
+ * @param x X
+ * @param y Y
+ */
+ public void setPoint(double x, double y) {
+ this.x = x;
+ this.y = y;
+ Extent aExtent = new Extent();
+ aExtent.minX = x;
+ aExtent.maxX = x;
+ aExtent.minY = y;
+ aExtent.maxY = y;
+ this.setExtent(aExtent);
+ }
+
+ /**
+ * To string
+ *
+ * @return String
+ */
+ @Override
+ public String toString() {
+ if (this.text.size() == 1) {
+ return this.text.get(0);
+ } else {
+ String r = "";
+ for (int i = 0; i < this.text.size(); i++) {
+ if (i == 0) {
+ r = this.text.get(i);
+ } else {
+ r = r + "\n" + this.text.get(i);
+ }
+ }
+ return r;
+ }
+ }
+
+ /**
+ * Draw text
+ *
+ * @param g Graphics2D
+ * @param x X
+ * @param y Y
+ */
+ public void draw(Graphics2D g, float x, float y) {
+ Dimension dim = this.getDimension(g);
+ x += this.xShift;
+ y += this.yShift;
+
+ AffineTransform tempTrans = g.getTransform();
+ if (this.angle != 0) {
+ //AffineTransform myTrans = new AffineTransform();
+ AffineTransform myTrans = (AffineTransform) tempTrans.clone();
+ myTrans.translate(x, y);
+ //myTrans.translate(tempTrans.getTranslateX() + x, tempTrans.getTranslateY() + y);
+ myTrans.rotate(-angle * Math.PI / 180);
+ g.setTransform(myTrans);
+ x = 0;
+ y = 0;
+ }
+
+ Rectangle.Double rect = new Rectangle.Double(x, y - dim.getHeight(), dim.getWidth(), dim.getHeight());
+ rect.setRect(rect.x - gap, rect.y - gap, rect.width + gap * 2,
+ rect.height + gap * 2);
+ if (this.drawBackground) {
+ g.setColor(this.background);
+ g.fill(rect);
+ }
+ if (this.drawNeatline) {
+ g.setColor(this.neatLineColor);
+ Stroke oldStroke = g.getStroke();
+ g.setStroke(new BasicStroke(neatLineSize));
+ g.draw(rect);
+ g.setStroke(oldStroke);
+ }
+
+ g.setColor(this.color);
+ g.setFont(font);
+ switch (this.yAlign) {
+ case BOTTOM:
+ y = y - dim.height;
+ break;
+ case CENTER:
+ y = y - dim.height * 0.5f;
+ break;
+ }
+
+ for (String str : this.text) {
+ dim = Draw.getStringDimension(str, g);
+ Draw.drawString(g, x, y, str, xAlign, YAlign.TOP, useExternalFont);
+ y += dim.height;
+ y += this.lineSpace;
+ }
+
+ if (this.angle != 0) {
+ g.setTransform(tempTrans);
+ }
+ }
+
+ /**
+ * Clone
+ *
+ * @return Cloned object
+ */
+ @Override
+ public Object clone() {
+ ChartText ct = new ChartText();
+ ct.angle = this.angle;
+ ct.background = this.background;
+ ct.color = this.color;
+ ct.coordinates = this.coordinates;
+ ct.drawBackground = this.drawBackground;
+ ct.drawNeatline = this.drawNeatline;
+ ct.font = this.font;
+ ct.gap = this.gap;
+ ct.lineSpace = this.lineSpace;
+ ct.neatLineColor = this.neatLineColor;
+ ct.neatLineSize = this.neatLineSize;
+ ct.text = this.text;
+ ct.useExternalFont = this.useExternalFont;
+ ct.x = this.x;
+ ct.xAlign = this.xAlign;
+ ct.y = this.y;
+ ct.yAlign = this.yAlign;
+
+ return ct;
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/ChartText3D.java b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/ChartText3D.java
index c2fcef04..9f1bdd42 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/ChartText3D.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/ChartText3D.java
@@ -1,127 +1,127 @@
-/* This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.chart;
-
-import java.awt.Point;
-import org.meteoinfo.chart.plot3d.Projector;
-import org.meteoinfo.data.DataMath;
-import org.meteoinfo.global.Extent3D;
-import org.meteoinfo.shape.PointZ;
-
-/**
- *
- * @author Yaqiang Wang
- * yaqiang.wang@gmail.com
- */
-public class ChartText3D extends ChartText {
- private double z;
- private PointZ zdir = null;
-
- /**
- * Get z coordinate value
- * @return Z coordinate value
- */
- public double getZ(){
- return this.z;
- }
-
- /**
- * Set z coordinate value
- * @param value Z coordinate value
- */
- public void setZ(double value){
- this.z = value;
- }
-
- /**
- * Get zdir point
- * @return ZDir point
- */
- public PointZ getZDir(){
- return zdir;
- }
-
- /**
- * Set zdir point
- * @param value ZDir point
- */
- public void setZDir(PointZ value){
- this.zdir = value;
- }
-
- /**
- * Set zdir point
- * @param x X coordinate value
- * @param y Y coordinate value
- * @param z Z coordinate value
- */
- public void setZDir(float x, float y, float z){
- if (x == 0 && y == 0 && z == 0)
- this.zdir = null;
- else
- this.zdir = new PointZ(x, y, z);
- }
-
- /**
- * Set zdir point
- * @param value ZDir point
- */
- public void setZDir(String value){
- float x1 = 0, y1 = 0, z1 = 0;
- switch(value.toLowerCase()){
- case "x":
- x1 = 1;
- break;
- case "y":
- y1 = 1;
- break;
- case "z":
- z1 = 1;
- break;
- }
- this.setZDir(x1, y1, z1);
- }
-
- /**
- * Set point
- *
- * @param x X
- * @param y Y
- * @param z Z
- */
- public void setPoint(double x, double y, double z) {
- this.x = x;
- this.y = y;
- this.z = z;
- Extent3D aExtent = new Extent3D();
- aExtent.minX = x;
- aExtent.maxX = x;
- aExtent.minY = y;
- aExtent.maxY = y;
- aExtent.minZ = z;
- aExtent.maxZ = z;
- this.setExtent(aExtent);
- }
-
- /**
- * Update angle
- * @param projector Projector
- */
- public void updateAngle(Projector projector){
- if (this.zdir == null)
- return;
-
- Point p0 = projector.project(0, 0, 0);
- Point p1 = projector.project((float)this.zdir.X, (float)this.zdir.Y, (float)this.zdir.Z);
- double[] value = DataMath.getDSFromUV(p1.x - p0.x, p1.y - p0.y);
- this.angle = (float)value[0];
- }
-}
+/* This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ */
+package org.meteoinfo.chart;
+
+import java.awt.Point;
+import org.meteoinfo.chart.plot3d.Projector;
+import org.meteoinfo.common.Extent3D;
+import org.meteoinfo.data.DataMath;
+import org.meteoinfo.shape.PointZ;
+
+/**
+ *
+ * @author Yaqiang Wang
+ * yaqiang.wang@gmail.com
+ */
+public class ChartText3D extends ChartText {
+ private double z;
+ private PointZ zdir = null;
+
+ /**
+ * Get z coordinate value
+ * @return Z coordinate value
+ */
+ public double getZ(){
+ return this.z;
+ }
+
+ /**
+ * Set z coordinate value
+ * @param value Z coordinate value
+ */
+ public void setZ(double value){
+ this.z = value;
+ }
+
+ /**
+ * Get zdir point
+ * @return ZDir point
+ */
+ public PointZ getZDir(){
+ return zdir;
+ }
+
+ /**
+ * Set zdir point
+ * @param value ZDir point
+ */
+ public void setZDir(PointZ value){
+ this.zdir = value;
+ }
+
+ /**
+ * Set zdir point
+ * @param x X coordinate value
+ * @param y Y coordinate value
+ * @param z Z coordinate value
+ */
+ public void setZDir(float x, float y, float z){
+ if (x == 0 && y == 0 && z == 0)
+ this.zdir = null;
+ else
+ this.zdir = new PointZ(x, y, z);
+ }
+
+ /**
+ * Set zdir point
+ * @param value ZDir point
+ */
+ public void setZDir(String value){
+ float x1 = 0, y1 = 0, z1 = 0;
+ switch(value.toLowerCase()){
+ case "x":
+ x1 = 1;
+ break;
+ case "y":
+ y1 = 1;
+ break;
+ case "z":
+ z1 = 1;
+ break;
+ }
+ this.setZDir(x1, y1, z1);
+ }
+
+ /**
+ * Set point
+ *
+ * @param x X
+ * @param y Y
+ * @param z Z
+ */
+ public void setPoint(double x, double y, double z) {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ Extent3D aExtent = new Extent3D();
+ aExtent.minX = x;
+ aExtent.maxX = x;
+ aExtent.minY = y;
+ aExtent.maxY = y;
+ aExtent.minZ = z;
+ aExtent.maxZ = z;
+ this.setExtent(aExtent);
+ }
+
+ /**
+ * Update angle
+ * @param projector Projector
+ */
+ public void updateAngle(Projector projector){
+ if (this.zdir == null)
+ return;
+
+ Point p0 = projector.project(0, 0, 0);
+ Point p1 = projector.project((float)this.zdir.X, (float)this.zdir.Y, (float)this.zdir.Z);
+ double[] value = DataMath.getDSFromUV(p1.x - p0.x, p1.y - p0.y);
+ this.angle = (float)value[0];
+ }
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/ChartWindArrow.java b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/ChartWindArrow.java
index 77d27fcf..bb279fcc 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/ChartWindArrow.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/ChartWindArrow.java
@@ -1,390 +1,391 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.meteoinfo.chart;
-
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.Font;
-import java.awt.Graphics2D;
-import java.awt.RenderingHints;
-import java.awt.geom.Rectangle2D;
-import org.meteoinfo.drawing.Draw;
-import org.meteoinfo.global.DataConvert;
-import org.meteoinfo.global.PointF;
-import org.meteoinfo.layer.VectorLayer;
-import org.meteoinfo.legend.ArrowBreak;
-import org.meteoinfo.shape.GraphicCollection;
-import org.meteoinfo.shape.WindArrow;
-
-/**
- *
- * @author Yaqiang Wang
- */
-public class ChartWindArrow {
-
- //
- private final WindArrow windArrow;
- private ArrowBreak arrowBreak;
- private Font font;
- //private Color color;
- private Color labelColor;
- private float x;
- private float y;
- private String label;
- private int labelSep;
- private Object layer;
- private Color background;
- private boolean drawBackground;
- private boolean drawNeatline;
- private Color neatLineColor;
- private float neatLineSize;
-
- //
- //
- /**
- * Constructor
- */
- public ChartWindArrow() {
- this.windArrow = new WindArrow();
- this.windArrow.angle = 270;
- this.windArrow.length = 20;
- this.arrowBreak = new ArrowBreak();
- this.font = new Font("Arial", Font.PLAIN, 12);
- //this.color = Color.black;
- this.labelColor = Color.black;
- this.labelSep = 5;
- this.background = Color.white;
- this.drawBackground = false;
- this.drawNeatline = false;
- this.neatLineColor = Color.black;
- this.neatLineSize = 1.0f;
- }
-
- //
- //
- /**
- * Get wind arrow
- *
- * @return Wind arrow
- */
- public WindArrow getWindArrow() {
- return this.windArrow;
- }
-
- /**
- * Get arrow break
- * @return Arrow break
- */
- public ArrowBreak getArrowBreak() {
- return this.arrowBreak;
- }
-
- /**
- * Set arrow break
- * @param value Arrow break
- */
- public void setArrowBreak(ArrowBreak value) {
- this.arrowBreak = value;
- }
-
- /**
- * Get length
- *
- * @return Length
- */
- public float getLength() {
- return this.windArrow.length;
- }
-
- /**
- * Set length
- *
- * @param value Length
- */
- public void setLength(float value) {
- this.windArrow.length = value;
- this.label = String.valueOf(value);
- this.label = DataConvert.removeTailingZeros(this.label);
- }
-
- /**
- * Get angle
- *
- * @return Angle
- */
- public double getAngle() {
- return this.windArrow.angle;
- }
-
- /**
- * Set angle
- *
- * @param value Angle
- */
- public void setAngle(double value) {
- this.windArrow.angle = value;
- }
-
- /**
- * Get layer
- *
- * @return Layer
- */
- public Object getLayer() {
- return this.layer;
- }
-
- /**
- * Set layer
- *
- * @param value Layer
- */
- public void setLayer(Object value) {
- this.layer = value;
- }
-
- /**
- * Get font
- *
- * @return Font
- */
- public Font getFont() {
- return font;
- }
-
- /**
- * Set font
- *
- * @param value Font
- */
- public void setFont(Font value) {
- font = value;
- }
-
- /**
- * Get label color
- *
- * @return Label color
- */
- public Color getLabelColor() {
- return this.labelColor;
- }
-
- /**
- * Set label color
- *
- * @param value Label color
- */
- public void setLabelColor(Color value) {
- this.labelColor = value;
- }
-
- /**
- * Get the distance between arrow and label
- * @return Distance between arrow and label
- */
- public int getLabelSep(){
- return this.labelSep;
- }
-
- /**
- * Set the distance between arrow and label
- * @param value Distance between arrow and label
- */
- public void setLabelSep(int value) {
- this.labelSep = value;
- }
-
- /**
- * Get x
- *
- * @return X
- */
- public float getX() {
- return this.x;
- }
-
- /**
- * Set x
- *
- * @param value X
- */
- public void setX(float value) {
- this.x = value;
- }
-
- /**
- * Get y
- *
- * @return Y
- */
- public float getY() {
- return this.y;
- }
-
- /**
- * Set y
- *
- * @param value Y
- */
- public void setY(float value) {
- this.y = value;
- }
-
- /**
- * Get label
- *
- * @return Label
- */
- public String getLabel() {
- return this.label;
- }
-
- /**
- * Set label
- *
- * @param value Label
- */
- public void setLabel(String value) {
- this.label = value;
- }
-
- /**
- * Get background color
- *
- * @return Background color
- */
- public Color getBackground() {
- return this.background;
- }
-
- /**
- * Set background color
- *
- * @param value Background color
- */
- public void setBackground(Color value) {
- this.background = value;
- }
-
- /**
- * Get if is fill background
- *
- * @return Boolean
- */
- public boolean isFill() {
- return this.drawBackground;
- }
-
- /**
- * Set fill background or not
- *
- * @param value Boolean
- */
- public void setFill(boolean value) {
- this.drawBackground = value;
- }
-
- /**
- * Get draw neatline or not
- *
- * @return Boolean
- */
- public boolean isDrawNeatline() {
- return this.drawNeatline;
- }
-
- /**
- * Set draw neatline or not
- *
- * @param value Boolean
- */
- public void setDrawNeatline(boolean value) {
- this.drawNeatline = value;
- }
-
- /**
- * Get neatline color
- *
- * @return Neatline color
- */
- public Color getNeatlineColor() {
- return this.neatLineColor;
- }
-
- /**
- * Set neatline color
- *
- * @param value Neatline color
- */
- public void setNeatlineColor(Color value) {
- this.neatLineColor = value;
- }
-
- /**
- * Get neatline size
- *
- * @return Neatline size
- */
- public float getNeatlineSize() {
- return this.neatLineSize;
- }
-
- /**
- * Set neatline size
- *
- * @param value Neatline size
- */
- public void setNeatlineSize(float value) {
- this.neatLineSize = value;
- }
-
- //
- //
- /**
- * Draw text
- *
- * @param g Graphics2D
- * @param x X
- * @param y Y
- */
- public void draw(Graphics2D g, float x, float y) {
- Object rendering = g.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
- g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
- float zoom = 1.0f;
- if (this.layer != null) {
- if (this.layer instanceof VectorLayer) {
- zoom = ((VectorLayer) this.layer).getDrawingZoom();
- } else if (this.layer instanceof GraphicCollection) {
- zoom = ((GraphicCollection) this.layer).getArrowZoom();
- }
- }
- g.setFont(this.font);
- //String drawStr = this.label wa.getLabel();
- Dimension dim = Draw.getStringDimension(this.label, g);
- if (this.drawBackground || this.drawNeatline) {
- Rectangle2D rect = Draw.getArrawBorder(new PointF(x, y), this.windArrow, g, zoom);
- double gap = 5;
- double width = Math.max(rect.getWidth(), dim.getWidth());
- rect.setRect(rect.getX() - gap, rect.getY() - gap - 2, width + gap * 2,
- rect.getHeight() + dim.height + this.labelSep + gap + 2);
- if (this.drawBackground) {
- g.setColor(this.background);
- g.fill(rect);
- }
- if (this.drawNeatline) {
- g.setColor(this.neatLineColor);
- 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);
- g.setColor(this.labelColor);
- Draw.drawString(g, this.label, x, y + dim.height + this.labelSep);
- g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, rendering);
- }
- //
-}
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.meteoinfo.chart;
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+import java.awt.geom.Rectangle2D;
+
+import org.meteoinfo.common.PointF;
+import org.meteoinfo.drawing.Draw;
+import org.meteoinfo.global.DataConvert;
+import org.meteoinfo.layer.VectorLayer;
+import org.meteoinfo.legend.ArrowBreak;
+import org.meteoinfo.shape.GraphicCollection;
+import org.meteoinfo.shape.WindArrow;
+
+/**
+ *
+ * @author Yaqiang Wang
+ */
+public class ChartWindArrow {
+
+ //
+ private final WindArrow windArrow;
+ private ArrowBreak arrowBreak;
+ private Font font;
+ //private Color color;
+ private Color labelColor;
+ private float x;
+ private float y;
+ private String label;
+ private int labelSep;
+ private Object layer;
+ private Color background;
+ private boolean drawBackground;
+ private boolean drawNeatline;
+ private Color neatLineColor;
+ private float neatLineSize;
+
+ //
+ //
+ /**
+ * Constructor
+ */
+ public ChartWindArrow() {
+ this.windArrow = new WindArrow();
+ this.windArrow.angle = 270;
+ this.windArrow.length = 20;
+ this.arrowBreak = new ArrowBreak();
+ this.font = new Font("Arial", Font.PLAIN, 12);
+ //this.color = Color.black;
+ this.labelColor = Color.black;
+ this.labelSep = 5;
+ this.background = Color.white;
+ this.drawBackground = false;
+ this.drawNeatline = false;
+ this.neatLineColor = Color.black;
+ this.neatLineSize = 1.0f;
+ }
+
+ //
+ //
+ /**
+ * Get wind arrow
+ *
+ * @return Wind arrow
+ */
+ public WindArrow getWindArrow() {
+ return this.windArrow;
+ }
+
+ /**
+ * Get arrow break
+ * @return Arrow break
+ */
+ public ArrowBreak getArrowBreak() {
+ return this.arrowBreak;
+ }
+
+ /**
+ * Set arrow break
+ * @param value Arrow break
+ */
+ public void setArrowBreak(ArrowBreak value) {
+ this.arrowBreak = value;
+ }
+
+ /**
+ * Get length
+ *
+ * @return Length
+ */
+ public float getLength() {
+ return this.windArrow.length;
+ }
+
+ /**
+ * Set length
+ *
+ * @param value Length
+ */
+ public void setLength(float value) {
+ this.windArrow.length = value;
+ this.label = String.valueOf(value);
+ this.label = DataConvert.removeTailingZeros(this.label);
+ }
+
+ /**
+ * Get angle
+ *
+ * @return Angle
+ */
+ public double getAngle() {
+ return this.windArrow.angle;
+ }
+
+ /**
+ * Set angle
+ *
+ * @param value Angle
+ */
+ public void setAngle(double value) {
+ this.windArrow.angle = value;
+ }
+
+ /**
+ * Get layer
+ *
+ * @return Layer
+ */
+ public Object getLayer() {
+ return this.layer;
+ }
+
+ /**
+ * Set layer
+ *
+ * @param value Layer
+ */
+ public void setLayer(Object value) {
+ this.layer = value;
+ }
+
+ /**
+ * Get font
+ *
+ * @return Font
+ */
+ public Font getFont() {
+ return font;
+ }
+
+ /**
+ * Set font
+ *
+ * @param value Font
+ */
+ public void setFont(Font value) {
+ font = value;
+ }
+
+ /**
+ * Get label color
+ *
+ * @return Label color
+ */
+ public Color getLabelColor() {
+ return this.labelColor;
+ }
+
+ /**
+ * Set label color
+ *
+ * @param value Label color
+ */
+ public void setLabelColor(Color value) {
+ this.labelColor = value;
+ }
+
+ /**
+ * Get the distance between arrow and label
+ * @return Distance between arrow and label
+ */
+ public int getLabelSep(){
+ return this.labelSep;
+ }
+
+ /**
+ * Set the distance between arrow and label
+ * @param value Distance between arrow and label
+ */
+ public void setLabelSep(int value) {
+ this.labelSep = value;
+ }
+
+ /**
+ * Get x
+ *
+ * @return X
+ */
+ public float getX() {
+ return this.x;
+ }
+
+ /**
+ * Set x
+ *
+ * @param value X
+ */
+ public void setX(float value) {
+ this.x = value;
+ }
+
+ /**
+ * Get y
+ *
+ * @return Y
+ */
+ public float getY() {
+ return this.y;
+ }
+
+ /**
+ * Set y
+ *
+ * @param value Y
+ */
+ public void setY(float value) {
+ this.y = value;
+ }
+
+ /**
+ * Get label
+ *
+ * @return Label
+ */
+ public String getLabel() {
+ return this.label;
+ }
+
+ /**
+ * Set label
+ *
+ * @param value Label
+ */
+ public void setLabel(String value) {
+ this.label = value;
+ }
+
+ /**
+ * Get background color
+ *
+ * @return Background color
+ */
+ public Color getBackground() {
+ return this.background;
+ }
+
+ /**
+ * Set background color
+ *
+ * @param value Background color
+ */
+ public void setBackground(Color value) {
+ this.background = value;
+ }
+
+ /**
+ * Get if is fill background
+ *
+ * @return Boolean
+ */
+ public boolean isFill() {
+ return this.drawBackground;
+ }
+
+ /**
+ * Set fill background or not
+ *
+ * @param value Boolean
+ */
+ public void setFill(boolean value) {
+ this.drawBackground = value;
+ }
+
+ /**
+ * Get draw neatline or not
+ *
+ * @return Boolean
+ */
+ public boolean isDrawNeatline() {
+ return this.drawNeatline;
+ }
+
+ /**
+ * Set draw neatline or not
+ *
+ * @param value Boolean
+ */
+ public void setDrawNeatline(boolean value) {
+ this.drawNeatline = value;
+ }
+
+ /**
+ * Get neatline color
+ *
+ * @return Neatline color
+ */
+ public Color getNeatlineColor() {
+ return this.neatLineColor;
+ }
+
+ /**
+ * Set neatline color
+ *
+ * @param value Neatline color
+ */
+ public void setNeatlineColor(Color value) {
+ this.neatLineColor = value;
+ }
+
+ /**
+ * Get neatline size
+ *
+ * @return Neatline size
+ */
+ public float getNeatlineSize() {
+ return this.neatLineSize;
+ }
+
+ /**
+ * Set neatline size
+ *
+ * @param value Neatline size
+ */
+ public void setNeatlineSize(float value) {
+ this.neatLineSize = value;
+ }
+
+ //
+ //
+ /**
+ * Draw text
+ *
+ * @param g Graphics2D
+ * @param x X
+ * @param y Y
+ */
+ public void draw(Graphics2D g, float x, float y) {
+ Object rendering = g.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ float zoom = 1.0f;
+ if (this.layer != null) {
+ if (this.layer instanceof VectorLayer) {
+ zoom = ((VectorLayer) this.layer).getDrawingZoom();
+ } else if (this.layer instanceof GraphicCollection) {
+ zoom = ((GraphicCollection) this.layer).getArrowZoom();
+ }
+ }
+ g.setFont(this.font);
+ //String drawStr = this.label wa.getLabel();
+ Dimension dim = Draw.getStringDimension(this.label, g);
+ if (this.drawBackground || this.drawNeatline) {
+ Rectangle2D rect = Draw.getArrawBorder(new PointF(x, y), this.windArrow, g, zoom);
+ double gap = 5;
+ double width = Math.max(rect.getWidth(), dim.getWidth());
+ rect.setRect(rect.getX() - gap, rect.getY() - gap - 2, width + gap * 2,
+ rect.getHeight() + dim.height + this.labelSep + gap + 2);
+ if (this.drawBackground) {
+ g.setColor(this.background);
+ g.fill(rect);
+ }
+ if (this.drawNeatline) {
+ g.setColor(this.neatLineColor);
+ 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);
+ g.setColor(this.labelColor);
+ Draw.drawString(g, this.label, x, y + dim.height + this.labelSep);
+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, rendering);
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/axis/Axis.java b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/axis/Axis.java
index 30cf6687..88611ba4 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/axis/Axis.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/axis/Axis.java
@@ -23,10 +23,10 @@ import org.meteoinfo.chart.Location;
import org.meteoinfo.chart.plot.AbstractPlot2D;
import org.meteoinfo.chart.plot.XAlign;
import org.meteoinfo.chart.plot.YAlign;
+import org.meteoinfo.common.MIMath;
+import org.meteoinfo.common.util.JDateUtil;
import org.meteoinfo.drawing.Draw;
import org.meteoinfo.global.DataConvert;
-import org.meteoinfo.global.MIMath;
-import org.meteoinfo.global.util.JDateUtil;
import org.meteoinfo.legend.LineStyles;
import org.meteoinfo.ndarray.util.BigDecimalUtil;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/axis/LogAxis.java b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/axis/LogAxis.java
index f2bf2201..ba2f4874 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/axis/LogAxis.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/axis/LogAxis.java
@@ -1,83 +1,83 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.meteoinfo.chart.axis;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.meteoinfo.chart.ChartText;
-import org.meteoinfo.global.DataConvert;
-import org.meteoinfo.global.MIMath;
-
-/**
- *
- * @author Yaqiang Wang
- */
-public class LogAxis extends Axis {
- //
- //
- //
- /**
- * Constructor
- * @param axis Axis
- */
- public LogAxis(Axis axis){
- super(axis);
- }
- //
- //
- //
- //
- /**
- * Update tick values
- */
- @Override
- public void updateTickValues() {
- double[] r = MIMath.getIntervalValues_Log(this.getMinValue(), this.getMaxValue());
- this.setTickValues((double[]) r);
- this.setTickDeltaValue(1);
- }
-
- @Override
- public void updateTickLabels(){
- List tls = new ArrayList<>();
- String lab;
- if (this.isAutoTick()) {
- if (this.getTickValues() == null) {
- return;
- }
- for (double value : this.getTickValues()) {
- lab = String.valueOf(value);
- lab = DataConvert.removeTailingZeros(lab);
- tls.add(new ChartText(lab));
- }
-
- List values = new ArrayList<>();
- for (ChartText tl : tls){
- values.add(Double.parseDouble(tl.getText()));
- }
- tls.clear();
- int e;
- for (Double v : values){
- e = (int) Math.floor(Math.log10(v));
- tls.add(new ChartText("$10^{" + String.valueOf(e) + "}$"));
- }
- } else {
- for (int i = 0; i < this.getTickLocations().size(); i++) {
- if (i >= this.getTickLabels().size()) {
- break;
- }
- double v = this.getTickLocations().get(i);
- if (v >= this.getMinValue() && v <= this.getMaxValue()) {
- tls.add(this.getTickLabels().get(i));
- }
- }
- }
-
- this.setTickLabels(tls);
- }
-
- //
-}
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.meteoinfo.chart.axis;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.meteoinfo.chart.ChartText;
+import org.meteoinfo.common.MIMath;
+import org.meteoinfo.global.DataConvert;
+
+/**
+ *
+ * @author Yaqiang Wang
+ */
+public class LogAxis extends Axis {
+ //
+ //
+ //
+ /**
+ * Constructor
+ * @param axis Axis
+ */
+ public LogAxis(Axis axis){
+ super(axis);
+ }
+ //
+ //
+ //
+ //
+ /**
+ * Update tick values
+ */
+ @Override
+ public void updateTickValues() {
+ double[] r = MIMath.getIntervalValues_Log(this.getMinValue(), this.getMaxValue());
+ this.setTickValues((double[]) r);
+ this.setTickDeltaValue(1);
+ }
+
+ @Override
+ public void updateTickLabels(){
+ List tls = new ArrayList<>();
+ String lab;
+ if (this.isAutoTick()) {
+ if (this.getTickValues() == null) {
+ return;
+ }
+ for (double value : this.getTickValues()) {
+ lab = String.valueOf(value);
+ lab = DataConvert.removeTailingZeros(lab);
+ tls.add(new ChartText(lab));
+ }
+
+ List values = new ArrayList<>();
+ for (ChartText tl : tls){
+ values.add(Double.parseDouble(tl.getText()));
+ }
+ tls.clear();
+ int e;
+ for (Double v : values){
+ e = (int) Math.floor(Math.log10(v));
+ tls.add(new ChartText("$10^{" + String.valueOf(e) + "}$"));
+ }
+ } else {
+ for (int i = 0; i < this.getTickLocations().size(); i++) {
+ if (i >= this.getTickLabels().size()) {
+ break;
+ }
+ double v = this.getTickLocations().get(i);
+ if (v >= this.getMinValue() && v <= this.getMaxValue()) {
+ tls.add(this.getTickLabels().get(i));
+ }
+ }
+ }
+
+ this.setTickLabels(tls);
+ }
+
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/axis/ProjLonLatAxis.java b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/axis/ProjLonLatAxis.java
index 9a6d2182..ff14ef5e 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/axis/ProjLonLatAxis.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/axis/ProjLonLatAxis.java
@@ -1,174 +1,174 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.meteoinfo.chart.axis;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.meteoinfo.chart.ChartText;
-import org.meteoinfo.global.DataConvert;
-import org.meteoinfo.global.MIMath;
-import org.meteoinfo.projection.KnownCoordinateSystems;
-import org.meteoinfo.projection.info.ProjectionInfo;
-import org.meteoinfo.projection.Reproject;
-
-/**
- *
- * @author Yaqiang Wang
- */
-public class ProjLonLatAxis extends LonLatAxis{
- //
- private ProjectionInfo proj;
- private double x_y;
- //
- //
- /**
- * Constructor
- * @param label Label
- * @param isX Is x/longitude axis or not
- * @param proj Projection
- */
- public ProjLonLatAxis(String label, boolean isX, ProjectionInfo proj){
- super(label, isX, isX);
- this.proj = proj;
- }
-
- /**
- * Constructor
- * @param label Label
- * @param isX Is x/longitude axis or not
- * @param proj Projection
- * @param xy X or Y value of the axis - using for projection
- */
- public ProjLonLatAxis(String label, boolean isX, ProjectionInfo proj, double xy){
- super(label, isX);
- this.proj = proj;
- this.x_y = xy;
- }
- //
- //
- /**
- * Get projection
- * @return Projection
- */
- public ProjectionInfo getProject(){
- return this.proj;
- }
-
- /**
- * Set projection
- * @param value Projection
- */
- public void setProject(ProjectionInfo value){
- this.proj = value;
- }
-
- /**
- * Get x_y value
- * @return x_y value
- */
- public double getX_Y(){
- return this.x_y;
- }
-
- /**
- * Set x_y value
- * @param value x_y value
- */
- public void setX_Y(double value){
- this.x_y = value;
- //this.updateTickValues();
- }
- //
- //
- /**
- * Update tick values
- */
- @Override
- public void updateTickValues() {
- if (this.proj == null)
- return;
-
- double min = this.getMinValue();
- double max = this.getMaxValue();
- //Calculate min and max lon or lat
- ProjectionInfo toproj = KnownCoordinateSystems.geographic.world.WGS1984;
- double minv, maxv;
- double[][] points = new double[2][];
- if (this.isXAxis()){
- points[0] = new double[]{min, this.x_y};
- points[1] = new double[]{max, this.x_y};
- Reproject.reprojectPoints(points, this.proj, toproj);
- minv = points[0][0];
- maxv = points[1][0];
- } else {
- points[0] = new double[]{this.x_y, min};
- points[1] = new double[]{this.x_y, max};
- Reproject.reprojectPoints(points, this.proj, toproj);
- minv = points[0][1];
- maxv = points[1][1];
- }
- //Get tick values
- List r = MIMath.getIntervalValues1(minv, maxv);
- double[] values = (double[])r.get(0);
- double[] tickValues = new double[values.length];
-
- this.setTickValues((double[]) r.get(0));
- this.setTickDeltaValue((Double) r.get(1));
- }
-
- /**
- * Get tick labels
- *
- */
- @Override
- public void updateTickLabels() {
- List tls = new ArrayList<>();
- String lab;
- for (double v : this.getTickValues()) {
- double value = v;
- if (value > 180) {
- value = value - 360;
- }
- lab = String.valueOf(value);
- lab = DataConvert.removeTailingZeros(lab);
- if (this.isXAxis()) {
- if (value == -180) {
- lab = "180";
- } else if (!(value == 0 || value == 180)) {
- if (lab.substring(0, 1).equals("-")) {
- lab = lab.substring(1) + "W";
- } else {
- lab = lab + "E";
- }
- }
- } else {
- if (!(value == 0)) {
- if (lab.substring(0, 1).equals("-")) {
- lab = lab.substring(1) + "S";
- } else {
- lab = lab + "N";
- }
- }
- }
- if (this.isDrawDegreeSymbol()) {
- if (lab.endsWith("E") || lab.endsWith("W") || lab.endsWith("N") || lab.endsWith("S")) {
- lab = lab.substring(0, lab.length() - 1) + String.valueOf((char) 186) + lab.substring(lab.length() - 1);
- } else {
- lab = lab + String.valueOf((char) 186);
- }
- }
- tls.add(new ChartText(lab));
- }
-
- this.setTickLabels(tls);
- }
-
- @Override
- public Object clone() throws CloneNotSupportedException {
- return (ProjLonLatAxis)super.clone();
- }
- //
-}
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.meteoinfo.chart.axis;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.meteoinfo.chart.ChartText;
+import org.meteoinfo.common.MIMath;
+import org.meteoinfo.global.DataConvert;
+import org.meteoinfo.projection.KnownCoordinateSystems;
+import org.meteoinfo.projection.info.ProjectionInfo;
+import org.meteoinfo.projection.Reproject;
+
+/**
+ *
+ * @author Yaqiang Wang
+ */
+public class ProjLonLatAxis extends LonLatAxis{
+ //
+ private ProjectionInfo proj;
+ private double x_y;
+ //
+ //
+ /**
+ * Constructor
+ * @param label Label
+ * @param isX Is x/longitude axis or not
+ * @param proj Projection
+ */
+ public ProjLonLatAxis(String label, boolean isX, ProjectionInfo proj){
+ super(label, isX, isX);
+ this.proj = proj;
+ }
+
+ /**
+ * Constructor
+ * @param label Label
+ * @param isX Is x/longitude axis or not
+ * @param proj Projection
+ * @param xy X or Y value of the axis - using for projection
+ */
+ public ProjLonLatAxis(String label, boolean isX, ProjectionInfo proj, double xy){
+ super(label, isX);
+ this.proj = proj;
+ this.x_y = xy;
+ }
+ //
+ //
+ /**
+ * Get projection
+ * @return Projection
+ */
+ public ProjectionInfo getProject(){
+ return this.proj;
+ }
+
+ /**
+ * Set projection
+ * @param value Projection
+ */
+ public void setProject(ProjectionInfo value){
+ this.proj = value;
+ }
+
+ /**
+ * Get x_y value
+ * @return x_y value
+ */
+ public double getX_Y(){
+ return this.x_y;
+ }
+
+ /**
+ * Set x_y value
+ * @param value x_y value
+ */
+ public void setX_Y(double value){
+ this.x_y = value;
+ //this.updateTickValues();
+ }
+ //
+ //
+ /**
+ * Update tick values
+ */
+ @Override
+ public void updateTickValues() {
+ if (this.proj == null)
+ return;
+
+ double min = this.getMinValue();
+ double max = this.getMaxValue();
+ //Calculate min and max lon or lat
+ ProjectionInfo toproj = KnownCoordinateSystems.geographic.world.WGS1984;
+ double minv, maxv;
+ double[][] points = new double[2][];
+ if (this.isXAxis()){
+ points[0] = new double[]{min, this.x_y};
+ points[1] = new double[]{max, this.x_y};
+ Reproject.reprojectPoints(points, this.proj, toproj);
+ minv = points[0][0];
+ maxv = points[1][0];
+ } else {
+ points[0] = new double[]{this.x_y, min};
+ points[1] = new double[]{this.x_y, max};
+ Reproject.reprojectPoints(points, this.proj, toproj);
+ minv = points[0][1];
+ maxv = points[1][1];
+ }
+ //Get tick values
+ List r = MIMath.getIntervalValues1(minv, maxv);
+ double[] values = (double[])r.get(0);
+ double[] tickValues = new double[values.length];
+
+ this.setTickValues((double[]) r.get(0));
+ this.setTickDeltaValue((Double) r.get(1));
+ }
+
+ /**
+ * Get tick labels
+ *
+ */
+ @Override
+ public void updateTickLabels() {
+ List tls = new ArrayList<>();
+ String lab;
+ for (double v : this.getTickValues()) {
+ double value = v;
+ if (value > 180) {
+ value = value - 360;
+ }
+ lab = String.valueOf(value);
+ lab = DataConvert.removeTailingZeros(lab);
+ if (this.isXAxis()) {
+ if (value == -180) {
+ lab = "180";
+ } else if (!(value == 0 || value == 180)) {
+ if (lab.substring(0, 1).equals("-")) {
+ lab = lab.substring(1) + "W";
+ } else {
+ lab = lab + "E";
+ }
+ }
+ } else {
+ if (!(value == 0)) {
+ if (lab.substring(0, 1).equals("-")) {
+ lab = lab.substring(1) + "S";
+ } else {
+ lab = lab + "N";
+ }
+ }
+ }
+ if (this.isDrawDegreeSymbol()) {
+ if (lab.endsWith("E") || lab.endsWith("W") || lab.endsWith("N") || lab.endsWith("S")) {
+ lab = lab.substring(0, lab.length() - 1) + String.valueOf((char) 186) + lab.substring(lab.length() - 1);
+ } else {
+ lab = lab + String.valueOf((char) 186);
+ }
+ }
+ tls.add(new ChartText(lab));
+ }
+
+ this.setTickLabels(tls);
+ }
+
+ @Override
+ public Object clone() throws CloneNotSupportedException {
+ return (ProjLonLatAxis)super.clone();
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/axis/TimeAxis.java b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/axis/TimeAxis.java
index 5841f86b..8694fa7c 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/axis/TimeAxis.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/axis/TimeAxis.java
@@ -8,10 +8,9 @@ package org.meteoinfo.chart.axis;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
-import java.util.Calendar;
import java.util.List;
import org.meteoinfo.chart.ChartText;
-import org.meteoinfo.global.util.JDateUtil;
+import org.meteoinfo.common.util.JDateUtil;
/**
*
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/jogl/GLChartPanel.java b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/jogl/GLChartPanel.java
index 2427ed24..46276ab1 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/jogl/GLChartPanel.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/jogl/GLChartPanel.java
@@ -18,7 +18,6 @@ import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.*;
-import javax.imageio.metadata.IIOInvalidTreeException;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.plugins.jpeg.JPEGImageWriteParam;
import javax.imageio.stream.ImageOutputStream;
@@ -26,7 +25,7 @@ import javax.swing.*;
import org.meteoinfo.chart.IChartPanel;
import org.meteoinfo.chart.MouseMode;
-import org.meteoinfo.global.Extent3D;
+import org.meteoinfo.common.Extent3D;
import org.meteoinfo.image.ImageUtil;
import org.w3c.dom.Element;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/jogl/IsosurfaceGraphics.java b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/jogl/IsosurfaceGraphics.java
index a164f92e..6fbccfbb 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/jogl/IsosurfaceGraphics.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/jogl/IsosurfaceGraphics.java
@@ -1,58 +1,59 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.meteoinfo.chart.jogl;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.meteoinfo.chart.plot3d.GraphicCollection3D;
-import org.meteoinfo.global.Extent3D;
-import org.meteoinfo.global.MIMath;
-import org.meteoinfo.shape.PointZ;
-
-/**
- *
- * @author yaqiang
- */
-public class IsosurfaceGraphics extends GraphicCollection3D {
- private List triangles = new ArrayList<>();
-
- /**
- * Constructor
- */
- public IsosurfaceGraphics() {
- super();
- this.allTriangle = true;
- }
-
- /**
- * Get triangles
- * @return Triangles
- */
- public List getTriangles() {
- return this.triangles;
- }
-
- /**
- * Set triangles
- * @param value Triangles
- */
- public void setTriangles(List value) {
- this.triangles = value;
- }
-
- /**
- * Add a triangle
- * @param triangle Triangle
- */
- public void addTriangle(PointZ[] triangle) {
- this.triangles.add(triangle);
- Extent3D extent = MIMath.getExtent(triangle);
- if (this.triangles.size() == 1)
- this.setExtent(extent);
- else
- this.setExtent(MIMath.getLagerExtent(extent, this.getExtent()));
- }
-}
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.meteoinfo.chart.jogl;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.meteoinfo.chart.plot3d.GraphicCollection3D;
+import org.meteoinfo.common.Extent3D;
+import org.meteoinfo.common.MIMath;
+import org.meteoinfo.geoprocess.GeometryUtil;
+import org.meteoinfo.shape.PointZ;
+
+/**
+ *
+ * @author yaqiang
+ */
+public class IsosurfaceGraphics extends GraphicCollection3D {
+ private List triangles = new ArrayList<>();
+
+ /**
+ * Constructor
+ */
+ public IsosurfaceGraphics() {
+ super();
+ this.allTriangle = true;
+ }
+
+ /**
+ * Get triangles
+ * @return Triangles
+ */
+ public List getTriangles() {
+ return this.triangles;
+ }
+
+ /**
+ * Set triangles
+ * @param value Triangles
+ */
+ public void setTriangles(List value) {
+ this.triangles = value;
+ }
+
+ /**
+ * Add a triangle
+ * @param triangle Triangle
+ */
+ public void addTriangle(PointZ[] triangle) {
+ this.triangles.add(triangle);
+ Extent3D extent = GeometryUtil.getExtent(triangle);
+ if (this.triangles.size() == 1)
+ this.setExtent(extent);
+ else
+ this.setExtent(MIMath.getLagerExtent(extent, this.getExtent()));
+ }
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/jogl/JOGLUtil.java b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/jogl/JOGLUtil.java
index 30af1c35..3dbe88ed 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/jogl/JOGLUtil.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/jogl/JOGLUtil.java
@@ -15,8 +15,8 @@ import java.util.Random;
import org.meteoinfo.chart.jogl.mc.MarchingCubes;
import org.meteoinfo.chart.jogl.mc.CallbackMC;
import org.meteoinfo.chart.plot3d.GraphicCollection3D;
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.global.Extent3D;
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.Extent3D;
import org.meteoinfo.layer.ImageLayer;
import org.meteoinfo.legend.ColorBreak;
import org.meteoinfo.legend.LegendScheme;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/jogl/Plot3DGL.java b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/jogl/Plot3DGL.java
index d0b24087..6c75b446 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/jogl/Plot3DGL.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/jogl/Plot3DGL.java
@@ -6,15 +6,12 @@
package org.meteoinfo.chart.jogl;
import com.jogamp.opengl.*;
-import com.jogamp.opengl.fixedfunc.GLLightingFunc;
import com.jogamp.opengl.glu.GLU;
import com.jogamp.opengl.glu.GLUquadric;
import com.jogamp.opengl.glu.GLUtessellator;
-import com.jogamp.opengl.glu.GLUtessellatorCallback;
import com.jogamp.opengl.util.awt.AWTGLReadBufferUtil;
import com.jogamp.opengl.util.awt.TextRenderer;
import com.jogamp.opengl.util.texture.Texture;
-import com.jogamp.opengl.util.texture.TextureCoords;
import com.jogamp.opengl.util.texture.awt.AWTTextureIO;
import com.jogamp.opengl.util.gl2.GLUT;
import com.jogamp.opengl.math.VectorUtil;
@@ -33,7 +30,6 @@ import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
-import jogamp.opengl.glu.tessellator.GLUtessellatorImpl;
import org.meteoinfo.chart.ChartColorBar;
import org.meteoinfo.chart.ChartLegend;
import org.meteoinfo.chart.ChartText;
@@ -41,23 +37,18 @@ import org.meteoinfo.chart.ChartText3D;
import org.meteoinfo.chart.Margin;
import org.meteoinfo.chart.axis.Axis;
import org.meteoinfo.chart.jogl.tessellator.Primitive;
-import org.meteoinfo.chart.jogl.tessellator.PrimitiveTessellator;
import org.meteoinfo.chart.jogl.tessellator.TessPolygon;
-import org.meteoinfo.chart.jogl.tessellator.TriangleTessellator;
import org.meteoinfo.chart.plot.*;
import org.meteoinfo.chart.plot3d.GraphicCollection3D;
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.Extent3D;
import org.meteoinfo.data.Dataset;
import org.meteoinfo.geoprocess.GeometryUtil;
import org.meteoinfo.global.DataConvert;
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.global.Extent3D;
-import org.meteoinfo.global.util.FontUtil;
import org.meteoinfo.legend.*;
import org.meteoinfo.math.meteo.MeteoMath;
import org.meteoinfo.shape.*;
-import static org.meteoinfo.shape.ShapeTypes.PointZ;
-
/**
*
* @author wyq
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/jogl/SurfaceGraphics.java b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/jogl/SurfaceGraphics.java
index d2951e85..dc884495 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/jogl/SurfaceGraphics.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/jogl/SurfaceGraphics.java
@@ -6,7 +6,7 @@
package org.meteoinfo.chart.jogl;
import org.meteoinfo.chart.plot3d.GraphicCollection3D;
-import org.meteoinfo.global.Extent3D;
+import org.meteoinfo.common.Extent3D;
import org.meteoinfo.legend.ColorBreak;
import org.meteoinfo.legend.LegendScheme;
import org.meteoinfo.legend.PolygonBreak;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/jogl/Transform.java b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/jogl/Transform.java
index 8936a203..9bedae10 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/jogl/Transform.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/jogl/Transform.java
@@ -1,6 +1,6 @@
package org.meteoinfo.chart.jogl;
-import org.meteoinfo.global.Extent3D;
+import org.meteoinfo.common.Extent3D;
import org.meteoinfo.shape.PointZ;
public class Transform {
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/plot/AbstractPlot2D.java b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/plot/AbstractPlot2D.java
index 370abcf2..7fcd0727 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/plot/AbstractPlot2D.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/plot/AbstractPlot2D.java
@@ -27,11 +27,9 @@ import org.meteoinfo.chart.Location;
import org.meteoinfo.chart.Margin;
import org.meteoinfo.chart.axis.Axis;
import org.meteoinfo.chart.axis.LogAxis;
-import static org.meteoinfo.chart.plot.Plot.MINIMUM_HEIGHT_TO_DRAW;
-import static org.meteoinfo.chart.plot.Plot.MINIMUM_WIDTH_TO_DRAW;
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.PointF;
import org.meteoinfo.drawing.Draw;
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.global.PointF;
/**
*
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/plot/GraphicFactory.java b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/plot/GraphicFactory.java
index 631a6090..6abfbbd6 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/plot/GraphicFactory.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/plot/GraphicFactory.java
@@ -18,20 +18,19 @@ import java.util.List;
import org.apache.commons.lang3.ArrayUtils;
import org.meteoinfo.chart.ChartText;
import org.meteoinfo.chart.plot3d.GraphicCollection3D;
-import org.meteoinfo.math.ArrayMath;
-import org.meteoinfo.math.ArrayUtil;
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.Extent3D;
+import org.meteoinfo.common.MIMath;
+import org.meteoinfo.common.PointD;
import org.meteoinfo.data.GridArray;
import org.meteoinfo.data.GridData;
import org.meteoinfo.data.XYListDataset;
import org.meteoinfo.data.analysis.Statistics;
import org.meteoinfo.drawing.ContourDraw;
import org.meteoinfo.drawing.Draw;
+import org.meteoinfo.geoprocess.GeometryUtil;
import org.meteoinfo.legend.PointStyle;
import org.meteoinfo.geoprocess.GeoComputation;
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.global.Extent3D;
-import org.meteoinfo.global.MIMath;
-import org.meteoinfo.global.PointD;
import org.meteoinfo.layer.ImageLayer;
import org.meteoinfo.layer.VectorLayer;
import org.meteoinfo.legend.ArrowLineBreak;
@@ -48,6 +47,8 @@ import org.meteoinfo.legend.PointBreak;
import org.meteoinfo.legend.PolygonBreak;
import org.meteoinfo.legend.PolylineBreak;
import org.meteoinfo.legend.StreamlineBreak;
+import org.meteoinfo.math.ArrayMath;
+import org.meteoinfo.math.ArrayUtil;
import org.meteoinfo.math.meteo.MeteoMath;
import org.meteoinfo.ndarray.*;
import org.meteoinfo.ndarray.util.BigDecimalUtil;
@@ -3100,7 +3101,7 @@ public class GraphicFactory {
}
aPolyline.setPoints(pList);
aPolyline.setValue(v);
- aPolyline.setExtent(MIMath.getPointsExtent(pList));
+ aPolyline.setExtent(GeometryUtil.getPointsExtent(pList));
switch (ls.getLegendType()) {
case UniqueValue:
@@ -3216,7 +3217,7 @@ public class GraphicFactory {
}
aPolyline.setPoints(pList);
aPolyline.setValue(v);
- aPolyline.setExtent(MIMath.getPointsExtent(pList));
+ aPolyline.setExtent(GeometryUtil.getPointsExtent(pList));
cbb = ls.findLegendBreak(v);
graphics.add(new Graphic(aPolyline, cbb));
}
@@ -3325,7 +3326,7 @@ public class GraphicFactory {
}
aPolyline.setPoints(pList);
aPolyline.setValue(v);
- aPolyline.setExtent(MIMath.getPointsExtent(pList));
+ aPolyline.setExtent(GeometryUtil.getPointsExtent(pList));
cbb = ls.findLegendBreak(v);
graphics.add(new Graphic(aPolyline, cbb));
}
@@ -3391,7 +3392,7 @@ public class GraphicFactory {
}
PolygonShape aPolygonShape = new PolygonShape();
aPolygonShape.setPoints(pList);
- aPolygonShape.setExtent(MIMath.getPointsExtent(pList));
+ aPolygonShape.setExtent(GeometryUtil.getPointsExtent(pList));
aPolygonShape.lowValue = v;
if (poly.HasHoles()) {
for (PolyLine holeLine : poly.HoleLines) {
@@ -3555,7 +3556,7 @@ public class GraphicFactory {
}
PolygonZShape aPolygonShape = new PolygonZShape();
aPolygonShape.setPoints(pList);
- aPolygonShape.setExtent(MIMath.getPointsExtent(pList));
+ aPolygonShape.setExtent(GeometryUtil.getPointsExtent(pList));
aPolygonShape.lowValue = v;
if (poly.HasHoles()) {
switch (zdir) {
@@ -3734,7 +3735,7 @@ public class GraphicFactory {
}
PolygonZShape aPolygonShape = new PolygonZShape();
aPolygonShape.setPoints(pList);
- aPolygonShape.setExtent(MIMath.getPointsExtent(pList));
+ aPolygonShape.setExtent(GeometryUtil.getPointsExtent(pList));
aPolygonShape.lowValue = v;
if (poly.HasHoles()) {
switch (zdir) {
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/plot/MapPlot.java b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/plot/MapPlot.java
index c24c86fe..b9900e09 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/plot/MapPlot.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/plot/MapPlot.java
@@ -28,15 +28,14 @@ import org.meteoinfo.chart.ChartScaleBar;
import org.meteoinfo.chart.ChartText;
import org.meteoinfo.chart.Location;
import org.meteoinfo.chart.axis.LonLatAxis;
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.MIMath;
+import org.meteoinfo.common.PointD;
+import org.meteoinfo.common.PointF;
import org.meteoinfo.data.Dataset;
import org.meteoinfo.data.mapdata.webmap.IWebMapPanel;
import org.meteoinfo.data.mapdata.webmap.TileLoadListener;
import org.meteoinfo.drawing.Draw;
-import org.meteoinfo.global.Direction;
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.global.MIMath;
-import org.meteoinfo.global.PointD;
-import org.meteoinfo.global.PointF;
import org.meteoinfo.layer.LayerCollection;
import org.meteoinfo.layer.MapLayer;
import org.meteoinfo.legend.LabelBreak;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/plot/PiePlot.java b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/plot/PiePlot.java
index 7ec6b371..6c4865a9 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/plot/PiePlot.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/plot/PiePlot.java
@@ -1,160 +1,161 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.meteoinfo.chart.plot;
-
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.Font;
-import java.awt.Graphics2D;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Rectangle2D;
-import org.meteoinfo.drawing.Draw;
-import org.meteoinfo.global.PointF;
-import org.meteoinfo.legend.ColorBreak;
-import org.meteoinfo.legend.PolygonBreak;
-import org.meteoinfo.shape.ArcShape;
-import org.meteoinfo.shape.Graphic;
-import org.meteoinfo.shape.GraphicCollection;
-import org.meteoinfo.shape.Shape;
-
-/**
- *
- * @author Yaqiang Wang
- */
-public class PiePlot extends Plot2D {
-
- //
- //
- //
- /**
- * Constructor
- */
- public PiePlot(){
- super();
- this.setAutoAspect(false);
- }
- //
- //
- //
- //
- @Override
- void drawGraph(Graphics2D g, Rectangle2D area) {
- AffineTransform oldMatrix = g.getTransform();
- //Rectangle oldRegion = g.getClipBounds();
- //g.setClip(area);
- g.translate(area.getX(), area.getY());
-
- //Draw background
- if (this.background != null) {
- g.setColor(this.getBackground());
- g.fill(new Rectangle2D.Double(0, 0, area.getWidth(), area.getHeight()));
- }
-
- for (int m = 0; m < this.getGraphics().getNumGraphics(); m++) {
- Graphic graphic = this.getGraphics().get(m);
- ColorBreak cb = graphic.getLegend();
- float dist = 5;
- float ex = this.getExplode();
- Font labelFont = ((GraphicCollection)graphic).getLabelSet().getLabelFont();
- Color labelColor = ((GraphicCollection)graphic).getLabelSet().getLabelColor();
- for (int i = 0; i < graphic.getNumGraphics(); i++) {
- Graphic gg = graphic.getGraphicN(i);
- if (!graphic.isSingleLegend()) {
- cb = gg.getLegend();
- }
- Shape shape = gg.getShape();
- this.drawArc(g, (ArcShape) shape, (PolygonBreak) cb, area, dist, ex, labelFont,
- labelColor);
- }
- }
-
- g.setTransform(oldMatrix);
- //g.setClip(oldRegion);
- }
-
- private float getExplode() {
- Graphic graphic = this.getGraphics().get(0);
- float ex = 0;
- for (int i = 0; i < graphic.getNumGraphics(); i++) {
- Graphic gg = graphic.getGraphicN(i);
- ArcShape shape = (ArcShape) gg.getShape();
- if (shape.getExplode() > 0) {
- ex = 10;
- break;
- }
- }
- return ex;
- }
-
- private void drawArc(Graphics2D g, ArcShape aShape, PolygonBreak aPGB,
- Rectangle2D area, float dist, float ex, Font labelFont, Color labelColor) {
- float startAngle = aShape.getStartAngle();
- float sweepAngle = aShape.getSweepAngle();
- float angle = startAngle + sweepAngle / 2;
- float space = 20;
- Rectangle2D rect = new Rectangle2D.Double(area.getX() + ex + space, area.getY() + ex + space, area.getWidth() - ex - space,
- area.getHeight() - ex - space);
- double dx = 0, dy = 0;
- if (aShape.getExplode() > 0) {
- dx = ex * Math.cos((360 - angle) * Math.PI / 180);
- dy = ex * Math.sin((360 - angle) * Math.PI / 180);
- rect.setRect(rect.getX() + dx, rect.getY() + dy, rect.getWidth(), rect.getHeight());
- }
- float sx = (float) (rect.getX() - area.getX());
- float sy = (float) (rect.getY() - area.getY());
- Draw.drawPie(new PointF(sx, sy), (float) rect.getWidth(), (float) rect.getHeight(),
- startAngle, sweepAngle, aPGB, g);
-
- //Draw label
- //Rectangle clip = g.getClipBounds();
- //if (clip != null) {
- // g.setClip(null);
- //}
- float x, y, w, h;
- PointF sPoint = new PointF((float) (rect.getWidth() * 0.5 + sx), (float) (rect.getHeight() * 0.5 + sy));
- String label = aPGB.getCaption();
- if (angle > 360) {
- angle = angle - 360;
- }
- float r = (float) (rect.getWidth() * 0.5) + dist;
- PointF lPoint = Draw.getPieLabelPoint(sPoint, r, angle);
- x = lPoint.X;
- y = lPoint.Y;
- Dimension dim = Draw.getStringDimension(label, g);
- h = dim.height;
- w = dim.width;
- if ((angle >= 0 && angle < 45)) {
- //x = x + dis;
- y = y - h;
- } else if (angle >= 45 && angle < 90) {
- //y = y - dis;
- } else if (angle >= 90 && angle < 135) {
- x = x - w;
- //y = y - dis;
- } else if (angle >= 135 && angle < 225) {
- x = x - w - 3;
- y = y + h / 2;
- } else if (angle >= 225 && angle < 270) {
- x = x - w / 2;
- y = y + h;
- } else if (angle >= 270 && angle < 315) {
- //x = x + dis;
- y = y + h;
- } else {
- //x = x + dis;
- y = y + h / 2;
- }
- g.setFont(labelFont);
- g.setColor(labelColor);
- //g.drawOval((int)(x - 3), (int)(y - 3), 6, 6);
- g.drawString(label, x, y);
-
- //if (clip != null) {
- // g.setClip(clip);
- //}
- }
- //
-}
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.meteoinfo.chart.plot;
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.Graphics2D;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+
+import org.meteoinfo.common.PointF;
+import org.meteoinfo.drawing.Draw;
+import org.meteoinfo.legend.ColorBreak;
+import org.meteoinfo.legend.PolygonBreak;
+import org.meteoinfo.shape.ArcShape;
+import org.meteoinfo.shape.Graphic;
+import org.meteoinfo.shape.GraphicCollection;
+import org.meteoinfo.shape.Shape;
+
+/**
+ *
+ * @author Yaqiang Wang
+ */
+public class PiePlot extends Plot2D {
+
+ //
+ //
+ //
+ /**
+ * Constructor
+ */
+ public PiePlot(){
+ super();
+ this.setAutoAspect(false);
+ }
+ //
+ //
+ //
+ //
+ @Override
+ void drawGraph(Graphics2D g, Rectangle2D area) {
+ AffineTransform oldMatrix = g.getTransform();
+ //Rectangle oldRegion = g.getClipBounds();
+ //g.setClip(area);
+ g.translate(area.getX(), area.getY());
+
+ //Draw background
+ if (this.background != null) {
+ g.setColor(this.getBackground());
+ g.fill(new Rectangle2D.Double(0, 0, area.getWidth(), area.getHeight()));
+ }
+
+ for (int m = 0; m < this.getGraphics().getNumGraphics(); m++) {
+ Graphic graphic = this.getGraphics().get(m);
+ ColorBreak cb = graphic.getLegend();
+ float dist = 5;
+ float ex = this.getExplode();
+ Font labelFont = ((GraphicCollection)graphic).getLabelSet().getLabelFont();
+ Color labelColor = ((GraphicCollection)graphic).getLabelSet().getLabelColor();
+ for (int i = 0; i < graphic.getNumGraphics(); i++) {
+ Graphic gg = graphic.getGraphicN(i);
+ if (!graphic.isSingleLegend()) {
+ cb = gg.getLegend();
+ }
+ Shape shape = gg.getShape();
+ this.drawArc(g, (ArcShape) shape, (PolygonBreak) cb, area, dist, ex, labelFont,
+ labelColor);
+ }
+ }
+
+ g.setTransform(oldMatrix);
+ //g.setClip(oldRegion);
+ }
+
+ private float getExplode() {
+ Graphic graphic = this.getGraphics().get(0);
+ float ex = 0;
+ for (int i = 0; i < graphic.getNumGraphics(); i++) {
+ Graphic gg = graphic.getGraphicN(i);
+ ArcShape shape = (ArcShape) gg.getShape();
+ if (shape.getExplode() > 0) {
+ ex = 10;
+ break;
+ }
+ }
+ return ex;
+ }
+
+ private void drawArc(Graphics2D g, ArcShape aShape, PolygonBreak aPGB,
+ Rectangle2D area, float dist, float ex, Font labelFont, Color labelColor) {
+ float startAngle = aShape.getStartAngle();
+ float sweepAngle = aShape.getSweepAngle();
+ float angle = startAngle + sweepAngle / 2;
+ float space = 20;
+ Rectangle2D rect = new Rectangle2D.Double(area.getX() + ex + space, area.getY() + ex + space, area.getWidth() - ex - space,
+ area.getHeight() - ex - space);
+ double dx = 0, dy = 0;
+ if (aShape.getExplode() > 0) {
+ dx = ex * Math.cos((360 - angle) * Math.PI / 180);
+ dy = ex * Math.sin((360 - angle) * Math.PI / 180);
+ rect.setRect(rect.getX() + dx, rect.getY() + dy, rect.getWidth(), rect.getHeight());
+ }
+ float sx = (float) (rect.getX() - area.getX());
+ float sy = (float) (rect.getY() - area.getY());
+ Draw.drawPie(new PointF(sx, sy), (float) rect.getWidth(), (float) rect.getHeight(),
+ startAngle, sweepAngle, aPGB, g);
+
+ //Draw label
+ //Rectangle clip = g.getClipBounds();
+ //if (clip != null) {
+ // g.setClip(null);
+ //}
+ float x, y, w, h;
+ PointF sPoint = new PointF((float) (rect.getWidth() * 0.5 + sx), (float) (rect.getHeight() * 0.5 + sy));
+ String label = aPGB.getCaption();
+ if (angle > 360) {
+ angle = angle - 360;
+ }
+ float r = (float) (rect.getWidth() * 0.5) + dist;
+ PointF lPoint = Draw.getPieLabelPoint(sPoint, r, angle);
+ x = lPoint.X;
+ y = lPoint.Y;
+ Dimension dim = Draw.getStringDimension(label, g);
+ h = dim.height;
+ w = dim.width;
+ if ((angle >= 0 && angle < 45)) {
+ //x = x + dis;
+ y = y - h;
+ } else if (angle >= 45 && angle < 90) {
+ //y = y - dis;
+ } else if (angle >= 90 && angle < 135) {
+ x = x - w;
+ //y = y - dis;
+ } else if (angle >= 135 && angle < 225) {
+ x = x - w - 3;
+ y = y + h / 2;
+ } else if (angle >= 225 && angle < 270) {
+ x = x - w / 2;
+ y = y + h;
+ } else if (angle >= 270 && angle < 315) {
+ //x = x + dis;
+ y = y + h;
+ } else {
+ //x = x + dis;
+ y = y + h / 2;
+ }
+ g.setFont(labelFont);
+ g.setColor(labelColor);
+ //g.drawOval((int)(x - 3), (int)(y - 3), 6, 6);
+ g.drawString(label, x, y);
+
+ //if (clip != null) {
+ // g.setClip(clip);
+ //}
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/plot/Plot2D.java b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/plot/Plot2D.java
index 71f0dccb..6010a86f 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/plot/Plot2D.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/plot/Plot2D.java
@@ -35,16 +35,17 @@ 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.common.Extent;
+import org.meteoinfo.common.MIMath;
+import org.meteoinfo.common.PointD;
+import org.meteoinfo.common.PointF;
import org.meteoinfo.data.Dataset;
import org.meteoinfo.drawing.Draw;
import static org.meteoinfo.drawing.Draw.getHatchImage;
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.global.MIMath;
-import org.meteoinfo.global.PointD;
-import org.meteoinfo.global.PointF;
+
+import org.meteoinfo.geoprocess.GeometryUtil;
import org.meteoinfo.legend.ArrowBreak;
import org.meteoinfo.legend.BarBreak;
-import static org.meteoinfo.legend.BreakTypes.LabelBreak;
import org.meteoinfo.legend.ColorBreak;
import org.meteoinfo.legend.ColorBreakCollection;
import org.meteoinfo.legend.LabelBreak;
@@ -767,7 +768,7 @@ public class Plot2D extends AbstractPlot2D {
aY = (float) sXY[1];
points.add(new PointD(aX, aY));
}
- Extent aExtent = MIMath.getPointsExtent(points);
+ Extent aExtent = GeometryUtil.getPointsExtent(points);
rect.x = (int) aExtent.minX;
rect.y = (int) aExtent.minY;
rect.width = (int) (aExtent.maxX - aExtent.minX);
@@ -779,7 +780,7 @@ public class Plot2D extends AbstractPlot2D {
}
private List drawPolygon(Graphics2D g, Polygon aPG, PolygonBreak aPGB,
- boolean isSelected, Rectangle2D area) {
+ boolean isSelected, Rectangle2D area) {
int len = aPG.getOutLine().size();
GeneralPath path = new GeneralPath(GeneralPath.WIND_EVEN_ODD, len);
PointD wPoint;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/plot/Plot3D.java b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/plot/Plot3D.java
index 8f938963..958dcbd6 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/plot/Plot3D.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/plot/Plot3D.java
@@ -10,7 +10,6 @@ import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
-import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
@@ -31,13 +30,13 @@ import org.meteoinfo.chart.axis.Axis;
import org.meteoinfo.chart.axis.LogAxis;
import org.meteoinfo.chart.plot3d.GraphicCollection3D;
import org.meteoinfo.chart.plot3d.Projector;
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.Extent3D;
+import org.meteoinfo.common.MIMath;
+import org.meteoinfo.common.PointF;
import org.meteoinfo.data.DataMath;
import org.meteoinfo.data.Dataset;
import org.meteoinfo.drawing.Draw;
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.global.Extent3D;
-import org.meteoinfo.global.MIMath;
-import org.meteoinfo.global.PointF;
import org.meteoinfo.legend.*;
import org.meteoinfo.math.sort.QuickSort;
import org.meteoinfo.shape.*;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/plot/PolarPlot.java b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/plot/PolarPlot.java
index a3b4c9d2..d233f8e0 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/plot/PolarPlot.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/plot/PolarPlot.java
@@ -16,11 +16,11 @@ import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.List;
import org.meteoinfo.chart.Margin;
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.MIMath;
import org.meteoinfo.drawing.Draw;
import static org.meteoinfo.drawing.Draw.getDashPattern;
import org.meteoinfo.global.DataConvert;
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.global.MIMath;
import org.meteoinfo.legend.LineStyles;
import org.meteoinfo.shape.Graphic;
import org.meteoinfo.shape.GraphicCollection;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/plot/XY1DPlot.java b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/plot/XY1DPlot.java
index 384f1a4e..abcf29e4 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/chart/plot/XY1DPlot.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/chart/plot/XY1DPlot.java
@@ -1,874 +1,874 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.meteoinfo.chart.plot;
-
-import java.awt.Color;
-import java.awt.Graphics2D;
-import java.awt.Rectangle;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Line2D;
-import java.awt.geom.Rectangle2D;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import org.meteoinfo.chart.ChartLegend;
-import org.meteoinfo.chart.Location;
-import org.meteoinfo.chart.axis.TimeAxis;
-import org.meteoinfo.data.Dataset;
-import org.meteoinfo.data.XYDataset;
-import org.meteoinfo.data.XYErrorSeriesData;
-import org.meteoinfo.data.XYListDataset;
-import org.meteoinfo.data.XYSeriesData;
-import org.meteoinfo.data.XYYSeriesData;
-import org.meteoinfo.drawing.Draw;
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.global.MIMath;
-import org.meteoinfo.global.PointF;
-import org.meteoinfo.global.colors.ColorUtil;
-import org.meteoinfo.legend.ColorBreak;
-import org.meteoinfo.legend.LegendScheme;
-import org.meteoinfo.legend.PointBreak;
-import org.meteoinfo.legend.PolygonBreak;
-import org.meteoinfo.legend.PolylineBreak;
-import org.meteoinfo.shape.ShapeTypes;
-
-/**
- *
- * @author yaqiang
- */
-public class XY1DPlot extends AbstractPlot2D {
-
- //
- private XYListDataset dataset;
- private ChartPlotMethod chartPlotMethod;
- private List seriesLegends;
- private boolean useBreak2D;
- private float barWidth;
- private boolean autoBarWidth;
-
- //
- //
- /**
- * Constructor
- */
- public XY1DPlot() {
- super();
-
- this.dataset = new XYListDataset();
- this.chartPlotMethod = ChartPlotMethod.LINE;
- this.useBreak2D = false;
- this.seriesLegends = new ArrayList<>();
- this.barWidth = 0.8f;
- this.autoBarWidth = true;
- }
-
- /**
- * Constructor
- *
- * @param dateset Dataset
- */
- public XY1DPlot(XYDataset dateset) {
- this();
- this.setDataset(dateset);
- }
-
- /**
- * Constructor
- *
- * @param orientation Plot orientation
- * @param dateset Dataset
- */
- public XY1DPlot(PlotOrientation orientation, XYDataset dateset) {
- this();
- this.setPlotOrientation(orientation);
- this.setDataset(dateset);
- }
-
- /**
- * Constructor
- *
- * @param isTime If x axis is time
- * @param dateset Dataset
- */
- public XY1DPlot(boolean isTime, XYDataset dateset) {
- this();
- if (isTime) {
- try {
- this.setXAxis(new TimeAxis("X", true));
- } catch (CloneNotSupportedException ex) {
- Logger.getLogger(XY1DPlot.class.getName()).log(Level.SEVERE, null, ex);
- }
- this.getAxis(Location.TOP).setDrawTickLabel(false);
- }
- //this.getXAxis().setTimeAxis(isTime);
- this.setDataset(dateset);
- }
-
- /**
- * Constructor
- *
- * @param isTime If x axis is time
- * @param cpMethod Plot method
- * @param dateset Dataset
- */
- public XY1DPlot(boolean isTime, ChartPlotMethod cpMethod, XYDataset dateset) {
- this();
- if (isTime) {
- try {
- this.setXAxis(new TimeAxis("X", true));
- } catch (CloneNotSupportedException ex) {
- Logger.getLogger(XY1DPlot.class.getName()).log(Level.SEVERE, null, ex);
- }
- this.getAxis(Location.TOP).setDrawTickLabel(false);
- }
- //this.getXAxis().setTimeAxis(isTime);
- this.setChartPlotMethod(cpMethod);
- this.setDataset(dateset);
- }
-
- /**
- * Constructor
- *
- * @param isTime If x axis is time
- * @param orientation Plot orientation
- * @param dateset Dataset
- */
- public XY1DPlot(boolean isTime, PlotOrientation orientation, XYDataset dateset) {
- this();
- if (isTime) {
- try {
- this.setXAxis(new TimeAxis("X", true));
- } catch (CloneNotSupportedException ex) {
- Logger.getLogger(XY1DPlot.class.getName()).log(Level.SEVERE, null, ex);
- }
- this.getAxis(Location.TOP).setDrawTickLabel(false);
- }
- //this.getXAxis().setTimeAxis(isTime);
- this.setPlotOrientation(orientation);
- this.setDataset(dateset);
- }
-
- //
- //
- @Override
- public XYDataset getDataset() {
- return dataset;
- }
-
- @Override
- public void setDataset(Dataset value) {
- dataset = (XYListDataset) value;
- Extent extent = this.getAutoExtent();
- this.setDrawExtent(extent);
- this.setExtent(extent);
- this.updateSeriesLegend();
- }
-
- private void updateSeriesLegend() {
- //this.seriesLegends.clear();
- int si = this.seriesLegends.size();
- if (si > dataset.getSeriesCount()) {
- si = 0;
- }
- for (int i = si; i < dataset.getSeriesCount(); i++) {
- Color color = ColorUtil.getCommonColor(i);
- switch (this.chartPlotMethod) {
- case LINE:
- case LINE_POINT:
- PolylineBreak plb = new PolylineBreak();
- if (this.chartPlotMethod == ChartPlotMethod.LINE) {
- plb.setDrawSymbol(false);
- } else {
- plb.setDrawSymbol(true);
- plb.setSymbolColor(color);
- plb.setSymbolFillColor(color);
- }
- plb.setColor(color);
- plb.setCaption(dataset.getSeriesKey(i));
- seriesLegends.add(new SeriesLegend(plb));
- break;
- case POINT:
- PointBreak pb = new PointBreak();
- pb.setColor(color);
- pb.setCaption(dataset.getSeriesKey(i));
- seriesLegends.add(new SeriesLegend(pb));
- break;
- case BAR:
- PolygonBreak pgb = new PolygonBreak();
- pgb.setColor(color);
- pgb.setCaption(dataset.getSeriesKey(i));
- seriesLegends.add(new SeriesLegend(pgb));
- break;
- }
- }
- }
-
- /**
- * Get chart plot method
- *
- * @return Chart plot method
- */
- public ChartPlotMethod getChartPlotMethod() {
- return this.chartPlotMethod;
- }
-
- /**
- * Set chart plot method
- *
- * @param value Chart plot method
- */
- public void setChartPlotMethod(ChartPlotMethod value) {
- this.chartPlotMethod = value;
- if (this.dataset != null) {
- this.updateSeriesLegend();
- }
- }
-
- @Override
- public PlotType getPlotType() {
- return PlotType.XY;
- }
-
- /**
- * Get Series legend breaks
- *
- * @return Series legend breaks
- */
- public List getLegendBreaks() {
- return this.seriesLegends;
- }
-
-// /**
-// * Get point breaks
-// *
-// * @return Point breaks
-// */
-// public PointBreak[] getPointBreaks() {
-// return this.pointBreaks;
-// }
- /**
- * If use item 2D point breaks
- *
- * @return Boolean
- */
- public boolean isUseBreak2D() {
- return this.useBreak2D;
- }
-
- /**
- * Set if use item 2D point breaks
- *
- * @param value Boolean
- */
- public void setUseBeak2D(boolean value) {
- this.useBreak2D = value;
- }
-
- /**
- * Get bar width ratio
- *
- * @return Bar width ratio
- */
- public float getBarWidth() {
- return this.barWidth;
- }
-
- /**
- * Set bar width ratio
- *
- * @param value Bar width ratio
- */
- public void setBarWidth(float value) {
- this.barWidth = value;
- }
-
- /**
- * Get if automatically decide bar width
- *
- * @return Boolean
- */
- public boolean isAutoBarWidth() {
- return this.autoBarWidth;
- }
-
- /**
- * Set if automatically decide bar height
- *
- * @param value Boolean
- */
- public void setAutoBarWidth(boolean value) {
- this.autoBarWidth = value;
- }
-
- //
- //
- /**
- * Add a series data
- *
- * @param seriesKey Series key
- * @param xvs X value array
- * @param yvs Y value array
- */
- public void addSeries(String seriesKey, double[] xvs, double[] yvs) {
- ((XYListDataset) this.dataset).addSeries(seriesKey, xvs, yvs);
- PolylineBreak plb = new PolylineBreak();
- plb.setColor(ColorUtil.getCommonColor(this.dataset.getSeriesCount()));
- plb.setCaption(seriesKey);
- seriesLegends.add(new SeriesLegend(plb));
-
- Extent extent = this.getAutoExtent();
- this.setDrawExtent(extent);
- }
-
- /**
- * Remove last series
- */
- public void removeLastSeries() {
- XYListDataset ds = (XYListDataset) this.dataset;
- ds.removeSeries(dataset.getSeriesCount() - 1);
- this.seriesLegends.remove(this.seriesLegends.size() - 1);
-
- Extent extent = this.getAutoExtent();
- this.setDrawExtent(extent);
- }
-
- private PointF[] getScreenPoints(double[] xdata, double[] ydata, List mvIdx, Rectangle2D area) {
- int len = xdata.length;
- PointF[] points = new PointF[len];
- double[] xy;
- if (this.getPlotOrientation() == PlotOrientation.VERTICAL) {
- for (int j = 0; j < len; j++) {
- xy = this.projToScreen(xdata[j], ydata[j], area);
- points[j] = new PointF((float) xy[0], (float) xy[1]);
- }
- } else {
- for (int j = 0; j < len; j++) {
- xy = this.projToScreen(xdata[j], ydata[j], area);
- points[j] = new PointF((float) xy[0], (float) xy[1]);
- }
- }
-// if (this.getYAxis().isInverse()) {
-// PointF[] npoints = new PointF[len];
-// PointF p;
-// float y;
-// for (int j = 0; j < len; j++) {
-// p = points[len - j - 1];
-// y = (float) area.getHeight() - p.Y;
-// npoints[j] = new PointF(p.X, y);
-// }
-// points = npoints;
-// if (!mvIdx.isEmpty()) {
-// for (int j = 0; j < mvIdx.size(); j++) {
-// mvIdx.set(j, len - mvIdx.get(j) - 1);
-// }
-// }
-// }
-// if (this.getXAxis().isInverse()) {
-// PointF[] npoints = new PointF[len];
-// PointF p;
-// float x;
-// for (int j = 0; j < len; j++) {
-// p = points[len - j - 1];
-// x = (float) area.getWidth() - p.X;
-// npoints[j] = new PointF(x, p.Y);
-// }
-// points = npoints;
-// if (!mvIdx.isEmpty()) {
-// for (int j = 0; j < mvIdx.size(); j++) {
-// mvIdx.set(j, len - mvIdx.get(j) - 1);
-// }
-// }
-// }
-
- return points;
- }
-
- @Override
- void drawGraph(Graphics2D g, Rectangle2D area) {
- AffineTransform oldMatrix = g.getTransform();
- Rectangle oldRegion = g.getClipBounds();
- g.setClip(area);
- g.translate(area.getX(), area.getY());
-
- //Draw background
- if (this.background != null) {
- g.setColor(this.getBackground());
- g.fill(new Rectangle2D.Double(0, 0, area.getWidth(), area.getHeight()));
- }
-
- double[] xy;
- xy = this.projToScreen(0, 0, area);
- float y0 = (float) xy[1];
- boolean drawBaseline = false;
- for (int i = 0; i < this.dataset.getSeriesCount(); i++) {
- XYSeriesData sdata = this.dataset.getSeriesData(i);
- int len = sdata.dataLength();
- List mvIdx = sdata.getMissingValueIndex();
- PointF[] points = getScreenPoints(sdata.getXdata(), sdata.getYdata(), mvIdx, area);
- SeriesLegend slegend = this.seriesLegends.get(i);
- if (slegend.isLine()) {
- if (mvIdx.isEmpty()) {
- Draw.drawPolyline(points, (PolylineBreak) slegend.getLegendBreak(), g);
- } else {
- Draw.drawPolyline(points, (PolylineBreak) slegend.getLegendBreak(), g, mvIdx);
- }
- } else if (slegend.isPoint()) {
- if (slegend.isMutiple()) {
- for (int j = 0; j < len; j++) {
- if (!mvIdx.contains(j)) {
- Draw.drawPoint(points[j], (PointBreak) slegend.getLegendBreak(j), g);
- }
- }
- } else {
- for (int j = 0; j < len; j++) {
- if (!mvIdx.contains(j)) {
- Draw.drawPoint(points[j], (PointBreak) slegend.getLegendBreak(), g);
- }
- }
- }
- } else if (slegend.isPolygon()) {
- switch (slegend.getPlotMethod()) {
- case BAR:
- if (sdata instanceof XYErrorSeriesData) {
- drawBaseline = true;
- XYErrorSeriesData esdata = (XYErrorSeriesData) sdata;
- double[] bottom = esdata.getBottom();
- float[] yBottoms = null;
- if (bottom != null) {
- yBottoms = new float[bottom.length];
- for (int j = 0; j < bottom.length; j++) {
- xy = this.projToScreen(esdata.getBottom(j), esdata.getBottom(j), area);
- yBottoms[j] = (float) xy[1];
- }
- }
- float width = this.barWidth;
- if (this.autoBarWidth) {
- if (points.length > 1) {
- width = (float) ((points[1].X - points[0].X) * 0.5) / this.dataset.getSeriesCount();
- } else {
- width = (float) (area.getWidth() / 10) / this.dataset.getSeriesCount();
- }
- float height;
- PolygonBreak pgb;
- for (int j = 0; j < len; j++) {
- if (!mvIdx.contains(j)) {
- pgb = (PolygonBreak) slegend.getLegendBreak(j);
- height = Math.abs((float) (points[j].Y - y0));
- float yBottom = y0;
- if (yBottoms != null) {
- if (j < yBottoms.length) {
- yBottom = yBottoms[j];
- } else {
- yBottom = yBottoms[0];
- }
- }
- float yb = yBottom;
- if (points[j].Y >= y0) {
- yb += height;
- }
- Draw.drawBar(new PointF(points[j].X - width * this.dataset.getSeriesCount() / 2
- + i * width, yb), width, height, pgb, g, false, 5);
- if (esdata.getYerror() != null) {
- PointF p = (PointF) points[j].clone();
- p.Y -= y0 - yBottom;
- double elen = 6;
- double error = esdata.getYerror(j);
- error = this.projYLength(error, area);
- double x = p.X - width * this.dataset.getSeriesCount() / 2
- + i * width + width / 2;
- g.setColor(slegend.getErrorColor());
- g.draw(new Line2D.Double(x, p.Y - error, x, p.Y + error));
- g.draw(new Line2D.Double(x - (elen * 0.5), p.Y - error, x + (elen * 0.5), p.Y - error));
- g.draw(new Line2D.Double(x - (elen * 0.5), p.Y + error, x + (elen * 0.5), p.Y + error));
- }
- }
- }
- } else {
- width = (float) this.projXLength(width, area);
- float height;
- PolygonBreak pgb;
- for (int j = 0; j < len; j++) {
- if (!mvIdx.contains(j)) {
- pgb = (PolygonBreak) slegend.getLegendBreak(j);
- height = Math.abs((float) (points[j].Y - y0));
- float yBottom = y0;
- if (yBottoms != null) {
- if (j < yBottoms.length) {
- yBottom = yBottoms[j];
- } else {
- yBottom = yBottoms[0];
- }
- }
- float yb = yBottom;
- if (points[j].Y >= y0) {
- yb += height;
- }
- Draw.drawBar(new PointF(points[j].X, yb), width, height, pgb, g, false, 5);
- if (esdata.getYerror() != null) {
- PointF p = (PointF) points[j].clone();
- p.Y -= y0 - yBottom;
- double elen = 6;
- double error = esdata.getYerror(j);
- error = this.projYLength(error, area);
- double x = p.X + width / 2;
- g.setColor(slegend.getErrorColor());
- g.draw(new Line2D.Double(x, p.Y - error, x, p.Y + error));
- g.draw(new Line2D.Double(x - (elen * 0.5), p.Y - error, x + (elen * 0.5), p.Y - error));
- g.draw(new Line2D.Double(x - (elen * 0.5), p.Y + error, x + (elen * 0.5), p.Y + error));
- }
- }
- }
- }
- } else {
- drawBaseline = true;
- float width = this.barWidth;
- if (this.autoBarWidth) {
- if (points.length > 1) {
- width = (float) ((points[1].X - points[0].X) * 0.5) / this.dataset.getSeriesCount();
- } else {
- width = (float) (area.getWidth() / 10) / this.dataset.getSeriesCount();
- }
- float height;
- PolygonBreak pgb;
- for (int j = 0; j < len; j++) {
- if (!mvIdx.contains(j)) {
- pgb = (PolygonBreak) slegend.getLegendBreak(j);
- height = Math.abs((float) (points[j].Y - y0));
- float yb = y0;
- if (points[j].Y >= y0) {
- yb += height;
- }
- Draw.drawBar(new PointF(points[j].X - width * this.dataset.getSeriesCount() / 2
- + i * width, yb), width, height, pgb, g, false, 5);
- }
- }
- } else {
- width = (float) this.projXLength(width, area);
- float height;
- PolygonBreak pgb;
- for (int j = 0; j < len; j++) {
- if (!mvIdx.contains(j)) {
- pgb = (PolygonBreak) slegend.getLegendBreak(j);
- height = Math.abs((float) (points[j].Y - y0));
- float yb = y0;
- if (points[j].Y >= y0) {
- yb += height;
- }
- Draw.drawBar(new PointF(points[j].X, yb), width, height, pgb, g, false, 5);
- }
- }
- }
- }
- break;
- case FILL:
- XYYSeriesData xyydata = (XYYSeriesData) sdata;
- PointF[] y2Points = this.getScreenPoints(xyydata.getXdata(), xyydata.getY2data(), mvIdx, area);
- if (xyydata.getWhere() == null) {
- PointF[] npoints = new PointF[len * 2];
- for (int j = 0; j < len; j++) {
- npoints[j] = points[len - j - 1];
- npoints[j + len] = y2Points[j];
- }
- Draw.drawPolygon(npoints, (PolygonBreak) slegend.getLegendBreak(), g);
- } else {
- boolean ob = false;
- List> idxs = new ArrayList<>();
- List idx = new ArrayList<>();
- for (int j = 0; j < len; j++) {
- if (xyydata.getWhere().get(j)) {
- if (!ob) {
- idx = new ArrayList<>();
- }
- idx.add(j);
- } else if (ob) {
- idxs.add(idx);
- }
- ob = xyydata.getWhere().get(j);
- }
- for (List index : idxs) {
- int nn = index.size();
- if (nn >= 2) {
- PointF[] npoints = new PointF[nn * 2];
- int ii, ii2;
- for (int j = 0; j < nn; j++) {
- ii = index.get(j);
- ii2 = index.get(nn - j - 1);
- npoints[j] = points[ii];
- npoints[j + index.size()] = y2Points[ii2];
- }
- Draw.drawPolygon(npoints, (PolygonBreak) slegend.getLegendBreak(), g);
- }
- }
- }
- break;
- }
- }
-
- //Draw baseline
- if (drawBaseline) {
- g.setColor(Color.black);
- g.draw(new Line2D.Double(0, y0, area.getWidth(), y0));
- }
-
- //Draw error bar
- if (sdata instanceof XYErrorSeriesData) {
- XYErrorSeriesData esdata = (XYErrorSeriesData) sdata;
- g.setColor(slegend.getLegendBreak().getColor());
- PointF p;
- double error;
- double elen = 6;
- if (esdata.getYerror() != null) {
- if (slegend.getPlotMethod() == ChartPlotMethod.BAR) {
-
- } else {
- for (int j = 0; j < len; j++) {
- if (!mvIdx.contains(j)) {
- p = points[j];
- error = esdata.getYerror(j);
- error = this.projYLength(error, area);
- g.draw(new Line2D.Double(p.X, p.Y - error, p.X, p.Y + error));
- g.draw(new Line2D.Double(p.X - (elen * 0.5), p.Y - error, p.X + (elen * 0.5), p.Y - error));
- g.draw(new Line2D.Double(p.X - (elen * 0.5), p.Y + error, p.X + (elen * 0.5), p.Y + error));
- }
- }
- }
- }
- if (esdata.getXerror() != null) {
- for (int j = 0; j < len; j++) {
- if (!mvIdx.contains(j)) {
- p = points[j];
- error = esdata.getXerror(j);
- error = this.projXLength(error, area);
- g.draw(new Line2D.Double(p.X - error, p.Y, p.X + error, p.Y));
- g.draw(new Line2D.Double(p.X - error, p.Y - (elen * 0.5), p.X - error, p.Y + (elen * 0.5)));
- g.draw(new Line2D.Double(p.X + error, p.Y - (elen * 0.5), p.X + error, p.Y + (elen * 0.5)));
- }
- }
- }
- }
- }
-
- //Draw texts
-// for (ChartText text : this.getTexts()) {
-// xy = this.projToScreen(text.getX(), text.getY(), area);
-// float x = (float) xy[0];
-// float y = (float) xy[1];
-// g.setFont(text.getFont());
-// g.setColor(text.getColor());
-// //Dimension dim = Draw.getStringDimension(text.getText(), g);
-// //y -= dim.height * 2 / 3;
-// Draw.drawString(g, text.getText(), x, y);
-// }
- g.setTransform(oldMatrix);
- g.setClip(oldRegion);
- }
-
- /**
- * Get a item point break
- *
- * @param seriesIdx Series index
- * @param itemIdx Item index
- * @return Item point break;
- */
- public PointBreak getItemPointBreak(int seriesIdx, int itemIdx) {
- return (PointBreak) this.seriesLegends.get(seriesIdx).getLegendBreak(itemIdx);
- }
-
- /**
- * Set item point break
- *
- * @param seriesIdx Series index
- * @param itemIdx Item index
- * @param pb Item point break
- */
- public void setItemPointBreak(int seriesIdx, int itemIdx, PointBreak pb) {
- this.seriesLegends.get(seriesIdx).setLegendBreak(itemIdx, pb);
- }
-
- /**
- * Get legend break
- *
- * @param seriesIdx Series index
- * @return Legend break
- */
- public ColorBreak getLegendBreak(int seriesIdx) {
- return this.seriesLegends.get(seriesIdx).getLegendBreak();
- }
-
- /**
- * Set legend break
- *
- * @param seriesIdx Series index
- * @param cb Legend break
- */
- public void setLegendBreak(int seriesIdx, ColorBreak cb) {
- this.seriesLegends.get(seriesIdx).setLegendBreak(cb);
- }
-
- /**
- * Set series legend
- *
- * @param seriesIdx Series index
- * @param sLegend SeriesLegend
- */
- public void setLegendBreak(int seriesIdx, SeriesLegend sLegend) {
- this.seriesLegends.set(seriesIdx, sLegend);
- }
-
-// /**
-// * Get point break
-// *
-// * @param seriesIdx Series index
-// * @return Point break
-// */
-// public PointBreak getPointBreak(int seriesIdx) {
-// return this.pointBreaks[seriesIdx];
-// }
-//
-// /**
-// * Set point break
-// *
-// * @param seriesIdx Series index
-// * @param pb Point break
-// */
-// public void setPointBreak(int seriesIdx, PointBreak pb) {
-// this.pointBreaks[seriesIdx] = pb;
-// }
-//
-// /**
-// * Get polygon break
-// *
-// * @param seriesIdx Series index
-// * @return Polygon break
-// */
-// public PolygonBreak getPolygonBreak(int seriesIdx) {
-// return this.polygonBreaks[seriesIdx];
-// }
-//
-// /**
-// * Set polygon break
-// *
-// * @param seriesIdx Series index
-// * @param pgb Polygon break
-// */
-// public void setPolygonBreak(int seriesIdx, PolygonBreak pgb) {
-// this.polygonBreaks[seriesIdx] = pgb;
-// }
- private double getBarXInterval(int idx) {
- double[] xvalues = this.dataset.getXValues(idx);
- if (xvalues.length == 1) {
- if (xvalues[0] == 0) {
- return 1;
- } else {
- return xvalues[0] / 10;
- }
- } else {
- return xvalues[1] - xvalues[0];
- }
- }
-
- private int getBarIndex() {
- int idx = -1;
- for (int i = 0; i < this.seriesLegends.size(); i++) {
- if (this.seriesLegends.get(i).getPlotMethod() == ChartPlotMethod.BAR) {
- idx = i;
- break;
- }
- }
- return idx;
- }
-
- /**
- * Get auto extent
- *
- * @return Auto extent
- */
- @Override
- public Extent getAutoExtent() {
- Extent extent = dataset.getDataExtent();
- if (extent.minX == extent.maxX){
- 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);
- }
-
- int barIdx = this.getBarIndex();
- if (barIdx >= 0) {
- double dx = getBarXInterval(barIdx);
- extent.minX -= dx;
- extent.maxX += dx;
- }
- double[] xValues;
- if (this.getXAxis() instanceof TimeAxis) {
- //if (this.getXAxis().isTimeAxis()) {
- xValues = (double[]) MIMath.getIntervalValues(extent.minX, extent.maxX, false).get(0);
- xValues[0] = extent.minX;
- xValues[xValues.length - 1] = extent.maxX;
- } else {
- xValues = (double[]) MIMath.getIntervalValues(extent.minX, extent.maxX, true).get(0);
- }
- double[] yValues = (double[]) MIMath.getIntervalValues(extent.minY, extent.maxY, true).get(0);
- if (this.getPlotOrientation() == PlotOrientation.VERTICAL) {
- return new Extent(xValues[0], xValues[xValues.length - 1], yValues[0], yValues[yValues.length - 1]);
- } else {
- return new Extent(yValues[0], yValues[yValues.length - 1], xValues[0], xValues[xValues.length - 1]);
- }
- }
-
- /**
- * Set auto extent
- */
- @Override
- public void setAutoExtent() {
- Extent extent = this.getAutoExtent();
- this.setDrawExtent(extent);
- }
-
- /**
- * Get legend scheme
- *
- * @return Legend scheme
- */
- public LegendScheme getLegendScheme() {
-// LegendScheme ls = null;
-// switch (this.chartPlotMethod) {
-// case LINE:
-// case LINE_POINT:
-// ls = new LegendScheme(ShapeTypes.Polyline);
-// ls.getLegendBreaks().addAll(Arrays.asList(this.lineBreaks));
-// break;
-// case POINT:
-// ls = new LegendScheme(ShapeTypes.Point);
-// ls.getLegendBreaks().addAll(Arrays.asList(this.pointBreaks));
-// break;
-// case BAR:
-// ls = new LegendScheme(ShapeTypes.Polygon);
-// ls.getLegendBreaks().addAll(Arrays.asList(this.polygonBreaks));
-// break;
-// }
- ShapeTypes stype = ShapeTypes.Polyline;
- LegendScheme ls = new LegendScheme(stype);
- for (SeriesLegend slegend : this.seriesLegends) {
- ls.getLegendBreaks().add(slegend.getLegendBreak());
- }
- return ls;
- }
-
- @Override
- public void updateLegendScheme() {
- if (this.getLegend() == null) {
- this.setLegend(new ChartLegend(this.getLegendScheme()));
- } else {
- this.getLegend().setLegendScheme(this.getLegendScheme());
- }
- }
-
- //
-}
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.meteoinfo.chart.plot;
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Line2D;
+import java.awt.geom.Rectangle2D;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.meteoinfo.chart.ChartLegend;
+import org.meteoinfo.chart.Location;
+import org.meteoinfo.chart.axis.TimeAxis;
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.MIMath;
+import org.meteoinfo.common.PointF;
+import org.meteoinfo.data.Dataset;
+import org.meteoinfo.data.XYDataset;
+import org.meteoinfo.data.XYErrorSeriesData;
+import org.meteoinfo.data.XYListDataset;
+import org.meteoinfo.data.XYSeriesData;
+import org.meteoinfo.data.XYYSeriesData;
+import org.meteoinfo.drawing.Draw;
+import org.meteoinfo.global.colors.ColorUtil;
+import org.meteoinfo.legend.ColorBreak;
+import org.meteoinfo.legend.LegendScheme;
+import org.meteoinfo.legend.PointBreak;
+import org.meteoinfo.legend.PolygonBreak;
+import org.meteoinfo.legend.PolylineBreak;
+import org.meteoinfo.shape.ShapeTypes;
+
+/**
+ *
+ * @author yaqiang
+ */
+public class XY1DPlot extends AbstractPlot2D {
+
+ //
+ private XYListDataset dataset;
+ private ChartPlotMethod chartPlotMethod;
+ private List seriesLegends;
+ private boolean useBreak2D;
+ private float barWidth;
+ private boolean autoBarWidth;
+
+ //
+ //
+ /**
+ * Constructor
+ */
+ public XY1DPlot() {
+ super();
+
+ this.dataset = new XYListDataset();
+ this.chartPlotMethod = ChartPlotMethod.LINE;
+ this.useBreak2D = false;
+ this.seriesLegends = new ArrayList<>();
+ this.barWidth = 0.8f;
+ this.autoBarWidth = true;
+ }
+
+ /**
+ * Constructor
+ *
+ * @param dateset Dataset
+ */
+ public XY1DPlot(XYDataset dateset) {
+ this();
+ this.setDataset(dateset);
+ }
+
+ /**
+ * Constructor
+ *
+ * @param orientation Plot orientation
+ * @param dateset Dataset
+ */
+ public XY1DPlot(PlotOrientation orientation, XYDataset dateset) {
+ this();
+ this.setPlotOrientation(orientation);
+ this.setDataset(dateset);
+ }
+
+ /**
+ * Constructor
+ *
+ * @param isTime If x axis is time
+ * @param dateset Dataset
+ */
+ public XY1DPlot(boolean isTime, XYDataset dateset) {
+ this();
+ if (isTime) {
+ try {
+ this.setXAxis(new TimeAxis("X", true));
+ } catch (CloneNotSupportedException ex) {
+ Logger.getLogger(XY1DPlot.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ this.getAxis(Location.TOP).setDrawTickLabel(false);
+ }
+ //this.getXAxis().setTimeAxis(isTime);
+ this.setDataset(dateset);
+ }
+
+ /**
+ * Constructor
+ *
+ * @param isTime If x axis is time
+ * @param cpMethod Plot method
+ * @param dateset Dataset
+ */
+ public XY1DPlot(boolean isTime, ChartPlotMethod cpMethod, XYDataset dateset) {
+ this();
+ if (isTime) {
+ try {
+ this.setXAxis(new TimeAxis("X", true));
+ } catch (CloneNotSupportedException ex) {
+ Logger.getLogger(XY1DPlot.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ this.getAxis(Location.TOP).setDrawTickLabel(false);
+ }
+ //this.getXAxis().setTimeAxis(isTime);
+ this.setChartPlotMethod(cpMethod);
+ this.setDataset(dateset);
+ }
+
+ /**
+ * Constructor
+ *
+ * @param isTime If x axis is time
+ * @param orientation Plot orientation
+ * @param dateset Dataset
+ */
+ public XY1DPlot(boolean isTime, PlotOrientation orientation, XYDataset dateset) {
+ this();
+ if (isTime) {
+ try {
+ this.setXAxis(new TimeAxis("X", true));
+ } catch (CloneNotSupportedException ex) {
+ Logger.getLogger(XY1DPlot.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ this.getAxis(Location.TOP).setDrawTickLabel(false);
+ }
+ //this.getXAxis().setTimeAxis(isTime);
+ this.setPlotOrientation(orientation);
+ this.setDataset(dateset);
+ }
+
+ //
+ //
+ @Override
+ public XYDataset getDataset() {
+ return dataset;
+ }
+
+ @Override
+ public void setDataset(Dataset value) {
+ dataset = (XYListDataset) value;
+ Extent extent = this.getAutoExtent();
+ this.setDrawExtent(extent);
+ this.setExtent(extent);
+ this.updateSeriesLegend();
+ }
+
+ private void updateSeriesLegend() {
+ //this.seriesLegends.clear();
+ int si = this.seriesLegends.size();
+ if (si > dataset.getSeriesCount()) {
+ si = 0;
+ }
+ for (int i = si; i < dataset.getSeriesCount(); i++) {
+ Color color = ColorUtil.getCommonColor(i);
+ switch (this.chartPlotMethod) {
+ case LINE:
+ case LINE_POINT:
+ PolylineBreak plb = new PolylineBreak();
+ if (this.chartPlotMethod == ChartPlotMethod.LINE) {
+ plb.setDrawSymbol(false);
+ } else {
+ plb.setDrawSymbol(true);
+ plb.setSymbolColor(color);
+ plb.setSymbolFillColor(color);
+ }
+ plb.setColor(color);
+ plb.setCaption(dataset.getSeriesKey(i));
+ seriesLegends.add(new SeriesLegend(plb));
+ break;
+ case POINT:
+ PointBreak pb = new PointBreak();
+ pb.setColor(color);
+ pb.setCaption(dataset.getSeriesKey(i));
+ seriesLegends.add(new SeriesLegend(pb));
+ break;
+ case BAR:
+ PolygonBreak pgb = new PolygonBreak();
+ pgb.setColor(color);
+ pgb.setCaption(dataset.getSeriesKey(i));
+ seriesLegends.add(new SeriesLegend(pgb));
+ break;
+ }
+ }
+ }
+
+ /**
+ * Get chart plot method
+ *
+ * @return Chart plot method
+ */
+ public ChartPlotMethod getChartPlotMethod() {
+ return this.chartPlotMethod;
+ }
+
+ /**
+ * Set chart plot method
+ *
+ * @param value Chart plot method
+ */
+ public void setChartPlotMethod(ChartPlotMethod value) {
+ this.chartPlotMethod = value;
+ if (this.dataset != null) {
+ this.updateSeriesLegend();
+ }
+ }
+
+ @Override
+ public PlotType getPlotType() {
+ return PlotType.XY;
+ }
+
+ /**
+ * Get Series legend breaks
+ *
+ * @return Series legend breaks
+ */
+ public List getLegendBreaks() {
+ return this.seriesLegends;
+ }
+
+// /**
+// * Get point breaks
+// *
+// * @return Point breaks
+// */
+// public PointBreak[] getPointBreaks() {
+// return this.pointBreaks;
+// }
+ /**
+ * If use item 2D point breaks
+ *
+ * @return Boolean
+ */
+ public boolean isUseBreak2D() {
+ return this.useBreak2D;
+ }
+
+ /**
+ * Set if use item 2D point breaks
+ *
+ * @param value Boolean
+ */
+ public void setUseBeak2D(boolean value) {
+ this.useBreak2D = value;
+ }
+
+ /**
+ * Get bar width ratio
+ *
+ * @return Bar width ratio
+ */
+ public float getBarWidth() {
+ return this.barWidth;
+ }
+
+ /**
+ * Set bar width ratio
+ *
+ * @param value Bar width ratio
+ */
+ public void setBarWidth(float value) {
+ this.barWidth = value;
+ }
+
+ /**
+ * Get if automatically decide bar width
+ *
+ * @return Boolean
+ */
+ public boolean isAutoBarWidth() {
+ return this.autoBarWidth;
+ }
+
+ /**
+ * Set if automatically decide bar height
+ *
+ * @param value Boolean
+ */
+ public void setAutoBarWidth(boolean value) {
+ this.autoBarWidth = value;
+ }
+
+ //
+ //
+ /**
+ * Add a series data
+ *
+ * @param seriesKey Series key
+ * @param xvs X value array
+ * @param yvs Y value array
+ */
+ public void addSeries(String seriesKey, double[] xvs, double[] yvs) {
+ ((XYListDataset) this.dataset).addSeries(seriesKey, xvs, yvs);
+ PolylineBreak plb = new PolylineBreak();
+ plb.setColor(ColorUtil.getCommonColor(this.dataset.getSeriesCount()));
+ plb.setCaption(seriesKey);
+ seriesLegends.add(new SeriesLegend(plb));
+
+ Extent extent = this.getAutoExtent();
+ this.setDrawExtent(extent);
+ }
+
+ /**
+ * Remove last series
+ */
+ public void removeLastSeries() {
+ XYListDataset ds = (XYListDataset) this.dataset;
+ ds.removeSeries(dataset.getSeriesCount() - 1);
+ this.seriesLegends.remove(this.seriesLegends.size() - 1);
+
+ Extent extent = this.getAutoExtent();
+ this.setDrawExtent(extent);
+ }
+
+ private PointF[] getScreenPoints(double[] xdata, double[] ydata, List mvIdx, Rectangle2D area) {
+ int len = xdata.length;
+ PointF[] points = new PointF[len];
+ double[] xy;
+ if (this.getPlotOrientation() == PlotOrientation.VERTICAL) {
+ for (int j = 0; j < len; j++) {
+ xy = this.projToScreen(xdata[j], ydata[j], area);
+ points[j] = new PointF((float) xy[0], (float) xy[1]);
+ }
+ } else {
+ for (int j = 0; j < len; j++) {
+ xy = this.projToScreen(xdata[j], ydata[j], area);
+ points[j] = new PointF((float) xy[0], (float) xy[1]);
+ }
+ }
+// if (this.getYAxis().isInverse()) {
+// PointF[] npoints = new PointF[len];
+// PointF p;
+// float y;
+// for (int j = 0; j < len; j++) {
+// p = points[len - j - 1];
+// y = (float) area.getHeight() - p.Y;
+// npoints[j] = new PointF(p.X, y);
+// }
+// points = npoints;
+// if (!mvIdx.isEmpty()) {
+// for (int j = 0; j < mvIdx.size(); j++) {
+// mvIdx.set(j, len - mvIdx.get(j) - 1);
+// }
+// }
+// }
+// if (this.getXAxis().isInverse()) {
+// PointF[] npoints = new PointF[len];
+// PointF p;
+// float x;
+// for (int j = 0; j < len; j++) {
+// p = points[len - j - 1];
+// x = (float) area.getWidth() - p.X;
+// npoints[j] = new PointF(x, p.Y);
+// }
+// points = npoints;
+// if (!mvIdx.isEmpty()) {
+// for (int j = 0; j < mvIdx.size(); j++) {
+// mvIdx.set(j, len - mvIdx.get(j) - 1);
+// }
+// }
+// }
+
+ return points;
+ }
+
+ @Override
+ void drawGraph(Graphics2D g, Rectangle2D area) {
+ AffineTransform oldMatrix = g.getTransform();
+ Rectangle oldRegion = g.getClipBounds();
+ g.setClip(area);
+ g.translate(area.getX(), area.getY());
+
+ //Draw background
+ if (this.background != null) {
+ g.setColor(this.getBackground());
+ g.fill(new Rectangle2D.Double(0, 0, area.getWidth(), area.getHeight()));
+ }
+
+ double[] xy;
+ xy = this.projToScreen(0, 0, area);
+ float y0 = (float) xy[1];
+ boolean drawBaseline = false;
+ for (int i = 0; i < this.dataset.getSeriesCount(); i++) {
+ XYSeriesData sdata = this.dataset.getSeriesData(i);
+ int len = sdata.dataLength();
+ List mvIdx = sdata.getMissingValueIndex();
+ PointF[] points = getScreenPoints(sdata.getXdata(), sdata.getYdata(), mvIdx, area);
+ SeriesLegend slegend = this.seriesLegends.get(i);
+ if (slegend.isLine()) {
+ if (mvIdx.isEmpty()) {
+ Draw.drawPolyline(points, (PolylineBreak) slegend.getLegendBreak(), g);
+ } else {
+ Draw.drawPolyline(points, (PolylineBreak) slegend.getLegendBreak(), g, mvIdx);
+ }
+ } else if (slegend.isPoint()) {
+ if (slegend.isMutiple()) {
+ for (int j = 0; j < len; j++) {
+ if (!mvIdx.contains(j)) {
+ Draw.drawPoint(points[j], (PointBreak) slegend.getLegendBreak(j), g);
+ }
+ }
+ } else {
+ for (int j = 0; j < len; j++) {
+ if (!mvIdx.contains(j)) {
+ Draw.drawPoint(points[j], (PointBreak) slegend.getLegendBreak(), g);
+ }
+ }
+ }
+ } else if (slegend.isPolygon()) {
+ switch (slegend.getPlotMethod()) {
+ case BAR:
+ if (sdata instanceof XYErrorSeriesData) {
+ drawBaseline = true;
+ XYErrorSeriesData esdata = (XYErrorSeriesData) sdata;
+ double[] bottom = esdata.getBottom();
+ float[] yBottoms = null;
+ if (bottom != null) {
+ yBottoms = new float[bottom.length];
+ for (int j = 0; j < bottom.length; j++) {
+ xy = this.projToScreen(esdata.getBottom(j), esdata.getBottom(j), area);
+ yBottoms[j] = (float) xy[1];
+ }
+ }
+ float width = this.barWidth;
+ if (this.autoBarWidth) {
+ if (points.length > 1) {
+ width = (float) ((points[1].X - points[0].X) * 0.5) / this.dataset.getSeriesCount();
+ } else {
+ width = (float) (area.getWidth() / 10) / this.dataset.getSeriesCount();
+ }
+ float height;
+ PolygonBreak pgb;
+ for (int j = 0; j < len; j++) {
+ if (!mvIdx.contains(j)) {
+ pgb = (PolygonBreak) slegend.getLegendBreak(j);
+ height = Math.abs((float) (points[j].Y - y0));
+ float yBottom = y0;
+ if (yBottoms != null) {
+ if (j < yBottoms.length) {
+ yBottom = yBottoms[j];
+ } else {
+ yBottom = yBottoms[0];
+ }
+ }
+ float yb = yBottom;
+ if (points[j].Y >= y0) {
+ yb += height;
+ }
+ Draw.drawBar(new PointF(points[j].X - width * this.dataset.getSeriesCount() / 2
+ + i * width, yb), width, height, pgb, g, false, 5);
+ if (esdata.getYerror() != null) {
+ PointF p = (PointF) points[j].clone();
+ p.Y -= y0 - yBottom;
+ double elen = 6;
+ double error = esdata.getYerror(j);
+ error = this.projYLength(error, area);
+ double x = p.X - width * this.dataset.getSeriesCount() / 2
+ + i * width + width / 2;
+ g.setColor(slegend.getErrorColor());
+ g.draw(new Line2D.Double(x, p.Y - error, x, p.Y + error));
+ g.draw(new Line2D.Double(x - (elen * 0.5), p.Y - error, x + (elen * 0.5), p.Y - error));
+ g.draw(new Line2D.Double(x - (elen * 0.5), p.Y + error, x + (elen * 0.5), p.Y + error));
+ }
+ }
+ }
+ } else {
+ width = (float) this.projXLength(width, area);
+ float height;
+ PolygonBreak pgb;
+ for (int j = 0; j < len; j++) {
+ if (!mvIdx.contains(j)) {
+ pgb = (PolygonBreak) slegend.getLegendBreak(j);
+ height = Math.abs((float) (points[j].Y - y0));
+ float yBottom = y0;
+ if (yBottoms != null) {
+ if (j < yBottoms.length) {
+ yBottom = yBottoms[j];
+ } else {
+ yBottom = yBottoms[0];
+ }
+ }
+ float yb = yBottom;
+ if (points[j].Y >= y0) {
+ yb += height;
+ }
+ Draw.drawBar(new PointF(points[j].X, yb), width, height, pgb, g, false, 5);
+ if (esdata.getYerror() != null) {
+ PointF p = (PointF) points[j].clone();
+ p.Y -= y0 - yBottom;
+ double elen = 6;
+ double error = esdata.getYerror(j);
+ error = this.projYLength(error, area);
+ double x = p.X + width / 2;
+ g.setColor(slegend.getErrorColor());
+ g.draw(new Line2D.Double(x, p.Y - error, x, p.Y + error));
+ g.draw(new Line2D.Double(x - (elen * 0.5), p.Y - error, x + (elen * 0.5), p.Y - error));
+ g.draw(new Line2D.Double(x - (elen * 0.5), p.Y + error, x + (elen * 0.5), p.Y + error));
+ }
+ }
+ }
+ }
+ } else {
+ drawBaseline = true;
+ float width = this.barWidth;
+ if (this.autoBarWidth) {
+ if (points.length > 1) {
+ width = (float) ((points[1].X - points[0].X) * 0.5) / this.dataset.getSeriesCount();
+ } else {
+ width = (float) (area.getWidth() / 10) / this.dataset.getSeriesCount();
+ }
+ float height;
+ PolygonBreak pgb;
+ for (int j = 0; j < len; j++) {
+ if (!mvIdx.contains(j)) {
+ pgb = (PolygonBreak) slegend.getLegendBreak(j);
+ height = Math.abs((float) (points[j].Y - y0));
+ float yb = y0;
+ if (points[j].Y >= y0) {
+ yb += height;
+ }
+ Draw.drawBar(new PointF(points[j].X - width * this.dataset.getSeriesCount() / 2
+ + i * width, yb), width, height, pgb, g, false, 5);
+ }
+ }
+ } else {
+ width = (float) this.projXLength(width, area);
+ float height;
+ PolygonBreak pgb;
+ for (int j = 0; j < len; j++) {
+ if (!mvIdx.contains(j)) {
+ pgb = (PolygonBreak) slegend.getLegendBreak(j);
+ height = Math.abs((float) (points[j].Y - y0));
+ float yb = y0;
+ if (points[j].Y >= y0) {
+ yb += height;
+ }
+ Draw.drawBar(new PointF(points[j].X, yb), width, height, pgb, g, false, 5);
+ }
+ }
+ }
+ }
+ break;
+ case FILL:
+ XYYSeriesData xyydata = (XYYSeriesData) sdata;
+ PointF[] y2Points = this.getScreenPoints(xyydata.getXdata(), xyydata.getY2data(), mvIdx, area);
+ if (xyydata.getWhere() == null) {
+ PointF[] npoints = new PointF[len * 2];
+ for (int j = 0; j < len; j++) {
+ npoints[j] = points[len - j - 1];
+ npoints[j + len] = y2Points[j];
+ }
+ Draw.drawPolygon(npoints, (PolygonBreak) slegend.getLegendBreak(), g);
+ } else {
+ boolean ob = false;
+ List> idxs = new ArrayList<>();
+ List idx = new ArrayList<>();
+ for (int j = 0; j < len; j++) {
+ if (xyydata.getWhere().get(j)) {
+ if (!ob) {
+ idx = new ArrayList<>();
+ }
+ idx.add(j);
+ } else if (ob) {
+ idxs.add(idx);
+ }
+ ob = xyydata.getWhere().get(j);
+ }
+ for (List index : idxs) {
+ int nn = index.size();
+ if (nn >= 2) {
+ PointF[] npoints = new PointF[nn * 2];
+ int ii, ii2;
+ for (int j = 0; j < nn; j++) {
+ ii = index.get(j);
+ ii2 = index.get(nn - j - 1);
+ npoints[j] = points[ii];
+ npoints[j + index.size()] = y2Points[ii2];
+ }
+ Draw.drawPolygon(npoints, (PolygonBreak) slegend.getLegendBreak(), g);
+ }
+ }
+ }
+ break;
+ }
+ }
+
+ //Draw baseline
+ if (drawBaseline) {
+ g.setColor(Color.black);
+ g.draw(new Line2D.Double(0, y0, area.getWidth(), y0));
+ }
+
+ //Draw error bar
+ if (sdata instanceof XYErrorSeriesData) {
+ XYErrorSeriesData esdata = (XYErrorSeriesData) sdata;
+ g.setColor(slegend.getLegendBreak().getColor());
+ PointF p;
+ double error;
+ double elen = 6;
+ if (esdata.getYerror() != null) {
+ if (slegend.getPlotMethod() == ChartPlotMethod.BAR) {
+
+ } else {
+ for (int j = 0; j < len; j++) {
+ if (!mvIdx.contains(j)) {
+ p = points[j];
+ error = esdata.getYerror(j);
+ error = this.projYLength(error, area);
+ g.draw(new Line2D.Double(p.X, p.Y - error, p.X, p.Y + error));
+ g.draw(new Line2D.Double(p.X - (elen * 0.5), p.Y - error, p.X + (elen * 0.5), p.Y - error));
+ g.draw(new Line2D.Double(p.X - (elen * 0.5), p.Y + error, p.X + (elen * 0.5), p.Y + error));
+ }
+ }
+ }
+ }
+ if (esdata.getXerror() != null) {
+ for (int j = 0; j < len; j++) {
+ if (!mvIdx.contains(j)) {
+ p = points[j];
+ error = esdata.getXerror(j);
+ error = this.projXLength(error, area);
+ g.draw(new Line2D.Double(p.X - error, p.Y, p.X + error, p.Y));
+ g.draw(new Line2D.Double(p.X - error, p.Y - (elen * 0.5), p.X - error, p.Y + (elen * 0.5)));
+ g.draw(new Line2D.Double(p.X + error, p.Y - (elen * 0.5), p.X + error, p.Y + (elen * 0.5)));
+ }
+ }
+ }
+ }
+ }
+
+ //Draw texts
+// for (ChartText text : this.getTexts()) {
+// xy = this.projToScreen(text.getX(), text.getY(), area);
+// float x = (float) xy[0];
+// float y = (float) xy[1];
+// g.setFont(text.getFont());
+// g.setColor(text.getColor());
+// //Dimension dim = Draw.getStringDimension(text.getText(), g);
+// //y -= dim.height * 2 / 3;
+// Draw.drawString(g, text.getText(), x, y);
+// }
+ g.setTransform(oldMatrix);
+ g.setClip(oldRegion);
+ }
+
+ /**
+ * Get a item point break
+ *
+ * @param seriesIdx Series index
+ * @param itemIdx Item index
+ * @return Item point break;
+ */
+ public PointBreak getItemPointBreak(int seriesIdx, int itemIdx) {
+ return (PointBreak) this.seriesLegends.get(seriesIdx).getLegendBreak(itemIdx);
+ }
+
+ /**
+ * Set item point break
+ *
+ * @param seriesIdx Series index
+ * @param itemIdx Item index
+ * @param pb Item point break
+ */
+ public void setItemPointBreak(int seriesIdx, int itemIdx, PointBreak pb) {
+ this.seriesLegends.get(seriesIdx).setLegendBreak(itemIdx, pb);
+ }
+
+ /**
+ * Get legend break
+ *
+ * @param seriesIdx Series index
+ * @return Legend break
+ */
+ public ColorBreak getLegendBreak(int seriesIdx) {
+ return this.seriesLegends.get(seriesIdx).getLegendBreak();
+ }
+
+ /**
+ * Set legend break
+ *
+ * @param seriesIdx Series index
+ * @param cb Legend break
+ */
+ public void setLegendBreak(int seriesIdx, ColorBreak cb) {
+ this.seriesLegends.get(seriesIdx).setLegendBreak(cb);
+ }
+
+ /**
+ * Set series legend
+ *
+ * @param seriesIdx Series index
+ * @param sLegend SeriesLegend
+ */
+ public void setLegendBreak(int seriesIdx, SeriesLegend sLegend) {
+ this.seriesLegends.set(seriesIdx, sLegend);
+ }
+
+// /**
+// * Get point break
+// *
+// * @param seriesIdx Series index
+// * @return Point break
+// */
+// public PointBreak getPointBreak(int seriesIdx) {
+// return this.pointBreaks[seriesIdx];
+// }
+//
+// /**
+// * Set point break
+// *
+// * @param seriesIdx Series index
+// * @param pb Point break
+// */
+// public void setPointBreak(int seriesIdx, PointBreak pb) {
+// this.pointBreaks[seriesIdx] = pb;
+// }
+//
+// /**
+// * Get polygon break
+// *
+// * @param seriesIdx Series index
+// * @return Polygon break
+// */
+// public PolygonBreak getPolygonBreak(int seriesIdx) {
+// return this.polygonBreaks[seriesIdx];
+// }
+//
+// /**
+// * Set polygon break
+// *
+// * @param seriesIdx Series index
+// * @param pgb Polygon break
+// */
+// public void setPolygonBreak(int seriesIdx, PolygonBreak pgb) {
+// this.polygonBreaks[seriesIdx] = pgb;
+// }
+ private double getBarXInterval(int idx) {
+ double[] xvalues = this.dataset.getXValues(idx);
+ if (xvalues.length == 1) {
+ if (xvalues[0] == 0) {
+ return 1;
+ } else {
+ return xvalues[0] / 10;
+ }
+ } else {
+ return xvalues[1] - xvalues[0];
+ }
+ }
+
+ private int getBarIndex() {
+ int idx = -1;
+ for (int i = 0; i < this.seriesLegends.size(); i++) {
+ if (this.seriesLegends.get(i).getPlotMethod() == ChartPlotMethod.BAR) {
+ idx = i;
+ break;
+ }
+ }
+ return idx;
+ }
+
+ /**
+ * Get auto extent
+ *
+ * @return Auto extent
+ */
+ @Override
+ public Extent getAutoExtent() {
+ Extent extent = dataset.getDataExtent();
+ if (extent.minX == extent.maxX){
+ 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);
+ }
+
+ int barIdx = this.getBarIndex();
+ if (barIdx >= 0) {
+ double dx = getBarXInterval(barIdx);
+ extent.minX -= dx;
+ extent.maxX += dx;
+ }
+ double[] xValues;
+ if (this.getXAxis() instanceof TimeAxis) {
+ //if (this.getXAxis().isTimeAxis()) {
+ xValues = (double[]) MIMath.getIntervalValues(extent.minX, extent.maxX, false).get(0);
+ xValues[0] = extent.minX;
+ xValues[xValues.length - 1] = extent.maxX;
+ } else {
+ xValues = (double[]) MIMath.getIntervalValues(extent.minX, extent.maxX, true).get(0);
+ }
+ double[] yValues = (double[]) MIMath.getIntervalValues(extent.minY, extent.maxY, true).get(0);
+ if (this.getPlotOrientation() == PlotOrientation.VERTICAL) {
+ return new Extent(xValues[0], xValues[xValues.length - 1], yValues[0], yValues[yValues.length - 1]);
+ } else {
+ return new Extent(yValues[0], yValues[yValues.length - 1], xValues[0], xValues[xValues.length - 1]);
+ }
+ }
+
+ /**
+ * Set auto extent
+ */
+ @Override
+ public void setAutoExtent() {
+ Extent extent = this.getAutoExtent();
+ this.setDrawExtent(extent);
+ }
+
+ /**
+ * Get legend scheme
+ *
+ * @return Legend scheme
+ */
+ public LegendScheme getLegendScheme() {
+// LegendScheme ls = null;
+// switch (this.chartPlotMethod) {
+// case LINE:
+// case LINE_POINT:
+// ls = new LegendScheme(ShapeTypes.Polyline);
+// ls.getLegendBreaks().addAll(Arrays.asList(this.lineBreaks));
+// break;
+// case POINT:
+// ls = new LegendScheme(ShapeTypes.Point);
+// ls.getLegendBreaks().addAll(Arrays.asList(this.pointBreaks));
+// break;
+// case BAR:
+// ls = new LegendScheme(ShapeTypes.Polygon);
+// ls.getLegendBreaks().addAll(Arrays.asList(this.polygonBreaks));
+// break;
+// }
+ ShapeTypes stype = ShapeTypes.Polyline;
+ LegendScheme ls = new LegendScheme(stype);
+ for (SeriesLegend slegend : this.seriesLegends) {
+ ls.getLegendBreaks().add(slegend.getLegendBreak());
+ }
+ return ls;
+ }
+
+ @Override
+ public void updateLegendScheme() {
+ if (this.getLegend() == null) {
+ this.setLegend(new ChartLegend(this.getLegendScheme()));
+ } else {
+ this.getLegend().setLegendScheme(this.getLegendScheme());
+ }
+ }
+
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/DataMath.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/DataMath.java
index b63d9e01..e17f56c8 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/DataMath.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/DataMath.java
@@ -14,9 +14,10 @@
package org.meteoinfo.data;
import java.util.ArrayList;
-import org.meteoinfo.global.MIMath;
import java.util.Arrays;
import java.util.List;
+
+import org.meteoinfo.common.MIMath;
import org.meteoinfo.table.ColumnData;
/**
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/DataRange.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/DataRange.java
index 356940c3..00071c6a 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/DataRange.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/DataRange.java
@@ -1,96 +1,96 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.meteoinfo.data;
-
-import org.meteoinfo.global.MIMath;
-
-/**
- *
- * @author wyq
- */
-public class DataRange {
- //
- private double min;
- private double max;
- //
- //
- /**
- * Constructor
- */
- public DataRange(){
-
- }
-
- /**
- * Constructor
- * @param min Minimum value
- * @param max Maximum value
- */
- public DataRange(double min, double max){
- this.min = min;
- this.max = max;
- }
-
- /**
- * Constructor
- * @param value Data value
- */
- public DataRange(double value){
- this.min = value;
- this.max = value;
- }
- //
- //
- /**
- * Get minimum value
- * @return Minimum value
- */
- public double getMin(){
- return this.min;
- }
-
- /**
- * Set minimum value
- * @param value Minimum value
- */
- public void setMin(double value){
- this.min = value;
- }
-
- /**
- * Get maximum value
- * @return Maximum value
- */
- public double getMax(){
- return this.max;
- }
-
- /**
- * Set maximum value
- * @param value Maximum value
- */
- public void setMax(double value) {
- this.max = value;
- }
- //
- //
- /**
- * Get data range
- * @return Data range
- */
- public double getRange(){
- return this.max - this.min;
- }
-
- /**
- * Get if the data range is zero
- * @return Boolean
- */
- public boolean isFixed(){
- return MIMath.doubleEquals(max, min);
- }
- //
-}
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.meteoinfo.data;
+
+import org.meteoinfo.common.MIMath;
+
+/**
+ *
+ * @author wyq
+ */
+public class DataRange {
+ //
+ private double min;
+ private double max;
+ //
+ //
+ /**
+ * Constructor
+ */
+ public DataRange(){
+
+ }
+
+ /**
+ * Constructor
+ * @param min Minimum value
+ * @param max Maximum value
+ */
+ public DataRange(double min, double max){
+ this.min = min;
+ this.max = max;
+ }
+
+ /**
+ * Constructor
+ * @param value Data value
+ */
+ public DataRange(double value){
+ this.min = value;
+ this.max = value;
+ }
+ //
+ //
+ /**
+ * Get minimum value
+ * @return Minimum value
+ */
+ public double getMin(){
+ return this.min;
+ }
+
+ /**
+ * Set minimum value
+ * @param value Minimum value
+ */
+ public void setMin(double value){
+ this.min = value;
+ }
+
+ /**
+ * Get maximum value
+ * @return Maximum value
+ */
+ public double getMax(){
+ return this.max;
+ }
+
+ /**
+ * Set maximum value
+ * @param value Maximum value
+ */
+ public void setMax(double value) {
+ this.max = value;
+ }
+ //
+ //
+ /**
+ * Get data range
+ * @return Data range
+ */
+ public double getRange(){
+ return this.max - this.min;
+ }
+
+ /**
+ * Get if the data range is zero
+ * @return Boolean
+ */
+ public boolean isFixed(){
+ return MIMath.doubleEquals(max, min);
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/GridArray.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/GridArray.java
index 31bab42f..916f4f9e 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/GridArray.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/GridArray.java
@@ -13,16 +13,13 @@
*/
package org.meteoinfo.data;
-import org.meteoinfo.math.ArrayUtil;
-import org.meteoinfo.math.ArrayMath;
import java.io.BufferedWriter;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.global.MIMath;
+
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
@@ -31,6 +28,10 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.MIMath;
+import org.meteoinfo.math.ArrayMath;
+import org.meteoinfo.math.ArrayUtil;
import org.meteoinfo.ndarray.*;
import org.meteoinfo.ndarray.util.BigDecimalUtil;
import org.meteoinfo.data.meteodata.GridDataSetting;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/GridData.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/GridData.java
index ad5dcfa2..852042ac 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/GridData.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/GridData.java
@@ -14,10 +14,12 @@
package org.meteoinfo.data;
import java.io.BufferedReader;
+
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.MIMath;
+import org.meteoinfo.common.PointD;
import org.meteoinfo.geoprocess.GeoComputation;
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.global.MIMath;
-import org.meteoinfo.global.PointD;
+
import java.io.BufferedWriter;
import java.io.DataOutputStream;
import java.io.File;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/SeriesUtil.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/SeriesUtil.java
index 71ebee42..36781bab 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/SeriesUtil.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/SeriesUtil.java
@@ -1,164 +1,165 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.meteoinfo.data;
-
-import org.meteoinfo.math.ArrayMath;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import org.meteoinfo.ndarray.Array;
-
-/**
- *
- * @author Yaqiang Wang
- */
-public class SeriesUtil {
-
- /**
- * Get indices
- * @param index Index array
- * @param labels Labels
- * @return Indices
- */
- public static Object[] getIndices(List index, Array labels) {
- return getIndices(index, ArrayMath.asList(labels));
- }
-
- /**
- * Get indices
- * @param index Index array
- * @param labels Labels
- * @return Indices
- */
- public static Object[] getIndices(Array index, Array labels) {
- return getIndices(ArrayMath.asList(index), ArrayMath.asList(labels));
- }
-
- /**
- * Get indices
- * @param index Index array
- * @param labels Labels
- * @return Indices
- */
- public static Object[] getIndices(List index, List labels) {
- List r = new ArrayList<>();
- List rIndex = new ArrayList<>();
- List rData = new ArrayList<>();
- List rrIndex = new ArrayList<>();
- Object[] rr;
- List r1;
- List rIndex1;
- for (Object l : labels){
- rr = getIndices(index, l);
- r1 = (ArrayList)rr[0];
- rIndex1 = (ArrayList)rr[1];
- if (r1.isEmpty()){
- rData.add(0);
- rrIndex.add(l);
- } else {
- r.addAll(r1);
- rIndex.addAll(rIndex1);
- for (Iterator it = r1.iterator(); it.hasNext();) {
- it.next();
- rData.add(1);
- rrIndex.add(l);
- }
- }
- }
-
- return new Object[]{r, rIndex, rData, rrIndex};
- }
-
- /**
- * Get indices
- * @param index Index array
- * @param label Label
- * @return Indices
- */
- public static Object[] getIndices(List index, Object label) {
- List r = new ArrayList<>();
- List rIndex = new ArrayList<>();
- for (int i = 0; i < index.size(); i++){
- if (index.get(i).equals(label)){
- r.add(i);
- rIndex.add(index.get(i));
- }
- }
-
- return new Object[]{r, rIndex};
- }
-
- /**
- * Sub list by index
- * @param list The list
- * @param index The index
- * @return Result list
- */
- public static List subList(List list, List index){
- List r = new ArrayList<>();
- for (int i : index){
- r.add(list.get(i));
- }
-
- return r;
- }
-
-// /**
-// * Fill key list
-// * @param data Valid data array
-// * @param rrdata Result data flags
-// * @return Result data array with same length as key list
-// */
-// public static Array fillKeyList(Array data, List rrdata){
-// Array kdata = Array.factory(data.getDataType(), new int[]{rrdata.size()});
-// Object nanObj = null;
-// switch (data.getDataType()){
-// case FLOAT:
-// nanObj = Float.NaN;
-// break;
-// case DOUBLE:
-// nanObj = Double.NaN;
-// break;
-// }
-// int idx = 0;
-// int i = 0;
-// for (int f : rrdata){
-// if (f == 0)
-// kdata.setObject(i, nanObj);
-// else {
-// kdata.setObject(i, data.getObject(idx));
-// idx += 1;
-// }
-// i += 1;
-// }
-//
-// return kdata;
-// }
-
- /**
- * Fill key list
- * @param data Valid data array
- * @param rrdata Result data flags
- * @return Result data array with same length as key list
- */
- public static Array fillKeyList(Array data, List rrdata){
- Array kdata = Array.factory(data.getDataType(), new int[]{rrdata.size()});
- int idx = 0;
- int i = 0;
- for (int f : rrdata){
- if (f == 0)
- kdata.setObject(i, Double.NaN);
- else {
- kdata.setObject(i, data.getObject(idx));
- idx += 1;
- }
- i += 1;
- }
-
- return kdata;
- }
-
-}
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.meteoinfo.data;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.meteoinfo.math.ArrayMath;
+import org.meteoinfo.ndarray.Array;
+
+/**
+ *
+ * @author Yaqiang Wang
+ */
+public class SeriesUtil {
+
+ /**
+ * Get indices
+ * @param index Index array
+ * @param labels Labels
+ * @return Indices
+ */
+ public static Object[] getIndices(List index, Array labels) {
+ return getIndices(index, ArrayMath.asList(labels));
+ }
+
+ /**
+ * Get indices
+ * @param index Index array
+ * @param labels Labels
+ * @return Indices
+ */
+ public static Object[] getIndices(Array index, Array labels) {
+ return getIndices(ArrayMath.asList(index), ArrayMath.asList(labels));
+ }
+
+ /**
+ * Get indices
+ * @param index Index array
+ * @param labels Labels
+ * @return Indices
+ */
+ public static Object[] getIndices(List index, List labels) {
+ List r = new ArrayList<>();
+ List rIndex = new ArrayList<>();
+ List rData = new ArrayList<>();
+ List rrIndex = new ArrayList<>();
+ Object[] rr;
+ List r1;
+ List rIndex1;
+ for (Object l : labels){
+ rr = getIndices(index, l);
+ r1 = (ArrayList)rr[0];
+ rIndex1 = (ArrayList)rr[1];
+ if (r1.isEmpty()){
+ rData.add(0);
+ rrIndex.add(l);
+ } else {
+ r.addAll(r1);
+ rIndex.addAll(rIndex1);
+ for (Iterator it = r1.iterator(); it.hasNext();) {
+ it.next();
+ rData.add(1);
+ rrIndex.add(l);
+ }
+ }
+ }
+
+ return new Object[]{r, rIndex, rData, rrIndex};
+ }
+
+ /**
+ * Get indices
+ * @param index Index array
+ * @param label Label
+ * @return Indices
+ */
+ public static Object[] getIndices(List index, Object label) {
+ List r = new ArrayList<>();
+ List rIndex = new ArrayList<>();
+ for (int i = 0; i < index.size(); i++){
+ if (index.get(i).equals(label)){
+ r.add(i);
+ rIndex.add(index.get(i));
+ }
+ }
+
+ return new Object[]{r, rIndex};
+ }
+
+ /**
+ * Sub list by index
+ * @param list The list
+ * @param index The index
+ * @return Result list
+ */
+ public static List subList(List list, List index){
+ List r = new ArrayList<>();
+ for (int i : index){
+ r.add(list.get(i));
+ }
+
+ return r;
+ }
+
+// /**
+// * Fill key list
+// * @param data Valid data array
+// * @param rrdata Result data flags
+// * @return Result data array with same length as key list
+// */
+// public static Array fillKeyList(Array data, List rrdata){
+// Array kdata = Array.factory(data.getDataType(), new int[]{rrdata.size()});
+// Object nanObj = null;
+// switch (data.getDataType()){
+// case FLOAT:
+// nanObj = Float.NaN;
+// break;
+// case DOUBLE:
+// nanObj = Double.NaN;
+// break;
+// }
+// int idx = 0;
+// int i = 0;
+// for (int f : rrdata){
+// if (f == 0)
+// kdata.setObject(i, nanObj);
+// else {
+// kdata.setObject(i, data.getObject(idx));
+// idx += 1;
+// }
+// i += 1;
+// }
+//
+// return kdata;
+// }
+
+ /**
+ * Fill key list
+ * @param data Valid data array
+ * @param rrdata Result data flags
+ * @return Result data array with same length as key list
+ */
+ public static Array fillKeyList(Array data, List rrdata){
+ Array kdata = Array.factory(data.getDataType(), new int[]{rrdata.size()});
+ int idx = 0;
+ int i = 0;
+ for (int f : rrdata){
+ if (f == 0)
+ kdata.setObject(i, Double.NaN);
+ else {
+ kdata.setObject(i, data.getObject(idx));
+ idx += 1;
+ }
+ i += 1;
+ }
+
+ return kdata;
+ }
+
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/StationData.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/StationData.java
index 967b9941..8df35d0b 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/StationData.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/StationData.java
@@ -17,17 +17,19 @@ import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
+
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.MIMath;
+import org.meteoinfo.common.PointD;
import org.meteoinfo.data.meteodata.GridDataSetting;
import org.meteoinfo.geoprocess.analysis.InterpolationSetting;
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.global.MIMath;
+
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.meteoinfo.geoprocess.GeoComputation;
import org.meteoinfo.global.DataConvert;
-import org.meteoinfo.global.PointD;
import org.meteoinfo.layer.VectorLayer;
import org.meteoinfo.projection.info.ProjectionInfo;
import org.meteoinfo.projection.Reproject;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/StationTableData.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/StationTableData.java
index 2caf2b0d..ef0cb830 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/StationTableData.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/StationTableData.java
@@ -1,202 +1,203 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.meteoinfo.data;
-
-import java.io.BufferedReader;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-import java.util.List;
-import javax.swing.JOptionPane;
-import org.meteoinfo.global.util.GlobalUtil;
-import org.meteoinfo.ndarray.DataType;
-import org.meteoinfo.projection.KnownCoordinateSystems;
-import org.meteoinfo.projection.info.ProjectionInfo;
-
-/**
- *
- * @author yaqiang
- */
-public class StationTableData extends TableData{
- //
- private ProjectionInfo projInfo;
- private int stIdx;
- private int lonIdx;
- private int latIdx;
- //
- //
- /**
- * Constructor
- */
- public StationTableData(){
- this.projInfo = KnownCoordinateSystems.geographic.world.WGS1984;
- stIdx = 0;
- lonIdx = 1;
- latIdx = 2;
- }
- //
- //
- /**
- * Get projection info
- * @return Projection info
- */
- public ProjectionInfo getProjectionInfo(){
- return this.projInfo;
- }
-
- /**
- * Set projection info
- * @param value Projection info
- */
- public void setProjectionInfo(ProjectionInfo value){
- this.projInfo = value;
- }
-
- /**
- * Get station column index
- * @return Station column index
- */
- public int getStationIndex(){
- return this.stIdx;
- }
-
- /**
- * Set station column index
- * @param value Statin column index
- */
- public void setStationIndex(int value){
- this.stIdx = value;
- }
-
- /**
- * Get longitude column index
- * @return Longitude column index
- */
- public int getLonIndex(){
- return this.lonIdx;
- }
-
- /**
- * Set longitude column index
- * @param value Longitude column index
- */
- public void setLonIndex(int value){
- this.latIdx = value;
- }
-
- /**
- * Get latitude column index
- * @return Latitude column index
- */
- public int getLatIndex(){
- return this.latIdx;
- }
-
- /**
- * Set Latitude column index
- * @param value Latitude column index
- */
- public void setLatIndex(int value){
- this.lonIdx = value;
- }
- //
- //
- /**
- * Read data table from ASCII file
- *
- * @param fileName File name
- * @param lonIdx Longitude index
- * @param latIdx Latitude index
- * @throws java.io.FileNotFoundException
- */
- public void readASCIIFile(String fileName, int lonIdx, int latIdx) throws FileNotFoundException, IOException, Exception {
- this.readASCIIFile(fileName, 0, lonIdx, latIdx);
- }
-
- /**
- * Read data table from ASCII file
- *
- * @param fileName File name
- * @param stIdx Station column index
- * @param lonIdx Longitude column index
- * @param latIdx Latitude column index
- * @throws java.io.FileNotFoundException
- */
- public void readASCIIFile(String fileName, int stIdx, int lonIdx, int latIdx) throws FileNotFoundException, IOException, Exception {
- this.lonIdx = lonIdx;
- this.latIdx = latIdx;
- //DataTable dTable = new DataTable();
-
- BufferedReader sr = new BufferedReader(new InputStreamReader(new FileInputStream(fileName), "utf-8"));
- String title = sr.readLine().trim();
- //Determine separator
- String separator = GlobalUtil.getDelimiter(title);
- String[] titleArray = GlobalUtil.split(title, separator);
- if (titleArray.length < 2) {
- JOptionPane.showMessageDialog(null, "File Format Error!");
- sr.close();
- } else {
- //Get fields
- List dataIdxs = new ArrayList<>();
- String fieldName;
- for (int i = 0; i < titleArray.length; i++) {
- fieldName = titleArray[i];
- if (i == lonIdx || i == latIdx)
- this.addColumn(fieldName, DataType.FLOAT);
- else
- this.addColumn(fieldName, DataType.STRING);
- dataIdxs.add(i);
- }
-
- String[] dataArray;
- int rn = 0;
- String line = sr.readLine();
- while (line != null) {
- line = line.trim();
- if (line.isEmpty()) {
- continue;
- }
- dataArray = GlobalUtil.split(line, separator);
- this.addRow();
- int cn = 0;
- for (int idx : dataIdxs) {
- if (idx == lonIdx || idx == latIdx)
- this.setValue(rn, cn, Float.parseFloat(dataArray[idx]));
- else
- this.setValue(rn, cn, dataArray[idx]);
- cn++;
- }
-
- rn += 1;
- line = sr.readLine();
- }
-
- //dataTable = dTable;
- sr.close();
- }
- }
-
- /**
- * Clone
- * @return Cloned StationTableData object
- */
- @Override
- public Object clone(){
- StationTableData std = new StationTableData();
- std = (StationTableData)super.clone();
- //std.dataTable = (DataTable)this.dataTable.clone();
- std.missingValue = this.missingValue;
- std.projInfo = this.projInfo;
- std.stIdx = this.stIdx;
- std.lonIdx = this.lonIdx;
- std.latIdx = this.latIdx;
-
- return std;
- }
- //
-}
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.meteoinfo.data;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.List;
+import javax.swing.JOptionPane;
+
+import org.meteoinfo.common.util.GlobalUtil;
+import org.meteoinfo.ndarray.DataType;
+import org.meteoinfo.projection.KnownCoordinateSystems;
+import org.meteoinfo.projection.info.ProjectionInfo;
+
+/**
+ *
+ * @author yaqiang
+ */
+public class StationTableData extends TableData{
+ //
+ private ProjectionInfo projInfo;
+ private int stIdx;
+ private int lonIdx;
+ private int latIdx;
+ //
+ //
+ /**
+ * Constructor
+ */
+ public StationTableData(){
+ this.projInfo = KnownCoordinateSystems.geographic.world.WGS1984;
+ stIdx = 0;
+ lonIdx = 1;
+ latIdx = 2;
+ }
+ //
+ //
+ /**
+ * Get projection info
+ * @return Projection info
+ */
+ public ProjectionInfo getProjectionInfo(){
+ return this.projInfo;
+ }
+
+ /**
+ * Set projection info
+ * @param value Projection info
+ */
+ public void setProjectionInfo(ProjectionInfo value){
+ this.projInfo = value;
+ }
+
+ /**
+ * Get station column index
+ * @return Station column index
+ */
+ public int getStationIndex(){
+ return this.stIdx;
+ }
+
+ /**
+ * Set station column index
+ * @param value Statin column index
+ */
+ public void setStationIndex(int value){
+ this.stIdx = value;
+ }
+
+ /**
+ * Get longitude column index
+ * @return Longitude column index
+ */
+ public int getLonIndex(){
+ return this.lonIdx;
+ }
+
+ /**
+ * Set longitude column index
+ * @param value Longitude column index
+ */
+ public void setLonIndex(int value){
+ this.latIdx = value;
+ }
+
+ /**
+ * Get latitude column index
+ * @return Latitude column index
+ */
+ public int getLatIndex(){
+ return this.latIdx;
+ }
+
+ /**
+ * Set Latitude column index
+ * @param value Latitude column index
+ */
+ public void setLatIndex(int value){
+ this.lonIdx = value;
+ }
+ //
+ //
+ /**
+ * Read data table from ASCII file
+ *
+ * @param fileName File name
+ * @param lonIdx Longitude index
+ * @param latIdx Latitude index
+ * @throws java.io.FileNotFoundException
+ */
+ public void readASCIIFile(String fileName, int lonIdx, int latIdx) throws FileNotFoundException, IOException, Exception {
+ this.readASCIIFile(fileName, 0, lonIdx, latIdx);
+ }
+
+ /**
+ * Read data table from ASCII file
+ *
+ * @param fileName File name
+ * @param stIdx Station column index
+ * @param lonIdx Longitude column index
+ * @param latIdx Latitude column index
+ * @throws java.io.FileNotFoundException
+ */
+ public void readASCIIFile(String fileName, int stIdx, int lonIdx, int latIdx) throws FileNotFoundException, IOException, Exception {
+ this.lonIdx = lonIdx;
+ this.latIdx = latIdx;
+ //DataTable dTable = new DataTable();
+
+ BufferedReader sr = new BufferedReader(new InputStreamReader(new FileInputStream(fileName), "utf-8"));
+ String title = sr.readLine().trim();
+ //Determine separator
+ String separator = GlobalUtil.getDelimiter(title);
+ String[] titleArray = GlobalUtil.split(title, separator);
+ if (titleArray.length < 2) {
+ JOptionPane.showMessageDialog(null, "File Format Error!");
+ sr.close();
+ } else {
+ //Get fields
+ List dataIdxs = new ArrayList<>();
+ String fieldName;
+ for (int i = 0; i < titleArray.length; i++) {
+ fieldName = titleArray[i];
+ if (i == lonIdx || i == latIdx)
+ this.addColumn(fieldName, DataType.FLOAT);
+ else
+ this.addColumn(fieldName, DataType.STRING);
+ dataIdxs.add(i);
+ }
+
+ String[] dataArray;
+ int rn = 0;
+ String line = sr.readLine();
+ while (line != null) {
+ line = line.trim();
+ if (line.isEmpty()) {
+ continue;
+ }
+ dataArray = GlobalUtil.split(line, separator);
+ this.addRow();
+ int cn = 0;
+ for (int idx : dataIdxs) {
+ if (idx == lonIdx || idx == latIdx)
+ this.setValue(rn, cn, Float.parseFloat(dataArray[idx]));
+ else
+ this.setValue(rn, cn, dataArray[idx]);
+ cn++;
+ }
+
+ rn += 1;
+ line = sr.readLine();
+ }
+
+ //dataTable = dTable;
+ sr.close();
+ }
+ }
+
+ /**
+ * Clone
+ * @return Cloned StationTableData object
+ */
+ @Override
+ public Object clone(){
+ StationTableData std = new StationTableData();
+ std = (StationTableData)super.clone();
+ //std.dataTable = (DataTable)this.dataTable.clone();
+ std.missingValue = this.missingValue;
+ std.projInfo = this.projInfo;
+ std.stIdx = this.stIdx;
+ std.lonIdx = this.lonIdx;
+ std.latIdx = this.latIdx;
+
+ return std;
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/TableData.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/TableData.java
index 30b9dca1..130ba93c 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/TableData.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/TableData.java
@@ -26,9 +26,10 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.swing.JOptionPane;
+
+import org.meteoinfo.common.MIMath;
+import org.meteoinfo.common.util.GlobalUtil;
import org.meteoinfo.data.analysis.Statistics;
-import org.meteoinfo.global.MIMath;
-import org.meteoinfo.global.util.GlobalUtil;
import org.meteoinfo.ndarray.DataType;
import org.meteoinfo.table.DataColumn;
import org.meteoinfo.table.DataRow;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/TableUtil.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/TableUtil.java
index 76759ed0..68659b78 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/TableUtil.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/TableUtil.java
@@ -15,8 +15,9 @@ import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+
+import org.meteoinfo.common.util.GlobalUtil;
import org.meteoinfo.data.analysis.Statistics;
-import org.meteoinfo.global.util.GlobalUtil;
import org.meteoinfo.table.DataColumn;
import org.meteoinfo.table.DataRow;
import org.meteoinfo.table.DataTable;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/TimeTableData.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/TimeTableData.java
index b8179fe1..73749c7e 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/TimeTableData.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/TimeTableData.java
@@ -17,11 +17,12 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.swing.JOptionPane;
+
+import org.meteoinfo.common.util.GlobalUtil;
import org.meteoinfo.data.analysis.Statistics;
import org.meteoinfo.table.DataColumn;
import org.meteoinfo.table.DataRow;
import org.meteoinfo.table.DataTable;
-import org.meteoinfo.global.util.GlobalUtil;
import org.meteoinfo.ndarray.DataType;
/**
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/XYArrayDataset.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/XYArrayDataset.java
index b4332f19..9ff10728 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/XYArrayDataset.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/XYArrayDataset.java
@@ -1,342 +1,343 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.meteoinfo.data;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.global.MIMath;
-
-/**
- *
- * @author wyq
- */
-public class XYArrayDataset extends XYDataset {
-
- //
-
- private final double[][] xValues;
- private final double[][] yValues;
- private final int seriesCount;
- private final int itemCount;
- private String[] seriesKeys;
-
- //
- //
-
- /**
- * Constructor
- *
- * @param seriesNum Series number
- * @param itemNum Item number
- */
- public XYArrayDataset(int seriesNum, int itemNum) {
- this.seriesCount = seriesNum;
- this.itemCount = itemNum;
- xValues = new double[seriesNum][itemNum];
- yValues = new double[seriesNum][itemNum];
- seriesKeys = new String[seriesNum];
- }
-
- /**
- * Constructor
- *
- * @param xdata X station data
- * @param ydata Y station data
- * @param seriesKey Series key
- */
- public XYArrayDataset(StationData xdata, StationData ydata, String seriesKey) {
- List vdata = new ArrayList<>();
- double v1, v2;
- for (int i = 0; i < xdata.getStNum(); i++) {
- v1 = xdata.getValue(i);
- if (MIMath.doubleEquals(v1, xdata.missingValue)) {
- continue;
- }
- v2 = ydata.getValue(i);
- if (MIMath.doubleEquals(v2, ydata.missingValue)) {
- continue;
- }
- vdata.add(new double[]{v1, v2});
- }
- seriesCount = 1;
- seriesKeys = new String[seriesCount];
- seriesKeys[0] = seriesKey;
- itemCount = vdata.size();
- xValues = new double[seriesCount][itemCount];
- yValues = new double[seriesCount][itemCount];
- for (int i = 0; i < seriesCount; i++) {
- for (int j = 0; j < itemCount; j++) {
- xValues[i][j] = vdata.get(j)[0];
- yValues[i][j] = vdata.get(j)[1];
- }
- }
- }
-
- /**
- * Constructor
- *
- * @param xdata X data
- * @param ydata Y data
- * @param seriesKey Series key
- */
- public XYArrayDataset(List xdata, List ydata, String seriesKey) {
- List nxdata = new ArrayList<>();
- List nydata = new ArrayList<>();
- for (int i = 0; i < xdata.size(); i++) {
- nxdata.add(Double.parseDouble(xdata.get(i).toString()));
- nydata.add(Double.parseDouble(ydata.get(i).toString()));
- }
-
- List vdata = new ArrayList<>();
- double v1, v2;
- for (int i = 0; i < xdata.size(); i++) {
- v1 = nxdata.get(i);
- v2 = nydata.get(i);
- vdata.add(new double[]{v1, v2});
- }
- seriesCount = 1;
- seriesKeys = new String[seriesCount];
- seriesKeys[0] = seriesKey;
- itemCount = vdata.size();
- xValues = new double[seriesCount][itemCount];
- yValues = new double[seriesCount][itemCount];
- for (int i = 0; i < seriesCount; i++) {
- for (int j = 0; j < itemCount; j++) {
- xValues[i][j] = vdata.get(j)[0];
- yValues[i][j] = vdata.get(j)[1];
- }
- }
- }
-
- //
- //
-
- /**
- * Get series count
- * @return Series count
- */
- @Override
- public int getSeriesCount() {
- return this.seriesCount;
- }
-
- /**
- * Get series key by index
- * @param seriesIdx Series index
- * @return Series key
- */
- @Override
- public String getSeriesKey(int seriesIdx) {
- return seriesKeys[seriesIdx];
- }
-
- /**
- * Set series key by index
- * @param seriesIdx Series index
- * @param seriesKey Series key
- */
- @Override
- public void setSeriesKey(int seriesIdx, String seriesKey){
- this.seriesKeys[seriesIdx] = seriesKey;
- }
-
- /**
- * Get item count
- * @return Item count
- */
- @Override
- public int getItemCount() {
- return this.itemCount;
- }
-
- /**
- * Get item count
- * @param seriesIdx Series index
- * @return Item count
- */
- @Override
- public int getItemCount(int seriesIdx){
- return this.itemCount;
- }
-
- /**
- * Get x values
- * @param seriesIdx Series index
- * @return X values
- */
- @Override
- public double[] getXValues(int seriesIdx){
- return this.xValues[seriesIdx];
- }
-
- /**
- * Get y values
- * @param seriesIdx Series index
- * @return Y values
- */
- @Override
- public double[] getYValues(int seriesIdx){
- return this.yValues[seriesIdx];
- }
-
- /**
- * Get x value
- * @param seriesIdx Series index
- * @param itemIdx Item index
- * @return X value
- */
- @Override
- public double getX(int seriesIdx, int itemIdx) {
- return xValues[seriesIdx][itemIdx];
- }
-
- /**
- * Set x value
- * @param seriesIdx Series index
- * @param itemIdx Item index
- * @param value X value
- */
- @Override
- public void setX(int seriesIdx, int itemIdx, double value){
- xValues[seriesIdx][itemIdx] = value;
- }
-
- /**
- * Get Y value
- * @param seriesIdx Series index
- * @param itemIdx Item index
- * @return Y value
- */
- @Override
- public double getY(int seriesIdx, int itemIdx) {
- return yValues[seriesIdx][itemIdx];
- }
-
- /**
- * Set Y value
- * @param seriesIdx Series index
- * @param itemIdx Item index
- * @param value Y value
- */
- @Override
- public void setY(int seriesIdx, int itemIdx, double value){
- yValues[seriesIdx][itemIdx] = value;
- }
-
- /**
- * Get series keys
- * @return Series keys
- */
- @Override
- public List getSeriesKeys(){
- return Arrays.asList(this.seriesKeys);
- }
-
- /**
- * Set series keys
- * @param value Series keys
- */
- public void setSeriesKeys(String[] value){
- this.seriesKeys = value;
- }
-
- /**
- * Set series keys
- * @param value Series keys
- */
- @Override
- public void setSeriesKeys(List value){
- this.seriesKeys = (String[])value.toArray(new String[value.size()]);
- }
-
- //
- //
-
- /**
- * Get data extent
- * @return Data extent
- */
- @Override
- public Extent getDataExtent() {
- Extent cET = new Extent();
- double x, y;
- int n = 0;
- for (int i = 0; i < this.seriesCount; i++) {
- for (int j = 0; j < this.itemCount; j++) {
- x = xValues[i][j];
- y = yValues[i][j];
- if (MIMath.doubleEquals(y, this.getMissingValue()) || MIMath.doubleEquals(x, this.getMissingValue()))
- continue;
- if (n == 0) {
- cET.minX = x;
- cET.maxX = x;
- cET.minY = y;
- cET.maxY = y;
- } else {
- if (cET.minX > x) {
- cET.minX = x;
- } else if (cET.maxX < x) {
- cET.maxX = x;
- }
-
- if (cET.minY > y) {
- cET.minY = y;
- } else if (cET.maxY < y) {
- cET.maxY = y;
- }
- }
- n ++;
- }
- }
-
- return cET;
- }
-
- /**
- * Select data points
- * @param extent Selection extent
- * @return Selected data points
- */
- @Override
- public List selectPoints(Extent extent){
- List selIdxs = new ArrayList();
- double x, y;
- for (int i = 0; i < this.seriesCount; i++){
- for (int j = 0; j < this.itemCount; j++){
- x = this.getX(i, j);
- if (x >= extent.minX && x <= extent.maxX){
- y = this.getY(i, j);
- if (y >= extent.minY && y <= extent.maxY){
- selIdxs.add(new int[]{i, j});
- }
- }
- }
- }
-
- return selIdxs;
- }
-
- /**
- * Get missing value index list
- * @param seriesIdx Series index
- * @return Missing value index list
- */
- @Override
- public List getMissingValueIndex(int seriesIdx){
- List mvidx = new ArrayList();
- double[] xvs = this.getXValues(seriesIdx);
- double[] yvs = this.getYValues(seriesIdx);
- for (int i = 0; i < this.itemCount; i++){
- if (MIMath.doubleEquals(xvs[i], this.getMissingValue()) || MIMath.doubleEquals(yvs[i], this.getMissingValue()))
- mvidx.add(i);
- }
-
- return mvidx;
- }
- //
-}
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.meteoinfo.data;
+
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.MIMath;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ *
+ * @author wyq
+ */
+public class XYArrayDataset extends XYDataset {
+
+ //
+
+ private final double[][] xValues;
+ private final double[][] yValues;
+ private final int seriesCount;
+ private final int itemCount;
+ private String[] seriesKeys;
+
+ //
+ //
+
+ /**
+ * Constructor
+ *
+ * @param seriesNum Series number
+ * @param itemNum Item number
+ */
+ public XYArrayDataset(int seriesNum, int itemNum) {
+ this.seriesCount = seriesNum;
+ this.itemCount = itemNum;
+ xValues = new double[seriesNum][itemNum];
+ yValues = new double[seriesNum][itemNum];
+ seriesKeys = new String[seriesNum];
+ }
+
+ /**
+ * Constructor
+ *
+ * @param xdata X station data
+ * @param ydata Y station data
+ * @param seriesKey Series key
+ */
+ public XYArrayDataset(StationData xdata, StationData ydata, String seriesKey) {
+ List vdata = new ArrayList<>();
+ double v1, v2;
+ for (int i = 0; i < xdata.getStNum(); i++) {
+ v1 = xdata.getValue(i);
+ if (MIMath.doubleEquals(v1, xdata.missingValue)) {
+ continue;
+ }
+ v2 = ydata.getValue(i);
+ if (MIMath.doubleEquals(v2, ydata.missingValue)) {
+ continue;
+ }
+ vdata.add(new double[]{v1, v2});
+ }
+ seriesCount = 1;
+ seriesKeys = new String[seriesCount];
+ seriesKeys[0] = seriesKey;
+ itemCount = vdata.size();
+ xValues = new double[seriesCount][itemCount];
+ yValues = new double[seriesCount][itemCount];
+ for (int i = 0; i < seriesCount; i++) {
+ for (int j = 0; j < itemCount; j++) {
+ xValues[i][j] = vdata.get(j)[0];
+ yValues[i][j] = vdata.get(j)[1];
+ }
+ }
+ }
+
+ /**
+ * Constructor
+ *
+ * @param xdata X data
+ * @param ydata Y data
+ * @param seriesKey Series key
+ */
+ public XYArrayDataset(List xdata, List ydata, String seriesKey) {
+ List nxdata = new ArrayList<>();
+ List nydata = new ArrayList<>();
+ for (int i = 0; i < xdata.size(); i++) {
+ nxdata.add(Double.parseDouble(xdata.get(i).toString()));
+ nydata.add(Double.parseDouble(ydata.get(i).toString()));
+ }
+
+ List vdata = new ArrayList<>();
+ double v1, v2;
+ for (int i = 0; i < xdata.size(); i++) {
+ v1 = nxdata.get(i);
+ v2 = nydata.get(i);
+ vdata.add(new double[]{v1, v2});
+ }
+ seriesCount = 1;
+ seriesKeys = new String[seriesCount];
+ seriesKeys[0] = seriesKey;
+ itemCount = vdata.size();
+ xValues = new double[seriesCount][itemCount];
+ yValues = new double[seriesCount][itemCount];
+ for (int i = 0; i < seriesCount; i++) {
+ for (int j = 0; j < itemCount; j++) {
+ xValues[i][j] = vdata.get(j)[0];
+ yValues[i][j] = vdata.get(j)[1];
+ }
+ }
+ }
+
+ //
+ //
+
+ /**
+ * Get series count
+ * @return Series count
+ */
+ @Override
+ public int getSeriesCount() {
+ return this.seriesCount;
+ }
+
+ /**
+ * Get series key by index
+ * @param seriesIdx Series index
+ * @return Series key
+ */
+ @Override
+ public String getSeriesKey(int seriesIdx) {
+ return seriesKeys[seriesIdx];
+ }
+
+ /**
+ * Set series key by index
+ * @param seriesIdx Series index
+ * @param seriesKey Series key
+ */
+ @Override
+ public void setSeriesKey(int seriesIdx, String seriesKey){
+ this.seriesKeys[seriesIdx] = seriesKey;
+ }
+
+ /**
+ * Get item count
+ * @return Item count
+ */
+ @Override
+ public int getItemCount() {
+ return this.itemCount;
+ }
+
+ /**
+ * Get item count
+ * @param seriesIdx Series index
+ * @return Item count
+ */
+ @Override
+ public int getItemCount(int seriesIdx){
+ return this.itemCount;
+ }
+
+ /**
+ * Get x values
+ * @param seriesIdx Series index
+ * @return X values
+ */
+ @Override
+ public double[] getXValues(int seriesIdx){
+ return this.xValues[seriesIdx];
+ }
+
+ /**
+ * Get y values
+ * @param seriesIdx Series index
+ * @return Y values
+ */
+ @Override
+ public double[] getYValues(int seriesIdx){
+ return this.yValues[seriesIdx];
+ }
+
+ /**
+ * Get x value
+ * @param seriesIdx Series index
+ * @param itemIdx Item index
+ * @return X value
+ */
+ @Override
+ public double getX(int seriesIdx, int itemIdx) {
+ return xValues[seriesIdx][itemIdx];
+ }
+
+ /**
+ * Set x value
+ * @param seriesIdx Series index
+ * @param itemIdx Item index
+ * @param value X value
+ */
+ @Override
+ public void setX(int seriesIdx, int itemIdx, double value){
+ xValues[seriesIdx][itemIdx] = value;
+ }
+
+ /**
+ * Get Y value
+ * @param seriesIdx Series index
+ * @param itemIdx Item index
+ * @return Y value
+ */
+ @Override
+ public double getY(int seriesIdx, int itemIdx) {
+ return yValues[seriesIdx][itemIdx];
+ }
+
+ /**
+ * Set Y value
+ * @param seriesIdx Series index
+ * @param itemIdx Item index
+ * @param value Y value
+ */
+ @Override
+ public void setY(int seriesIdx, int itemIdx, double value){
+ yValues[seriesIdx][itemIdx] = value;
+ }
+
+ /**
+ * Get series keys
+ * @return Series keys
+ */
+ @Override
+ public List getSeriesKeys(){
+ return Arrays.asList(this.seriesKeys);
+ }
+
+ /**
+ * Set series keys
+ * @param value Series keys
+ */
+ public void setSeriesKeys(String[] value){
+ this.seriesKeys = value;
+ }
+
+ /**
+ * Set series keys
+ * @param value Series keys
+ */
+ @Override
+ public void setSeriesKeys(List value){
+ this.seriesKeys = (String[])value.toArray(new String[value.size()]);
+ }
+
+ //
+ //
+
+ /**
+ * Get data extent
+ * @return Data extent
+ */
+ @Override
+ public Extent getDataExtent() {
+ Extent cET = new Extent();
+ double x, y;
+ int n = 0;
+ for (int i = 0; i < this.seriesCount; i++) {
+ for (int j = 0; j < this.itemCount; j++) {
+ x = xValues[i][j];
+ y = yValues[i][j];
+ if (MIMath.doubleEquals(y, this.getMissingValue()) || MIMath.doubleEquals(x, this.getMissingValue()))
+ continue;
+ if (n == 0) {
+ cET.minX = x;
+ cET.maxX = x;
+ cET.minY = y;
+ cET.maxY = y;
+ } else {
+ if (cET.minX > x) {
+ cET.minX = x;
+ } else if (cET.maxX < x) {
+ cET.maxX = x;
+ }
+
+ if (cET.minY > y) {
+ cET.minY = y;
+ } else if (cET.maxY < y) {
+ cET.maxY = y;
+ }
+ }
+ n ++;
+ }
+ }
+
+ return cET;
+ }
+
+ /**
+ * Select data points
+ * @param extent Selection extent
+ * @return Selected data points
+ */
+ @Override
+ public List selectPoints(Extent extent){
+ List selIdxs = new ArrayList();
+ double x, y;
+ for (int i = 0; i < this.seriesCount; i++){
+ for (int j = 0; j < this.itemCount; j++){
+ x = this.getX(i, j);
+ if (x >= extent.minX && x <= extent.maxX){
+ y = this.getY(i, j);
+ if (y >= extent.minY && y <= extent.maxY){
+ selIdxs.add(new int[]{i, j});
+ }
+ }
+ }
+ }
+
+ return selIdxs;
+ }
+
+ /**
+ * Get missing value index list
+ * @param seriesIdx Series index
+ * @return Missing value index list
+ */
+ @Override
+ public List getMissingValueIndex(int seriesIdx){
+ List mvidx = new ArrayList();
+ double[] xvs = this.getXValues(seriesIdx);
+ double[] yvs = this.getYValues(seriesIdx);
+ for (int i = 0; i < this.itemCount; i++){
+ if (MIMath.doubleEquals(xvs[i], this.getMissingValue()) || MIMath.doubleEquals(yvs[i], this.getMissingValue()))
+ mvidx.add(i);
+ }
+
+ return mvidx;
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/XYDataset.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/XYDataset.java
index db1936dd..12a741a0 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/XYDataset.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/XYDataset.java
@@ -1,155 +1,156 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.meteoinfo.data;
-
-import java.util.List;
-import org.meteoinfo.global.Extent;
-
-/**
- *
- * @author yaqiang
- */
-public abstract class XYDataset extends Dataset{
-
- private double missingValue = -9999.0;
-
- /**
- * Get missing value
- * @return Missing value
- */
- public double getMissingValue(){
- return this.missingValue;
- }
-
- /**
- * Set missing value
- * @param value Missing value
- */
- public void setMissingValue(double value){
- this.missingValue = value;
- }
-
- /**
- * Get dataset type
- * @return Dataset type
- */
- @Override
- public DatasetType getDatasetType() {
- return DatasetType.XY;
- }
-
- /**
- * Get series count
- * @return Series count
- */
- public abstract int getSeriesCount();
-
- /**
- * Get item count
- * @return Item count
- */
- public abstract int getItemCount();
-
- /**
- * Get item count by series index
- * @param seriesIdx Series index
- * @return Item count
- */
- public abstract int getItemCount(int seriesIdx);
-
- /**
- * Get x value
- * @param seriesIdx Series index
- * @param itemIdx Item index
- * @return X value
- */
- public abstract double getX(int seriesIdx, int itemIdx);
-
- /**
- * Get y value
- * @param seriesIdx Series index
- * @param itemIdx Item index
- * @return Y value
- */
- public abstract double getY(int seriesIdx, int itemIdx);
-
- /**
- * Set x value
- * @param seriesIdx Series index
- * @param itemIdx Item index
- * @param value X value
- */
- public abstract void setX(int seriesIdx, int itemIdx, double value);
-
- /**
- * Set y value
- * @param seriesIdx Series index
- * @param itemIdx Item index
- * @param value Y value
- */
- public abstract void setY(int seriesIdx, int itemIdx, double value);
-
- /**
- * Get x values
- * @param seriesIdx Series index
- * @return X values
- */
- public abstract double[] getXValues(int seriesIdx);
-
- /**
- * Get y values
- * @param seriesIdx Series index
- * @return Y values
- */
- public abstract double[] getYValues(int seriesIdx);
-
- /**
- * Get series key by index
- * @param seriesIdx Series index
- * @return Series key
- */
- public abstract String getSeriesKey(int seriesIdx);
-
- /**
- * Set series key by index
- * @param seriesIdx Series index
- * @param seriesKey Series key
- */
- public abstract void setSeriesKey(int seriesIdx, String seriesKey);
-
- /**
- * Get series keys
- * @return Series keys
- */
- public abstract List getSeriesKeys();
-
- /**
- * Set series keys
- * @param keys Keys
- */
- public abstract void setSeriesKeys(List keys);
-
- /**
- * Get data extent
- * @return Data extent
- */
- public abstract Extent getDataExtent();
-
- /**
- * Get missing value index list
- * @param seriesIdx Series index
- * @return Missing value index list
- */
- public abstract List getMissingValueIndex(int seriesIdx);
-
- /**
- * Select data points
- * @param extent Selection extent
- * @return Selected data points
- */
- public abstract List selectPoints(Extent extent);
-
-}
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.meteoinfo.data;
+
+import org.meteoinfo.common.Extent;
+
+import java.util.List;
+
+/**
+ *
+ * @author yaqiang
+ */
+public abstract class XYDataset extends Dataset{
+
+ private double missingValue = -9999.0;
+
+ /**
+ * Get missing value
+ * @return Missing value
+ */
+ public double getMissingValue(){
+ return this.missingValue;
+ }
+
+ /**
+ * Set missing value
+ * @param value Missing value
+ */
+ public void setMissingValue(double value){
+ this.missingValue = value;
+ }
+
+ /**
+ * Get dataset type
+ * @return Dataset type
+ */
+ @Override
+ public DatasetType getDatasetType() {
+ return DatasetType.XY;
+ }
+
+ /**
+ * Get series count
+ * @return Series count
+ */
+ public abstract int getSeriesCount();
+
+ /**
+ * Get item count
+ * @return Item count
+ */
+ public abstract int getItemCount();
+
+ /**
+ * Get item count by series index
+ * @param seriesIdx Series index
+ * @return Item count
+ */
+ public abstract int getItemCount(int seriesIdx);
+
+ /**
+ * Get x value
+ * @param seriesIdx Series index
+ * @param itemIdx Item index
+ * @return X value
+ */
+ public abstract double getX(int seriesIdx, int itemIdx);
+
+ /**
+ * Get y value
+ * @param seriesIdx Series index
+ * @param itemIdx Item index
+ * @return Y value
+ */
+ public abstract double getY(int seriesIdx, int itemIdx);
+
+ /**
+ * Set x value
+ * @param seriesIdx Series index
+ * @param itemIdx Item index
+ * @param value X value
+ */
+ public abstract void setX(int seriesIdx, int itemIdx, double value);
+
+ /**
+ * Set y value
+ * @param seriesIdx Series index
+ * @param itemIdx Item index
+ * @param value Y value
+ */
+ public abstract void setY(int seriesIdx, int itemIdx, double value);
+
+ /**
+ * Get x values
+ * @param seriesIdx Series index
+ * @return X values
+ */
+ public abstract double[] getXValues(int seriesIdx);
+
+ /**
+ * Get y values
+ * @param seriesIdx Series index
+ * @return Y values
+ */
+ public abstract double[] getYValues(int seriesIdx);
+
+ /**
+ * Get series key by index
+ * @param seriesIdx Series index
+ * @return Series key
+ */
+ public abstract String getSeriesKey(int seriesIdx);
+
+ /**
+ * Set series key by index
+ * @param seriesIdx Series index
+ * @param seriesKey Series key
+ */
+ public abstract void setSeriesKey(int seriesIdx, String seriesKey);
+
+ /**
+ * Get series keys
+ * @return Series keys
+ */
+ public abstract List getSeriesKeys();
+
+ /**
+ * Set series keys
+ * @param keys Keys
+ */
+ public abstract void setSeriesKeys(List keys);
+
+ /**
+ * Get data extent
+ * @return Data extent
+ */
+ public abstract Extent getDataExtent();
+
+ /**
+ * Get missing value index list
+ * @param seriesIdx Series index
+ * @return Missing value index list
+ */
+ public abstract List getMissingValueIndex(int seriesIdx);
+
+ /**
+ * Select data points
+ * @param extent Selection extent
+ * @return Selected data points
+ */
+ public abstract List selectPoints(Extent extent);
+
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/XYListDataset.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/XYListDataset.java
index e8f7fe1c..258dcb5a 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/XYListDataset.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/XYListDataset.java
@@ -1,443 +1,444 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.meteoinfo.data;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.global.MIMath;
-import org.meteoinfo.ndarray.Array;
-
-/**
- *
- * @author wyq
- */
-public class XYListDataset extends XYDataset {
- //
- //private List xValues;
- //private List yValues;
- //private List seriesKeys;
- private List dataset;
- //
- //
- /**
- * Constructor
- */
- public XYListDataset(){
- //xValues = new ArrayList<>();
- //yValues = new ArrayList<>();
- //seriesKeys = new ArrayList<>();
- dataset = new ArrayList<>();
- }
-
- /**
- * Constructor
- *
- * @param seriesNum Series number
- * @param itemNum Item number
- */
- public XYListDataset(int seriesNum, int itemNum) {
- this();
-
- for (int i = 0; i < seriesNum; i++){
- //xValues.add(new double[itemNum]);
- //yValues.add(new double[itemNum]);
- //seriesKeys.add("");
- dataset.add(new XYSeriesData());
- }
- }
-
- /**
- * Constructor
- * @param xdata X station data
- * @param ydata Y station data
- * @param seriesKey Series key
- */
- public XYListDataset(StationData xdata, StationData ydata, String seriesKey){
- this();
- List vdata = new ArrayList<>();
- double v1, v2;
- for (int i = 0; i < xdata.getStNum(); i++) {
- v1 = xdata.getValue(i);
- if (MIMath.doubleEquals(v1, xdata.missingValue)) {
- continue;
- }
- v2 = ydata.getValue(i);
- if (MIMath.doubleEquals(v2, ydata.missingValue)) {
- continue;
- }
- vdata.add(new double[]{v1, v2});
- }
-
- int n = vdata.size();
- double[] xvs = new double[n];
- double[] yvs = new double[n];
- for (int i = 0; i < n; i++){
- xvs[i] = vdata.get(i)[0];
- yvs[i] = vdata.get(i)[1];
- }
- //this.xValues.add(xvs);
- //this.yValues.add(yvs);
- //this.seriesKeys.add(seriesKey);
- XYSeriesData sdata = new XYSeriesData(seriesKey, xvs, yvs);
- this.dataset.add(sdata);
- }
- //
- //
-
- /**
- * Get series data
- * @param seriesIdx Series index
- * @return Series data
- */
- public XYSeriesData getSeriesData(int seriesIdx){
- return this.dataset.get(seriesIdx);
- }
-
- @Override
- public int getSeriesCount() {
- //return this.xValues.size();
- return this.dataset.size();
- }
-
- @Override
- public String getSeriesKey(int seriesIdx) {
- //return this.seriesKeys.get(seriesIdx);
- return this.dataset.get(seriesIdx).getKey();
- }
-
- /**
- * Set series key by index
- * @param seriesIdx Series index
- * @param seriesKey Series key
- */
- @Override
- public void setSeriesKey(int seriesIdx, String seriesKey){
- //this.seriesKeys.set(seriesIdx, seriesKey);
- this.dataset.get(seriesIdx).setKey(seriesKey);
- }
-
- /**
- * Get series keys
- * @return Series keys
- */
- @Override
- public List getSeriesKeys(){
- //return this.seriesKeys;
- List keys = new ArrayList<>();
- for (XYSeriesData d :this.dataset){
- keys.add(d.getKey());
- }
- return keys;
- }
-
- /**
- * Set series keys
- * @param value Series keys
- */
- @Override
- public void setSeriesKeys(List value){
- //this.seriesKeys = value;
- int i = 0;
- for (XYSeriesData d :this.dataset){
- d.setKey(value.get(i));
- i++;
- }
- }
-
- @Override
- public int getItemCount(){
- int n = this.getItemCount(0);
- if (this.getSeriesCount() > 1){
- for (int i = 1; i < this.getSeriesCount(); i++){
- int nn = this.getItemCount(i);
- if (n < nn)
- n = nn;
- }
- }
-
- return n;
- }
-
- @Override
- public int getItemCount(int seriesIdx) {
- //return this.xValues.get(seriesIdx).length;
- return this.dataset.get(seriesIdx).dataLength();
- }
-
- @Override
- public double[] getXValues(int seriesIdx){
- //return this.xValues.get(seriesIdx);
- return this.dataset.get(seriesIdx).getXdata();
- }
-
- @Override
- public double[] getYValues(int seriesIdx){
- //return this.yValues.get(seriesIdx);
- return this.dataset.get(seriesIdx).getYdata();
- }
-
- @Override
- public double getX(int seriesIdx, int itemIdx) {
- //return this.xValues.get(seriesIdx)[itemIdx];
- return this.dataset.get(seriesIdx).getXdata()[itemIdx];
- }
-
- @Override
- public double getY(int seriesIdx, int itemIdx) {
- //return this.yValues.get(seriesIdx)[itemIdx];
- return this.dataset.get(seriesIdx).getYdata()[itemIdx];
- }
-
- @Override
- public void setX(int seriesIdx, int itemIdx, double value){
- //this.xValues.get(seriesIdx)[itemIdx] = value;
- this.dataset.get(seriesIdx).getXdata()[itemIdx] = value;
- }
-
- @Override
- public void setY(int seriesIdx, int itemIdx, double value){
- //this.yValues.get(seriesIdx)[itemIdx] = value;
- this.dataset.get(seriesIdx).getYdata()[itemIdx] = value;
- }
- //
- //
- /**
- * Add a series data
- * @param sdata Series data
- */
- public void addSeries(XYSeriesData sdata){
- this.dataset.add(sdata);
- }
-
- /**
- * Add a series data
- * @param seriesKey Series key
- * @param xvs X value array
- * @param yvs Y value array
- */
- public void addSeries(String seriesKey, double[] xvs, double[] yvs){
- //this.seriesKeys.add(seriesKey);
- //this.xValues.add(xvs);
- //this.yValues.add(yvs);
- XYSeriesData sdata = new XYSeriesData(seriesKey, xvs, yvs);
- this.dataset.add(sdata);
- }
-
- /**
- * Add a series data
- * @param seriesKey Series key
- * @param xvs X value array
- * @param yvs Y value array
- */
- public void addSeries(String seriesKey, List xvs, List yvs){
- double[] nxvs = new double[xvs.size()];
- double[] nyvs = new double[yvs.size()];
- double v;
- for (int i = 0; i < xvs.size(); i++){
- v = xvs.get(i).doubleValue();
- if (Double.isNaN(v))
- nxvs[i] = this.getMissingValue();
- else
- nxvs[i] = xvs.get(i).doubleValue();
- }
- for (int i = 0; i < yvs.size(); i++){
- v = yvs.get(i).doubleValue();
- if (Double.isNaN(v))
- nyvs[i] = this.getMissingValue();
- else
- nyvs[i] = v;
- }
-
- this.addSeries(seriesKey, nxvs, nyvs);
- }
-
- /**
- * Add a series data
- * @param seriesKey Series key
- * @param xvs X value array
- * @param yvs Y value array
- */
- public void addSeries(String seriesKey, List xvs, Array yvs){
- int xn = (int)xvs.size();
- int yn = (int)yvs.getSize();
- double[] nxvs = new double[xn];
- double[] nyvs = new double[yn];
- double v;
- for (int i = 0; i < xn; i++)
- nxvs[i] = xvs.get(i).doubleValue();
- for (int i = 0; i < yn; i++) {
- v = yvs.getDouble(i);
- if (Double.isNaN(v))
- nyvs[i] = this.getMissingValue();
- else
- nyvs[i] = v;
- }
-
- this.addSeries(seriesKey, nxvs, nyvs);
- }
-
- /**
- * Add a series data
- * @param seriesKey Series key
- * @param xvs X value array
- * @param yvs Y value array
- */
- public void addSeries(String seriesKey, Array xvs, Array yvs){
- int xn = (int)xvs.getSize();
- int yn = (int)yvs.getSize();
- double[] nxvs = new double[xn];
- double[] nyvs = new double[yn];
- double v;
- for (int i = 0; i < xn; i++)
- nxvs[i] = xvs.getDouble(i);
- for (int i = 0; i < yn; i++){
- v = yvs.getDouble(i);
- if (Double.isNaN(v))
- nyvs[i] = this.getMissingValue();
- else
- nyvs[i] = v;
- }
-
- this.addSeries(seriesKey, nxvs, nyvs);
- }
-
- /**
- * Add a series data
- * @param seriesKey Series key
- * @param xvs X value array
- * @param yvs Y value array
- */
- public void addSeries(String seriesKey, Array xvs, List yvs){
- int xn = (int)xvs.getSize();
- int yn = yvs.size();
- double[] nxvs = new double[xn];
- double[] nyvs = new double[yn];
- double v;
- for (int i = 0; i < xn; i++)
- nxvs[i] = xvs.getDouble(i);
- for (int i = 0; i < yn; i++){
- v = yvs.get(i).doubleValue();
- if (Double.isNaN(v))
- nyvs[i] = this.getMissingValue();
- else
- nyvs[i] = v;
- }
-
- this.addSeries(seriesKey, nxvs, nyvs);
- }
-
- /**
- * Remove a series data
- * @param seriesIdx Series data
- */
- public void removeSeries(int seriesIdx){
- //this.seriesKeys.remove(seriesIdx);
- //this.xValues.remove(seriesIdx);
- //this.yValues.remove(seriesIdx);
- this.dataset.remove(seriesIdx);
- }
-
- /**
- * Remove a series data
- * @param seriesKey Series key
- */
- public void removeSeries(String seriesKey){
- List keys = this.getSeriesKeys();
- int idx = keys.indexOf(seriesKey);
- if (idx >= 0){
- this.removeSeries(idx);
- }
- }
-
- /**
- * Get data extent
- * @return Data extent
- */
- @Override
- public Extent getDataExtent() {
- Extent cET = new Extent();
- double xmin, xmax, ymin, ymax;
- int n = 0;
- for (int i = 0; i < this.getSeriesCount(); i++) {
- XYSeriesData sdata = this.dataset.get(i);
- for (int j = 0; j < this.getItemCount(i); j++) {
- xmin = sdata.getX_min(j);
- xmax = sdata.getX_max(j);
- ymin = sdata.getY_min(j);
- ymax = sdata.getY_max(j);
- if (Double.isNaN(sdata.getX(j)) || Double.isNaN(sdata.getY(j)))
- continue;
- if (MIMath.doubleEquals(sdata.getX(j), this.getMissingValue()) || MIMath.doubleEquals(sdata.getY(j), this.getMissingValue()))
- continue;
- if (n == 0) {
- cET.minX = xmin;
- cET.maxX = xmax;
- cET.minY = ymin;
- cET.maxY = ymax;
- } else {
- if (cET.minX > xmin) {
- cET.minX = xmin;
- } else if (cET.maxX < xmax) {
- cET.maxX = xmax;
- }
-
- if (cET.minY > ymin) {
- cET.minY = ymin;
- } else if (cET.maxY < ymax) {
- cET.maxY = ymax;
- }
- }
- n ++;
- }
- }
-
- return cET;
- }
-
- /**
- * Get missing value index list
- * @param seriesIdx Series index
- * @return Missing value index list
- */
- @Override
- public List getMissingValueIndex(int seriesIdx){
- List mvidx = new ArrayList<>();
- double[] xvs = this.getXValues(seriesIdx);
- double[] yvs = this.getYValues(seriesIdx);
- for (int i = 0; i < yvs.length; i++){
- if (MIMath.doubleEquals(xvs[i], this.getMissingValue()) || MIMath.doubleEquals(yvs[i], this.getMissingValue()))
- mvidx.add(i);
- }
-
- return mvidx;
- }
-
- /**
- * Select data points
- * @param extent Selection extent
- * @return Selected data points
- */
- @Override
- public List selectPoints(Extent extent){
- List selIdxs = new ArrayList<>();
- double x, y;
- for (int i = 0; i < this.getSeriesCount(); i++){
- for (int j = 0; j < this.getItemCount(i); j++){
- x = this.getX(i, j);
- if (x >= extent.minX && x <= extent.maxX){
- y = this.getY(i, j);
- if (y >= extent.minY && y <= extent.maxY){
- selIdxs.add(new int[]{i, j});
- }
- }
- }
- }
-
- return selIdxs;
- }
- //
-}
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.meteoinfo.data;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.MIMath;
+import org.meteoinfo.ndarray.Array;
+
+/**
+ *
+ * @author wyq
+ */
+public class XYListDataset extends XYDataset {
+ //
+ //private List xValues;
+ //private List yValues;
+ //private List seriesKeys;
+ private List dataset;
+ //
+ //
+ /**
+ * Constructor
+ */
+ public XYListDataset(){
+ //xValues = new ArrayList<>();
+ //yValues = new ArrayList<>();
+ //seriesKeys = new ArrayList<>();
+ dataset = new ArrayList<>();
+ }
+
+ /**
+ * Constructor
+ *
+ * @param seriesNum Series number
+ * @param itemNum Item number
+ */
+ public XYListDataset(int seriesNum, int itemNum) {
+ this();
+
+ for (int i = 0; i < seriesNum; i++){
+ //xValues.add(new double[itemNum]);
+ //yValues.add(new double[itemNum]);
+ //seriesKeys.add("");
+ dataset.add(new XYSeriesData());
+ }
+ }
+
+ /**
+ * Constructor
+ * @param xdata X station data
+ * @param ydata Y station data
+ * @param seriesKey Series key
+ */
+ public XYListDataset(StationData xdata, StationData ydata, String seriesKey){
+ this();
+ List vdata = new ArrayList<>();
+ double v1, v2;
+ for (int i = 0; i < xdata.getStNum(); i++) {
+ v1 = xdata.getValue(i);
+ if (MIMath.doubleEquals(v1, xdata.missingValue)) {
+ continue;
+ }
+ v2 = ydata.getValue(i);
+ if (MIMath.doubleEquals(v2, ydata.missingValue)) {
+ continue;
+ }
+ vdata.add(new double[]{v1, v2});
+ }
+
+ int n = vdata.size();
+ double[] xvs = new double[n];
+ double[] yvs = new double[n];
+ for (int i = 0; i < n; i++){
+ xvs[i] = vdata.get(i)[0];
+ yvs[i] = vdata.get(i)[1];
+ }
+ //this.xValues.add(xvs);
+ //this.yValues.add(yvs);
+ //this.seriesKeys.add(seriesKey);
+ XYSeriesData sdata = new XYSeriesData(seriesKey, xvs, yvs);
+ this.dataset.add(sdata);
+ }
+ //
+ //
+
+ /**
+ * Get series data
+ * @param seriesIdx Series index
+ * @return Series data
+ */
+ public XYSeriesData getSeriesData(int seriesIdx){
+ return this.dataset.get(seriesIdx);
+ }
+
+ @Override
+ public int getSeriesCount() {
+ //return this.xValues.size();
+ return this.dataset.size();
+ }
+
+ @Override
+ public String getSeriesKey(int seriesIdx) {
+ //return this.seriesKeys.get(seriesIdx);
+ return this.dataset.get(seriesIdx).getKey();
+ }
+
+ /**
+ * Set series key by index
+ * @param seriesIdx Series index
+ * @param seriesKey Series key
+ */
+ @Override
+ public void setSeriesKey(int seriesIdx, String seriesKey){
+ //this.seriesKeys.set(seriesIdx, seriesKey);
+ this.dataset.get(seriesIdx).setKey(seriesKey);
+ }
+
+ /**
+ * Get series keys
+ * @return Series keys
+ */
+ @Override
+ public List getSeriesKeys(){
+ //return this.seriesKeys;
+ List keys = new ArrayList<>();
+ for (XYSeriesData d :this.dataset){
+ keys.add(d.getKey());
+ }
+ return keys;
+ }
+
+ /**
+ * Set series keys
+ * @param value Series keys
+ */
+ @Override
+ public void setSeriesKeys(List value){
+ //this.seriesKeys = value;
+ int i = 0;
+ for (XYSeriesData d :this.dataset){
+ d.setKey(value.get(i));
+ i++;
+ }
+ }
+
+ @Override
+ public int getItemCount(){
+ int n = this.getItemCount(0);
+ if (this.getSeriesCount() > 1){
+ for (int i = 1; i < this.getSeriesCount(); i++){
+ int nn = this.getItemCount(i);
+ if (n < nn)
+ n = nn;
+ }
+ }
+
+ return n;
+ }
+
+ @Override
+ public int getItemCount(int seriesIdx) {
+ //return this.xValues.get(seriesIdx).length;
+ return this.dataset.get(seriesIdx).dataLength();
+ }
+
+ @Override
+ public double[] getXValues(int seriesIdx){
+ //return this.xValues.get(seriesIdx);
+ return this.dataset.get(seriesIdx).getXdata();
+ }
+
+ @Override
+ public double[] getYValues(int seriesIdx){
+ //return this.yValues.get(seriesIdx);
+ return this.dataset.get(seriesIdx).getYdata();
+ }
+
+ @Override
+ public double getX(int seriesIdx, int itemIdx) {
+ //return this.xValues.get(seriesIdx)[itemIdx];
+ return this.dataset.get(seriesIdx).getXdata()[itemIdx];
+ }
+
+ @Override
+ public double getY(int seriesIdx, int itemIdx) {
+ //return this.yValues.get(seriesIdx)[itemIdx];
+ return this.dataset.get(seriesIdx).getYdata()[itemIdx];
+ }
+
+ @Override
+ public void setX(int seriesIdx, int itemIdx, double value){
+ //this.xValues.get(seriesIdx)[itemIdx] = value;
+ this.dataset.get(seriesIdx).getXdata()[itemIdx] = value;
+ }
+
+ @Override
+ public void setY(int seriesIdx, int itemIdx, double value){
+ //this.yValues.get(seriesIdx)[itemIdx] = value;
+ this.dataset.get(seriesIdx).getYdata()[itemIdx] = value;
+ }
+ //
+ //
+ /**
+ * Add a series data
+ * @param sdata Series data
+ */
+ public void addSeries(XYSeriesData sdata){
+ this.dataset.add(sdata);
+ }
+
+ /**
+ * Add a series data
+ * @param seriesKey Series key
+ * @param xvs X value array
+ * @param yvs Y value array
+ */
+ public void addSeries(String seriesKey, double[] xvs, double[] yvs){
+ //this.seriesKeys.add(seriesKey);
+ //this.xValues.add(xvs);
+ //this.yValues.add(yvs);
+ XYSeriesData sdata = new XYSeriesData(seriesKey, xvs, yvs);
+ this.dataset.add(sdata);
+ }
+
+ /**
+ * Add a series data
+ * @param seriesKey Series key
+ * @param xvs X value array
+ * @param yvs Y value array
+ */
+ public void addSeries(String seriesKey, List xvs, List yvs){
+ double[] nxvs = new double[xvs.size()];
+ double[] nyvs = new double[yvs.size()];
+ double v;
+ for (int i = 0; i < xvs.size(); i++){
+ v = xvs.get(i).doubleValue();
+ if (Double.isNaN(v))
+ nxvs[i] = this.getMissingValue();
+ else
+ nxvs[i] = xvs.get(i).doubleValue();
+ }
+ for (int i = 0; i < yvs.size(); i++){
+ v = yvs.get(i).doubleValue();
+ if (Double.isNaN(v))
+ nyvs[i] = this.getMissingValue();
+ else
+ nyvs[i] = v;
+ }
+
+ this.addSeries(seriesKey, nxvs, nyvs);
+ }
+
+ /**
+ * Add a series data
+ * @param seriesKey Series key
+ * @param xvs X value array
+ * @param yvs Y value array
+ */
+ public void addSeries(String seriesKey, List xvs, Array yvs){
+ int xn = (int)xvs.size();
+ int yn = (int)yvs.getSize();
+ double[] nxvs = new double[xn];
+ double[] nyvs = new double[yn];
+ double v;
+ for (int i = 0; i < xn; i++)
+ nxvs[i] = xvs.get(i).doubleValue();
+ for (int i = 0; i < yn; i++) {
+ v = yvs.getDouble(i);
+ if (Double.isNaN(v))
+ nyvs[i] = this.getMissingValue();
+ else
+ nyvs[i] = v;
+ }
+
+ this.addSeries(seriesKey, nxvs, nyvs);
+ }
+
+ /**
+ * Add a series data
+ * @param seriesKey Series key
+ * @param xvs X value array
+ * @param yvs Y value array
+ */
+ public void addSeries(String seriesKey, Array xvs, Array yvs){
+ int xn = (int)xvs.getSize();
+ int yn = (int)yvs.getSize();
+ double[] nxvs = new double[xn];
+ double[] nyvs = new double[yn];
+ double v;
+ for (int i = 0; i < xn; i++)
+ nxvs[i] = xvs.getDouble(i);
+ for (int i = 0; i < yn; i++){
+ v = yvs.getDouble(i);
+ if (Double.isNaN(v))
+ nyvs[i] = this.getMissingValue();
+ else
+ nyvs[i] = v;
+ }
+
+ this.addSeries(seriesKey, nxvs, nyvs);
+ }
+
+ /**
+ * Add a series data
+ * @param seriesKey Series key
+ * @param xvs X value array
+ * @param yvs Y value array
+ */
+ public void addSeries(String seriesKey, Array xvs, List yvs){
+ int xn = (int)xvs.getSize();
+ int yn = yvs.size();
+ double[] nxvs = new double[xn];
+ double[] nyvs = new double[yn];
+ double v;
+ for (int i = 0; i < xn; i++)
+ nxvs[i] = xvs.getDouble(i);
+ for (int i = 0; i < yn; i++){
+ v = yvs.get(i).doubleValue();
+ if (Double.isNaN(v))
+ nyvs[i] = this.getMissingValue();
+ else
+ nyvs[i] = v;
+ }
+
+ this.addSeries(seriesKey, nxvs, nyvs);
+ }
+
+ /**
+ * Remove a series data
+ * @param seriesIdx Series data
+ */
+ public void removeSeries(int seriesIdx){
+ //this.seriesKeys.remove(seriesIdx);
+ //this.xValues.remove(seriesIdx);
+ //this.yValues.remove(seriesIdx);
+ this.dataset.remove(seriesIdx);
+ }
+
+ /**
+ * Remove a series data
+ * @param seriesKey Series key
+ */
+ public void removeSeries(String seriesKey){
+ List keys = this.getSeriesKeys();
+ int idx = keys.indexOf(seriesKey);
+ if (idx >= 0){
+ this.removeSeries(idx);
+ }
+ }
+
+ /**
+ * Get data extent
+ * @return Data extent
+ */
+ @Override
+ public Extent getDataExtent() {
+ Extent cET = new Extent();
+ double xmin, xmax, ymin, ymax;
+ int n = 0;
+ for (int i = 0; i < this.getSeriesCount(); i++) {
+ XYSeriesData sdata = this.dataset.get(i);
+ for (int j = 0; j < this.getItemCount(i); j++) {
+ xmin = sdata.getX_min(j);
+ xmax = sdata.getX_max(j);
+ ymin = sdata.getY_min(j);
+ ymax = sdata.getY_max(j);
+ if (Double.isNaN(sdata.getX(j)) || Double.isNaN(sdata.getY(j)))
+ continue;
+ if (MIMath.doubleEquals(sdata.getX(j), this.getMissingValue()) || MIMath.doubleEquals(sdata.getY(j), this.getMissingValue()))
+ continue;
+ if (n == 0) {
+ cET.minX = xmin;
+ cET.maxX = xmax;
+ cET.minY = ymin;
+ cET.maxY = ymax;
+ } else {
+ if (cET.minX > xmin) {
+ cET.minX = xmin;
+ } else if (cET.maxX < xmax) {
+ cET.maxX = xmax;
+ }
+
+ if (cET.minY > ymin) {
+ cET.minY = ymin;
+ } else if (cET.maxY < ymax) {
+ cET.maxY = ymax;
+ }
+ }
+ n ++;
+ }
+ }
+
+ return cET;
+ }
+
+ /**
+ * Get missing value index list
+ * @param seriesIdx Series index
+ * @return Missing value index list
+ */
+ @Override
+ public List getMissingValueIndex(int seriesIdx){
+ List mvidx = new ArrayList<>();
+ double[] xvs = this.getXValues(seriesIdx);
+ double[] yvs = this.getYValues(seriesIdx);
+ for (int i = 0; i < yvs.length; i++){
+ if (MIMath.doubleEquals(xvs[i], this.getMissingValue()) || MIMath.doubleEquals(yvs[i], this.getMissingValue()))
+ mvidx.add(i);
+ }
+
+ return mvidx;
+ }
+
+ /**
+ * Select data points
+ * @param extent Selection extent
+ * @return Selected data points
+ */
+ @Override
+ public List selectPoints(Extent extent){
+ List selIdxs = new ArrayList<>();
+ double x, y;
+ for (int i = 0; i < this.getSeriesCount(); i++){
+ for (int j = 0; j < this.getItemCount(i); j++){
+ x = this.getX(i, j);
+ if (x >= extent.minX && x <= extent.maxX){
+ y = this.getY(i, j);
+ if (y >= extent.minY && y <= extent.maxY){
+ selIdxs.add(new int[]{i, j});
+ }
+ }
+ }
+ }
+
+ return selIdxs;
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/XYSeriesData.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/XYSeriesData.java
index 39fb4e80..b34c15db 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/XYSeriesData.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/XYSeriesData.java
@@ -1,258 +1,259 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.meteoinfo.data;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.meteoinfo.global.MIMath;
-import ucar.ma2.Array;
-
-/**
- *
- * @author yaqiang
- */
-public class XYSeriesData {
- //
- private String key;
- private double[] xdata;
- private double[] ydata;
- private double missingValue = -9999.0;
- //
- //
- /**
- * Constructor
- */
- public XYSeriesData(){
-
- }
-
- /**
- * Constructor
- * @param key Key
- */
- public XYSeriesData(String key){
- this.key = key;
- }
-
- /**
- * Constructor
- * @param key Series key
- * @param xdata X data
- * @param ydata Y data
- */
- public XYSeriesData(String key, double[] xdata, double[] ydata){
- this.key = key;
- this.xdata = xdata;
- this.ydata = ydata;
- }
- //
- //
- /**
- * Get series key
- * @return Series key
- */
- public String getKey(){
- return key;
- }
-
- /**
- * Set series key
- * @param value Series key
- */
- public void setKey(String value){
- key = value;
- }
-
- /**
- * Get X data
- * @return X data
- */
- public double[] getXdata(){
- return this.xdata;
- }
-
- /**
- * Set X data
- * @param value X data
- */
- public void setXdata(double[] value){
- this.xdata = value;
- }
-
- /**
- * Set X data
- * @param value X data
- */
- public void setXdata(List value){
- this.xdata = new double[value.size()];
- double v;
- for (int i = 0; i < value.size(); i++){
- v = value.get(i).doubleValue();
- if (Double.isNaN(v))
- xdata[i] = this.missingValue;
- else
- xdata[i] = v;
- }
- }
-
- /**
- * Set X data
- * @param value X data
- */
- public void setXdata(Array value){
- this.xdata = new double[(int)value.getSize()];
- double v;
- for (int i = 0; i < xdata.length; i++){
- v = value.getDouble(i);
- if (Double.isNaN(v))
- xdata[i] = this.missingValue;
- else
- xdata[i] = v;
- }
- }
-
- /**
- * Get Y data
- * @return Y data
- */
- public double[] getYdata(){
- return this.ydata;
- }
-
- /**
- * Set Y data
- * @param value Y data
- */
- public void setYdata(double[] value){
- this.ydata = value;
- }
-
- /**
- * Set Y data
- * @param value Y data
- */
- public void setYdata(List value){
- this.ydata = new double[value.size()];
- double v;
- for (int i = 0; i < value.size(); i++){
- v = value.get(i).doubleValue();
- if (Double.isNaN(v))
- ydata[i] = this.missingValue;
- else
- ydata[i] = v;
- }
- }
-
- /**
- * Set Y data
- * @param value Y data
- */
- public void setYdata(Array value){
- this.ydata = new double[(int)value.getSize()];
- double v;
- for (int i = 0; i < ydata.length; i++){
- v = value.getDouble(i);
- if (Double.isNaN(v))
- ydata[i] = this.missingValue;
- else
- ydata[i] = v;
- }
- }
-
- /**
- * Get missing value
- * @return Missing value
- */
- public double getMissingValue(){
- return this.missingValue;
- }
-
- /**
- * Set missing value
- * @param value Missing value
- */
- public void setMissingValue(double value){
- this.missingValue = value;
- }
- //
- //
- /**
- * Get data length
- * @return Data length
- */
- public int dataLength(){
- return this.xdata.length;
- }
-
- /**
- * Get x value
- * @param idx Index
- * @return X value
- */
- public double getX(int idx){
- return this.xdata[idx];
- }
-
- /**
- * Get x - error value
- * @param idx Index
- * @return X - error value
- */
- public double getX_min(int idx){
- return this.xdata[idx];
- }
-
- /**
- * Get x + error value
- * @param idx Index
- * @return X + error value
- */
- public double getX_max(int idx){
- return this.xdata[idx];
- }
-
- /**
- * Get y value
- * @param idx Index
- * @return Y value
- */
- public double getY(int idx){
- return this.ydata[idx];
- }
-
- /**
- * Get y - error value
- * @param idx Index
- * @return Y - error value
- */
- public double getY_min(int idx){
- return this.ydata[idx];
- }
-
- /**
- * Get y + error value
- * @param idx Index
- * @return Y + error value
- */
- public double getY_max(int idx){
- return this.ydata[idx];
- }
-
- /**
- * Get missing value index list
- * @return Missing value index list
- */
- public List getMissingValueIndex(){
- List mvidx = new ArrayList<>();
- for (int i = 0; i < xdata.length; i++){
- if (MIMath.doubleEquals(xdata[i], this.missingValue) || MIMath.doubleEquals(ydata[i], this.missingValue))
- mvidx.add(i);
- }
-
- return mvidx;
- }
- //
-}
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.meteoinfo.data;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.meteoinfo.common.MIMath;
+import ucar.ma2.Array;
+
+/**
+ *
+ * @author yaqiang
+ */
+public class XYSeriesData {
+ //
+ private String key;
+ private double[] xdata;
+ private double[] ydata;
+ private double missingValue = -9999.0;
+ //
+ //
+ /**
+ * Constructor
+ */
+ public XYSeriesData(){
+
+ }
+
+ /**
+ * Constructor
+ * @param key Key
+ */
+ public XYSeriesData(String key){
+ this.key = key;
+ }
+
+ /**
+ * Constructor
+ * @param key Series key
+ * @param xdata X data
+ * @param ydata Y data
+ */
+ public XYSeriesData(String key, double[] xdata, double[] ydata){
+ this.key = key;
+ this.xdata = xdata;
+ this.ydata = ydata;
+ }
+ //
+ //
+ /**
+ * Get series key
+ * @return Series key
+ */
+ public String getKey(){
+ return key;
+ }
+
+ /**
+ * Set series key
+ * @param value Series key
+ */
+ public void setKey(String value){
+ key = value;
+ }
+
+ /**
+ * Get X data
+ * @return X data
+ */
+ public double[] getXdata(){
+ return this.xdata;
+ }
+
+ /**
+ * Set X data
+ * @param value X data
+ */
+ public void setXdata(double[] value){
+ this.xdata = value;
+ }
+
+ /**
+ * Set X data
+ * @param value X data
+ */
+ public void setXdata(List value){
+ this.xdata = new double[value.size()];
+ double v;
+ for (int i = 0; i < value.size(); i++){
+ v = value.get(i).doubleValue();
+ if (Double.isNaN(v))
+ xdata[i] = this.missingValue;
+ else
+ xdata[i] = v;
+ }
+ }
+
+ /**
+ * Set X data
+ * @param value X data
+ */
+ public void setXdata(Array value){
+ this.xdata = new double[(int)value.getSize()];
+ double v;
+ for (int i = 0; i < xdata.length; i++){
+ v = value.getDouble(i);
+ if (Double.isNaN(v))
+ xdata[i] = this.missingValue;
+ else
+ xdata[i] = v;
+ }
+ }
+
+ /**
+ * Get Y data
+ * @return Y data
+ */
+ public double[] getYdata(){
+ return this.ydata;
+ }
+
+ /**
+ * Set Y data
+ * @param value Y data
+ */
+ public void setYdata(double[] value){
+ this.ydata = value;
+ }
+
+ /**
+ * Set Y data
+ * @param value Y data
+ */
+ public void setYdata(List value){
+ this.ydata = new double[value.size()];
+ double v;
+ for (int i = 0; i < value.size(); i++){
+ v = value.get(i).doubleValue();
+ if (Double.isNaN(v))
+ ydata[i] = this.missingValue;
+ else
+ ydata[i] = v;
+ }
+ }
+
+ /**
+ * Set Y data
+ * @param value Y data
+ */
+ public void setYdata(Array value){
+ this.ydata = new double[(int)value.getSize()];
+ double v;
+ for (int i = 0; i < ydata.length; i++){
+ v = value.getDouble(i);
+ if (Double.isNaN(v))
+ ydata[i] = this.missingValue;
+ else
+ ydata[i] = v;
+ }
+ }
+
+ /**
+ * Get missing value
+ * @return Missing value
+ */
+ public double getMissingValue(){
+ return this.missingValue;
+ }
+
+ /**
+ * Set missing value
+ * @param value Missing value
+ */
+ public void setMissingValue(double value){
+ this.missingValue = value;
+ }
+ //
+ //
+ /**
+ * Get data length
+ * @return Data length
+ */
+ public int dataLength(){
+ return this.xdata.length;
+ }
+
+ /**
+ * Get x value
+ * @param idx Index
+ * @return X value
+ */
+ public double getX(int idx){
+ return this.xdata[idx];
+ }
+
+ /**
+ * Get x - error value
+ * @param idx Index
+ * @return X - error value
+ */
+ public double getX_min(int idx){
+ return this.xdata[idx];
+ }
+
+ /**
+ * Get x + error value
+ * @param idx Index
+ * @return X + error value
+ */
+ public double getX_max(int idx){
+ return this.xdata[idx];
+ }
+
+ /**
+ * Get y value
+ * @param idx Index
+ * @return Y value
+ */
+ public double getY(int idx){
+ return this.ydata[idx];
+ }
+
+ /**
+ * Get y - error value
+ * @param idx Index
+ * @return Y - error value
+ */
+ public double getY_min(int idx){
+ return this.ydata[idx];
+ }
+
+ /**
+ * Get y + error value
+ * @param idx Index
+ * @return Y + error value
+ */
+ public double getY_max(int idx){
+ return this.ydata[idx];
+ }
+
+ /**
+ * Get missing value index list
+ * @return Missing value index list
+ */
+ public List getMissingValueIndex(){
+ List mvidx = new ArrayList<>();
+ for (int i = 0; i < xdata.length; i++){
+ if (MIMath.doubleEquals(xdata[i], this.missingValue) || MIMath.doubleEquals(ydata[i], this.missingValue))
+ mvidx.add(i);
+ }
+
+ return mvidx;
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/dataframe/Column.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/dataframe/Column.java
index 3830d909..e28598e6 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/dataframe/Column.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/dataframe/Column.java
@@ -1,267 +1,267 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.meteoinfo.data.dataframe;
-
-import java.text.DecimalFormat;
-import org.joda.time.DateTime;
-import org.meteoinfo.math.ArrayMath;
-import org.meteoinfo.global.DataConvert;
-import org.meteoinfo.ndarray.Array;
-import org.meteoinfo.ndarray.DataType;
-
-/**
- *
- * @author Yaqiang Wang
- */
-public class Column {
- //
- protected String name;
- protected DataType dataType;
- protected String format;
- protected int formatLen;
- //
- //
- /**
- * Constructor
- */
- public Column(){
- this("Column", DataType.OBJECT);
- }
-
- /**
- * Constructor
- * @param name Name
- */
- public Column(String name){
- this(name, DataType.OBJECT);
- }
-
- /**
- * Constructor
- * @param name Name
- * @param dataType Data type
- */
- public Column(String name, DataType dataType) {
- this.name = name;
- this.dataType = dataType;
- this.updateFormat();
- }
- //
- //
- /**
- * Get name
- * @return Name
- */
- public String getName(){
- return this.name;
- }
-
- /**
- * Set name
- * @param value Name
- */
- public void setName(String value){
- this.name = value;
- }
-
- /**
- * Get data type
- * @return Data type
- */
- public DataType getDataType(){
- return this.dataType;
- }
-
- /**
- * Set data type
- * @param value Data type
- */
- public void setDataType(DataType value) {
- this.dataType = value;
- }
-
- /**
- * Get format
- * @return Format
- */
- public String getFormat(){
- return this.format;
- }
-
- /**
- * Get Name format
- * @return
- */
- public String getNameFormat() {
- return "%" + String.valueOf(this.formatLen) + "s";
- }
-
- /**
- * Set format
- * @param value Format
- */
- public void setFormat(String value){
- this.format = value;
- }
-
- /**
- * Get format length
- * @return Format length
- */
- public int getFormatLen(){
- return this.formatLen;
- }
-
- /**
- * Set format length
- * @param value Format length
- */
- public void setFormatLen(int value) {
- this.formatLen = value;
- }
-
- //
- //
- /**
- * Factory method
- * @param name Name
- * @param dtype Data type
- * @return Column
- */
- public static Column factory(String name, DataType dtype){
- return new Column(name, dtype);
- }
-
- /**
- * Factory method
- * @param name Name
- * @param array Data array
- * @return Column
- */
- public static Column factory(String name, Array array){
- DataType dtype = array.getDataType();
- if (dtype == DataType.OBJECT && (array.getObject(0) instanceof DateTime)){
- DateTimeColumn col = new DateTimeColumn(name);
- col.updateFormat(array);
- return col;
- }
- return new Column(name, dtype);
- }
-
- /**
- * Update format
- */
- public void updateFormat(){
- this.format = null;
- switch (this.dataType){
- case FLOAT:
- case DOUBLE:
- this.format = "%f";
- break;
- }
- this.formatLen = this.name.length();
- }
-
- /**
- * Update format
- * @param data Data array
- */
- public void updateFormat(Array data) {
- this.formatLen = this.name.length();
- switch(this.dataType) {
- case DOUBLE:
- case FLOAT:
- double dmax = ArrayMath.max(data).doubleValue();
- DecimalFormat df = new DecimalFormat("0.0");
- df.setMaximumFractionDigits(6);
- int nf = 1, ci, nn;
- String str;
- for (int i = 0; i < data.getSize(); i++){
- str = df.format(data.getDouble(i));
- ci = str.indexOf(".");
- nn = str.length() - ci - 1;
- if (nf < nn) {
- nf = nn;
- if (nf == 6)
- break;
- }
- }
- String smax = df.format(dmax);
- ci = smax.indexOf(".");
- int len = ci + nf + 2;
- formatLen = Math.max(formatLen, len);
- this.format = "%" + String.valueOf(formatLen) + "." + String.valueOf(nf) + "f";
- break;
- case INT:
- int imax = (int)ArrayMath.max(data);
- smax = Integer.toString(imax);
- formatLen = Math.max(formatLen, smax.length());
- this.format = "%" + String.valueOf(formatLen) + "d";
- break;
- default:
- String v;
- for (int i = 0; i < data.getSize(); i++){
- if (data.getObject(i) == null)
- v = "null";
- else
- v = data.getObject(i).toString();
- if (formatLen < v.length())
- formatLen = v.length();
- }
- this.format = "%" + String.valueOf(formatLen) + "s";
- break;
- }
- }
-
- /**
- * Convert input data to current data type
- *
- * @param value Object value
- * @return Result object
- */
- public Object convertTo(Object value) {
- return DataConvert.convertTo(value, this.dataType, this.format);
- }
-
- /**
- * Convert input data to current data type
- * @param s Input string
- * @return Result object
- */
- public Object convertStringTo(String s) {
- return DataConvert.convertStringTo(s, dataType, format);
- }
-
- @Override
- public String toString(){
- return this.name;
- }
-
- /**
- * Convert an object (same datatype with this column) to string
- * @param o
- * @return String
- */
- public String toString(Object o){
- if (format == null)
- return o.toString();
- else
- return String.format(format, o);
- }
-
- /**
- *
- * @return Column
- */
- @Override
- public Object clone() {
- Column col = new Column(this.name, this.dataType);
- col.setFormat(this.format);
- col.setFormatLen(this.formatLen);
- return col;
- }
- //
-}
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.meteoinfo.data.dataframe;
+
+import java.text.DecimalFormat;
+import org.joda.time.DateTime;
+import org.meteoinfo.global.DataConvert;
+import org.meteoinfo.math.ArrayMath;
+import org.meteoinfo.ndarray.Array;
+import org.meteoinfo.ndarray.DataType;
+
+/**
+ *
+ * @author Yaqiang Wang
+ */
+public class Column {
+ //
+ protected String name;
+ protected DataType dataType;
+ protected String format;
+ protected int formatLen;
+ //
+ //
+ /**
+ * Constructor
+ */
+ public Column(){
+ this("Column", DataType.OBJECT);
+ }
+
+ /**
+ * Constructor
+ * @param name Name
+ */
+ public Column(String name){
+ this(name, DataType.OBJECT);
+ }
+
+ /**
+ * Constructor
+ * @param name Name
+ * @param dataType Data type
+ */
+ public Column(String name, DataType dataType) {
+ this.name = name;
+ this.dataType = dataType;
+ this.updateFormat();
+ }
+ //
+ //
+ /**
+ * Get name
+ * @return Name
+ */
+ public String getName(){
+ return this.name;
+ }
+
+ /**
+ * Set name
+ * @param value Name
+ */
+ public void setName(String value){
+ this.name = value;
+ }
+
+ /**
+ * Get data type
+ * @return Data type
+ */
+ public DataType getDataType(){
+ return this.dataType;
+ }
+
+ /**
+ * Set data type
+ * @param value Data type
+ */
+ public void setDataType(DataType value) {
+ this.dataType = value;
+ }
+
+ /**
+ * Get format
+ * @return Format
+ */
+ public String getFormat(){
+ return this.format;
+ }
+
+ /**
+ * Get Name format
+ * @return
+ */
+ public String getNameFormat() {
+ return "%" + String.valueOf(this.formatLen) + "s";
+ }
+
+ /**
+ * Set format
+ * @param value Format
+ */
+ public void setFormat(String value){
+ this.format = value;
+ }
+
+ /**
+ * Get format length
+ * @return Format length
+ */
+ public int getFormatLen(){
+ return this.formatLen;
+ }
+
+ /**
+ * Set format length
+ * @param value Format length
+ */
+ public void setFormatLen(int value) {
+ this.formatLen = value;
+ }
+
+ //
+ //
+ /**
+ * Factory method
+ * @param name Name
+ * @param dtype Data type
+ * @return Column
+ */
+ public static Column factory(String name, DataType dtype){
+ return new Column(name, dtype);
+ }
+
+ /**
+ * Factory method
+ * @param name Name
+ * @param array Data array
+ * @return Column
+ */
+ public static Column factory(String name, Array array){
+ DataType dtype = array.getDataType();
+ if (dtype == DataType.OBJECT && (array.getObject(0) instanceof DateTime)){
+ DateTimeColumn col = new DateTimeColumn(name);
+ col.updateFormat(array);
+ return col;
+ }
+ return new Column(name, dtype);
+ }
+
+ /**
+ * Update format
+ */
+ public void updateFormat(){
+ this.format = null;
+ switch (this.dataType){
+ case FLOAT:
+ case DOUBLE:
+ this.format = "%f";
+ break;
+ }
+ this.formatLen = this.name.length();
+ }
+
+ /**
+ * Update format
+ * @param data Data array
+ */
+ public void updateFormat(Array data) {
+ this.formatLen = this.name.length();
+ switch(this.dataType) {
+ case DOUBLE:
+ case FLOAT:
+ double dmax = ArrayMath.max(data).doubleValue();
+ DecimalFormat df = new DecimalFormat("0.0");
+ df.setMaximumFractionDigits(6);
+ int nf = 1, ci, nn;
+ String str;
+ for (int i = 0; i < data.getSize(); i++){
+ str = df.format(data.getDouble(i));
+ ci = str.indexOf(".");
+ nn = str.length() - ci - 1;
+ if (nf < nn) {
+ nf = nn;
+ if (nf == 6)
+ break;
+ }
+ }
+ String smax = df.format(dmax);
+ ci = smax.indexOf(".");
+ int len = ci + nf + 2;
+ formatLen = Math.max(formatLen, len);
+ this.format = "%" + String.valueOf(formatLen) + "." + String.valueOf(nf) + "f";
+ break;
+ case INT:
+ int imax = (int)ArrayMath.max(data);
+ smax = Integer.toString(imax);
+ formatLen = Math.max(formatLen, smax.length());
+ this.format = "%" + String.valueOf(formatLen) + "d";
+ break;
+ default:
+ String v;
+ for (int i = 0; i < data.getSize(); i++){
+ if (data.getObject(i) == null)
+ v = "null";
+ else
+ v = data.getObject(i).toString();
+ if (formatLen < v.length())
+ formatLen = v.length();
+ }
+ this.format = "%" + String.valueOf(formatLen) + "s";
+ break;
+ }
+ }
+
+ /**
+ * Convert input data to current data type
+ *
+ * @param value Object value
+ * @return Result object
+ */
+ public Object convertTo(Object value) {
+ return DataConvert.convertTo(value, this.dataType, this.format);
+ }
+
+ /**
+ * Convert input data to current data type
+ * @param s Input string
+ * @return Result object
+ */
+ public Object convertStringTo(String s) {
+ return DataConvert.convertStringTo(s, dataType, format);
+ }
+
+ @Override
+ public String toString(){
+ return this.name;
+ }
+
+ /**
+ * Convert an object (same datatype with this column) to string
+ * @param o
+ * @return String
+ */
+ public String toString(Object o){
+ if (format == null)
+ return o.toString();
+ else
+ return String.format(format, o);
+ }
+
+ /**
+ *
+ * @return Column
+ */
+ @Override
+ public Object clone() {
+ Column col = new Column(this.name, this.dataType);
+ col.setFormat(this.format);
+ col.setFormatLen(this.formatLen);
+ return col;
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/dataframe/DataFrame.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/dataframe/DataFrame.java
index 37725769..a89ea9af 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/dataframe/DataFrame.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/dataframe/DataFrame.java
@@ -28,9 +28,9 @@ import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
-import org.meteoinfo.global.util.JDateUtil;
-import org.meteoinfo.math.ArrayMath;
-import org.meteoinfo.math.ArrayUtil;
+import org.meteoinfo.common.util.GlobalUtil;
+import org.meteoinfo.common.util.JDateUtil;
+import org.meteoinfo.common.util.TypeUtils;
import org.meteoinfo.data.dataframe.impl.Aggregation;
import org.meteoinfo.data.dataframe.impl.Function;
import org.meteoinfo.data.dataframe.impl.Grouping;
@@ -40,8 +40,8 @@ import org.meteoinfo.data.dataframe.impl.Sorting;
import org.meteoinfo.data.dataframe.impl.Views;
import org.meteoinfo.data.dataframe.impl.WindowFunction;
import org.meteoinfo.global.DataConvert;
-import org.meteoinfo.global.util.GlobalUtil;
-import org.meteoinfo.global.util.TypeUtils;
+import org.meteoinfo.math.ArrayMath;
+import org.meteoinfo.math.ArrayUtil;
import org.meteoinfo.ndarray.Array;
import org.meteoinfo.ndarray.InvalidRangeException;
import org.meteoinfo.ndarray.Range;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/dataframe/DateTimeIndex.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/dataframe/DateTimeIndex.java
index 01fecda5..73c041fe 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/dataframe/DateTimeIndex.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/dataframe/DateTimeIndex.java
@@ -13,11 +13,11 @@ import java.util.List;
import java.time.LocalDateTime;
import java.time.temporal.TemporalAmount;
-import org.meteoinfo.math.ArrayMath;
+import org.meteoinfo.common.util.JDateUtil;
import org.meteoinfo.global.DataConvert;
-import org.meteoinfo.global.util.JDateUtil;
import org.meteoinfo.ndarray.Array;
import org.meteoinfo.ndarray.DataType;
+import org.meteoinfo.math.ArrayMath;
/**
*
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/dataframe/Index.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/dataframe/Index.java
index 0d25d6a6..f64e117e 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/dataframe/Index.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/dataframe/Index.java
@@ -10,8 +10,9 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
+
+import org.meteoinfo.common.MIMath;
import org.meteoinfo.math.ArrayMath;
-import org.meteoinfo.global.MIMath;
import org.meteoinfo.ndarray.Array;
import org.meteoinfo.ndarray.DataType;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/dataframe/Series.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/dataframe/Series.java
index 64ca6880..f40dd942 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/dataframe/Series.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/dataframe/Series.java
@@ -15,14 +15,15 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
-import org.meteoinfo.global.util.JDateUtil;
-import org.meteoinfo.math.ArrayMath;
+
+import org.meteoinfo.common.util.JDateUtil;
import org.meteoinfo.data.dataframe.impl.Grouping;
import org.meteoinfo.data.dataframe.impl.KeyFunction;
import org.meteoinfo.data.dataframe.impl.TimeFunction;
import org.meteoinfo.data.dataframe.impl.TimeFunctions;
import org.meteoinfo.data.dataframe.impl.Views;
import org.meteoinfo.data.dataframe.impl.WindowFunction;
+import org.meteoinfo.math.ArrayMath;
import org.meteoinfo.ndarray.Array;
import org.meteoinfo.ndarray.DataType;
import org.meteoinfo.ndarray.InvalidRangeException;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/dataframe/impl/Grouping.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/dataframe/impl/Grouping.java
index b49ce188..a15fb6bf 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/dataframe/impl/Grouping.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/dataframe/impl/Grouping.java
@@ -26,10 +26,11 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import org.meteoinfo.math.ArrayUtil;
+
import org.meteoinfo.data.dataframe.DataFrame;
import org.meteoinfo.data.dataframe.Series;
import org.meteoinfo.data.dataframe.impl.Transforms.CumulativeFunction;
+import org.meteoinfo.math.ArrayUtil;
import org.meteoinfo.ndarray.Array;
public class Grouping
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/dataframe/impl/WindowFunction.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/dataframe/impl/WindowFunction.java
index 06aec174..2a8bda08 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/dataframe/impl/WindowFunction.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/dataframe/impl/WindowFunction.java
@@ -5,7 +5,7 @@
*/
package org.meteoinfo.data.dataframe.impl;
-import org.meteoinfo.global.util.JDateUtil;
+import org.meteoinfo.common.util.JDateUtil;
import java.time.LocalDateTime;
import java.time.Period;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/mapdata/AttributeTable.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/mapdata/AttributeTable.java
index 4a8f3147..ceb7038f 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/mapdata/AttributeTable.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/mapdata/AttributeTable.java
@@ -17,7 +17,7 @@ import org.meteoinfo.table.DataColumn;
import org.meteoinfo.table.DataRow;
import org.meteoinfo.table.DataTable;
import org.meteoinfo.ndarray.DataType;
-import org.meteoinfo.io.EndianDataOutputStream;
+import org.meteoinfo.common.io.EndianDataOutputStream;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/mapdata/MapDataManage.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/mapdata/MapDataManage.java
index ba8ebff9..826bfcb7 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/mapdata/MapDataManage.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/mapdata/MapDataManage.java
@@ -13,13 +13,13 @@
*/
package org.meteoinfo.data.mapdata;
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.PointD;
+import org.meteoinfo.common.util.GlobalUtil;
import org.meteoinfo.data.GridData;
import org.meteoinfo.data.mapdata.geotiff.GeoTiff;
import org.meteoinfo.data.meteodata.DrawMeteoData;
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.global.util.GlobalUtil;
-import org.meteoinfo.global.MIMath;
-import org.meteoinfo.global.PointD;
+import org.meteoinfo.geoprocess.GeometryUtil;
import org.meteoinfo.ndarray.DataType;
import org.meteoinfo.layer.ImageLayer;
import org.meteoinfo.layer.LayerDrawType;
@@ -53,7 +53,7 @@ import org.meteoinfo.data.meteodata.ascii.ASCIIGridDataInfo;
import org.meteoinfo.data.meteodata.ascii.SurferGridDataInfo;
import org.meteoinfo.data.meteodata.bandraster.BILDataInfo;
import org.meteoinfo.global.DataConvert;
-import org.meteoinfo.io.IOUtil;
+import org.meteoinfo.common.io.IOUtil;
import org.meteoinfo.layer.RasterLayer;
import org.meteoinfo.legend.LegendScheme;
import org.meteoinfo.legend.LegendType;
@@ -293,7 +293,7 @@ public class MapDataManage {
PolylineShape aPolyline = new PolylineShape();
aPolyline.setValue(lineNum);
aPolyline.setPoints(pList);
- aPolyline.setExtent(MIMath.getPointsExtent(pList));
+ aPolyline.setExtent(GeometryUtil.getPointsExtent(pList));
aPolyline.setPartNum(1);
aPolyline.parts = new int[1];
aPolyline.parts[0] = 0;
@@ -521,7 +521,7 @@ public class MapDataManage {
}
PolylineShape aPLS = new PolylineShape();
aPLS.setValue(i);
- aPLS.setExtent(MIMath.getPointsExtent(pList));
+ aPLS.setExtent(GeometryUtil.getPointsExtent(pList));
aPLS.setPoints(pList);
int sNum = aLayer.getShapeNum();
@@ -554,7 +554,7 @@ public class MapDataManage {
PolygonShape aPGS = new PolygonShape();
aPGS.lowValue = i;
aPGS.highValue = i;
- aPGS.setExtent(MIMath.getPointsExtent(pList));
+ aPGS.setExtent(GeometryUtil.getPointsExtent(pList));
aPGS.setPoints(pList);
int sNum = aLayer.getShapeNum();
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/mapdata/ShapeFileManage.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/mapdata/ShapeFileManage.java
index e355f4ee..dea8df10 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/mapdata/ShapeFileManage.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/mapdata/ShapeFileManage.java
@@ -1,1053 +1,1051 @@
- /* Copyright 2012 Yaqiang Wang,
- * yaqiang.wang@gmail.com
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.data.mapdata;
-
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.global.PointD;
-import org.meteoinfo.io.EndianDataOutputStream;
-import org.meteoinfo.layer.LayerDrawType;
-import org.meteoinfo.layer.VectorLayer;
-import org.meteoinfo.legend.LegendManage;
-import org.meteoinfo.shape.PointShape;
-import org.meteoinfo.shape.PointZ;
-import org.meteoinfo.shape.PolygonShape;
-import org.meteoinfo.shape.PolylineShape;
-import org.meteoinfo.shape.PolylineZShape;
-import org.meteoinfo.shape.Shape;
-import org.meteoinfo.shape.ShapeTypes;
-import java.awt.Color;
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.DataInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.nio.Buffer;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import org.meteoinfo.projection.info.ProjectionInfo;
-import org.locationtech.proj4j.CRSFactory;
-import org.locationtech.proj4j.CoordinateReferenceSystem;
-import org.meteoinfo.shape.PointM;
-import org.meteoinfo.shape.PointZShape;
-import org.meteoinfo.shape.PolygonMShape;
-import org.meteoinfo.shape.PolygonZShape;
-
-/**
- * Shape file read and write
- *
- * @author yaqiang
- */
-public class ShapeFileManage {
-
- private final static String ENCODING = "UTF-8";
-
- /**
- * Load shape file
- *
- * @param shpfilepath Shape file path
- * @return Vector layer
- * @throws IOException
- * @throws java.io.FileNotFoundException
- */
- public static VectorLayer loadShapeFile(String shpfilepath) throws IOException, FileNotFoundException, Exception {
- String cpgfilepath = shpfilepath.replaceFirst(shpfilepath.substring(shpfilepath.lastIndexOf(".")), ".cpg");
- File cpgFile = new File(cpgfilepath);
- String encoding = ENCODING;
- if (cpgFile.exists()){
- BufferedReader sr = new BufferedReader(new FileReader(cpgFile));
- String ec = sr.readLine().trim();
- sr.close();
- encoding = ec;
- }
- return loadShapeFile(shpfilepath, encoding);
- }
-
- /**
- * Load shape file
- *
- * @param shpfilepath Shape file path
- * @param encoding Encoding
- * @return Vector layer
- * @throws IOException
- * @throws java.io.FileNotFoundException
- */
- public static VectorLayer loadShapeFile(String shpfilepath, String encoding) throws IOException, FileNotFoundException, Exception {
- //Set file names
- String shxfilepath = shpfilepath.replace(shpfilepath.substring(shpfilepath.lastIndexOf(".")), ".shx");
- String dbffilepath = shpfilepath.replace(shpfilepath.substring(shpfilepath.lastIndexOf(".")), ".dbf");
- String projfilepath = shpfilepath.replace(shpfilepath.substring(shpfilepath.lastIndexOf(".")), ".prj");
- File shpFile = new File(shpfilepath);
- File dbfFile = new File(dbffilepath);
- File shxFile = new File(shxfilepath);
- File prjFile = new File(projfilepath);
- if (!shxFile.exists()) {
- shxfilepath = shxfilepath.replace(".shx", ".SHX");
- shxFile = new File(shxfilepath);
- }
- if (!dbfFile.exists()) {
- dbffilepath = dbffilepath.replace(".dbf", ".DBF");
- dbfFile = new File(dbffilepath);
- }
- if (!prjFile.exists()) {
- projfilepath = projfilepath.replace(".prj", ".PRJ");
- prjFile = new File(projfilepath);
- }
-
- //Read shx file
- if ("".equals(shxfilepath)) {
- // MessageBox.Show("Open shx file error");
- return null;
- }
-
- long BytesSum = shxFile.length(); //Get file byte length
- int shapeNum = (int) (BytesSum - 100) / 8; //Get total number of records
- loadShxFile(shxFile);
-
- //Open shp file
- DataInputStream br = new DataInputStream(new BufferedInputStream(new FileInputStream(shpFile)));
- VectorLayer aLayer;
- //byte[] arr = new byte[(int)shpFile.length()];
- byte[] arr = new byte[100];
- br.read(arr);
- ByteBuffer buffer = ByteBuffer.wrap(arr);
- buffer.order(ByteOrder.LITTLE_ENDIAN);
- ((Buffer)buffer).position(32);
- //br.skipBytes(32); //先读出36个字节,紧接着是Box边界合
- int aShapeType = buffer.getInt();
- ShapeTypes aST = ShapeTypes.valueOf(aShapeType);
- //aLayer = new VectorLayer(aST);
- Extent aExtent = new Extent();
- aExtent.minX = buffer.getDouble(); //读出整个shp图层的边界合
- aExtent.minY = buffer.getDouble();
- aExtent.maxX = buffer.getDouble();
- aExtent.maxY = buffer.getDouble();
-
- //br.skipBytes(32); // shp中尚未使用的边界盒
- //buffer.position(buffer.position() + 32);
-
- //Get Shape Data
- switch (aST) {
- case Point://single point
- aLayer = readPointShapes(br, shapeNum);
- break;
- case PointZ:
- aLayer = readPointZShapes(br, shapeNum);
- break;
- case Polyline: //Polyline layer
- aLayer = readPolylineShapes(br, shapeNum);
- break;
- case PolylineZ:
- aLayer = readPolylineZShapes(br, shapeNum);
- break;
- case Polygon: //Polygon layer
- aLayer = readPolygonShapes(br, shapeNum);
- break;
- case PolygonM:
- aLayer = readPolygonMShapes(br, shapeNum);
- break;
- case PolygonZ:
- aLayer = readPolygonZShapes(br, shapeNum);
- break;
- default:
- System.out.println("The shape type is not supported: " + aST.toString());
- return null;
- }
- br.close();
-
- if (aLayer != null) {
- aLayer.setExtent(aExtent);
-
- //Layer property
- aLayer.setLayerDrawType(LayerDrawType.Map);
- aLayer.setFileName(shpfilepath);
- aLayer.setLayerName(shpFile.getName());
- aLayer.setVisible(true);
-
- //read out the layer attribute information
- AttributeTable attrTable = loadDbfFile(shpfilepath, encoding);
- aLayer.setAttributeTable(attrTable);
-
- //Get projection information
- if (prjFile.exists()) {
- aLayer.setProjInfo(loadProjFile(prjFile));
- }
- }
-
- return aLayer;
-
- }
-
- private static void readHeader(DataInputStream br) throws IOException {
- int i;
-
- int FileCode = swapByteOrder(br.readInt());
- for (i = 0; i < 5; i++) {
- br.readInt();
- }
- int FileLength = swapByteOrder(br.readInt());
- int Version = br.readInt();
- int aShapeType = br.readInt();
- Extent aExtent = new Extent();
- aExtent.minX = br.readDouble();
- aExtent.minY = br.readDouble();
- aExtent.maxX = br.readDouble();
- aExtent.maxY = br.readDouble();
- for (i = 0; i < 4; i++) {
- br.readDouble();
- }
- }
-
- private static VectorLayer readPointShapes(DataInputStream br, int shapeNum) throws IOException {
- int RecordNum, ContentLength, aShapeType;
- double x, y;
- VectorLayer aLayer = new VectorLayer(ShapeTypes.Point);
- byte[] bytes = new byte[28 * shapeNum];
- br.read(bytes);
- ByteBuffer buffer = ByteBuffer.wrap(bytes);
-
- for (int i = 0; i < shapeNum; i++) {
-
- //br.ReadBytes(12); //记录头8个字节和一个int(4个字节)的shapetype
- buffer.order(ByteOrder.BIG_ENDIAN);
- RecordNum = buffer.getInt();
- ContentLength = buffer.getInt();
-
- buffer.order(ByteOrder.LITTLE_ENDIAN);
- aShapeType = buffer.getInt();
-
- x = buffer.getDouble();
- y = buffer.getDouble();
-
- PointShape aP = new PointShape();
- PointD aPoint = new PointD();
- aPoint.X = x;
- aPoint.Y = y;
- aP.setPoint(aPoint);
- aLayer.addShape(aP);
- }
-
- //Create legend scheme
- aLayer.setLegendScheme(LegendManage.createSingleSymbolLegendScheme(ShapeTypes.Point, Color.black, 5));
- return aLayer;
- }
-
- private static VectorLayer readPointZShapes(DataInputStream br, int shapeNum) throws IOException {
- int RecordNum, ContentLength, aShapeType;
- double x, y, z, m;
- VectorLayer aLayer = new VectorLayer(ShapeTypes.PointZ);
- byte[] bytes = new byte[44 * shapeNum];
- br.read(bytes);
- ByteBuffer buffer = ByteBuffer.wrap(bytes);
-
- for (int i = 0; i < shapeNum; i++) {
-
- //br.ReadBytes(12); //记录头8个字节和一个int(4个字节)的shapetype
- buffer.order(ByteOrder.BIG_ENDIAN);
- RecordNum = buffer.getInt();
- ContentLength = buffer.getInt();
-
- buffer.order(ByteOrder.LITTLE_ENDIAN);
- aShapeType = buffer.getInt();
-
- x = buffer.getDouble();
- y = buffer.getDouble();
- z = buffer.getDouble();
- m = buffer.getDouble();
-
- PointZShape aP = new PointZShape();
- PointZ aPoint = new PointZ();
- aPoint.X = x;
- aPoint.Y = y;
- aPoint.Z = z;
- aPoint.M = m;
- aP.setPoint(aPoint);
- aLayer.addShape(aP);
- }
-
- //Create legend scheme
- aLayer.setLegendScheme(LegendManage.createSingleSymbolLegendScheme(ShapeTypes.Point, Color.black, 5));
- return aLayer;
- }
-
- private static VectorLayer readPolylineShapes(DataInputStream br, int shapeNum) throws IOException {
- VectorLayer aLayer = new VectorLayer(ShapeTypes.Polyline);
- int RecordNum, ContentLength, aShapeType;
- double x, y;
- byte[] bytes;
- ByteBuffer buffer;
-
- //PointD aPoint;
- for (int i = 0; i < shapeNum; i++) {
- bytes = new byte[8];
- br.read(bytes);
- buffer = ByteBuffer.wrap(bytes);
- //br.skipBytes(12);
- buffer.order(ByteOrder.BIG_ENDIAN);
- RecordNum = buffer.getInt();
- ContentLength = buffer.getInt();
-
- bytes = new byte[ContentLength * 2];
- br.read(bytes);
- buffer = ByteBuffer.wrap(bytes);
- buffer.order(ByteOrder.LITTLE_ENDIAN);
- aShapeType = buffer.getInt();
-
- PolylineShape aPL = new PolylineShape();
- Extent extent = new Extent();
- extent.minX = buffer.getDouble();
- extent.minY = buffer.getDouble();
- extent.maxX = buffer.getDouble();
- extent.maxY = buffer.getDouble();
- aPL.setExtent(extent);
-
- aPL.setPartNum(buffer.getInt());
- int numPoints = buffer.getInt();
- aPL.parts = new int[aPL.getPartNum()];
- List points = new ArrayList<>();
-
- //firstly read out parts begin pos in file
- for (int j = 0; j < aPL.getPartNum(); j++) {
- aPL.parts[j] = buffer.getInt();
- }
-
- //read out coordinates
- for (int j = 0; j < numPoints; j++) {
- x = buffer.getDouble();
- y = buffer.getDouble();
- PointD aPoint = new PointD();
- aPoint.X = x;
- aPoint.Y = y;
- points.add(aPoint);
- }
- aPL.setPoints(points);
- aLayer.addShape(aPL);
- }
-
- //Create legend scheme
- aLayer.setLegendScheme(LegendManage.createSingleSymbolLegendScheme(ShapeTypes.Polyline, Color.darkGray, 1.0F));
-
- return aLayer;
- }
-
- private static VectorLayer readPolylineZShapes(DataInputStream br, int shapeNum) throws IOException {
- VectorLayer aLayer = new VectorLayer(ShapeTypes.PolylineZ);
- int RecordNum, ContentLength, aShapeType;
- double x, y;
- byte[] bytes;
- ByteBuffer buffer;
-
- //PointD aPoint;
- for (int i = 0; i < shapeNum; i++) {
- //br.skipBytes(12);
- bytes = new byte[8];
- br.read(bytes);
- buffer = ByteBuffer.wrap(bytes);
- //br.skipBytes(12);
- buffer.order(ByteOrder.BIG_ENDIAN);
- RecordNum = buffer.getInt();
- ContentLength = buffer.getInt();
-
- bytes = new byte[ContentLength * 2];
- br.read(bytes);
- buffer = ByteBuffer.wrap(bytes);
- buffer.order(ByteOrder.LITTLE_ENDIAN);
- aShapeType = buffer.getInt();
-
- //Read bounding box
- PolylineZShape aPL = new PolylineZShape();
- Extent extent = new Extent();
- extent.minX = buffer.getDouble();
- extent.minY = buffer.getDouble();
- extent.maxX = buffer.getDouble();
- extent.maxY = buffer.getDouble();
- aPL.setExtent(extent);
-
- aPL.setPartNum(buffer.getInt());
- int numPoints = buffer.getInt();
- aPL.parts = new int[aPL.getPartNum()];
- List points = new ArrayList<>();
-
- //firstly read out parts begin position in file
- for (int j = 0; j < aPL.getPartNum(); j++) {
- aPL.parts[j] = buffer.getInt();
- }
-
- //read out coordinates
- for (int j = 0; j < numPoints; j++) {
- x = buffer.getDouble();
- y = buffer.getDouble();
- PointD aPoint = new PointD();
- aPoint.X = x;
- aPoint.Y = y;
- points.add(aPoint);
- }
- //aPL.Points = points;
-
- //Read Z
- double zmin = buffer.getDouble();
- double zmax = buffer.getDouble();
- double[] zArray = new double[numPoints];
- for (int j = 0; j < numPoints; j++) {
- zArray[j] = buffer.getDouble();
- }
-
- //Read measure
- double mmin = buffer.getDouble();
- double mmax = buffer.getDouble();
- double[] mArray = new double[numPoints];
- for (int j = 0; j < numPoints; j++) {
- mArray[j] = buffer.getDouble();
- }
-
- //Get pointZ list
- List pointZs = new ArrayList<>();
- for (int j = 0; j < numPoints; j++) {
- pointZs.add(new PointZ(points.get(j).X, points.get(j).Y, zArray[j], mArray[j]));
- }
-
- aPL.setPoints(pointZs);
- aLayer.addShape(aPL);
- }
-
- //Create legend scheme
- aLayer.setLegendScheme(LegendManage.createSingleSymbolLegendScheme(ShapeTypes.Polyline, Color.darkGray, 1.0F));
-
- return aLayer;
- }
-
- private static VectorLayer readPolygonShapes(DataInputStream br, int shapeNum) throws IOException {
- VectorLayer aLayer = new VectorLayer(ShapeTypes.Polygon);
- int RecordNum, ContentLength, aShapeType;
- double x, y;
- byte[] bytes;
- ByteBuffer buffer;
-
- for (int i = 0; i < shapeNum; i++) {
- //br.skipBytes(12);
- bytes = new byte[8];
- br.read(bytes);
- buffer = ByteBuffer.wrap(bytes);
- //br.skipBytes(12);
- buffer.order(ByteOrder.BIG_ENDIAN);
- RecordNum = buffer.getInt();
- ContentLength = buffer.getInt();
-
- bytes = new byte[ContentLength * 2];
- br.read(bytes);
- buffer = ByteBuffer.wrap(bytes);
- buffer.order(ByteOrder.LITTLE_ENDIAN);
- aShapeType = buffer.getInt();
-
- PolygonShape aSPG = new PolygonShape();
- Extent extent = new Extent();
- extent.minX = buffer.getDouble();
- extent.minY = buffer.getDouble();
- extent.maxX = buffer.getDouble();
- extent.maxY = buffer.getDouble();
- aSPG.setExtent(extent);
- aSPG.setPartNum(buffer.getInt());
- int numPoints = buffer.getInt();
- aSPG.parts = new int[aSPG.getPartNum()];
- List points = new ArrayList<>();
-
- //firstly read out parts begin pos in file
- for (int j = 0; j < aSPG.getPartNum(); j++) {
- aSPG.parts[j] = buffer.getInt();
- }
-
- //read out coordinates
- for (int j = 0; j < numPoints; j++) {
- x = buffer.getDouble();
- y = buffer.getDouble();
- PointD aPoint = new PointD();
- aPoint.X = x;
- aPoint.Y = y;
- points.add(aPoint);
- }
- aSPG.setPoints(points);
- aLayer.addShape(aSPG);
- }
-
- //Create legend scheme
- aLayer.setLegendScheme(LegendManage.createSingleSymbolLegendScheme(ShapeTypes.Polygon, new Color(255, 251, 195), 1.0F));
-
- return aLayer;
- }
-
- private static VectorLayer readPolygonMShapes(DataInputStream br, int shapeNum) throws IOException {
- VectorLayer aLayer = new VectorLayer(ShapeTypes.PolygonM);
- int RecordNum, ContentLength, aShapeType;
- double x, y;
- byte[] bytes;
- ByteBuffer buffer;
-
- for (int i = 0; i < shapeNum; i++) {
- //br.skipBytes(12);
- bytes = new byte[8];
- br.read(bytes);
- buffer = ByteBuffer.wrap(bytes);
- //br.skipBytes(12);
- buffer.order(ByteOrder.BIG_ENDIAN);
- RecordNum = buffer.getInt();
- ContentLength = buffer.getInt();
-
- bytes = new byte[ContentLength * 2];
- br.read(bytes);
- buffer = ByteBuffer.wrap(bytes);
- buffer.order(ByteOrder.LITTLE_ENDIAN);
- aShapeType = buffer.getInt();
-
- PolygonMShape aSPG = new PolygonMShape();
- Extent extent = new Extent();
- extent.minX = buffer.getDouble();
- extent.minY = buffer.getDouble();
- extent.maxX = buffer.getDouble();
- extent.maxY = buffer.getDouble();
- aSPG.setExtent(extent);
- aSPG.setPartNum(buffer.getInt());
- int numPoints = buffer.getInt();
- aSPG.parts = new int[aSPG.getPartNum()];
- List points = new ArrayList<>();
-
- //firstly read out parts begin pos in file
- for (int j = 0; j < aSPG.getPartNum(); j++) {
- aSPG.parts[j] = buffer.getInt();
- }
-
- //read out coordinates
- for (int j = 0; j < numPoints; j++) {
- x = buffer.getDouble();
- y = buffer.getDouble();
- PointD aPoint = new PointD();
- aPoint.X = x;
- aPoint.Y = y;
- points.add(aPoint);
- }
-
- //Read measure
- double mmin = buffer.getDouble();
- double mmax = buffer.getDouble();
- double[] mArray = new double[numPoints];
- for (int j = 0; j < numPoints; j++) {
- mArray[j] = buffer.getDouble();
- }
-
- //Get pointM list
- List pointMs = new ArrayList<>();
- for (int j = 0; j < numPoints; j++) {
- pointMs.add(new PointM(points.get(j).X, points.get(j).Y, mArray[j]));
- }
-
- aSPG.setPoints(pointMs);
- aLayer.addShape(aSPG);
- }
-
- //Create legend scheme
- aLayer.setLegendScheme(LegendManage.createSingleSymbolLegendScheme(ShapeTypes.Polygon, new Color(255, 251, 195), 1.0F));
-
- return aLayer;
- }
-
- private static VectorLayer readPolygonZShapes(DataInputStream br, int shapeNum) throws IOException {
- VectorLayer aLayer = new VectorLayer(ShapeTypes.PolygonZ);
- int RecordNum, ContentLength, aShapeType;
- double x, y;
- byte[] bytes;
- ByteBuffer buffer;
-
- for (int i = 0; i < shapeNum; i++) {
- //br.skipBytes(12);
- bytes = new byte[8];
- br.read(bytes);
- buffer = ByteBuffer.wrap(bytes);
- //br.skipBytes(12);
- buffer.order(ByteOrder.BIG_ENDIAN);
- RecordNum = buffer.getInt();
- ContentLength = buffer.getInt();
-
- bytes = new byte[ContentLength * 2];
- br.read(bytes);
- buffer = ByteBuffer.wrap(bytes);
- buffer.order(ByteOrder.LITTLE_ENDIAN);
- aShapeType = buffer.getInt();
-
- PolygonZShape aSPG = new PolygonZShape();
- Extent extent = new Extent();
- extent.minX = buffer.getDouble();
- extent.minY = buffer.getDouble();
- extent.maxX = buffer.getDouble();
- extent.maxY = buffer.getDouble();
- aSPG.setExtent(extent);
- aSPG.setPartNum(buffer.getInt());
- int numPoints = buffer.getInt();
- aSPG.parts = new int[aSPG.getPartNum()];
- List points = new ArrayList<>();
-
- //firstly read out parts begin pos in file
- for (int j = 0; j < aSPG.getPartNum(); j++) {
- aSPG.parts[j] = buffer.getInt();
- }
-
- //read out coordinates
- for (int j = 0; j < numPoints; j++) {
- x = buffer.getDouble();
- y = buffer.getDouble();
- PointD aPoint = new PointD();
- aPoint.X = x;
- aPoint.Y = y;
- points.add(aPoint);
- }
-
- //Read Z
- double zmin = buffer.getDouble();
- double zmax = buffer.getDouble();
- double[] zArray = new double[numPoints];
- for (int j = 0; j < numPoints; j++) {
- zArray[j] = buffer.getDouble();
- }
-
- //Read measure
- double mmin = buffer.getDouble();
- double mmax = buffer.getDouble();
- double[] mArray = new double[numPoints];
- for (int j = 0; j < numPoints; j++) {
- mArray[j] = buffer.getDouble();
- }
-
- //Get pointZ list
- List pointZs = new ArrayList<>();
- for (int j = 0; j < numPoints; j++) {
- pointZs.add(new PointZ(points.get(j).X, points.get(j).Y, zArray[j], mArray[j]));
- }
-
- aSPG.setPoints(pointZs);
- aLayer.addShape(aSPG);
- }
-
- //Create legend scheme
- aLayer.setLegendScheme(LegendManage.createSingleSymbolLegendScheme(ShapeTypes.Polygon, new Color(255, 251, 195), 1.0F));
-
- return aLayer;
- }
-
- private static void loadShxFile(File shxFile) throws FileNotFoundException, IOException {
- DataInputStream bridx = new DataInputStream(new BufferedInputStream(new FileInputStream(shxFile)));
- long BytesSum = shxFile.length(); //Get file byte length
- int shapeNum = (int) (BytesSum - 100) / 8; //Get total number of records
- readHeader(bridx);
-
- int OffSet = 0, ContentLength = 0;
- for (int i = 0; i < shapeNum; i++) {
- OffSet = swapByteOrder(bridx.readInt());
- ContentLength = swapByteOrder(bridx.readInt());
- }
-
- bridx.close();
- }
-
-// /**
-// * Load DBF data file
-// * @param shpFileName Shape file name
-// * @return Attribute table
-// * @throws Exception
-// */
-// public static AttributeTable loadDbfFile(String shpFileName) throws Exception{
-// AttributeTable attrTable = new AttributeTable();
-// attrTable.open(shpFileName);
-// attrTable.fill(attrTable.getNumRecords());
-//
-// return attrTable;
-// }
-
- /**
- * Load DBF data file
- * @param shpFileName Shape file name
- * @param encoding Encoding
- * @return Attribute table
- * @throws Exception
- */
- public static AttributeTable loadDbfFile(String shpFileName, String encoding) throws Exception{
- AttributeTable attrTable = new AttributeTable();
- attrTable.setEncoding(encoding);
- attrTable.open(shpFileName);
- attrTable.fill(attrTable.getNumRecords());
-
- return attrTable;
- }
-
- /**
- * Load projection file
- * @param projFile Projection file
- * @return Projection infomation
- * @throws FileNotFoundException
- * @throws IOException
- */
- public static ProjectionInfo loadProjFile(File projFile) throws FileNotFoundException, IOException {
- BufferedReader sr = new BufferedReader(new FileReader(projFile));
- String line;
- StringBuilder buffer = new StringBuilder();
- while ((line = sr.readLine()) != null) {
- buffer.append(line);
- }
-
- String esriString = buffer.toString();
- sr.close();
-
- ProjectionInfo projInfo = ProjectionInfo.factoryESRI(esriString);
-
- return projInfo;
- }
-
- /**
- * Save shape file
- * @param shpfilepath Shape file path
- * @param aLayer Vector layer
- * @return Boolean
- * @throws java.io.IOException*/
- public static boolean saveShapeFile(String shpfilepath, VectorLayer aLayer) throws IOException {
- String shxfilepath = shpfilepath.replace(shpfilepath.substring(shpfilepath.lastIndexOf(".")), ".shx");
- String dbffilepath = shpfilepath.replace(shpfilepath.substring(shpfilepath.lastIndexOf(".")), ".dbf");
- String projFilePath = shpfilepath.replace(shpfilepath.substring(shpfilepath.lastIndexOf(".")), ".prj");
-
- switch (aLayer.getShapeType()) {
- case Point:
- case PointZ:
- case Polyline:
- case PolylineZ:
- case Polygon:
- case PolygonZ:
- writeShxFile(shxfilepath, aLayer);
- writeShpFile(shpfilepath, aLayer);
- writeDbfFile(dbffilepath, aLayer);
- writeProjFile(projFilePath, aLayer);
- return true;
-
- default:
- return false;
- }
- }
-
- /**
- * Save shape file
- * @param shpfilepath Shape file path
- * @param aLayer Vector layer
- * @param encoding Encoding
- * @return Boolean
- * @throws java.io.IOException*/
- public static boolean saveShapeFile(String shpfilepath, VectorLayer aLayer, String encoding) throws IOException {
- String shxfilepath = shpfilepath.replace(shpfilepath.substring(shpfilepath.lastIndexOf(".")), ".shx");
- String dbffilepath = shpfilepath.replace(shpfilepath.substring(shpfilepath.lastIndexOf(".")), ".dbf");
- String projFilePath = shpfilepath.replace(shpfilepath.substring(shpfilepath.lastIndexOf(".")), ".prj");
-
- switch (aLayer.getShapeType()) {
- case Point:
- case PointZ:
- case Polyline:
- case PolylineZ:
- case Polygon:
- case PolygonZ:
- writeShxFile(shxfilepath, aLayer);
- writeShpFile(shpfilepath, aLayer);
- writeDbfFile(dbffilepath, aLayer, encoding);
- writeProjFile(projFilePath, aLayer);
- return true;
-
- default:
- return false;
- }
- }
-
- private static void writeShpFile(String shpfilepath, VectorLayer aLayer) throws FileNotFoundException, IOException {
- File shpFile = new File(shpfilepath);
- EndianDataOutputStream bw = new EndianDataOutputStream(new BufferedOutputStream(new FileOutputStream(shpFile)));
-
- //Write header
- int FileLength = getShpFileLength(aLayer);
- writeHeader(bw, aLayer, FileLength);
-
- //Write records
- int RecordNumber;
-
- for (int i = 0; i < aLayer.getShapeNum(); i++) {
- Shape aShape = aLayer.getShapes().get(i);
- RecordNumber = i + 1;
- writeRecord(bw, RecordNumber, aShape, aLayer.getShapeType());
- }
-
- //Close
- bw.close();
- }
-
- private static int getShpFileLength(VectorLayer aLayer) {
- int fileLength = 50;
-
- for (int i = 0; i < aLayer.getShapeNum(); i++) {
- Shape aShape = aLayer.getShapes().get(i);
- int cLen = getContentLength(aShape, aLayer.getShapeType());
- fileLength += 4 + cLen;
- }
-
- return fileLength;
- }
-
- private static int getContentLength(Shape aShape, ShapeTypes aST) {
- int contentLength = 0;
- switch (aST) {
- case Point:
- contentLength = 2 + 4 * 2;
- break;
- case PointZ:
- contentLength = 2 + 4 * 4;
- break;
- case Polyline:
- PolylineShape aPLS = (PolylineShape) aShape;
- contentLength = 2 + 4 * 4 + 2 + 2 + 2 * aPLS.getPartNum() + 4 * 2 * aPLS.getPointNum();
- break;
- case PolylineZ:
- PolylineZShape aPLZS = (PolylineZShape) aShape;
- contentLength = 2 + 4 * 4 + 2 + 2 + 2 * aPLZS.getPartNum() + 4 * 2 * aPLZS.getPointNum()
- + 4 + 4 + 4 * aPLZS.getPointNum() + 4 + 4 + 4 * aPLZS.getPointNum();
- break;
- case Polygon:
- PolygonShape aPGS = (PolygonShape) aShape;
- contentLength = 2 + 4 * 4 + 2 + 2 + 2 * aPGS.getPartNum() + 4 * 2 * aPGS.getPointNum();
- break;
- case PolygonZ:
- PolygonZShape aPGZS = (PolygonZShape) aShape;
- contentLength = 2 + 4 * 4 + 2 + 2 + 2 * aPGZS.getPartNum() + 4 * 2 * aPGZS.getPointNum()
- + 4 + 4 + 4 * aPGZS.getPointNum() + 4 + 4 + 4 * aPGZS.getPointNum();
- break;
- }
-
- return contentLength;
- }
-
- private static void writeRecord(EndianDataOutputStream bw, int RecordNumber, Shape aShape, ShapeTypes aST) throws IOException {
- int ContentLength, i;
-
- ContentLength = getContentLength(aShape, aST);
- bw.writeIntBE(RecordNumber);
- bw.writeIntBE(ContentLength);
- bw.writeIntLE(aST.getValue());
- switch (aST) {
- case Point:
- PointShape aPS = (PointShape) aShape;
- bw.writeDoubleLE(aPS.getPoint().X);
- bw.writeDoubleLE(aPS.getPoint().Y);
- break;
- case Polyline:
- PolylineShape aPLS = (PolylineShape) aShape;
- bw.writeDoubleLE(aPLS.getExtent().minX);
- bw.writeDoubleLE(aPLS.getExtent().minY);
- bw.writeDoubleLE(aPLS.getExtent().maxX);
- bw.writeDoubleLE(aPLS.getExtent().maxY);
- bw.writeIntLE(aPLS.getPartNum());
- bw.writeIntLE(aPLS.getPointNum());
- for (i = 0; i < aPLS.getPartNum(); i++) {
- bw.writeIntLE(aPLS.parts[i]);
- }
- for (i = 0; i < aPLS.getPointNum(); i++) {
- bw.writeDoubleLE((aPLS.getPoints().get(i)).X);
- bw.writeDoubleLE((aPLS.getPoints().get(i)).Y);
- }
- break;
- case PolylineZ:
- PolylineZShape aPLZS = (PolylineZShape) aShape;
- bw.writeDoubleLE(aPLZS.getExtent().minX);
- bw.writeDoubleLE(aPLZS.getExtent().minY);
- bw.writeDoubleLE(aPLZS.getExtent().maxX);
- bw.writeDoubleLE(aPLZS.getExtent().maxY);
- bw.writeIntLE(aPLZS.getPartNum());
- bw.writeIntLE(aPLZS.getPointNum());
- for (i = 0; i < aPLZS.getPartNum(); i++) {
- bw.writeIntLE(aPLZS.parts[i]);
- }
- for (i = 0; i < aPLZS.getPointNum(); i++) {
- bw.writeDoubleLE((aPLZS.getPoints().get(i)).X);
- bw.writeDoubleLE((aPLZS.getPoints().get(i)).Y);
- }
- bw.writeDoubleLE(aPLZS.getZRange()[0]);
- bw.writeDoubleLE(aPLZS.getZRange()[1]);
- for (i = 0; i < aPLZS.getPointNum(); i++) {
- bw.writeDoubleLE(aPLZS.getZArray()[i]);
- }
- bw.writeDoubleLE(aPLZS.getMRange()[0]);
- bw.writeDoubleLE(aPLZS.getMRange()[1]);
- for (i = 0; i < aPLZS.getPointNum(); i++) {
- bw.writeDoubleLE(aPLZS.getMArray()[i]);
- }
- break;
- case Polygon:
- PolygonShape aPGS = (PolygonShape) aShape;
- bw.writeDoubleLE(aPGS.getExtent().minX);
- bw.writeDoubleLE(aPGS.getExtent().minY);
- bw.writeDoubleLE(aPGS.getExtent().maxX);
- bw.writeDoubleLE(aPGS.getExtent().maxY);
- bw.writeIntLE(aPGS.getPartNum());
- bw.writeIntLE(aPGS.getPointNum());
- for (i = 0; i < aPGS.getPartNum(); i++) {
- bw.writeIntLE(aPGS.parts[i]);
- }
- for (i = 0; i < aPGS.getPointNum(); i++) {
- bw.writeDoubleLE((aPGS.getPoints().get(i)).X);
- bw.writeDoubleLE((aPGS.getPoints().get(i)).Y);
- }
- break;
- case PolygonZ:
- PolygonZShape aPGZS = (PolygonZShape) aShape;
- bw.writeDoubleLE(aPGZS.getExtent().minX);
- bw.writeDoubleLE(aPGZS.getExtent().minY);
- bw.writeDoubleLE(aPGZS.getExtent().maxX);
- bw.writeDoubleLE(aPGZS.getExtent().maxY);
- bw.writeIntLE(aPGZS.getPartNum());
- bw.writeIntLE(aPGZS.getPointNum());
- for (i = 0; i < aPGZS.getPartNum(); i++) {
- bw.writeIntLE(aPGZS.parts[i]);
- }
- for (i = 0; i < aPGZS.getPointNum(); i++) {
- bw.writeDoubleLE((aPGZS.getPoints().get(i)).X);
- bw.writeDoubleLE((aPGZS.getPoints().get(i)).Y);
- }
- bw.writeDoubleLE(aPGZS.getZRange()[0]);
- bw.writeDoubleLE(aPGZS.getZRange()[1]);
- for (i = 0; i < aPGZS.getPointNum(); i++) {
- bw.writeDoubleLE(aPGZS.getZArray()[i]);
- }
- bw.writeDoubleLE(aPGZS.getMRange()[0]);
- bw.writeDoubleLE(aPGZS.getMRange()[1]);
- for (i = 0; i < aPGZS.getPointNum(); i++) {
- bw.writeDoubleLE(aPGZS.getMArray()[i]);
- }
- break;
- }
- }
-
- private static void writeHeader(EndianDataOutputStream bw, VectorLayer aLayer, int FileLength) throws IOException {
- int i;
- int FileCode = 9994;
- //FileCode = swapByteOrder(FileCode);
- int Unused = 0;
- //Unused = swapByteOrder(Unused);
- //FileLength = swapByteOrder(FileLength);
- int Version = 1000;
- int aShapeType = aLayer.getShapeType().getValue();
-
- bw.writeIntBE(FileCode);
- for (i = 0; i < 5; i++) {
- bw.writeIntBE(Unused);
- }
- bw.writeIntBE(FileLength);
- bw.writeIntLE(Version);
- bw.writeIntLE(aShapeType);
- bw.writeDoubleLE(aLayer.getExtent().minX);
- bw.writeDoubleLE(aLayer.getExtent().minY);
- bw.writeDoubleLE(aLayer.getExtent().maxX);
- bw.writeDoubleLE(aLayer.getExtent().maxY);
- for (i = 0; i < 4; i++) {
- bw.writeDoubleLE(0.0);
- }
- }
-
- private static void writeShxFile(String shxfilepath, VectorLayer aLayer) throws IOException {
- File shxFile = new File(shxfilepath);
- EndianDataOutputStream bw = new EndianDataOutputStream(new BufferedOutputStream(new FileOutputStream(shxFile)));
-
- //Write header
- int FileLength = aLayer.getShapeNum() * 4 + 50;
- writeHeader(bw, aLayer, FileLength);
-
- //Write content
- int OffSet, ContentLength;
- OffSet = 50;
-
- for (int i = 0; i < aLayer.getShapeNum(); i++) {
- Shape aShape = aLayer.getShapes().get(i);
- ContentLength = getContentLength(aShape, aLayer.getShapeType());
-
- bw.writeIntBE(OffSet);
- bw.writeIntBE(ContentLength);
-
- OffSet = OffSet + 4 + ContentLength;
- }
-
- //Close
- bw.close();
- }
-
- private static void writeDbfFile(String dbffilepath, VectorLayer aLayer) {
- aLayer.getAttributeTable().saveAs(dbffilepath, true);
- }
-
- private static void writeDbfFile(String dbffilepath, VectorLayer aLayer, String encoding) {
- AttributeTable attTable = aLayer.getAttributeTable();
- attTable.setEncoding(encoding);
- attTable.saveAs(dbffilepath, true);
- }
-
- private static void writeProjFile(String projFilePath, VectorLayer aLayer) {
- BufferedWriter sw = null;
- try {
- String esriString = aLayer.getProjInfo().toEsriString();
- sw = new BufferedWriter(new FileWriter(new File(projFilePath)));
- sw.write(esriString);
- sw.flush();
- sw.close();
- } catch (IOException ex) {
- Logger.getLogger(ShapeFileManage.class.getName()).log(Level.SEVERE, null, ex);
- } finally {
- try {
- sw.close();
- } catch (IOException ex) {
- Logger.getLogger(ShapeFileManage.class.getName()).log(Level.SEVERE, null, ex);
- }
- }
- }
-
- /**
- * Swaps the byte order of an int32
- *
- * @param i Integer
- * @return Byte order swapped int
- */
- private static int swapByteOrder(int i) {
- byte[] buffer = intToBytes(i);
- return ((buffer[3] & 0xff) << 24) | ((buffer[2] & 0xff) << 16)
- | ((buffer[1] & 0xff) << 8) | (buffer[0] & 0xff);
- }
-
- private static byte[] intToBytes(int i) {
- byte[] result = new byte[4];
- result[0] = (byte) ((i >> 24) & 0xFF);
- result[1] = (byte) ((i >> 16) & 0xFF);
- result[2] = (byte) ((i >> 8) & 0xFF);
- result[3] = (byte) (i & 0xFF);
- return result;
- }
-
- private static int bytesToInt(byte[] buffer){
- return ((buffer[3] & 0xff) << 24) | ((buffer[2] & 0xff) << 16)
- | ((buffer[1] & 0xff) << 8) | (buffer[0] & 0xff);
- }
-}
+ /* Copyright 2012 Yaqiang Wang,
+ * yaqiang.wang@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ */
+package org.meteoinfo.data.mapdata;
+
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.PointD;
+import org.meteoinfo.common.io.EndianDataOutputStream;
+import org.meteoinfo.layer.LayerDrawType;
+import org.meteoinfo.layer.VectorLayer;
+import org.meteoinfo.legend.LegendManage;
+import org.meteoinfo.shape.PointShape;
+import org.meteoinfo.shape.PointZ;
+import org.meteoinfo.shape.PolygonShape;
+import org.meteoinfo.shape.PolylineShape;
+import org.meteoinfo.shape.PolylineZShape;
+import org.meteoinfo.shape.Shape;
+import org.meteoinfo.shape.ShapeTypes;
+import java.awt.Color;
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.meteoinfo.projection.info.ProjectionInfo;
+import org.meteoinfo.shape.PointM;
+import org.meteoinfo.shape.PointZShape;
+import org.meteoinfo.shape.PolygonMShape;
+import org.meteoinfo.shape.PolygonZShape;
+
+/**
+ * Shape file read and write
+ *
+ * @author yaqiang
+ */
+public class ShapeFileManage {
+
+ private final static String ENCODING = "UTF-8";
+
+ /**
+ * Load shape file
+ *
+ * @param shpfilepath Shape file path
+ * @return Vector layer
+ * @throws IOException
+ * @throws java.io.FileNotFoundException
+ */
+ public static VectorLayer loadShapeFile(String shpfilepath) throws IOException, FileNotFoundException, Exception {
+ String cpgfilepath = shpfilepath.replaceFirst(shpfilepath.substring(shpfilepath.lastIndexOf(".")), ".cpg");
+ File cpgFile = new File(cpgfilepath);
+ String encoding = ENCODING;
+ if (cpgFile.exists()){
+ BufferedReader sr = new BufferedReader(new FileReader(cpgFile));
+ String ec = sr.readLine().trim();
+ sr.close();
+ encoding = ec;
+ }
+ return loadShapeFile(shpfilepath, encoding);
+ }
+
+ /**
+ * Load shape file
+ *
+ * @param shpfilepath Shape file path
+ * @param encoding Encoding
+ * @return Vector layer
+ * @throws IOException
+ * @throws java.io.FileNotFoundException
+ */
+ public static VectorLayer loadShapeFile(String shpfilepath, String encoding) throws IOException, FileNotFoundException, Exception {
+ //Set file names
+ String shxfilepath = shpfilepath.replace(shpfilepath.substring(shpfilepath.lastIndexOf(".")), ".shx");
+ String dbffilepath = shpfilepath.replace(shpfilepath.substring(shpfilepath.lastIndexOf(".")), ".dbf");
+ String projfilepath = shpfilepath.replace(shpfilepath.substring(shpfilepath.lastIndexOf(".")), ".prj");
+ File shpFile = new File(shpfilepath);
+ File dbfFile = new File(dbffilepath);
+ File shxFile = new File(shxfilepath);
+ File prjFile = new File(projfilepath);
+ if (!shxFile.exists()) {
+ shxfilepath = shxfilepath.replace(".shx", ".SHX");
+ shxFile = new File(shxfilepath);
+ }
+ if (!dbfFile.exists()) {
+ dbffilepath = dbffilepath.replace(".dbf", ".DBF");
+ dbfFile = new File(dbffilepath);
+ }
+ if (!prjFile.exists()) {
+ projfilepath = projfilepath.replace(".prj", ".PRJ");
+ prjFile = new File(projfilepath);
+ }
+
+ //Read shx file
+ if ("".equals(shxfilepath)) {
+ // MessageBox.Show("Open shx file error");
+ return null;
+ }
+
+ long BytesSum = shxFile.length(); //Get file byte length
+ int shapeNum = (int) (BytesSum - 100) / 8; //Get total number of records
+ loadShxFile(shxFile);
+
+ //Open shp file
+ DataInputStream br = new DataInputStream(new BufferedInputStream(new FileInputStream(shpFile)));
+ VectorLayer aLayer;
+ //byte[] arr = new byte[(int)shpFile.length()];
+ byte[] arr = new byte[100];
+ br.read(arr);
+ ByteBuffer buffer = ByteBuffer.wrap(arr);
+ buffer.order(ByteOrder.LITTLE_ENDIAN);
+ ((Buffer)buffer).position(32);
+ //br.skipBytes(32); //先读出36个字节,紧接着是Box边界合
+ int aShapeType = buffer.getInt();
+ ShapeTypes aST = ShapeTypes.valueOf(aShapeType);
+ //aLayer = new VectorLayer(aST);
+ Extent aExtent = new Extent();
+ aExtent.minX = buffer.getDouble(); //读出整个shp图层的边界合
+ aExtent.minY = buffer.getDouble();
+ aExtent.maxX = buffer.getDouble();
+ aExtent.maxY = buffer.getDouble();
+
+ //br.skipBytes(32); // shp中尚未使用的边界盒
+ //buffer.position(buffer.position() + 32);
+
+ //Get Shape Data
+ switch (aST) {
+ case Point://single point
+ aLayer = readPointShapes(br, shapeNum);
+ break;
+ case PointZ:
+ aLayer = readPointZShapes(br, shapeNum);
+ break;
+ case Polyline: //Polyline layer
+ aLayer = readPolylineShapes(br, shapeNum);
+ break;
+ case PolylineZ:
+ aLayer = readPolylineZShapes(br, shapeNum);
+ break;
+ case Polygon: //Polygon layer
+ aLayer = readPolygonShapes(br, shapeNum);
+ break;
+ case PolygonM:
+ aLayer = readPolygonMShapes(br, shapeNum);
+ break;
+ case PolygonZ:
+ aLayer = readPolygonZShapes(br, shapeNum);
+ break;
+ default:
+ System.out.println("The shape type is not supported: " + aST.toString());
+ return null;
+ }
+ br.close();
+
+ if (aLayer != null) {
+ aLayer.setExtent(aExtent);
+
+ //Layer property
+ aLayer.setLayerDrawType(LayerDrawType.Map);
+ aLayer.setFileName(shpfilepath);
+ aLayer.setLayerName(shpFile.getName());
+ aLayer.setVisible(true);
+
+ //read out the layer attribute information
+ AttributeTable attrTable = loadDbfFile(shpfilepath, encoding);
+ aLayer.setAttributeTable(attrTable);
+
+ //Get projection information
+ if (prjFile.exists()) {
+ aLayer.setProjInfo(loadProjFile(prjFile));
+ }
+ }
+
+ return aLayer;
+
+ }
+
+ private static void readHeader(DataInputStream br) throws IOException {
+ int i;
+
+ int FileCode = swapByteOrder(br.readInt());
+ for (i = 0; i < 5; i++) {
+ br.readInt();
+ }
+ int FileLength = swapByteOrder(br.readInt());
+ int Version = br.readInt();
+ int aShapeType = br.readInt();
+ Extent aExtent = new Extent();
+ aExtent.minX = br.readDouble();
+ aExtent.minY = br.readDouble();
+ aExtent.maxX = br.readDouble();
+ aExtent.maxY = br.readDouble();
+ for (i = 0; i < 4; i++) {
+ br.readDouble();
+ }
+ }
+
+ private static VectorLayer readPointShapes(DataInputStream br, int shapeNum) throws IOException {
+ int RecordNum, ContentLength, aShapeType;
+ double x, y;
+ VectorLayer aLayer = new VectorLayer(ShapeTypes.Point);
+ byte[] bytes = new byte[28 * shapeNum];
+ br.read(bytes);
+ ByteBuffer buffer = ByteBuffer.wrap(bytes);
+
+ for (int i = 0; i < shapeNum; i++) {
+
+ //br.ReadBytes(12); //记录头8个字节和一个int(4个字节)的shapetype
+ buffer.order(ByteOrder.BIG_ENDIAN);
+ RecordNum = buffer.getInt();
+ ContentLength = buffer.getInt();
+
+ buffer.order(ByteOrder.LITTLE_ENDIAN);
+ aShapeType = buffer.getInt();
+
+ x = buffer.getDouble();
+ y = buffer.getDouble();
+
+ PointShape aP = new PointShape();
+ PointD aPoint = new PointD();
+ aPoint.X = x;
+ aPoint.Y = y;
+ aP.setPoint(aPoint);
+ aLayer.addShape(aP);
+ }
+
+ //Create legend scheme
+ aLayer.setLegendScheme(LegendManage.createSingleSymbolLegendScheme(ShapeTypes.Point, Color.black, 5));
+ return aLayer;
+ }
+
+ private static VectorLayer readPointZShapes(DataInputStream br, int shapeNum) throws IOException {
+ int RecordNum, ContentLength, aShapeType;
+ double x, y, z, m;
+ VectorLayer aLayer = new VectorLayer(ShapeTypes.PointZ);
+ byte[] bytes = new byte[44 * shapeNum];
+ br.read(bytes);
+ ByteBuffer buffer = ByteBuffer.wrap(bytes);
+
+ for (int i = 0; i < shapeNum; i++) {
+
+ //br.ReadBytes(12); //记录头8个字节和一个int(4个字节)的shapetype
+ buffer.order(ByteOrder.BIG_ENDIAN);
+ RecordNum = buffer.getInt();
+ ContentLength = buffer.getInt();
+
+ buffer.order(ByteOrder.LITTLE_ENDIAN);
+ aShapeType = buffer.getInt();
+
+ x = buffer.getDouble();
+ y = buffer.getDouble();
+ z = buffer.getDouble();
+ m = buffer.getDouble();
+
+ PointZShape aP = new PointZShape();
+ PointZ aPoint = new PointZ();
+ aPoint.X = x;
+ aPoint.Y = y;
+ aPoint.Z = z;
+ aPoint.M = m;
+ aP.setPoint(aPoint);
+ aLayer.addShape(aP);
+ }
+
+ //Create legend scheme
+ aLayer.setLegendScheme(LegendManage.createSingleSymbolLegendScheme(ShapeTypes.Point, Color.black, 5));
+ return aLayer;
+ }
+
+ private static VectorLayer readPolylineShapes(DataInputStream br, int shapeNum) throws IOException {
+ VectorLayer aLayer = new VectorLayer(ShapeTypes.Polyline);
+ int RecordNum, ContentLength, aShapeType;
+ double x, y;
+ byte[] bytes;
+ ByteBuffer buffer;
+
+ //PointD aPoint;
+ for (int i = 0; i < shapeNum; i++) {
+ bytes = new byte[8];
+ br.read(bytes);
+ buffer = ByteBuffer.wrap(bytes);
+ //br.skipBytes(12);
+ buffer.order(ByteOrder.BIG_ENDIAN);
+ RecordNum = buffer.getInt();
+ ContentLength = buffer.getInt();
+
+ bytes = new byte[ContentLength * 2];
+ br.read(bytes);
+ buffer = ByteBuffer.wrap(bytes);
+ buffer.order(ByteOrder.LITTLE_ENDIAN);
+ aShapeType = buffer.getInt();
+
+ PolylineShape aPL = new PolylineShape();
+ Extent extent = new Extent();
+ extent.minX = buffer.getDouble();
+ extent.minY = buffer.getDouble();
+ extent.maxX = buffer.getDouble();
+ extent.maxY = buffer.getDouble();
+ aPL.setExtent(extent);
+
+ aPL.setPartNum(buffer.getInt());
+ int numPoints = buffer.getInt();
+ aPL.parts = new int[aPL.getPartNum()];
+ List points = new ArrayList<>();
+
+ //firstly read out parts begin pos in file
+ for (int j = 0; j < aPL.getPartNum(); j++) {
+ aPL.parts[j] = buffer.getInt();
+ }
+
+ //read out coordinates
+ for (int j = 0; j < numPoints; j++) {
+ x = buffer.getDouble();
+ y = buffer.getDouble();
+ PointD aPoint = new PointD();
+ aPoint.X = x;
+ aPoint.Y = y;
+ points.add(aPoint);
+ }
+ aPL.setPoints(points);
+ aLayer.addShape(aPL);
+ }
+
+ //Create legend scheme
+ aLayer.setLegendScheme(LegendManage.createSingleSymbolLegendScheme(ShapeTypes.Polyline, Color.darkGray, 1.0F));
+
+ return aLayer;
+ }
+
+ private static VectorLayer readPolylineZShapes(DataInputStream br, int shapeNum) throws IOException {
+ VectorLayer aLayer = new VectorLayer(ShapeTypes.PolylineZ);
+ int RecordNum, ContentLength, aShapeType;
+ double x, y;
+ byte[] bytes;
+ ByteBuffer buffer;
+
+ //PointD aPoint;
+ for (int i = 0; i < shapeNum; i++) {
+ //br.skipBytes(12);
+ bytes = new byte[8];
+ br.read(bytes);
+ buffer = ByteBuffer.wrap(bytes);
+ //br.skipBytes(12);
+ buffer.order(ByteOrder.BIG_ENDIAN);
+ RecordNum = buffer.getInt();
+ ContentLength = buffer.getInt();
+
+ bytes = new byte[ContentLength * 2];
+ br.read(bytes);
+ buffer = ByteBuffer.wrap(bytes);
+ buffer.order(ByteOrder.LITTLE_ENDIAN);
+ aShapeType = buffer.getInt();
+
+ //Read bounding box
+ PolylineZShape aPL = new PolylineZShape();
+ Extent extent = new Extent();
+ extent.minX = buffer.getDouble();
+ extent.minY = buffer.getDouble();
+ extent.maxX = buffer.getDouble();
+ extent.maxY = buffer.getDouble();
+ aPL.setExtent(extent);
+
+ aPL.setPartNum(buffer.getInt());
+ int numPoints = buffer.getInt();
+ aPL.parts = new int[aPL.getPartNum()];
+ List points = new ArrayList<>();
+
+ //firstly read out parts begin position in file
+ for (int j = 0; j < aPL.getPartNum(); j++) {
+ aPL.parts[j] = buffer.getInt();
+ }
+
+ //read out coordinates
+ for (int j = 0; j < numPoints; j++) {
+ x = buffer.getDouble();
+ y = buffer.getDouble();
+ PointD aPoint = new PointD();
+ aPoint.X = x;
+ aPoint.Y = y;
+ points.add(aPoint);
+ }
+ //aPL.Points = points;
+
+ //Read Z
+ double zmin = buffer.getDouble();
+ double zmax = buffer.getDouble();
+ double[] zArray = new double[numPoints];
+ for (int j = 0; j < numPoints; j++) {
+ zArray[j] = buffer.getDouble();
+ }
+
+ //Read measure
+ double mmin = buffer.getDouble();
+ double mmax = buffer.getDouble();
+ double[] mArray = new double[numPoints];
+ for (int j = 0; j < numPoints; j++) {
+ mArray[j] = buffer.getDouble();
+ }
+
+ //Get pointZ list
+ List pointZs = new ArrayList<>();
+ for (int j = 0; j < numPoints; j++) {
+ pointZs.add(new PointZ(points.get(j).X, points.get(j).Y, zArray[j], mArray[j]));
+ }
+
+ aPL.setPoints(pointZs);
+ aLayer.addShape(aPL);
+ }
+
+ //Create legend scheme
+ aLayer.setLegendScheme(LegendManage.createSingleSymbolLegendScheme(ShapeTypes.Polyline, Color.darkGray, 1.0F));
+
+ return aLayer;
+ }
+
+ private static VectorLayer readPolygonShapes(DataInputStream br, int shapeNum) throws IOException {
+ VectorLayer aLayer = new VectorLayer(ShapeTypes.Polygon);
+ int RecordNum, ContentLength, aShapeType;
+ double x, y;
+ byte[] bytes;
+ ByteBuffer buffer;
+
+ for (int i = 0; i < shapeNum; i++) {
+ //br.skipBytes(12);
+ bytes = new byte[8];
+ br.read(bytes);
+ buffer = ByteBuffer.wrap(bytes);
+ //br.skipBytes(12);
+ buffer.order(ByteOrder.BIG_ENDIAN);
+ RecordNum = buffer.getInt();
+ ContentLength = buffer.getInt();
+
+ bytes = new byte[ContentLength * 2];
+ br.read(bytes);
+ buffer = ByteBuffer.wrap(bytes);
+ buffer.order(ByteOrder.LITTLE_ENDIAN);
+ aShapeType = buffer.getInt();
+
+ PolygonShape aSPG = new PolygonShape();
+ Extent extent = new Extent();
+ extent.minX = buffer.getDouble();
+ extent.minY = buffer.getDouble();
+ extent.maxX = buffer.getDouble();
+ extent.maxY = buffer.getDouble();
+ aSPG.setExtent(extent);
+ aSPG.setPartNum(buffer.getInt());
+ int numPoints = buffer.getInt();
+ aSPG.parts = new int[aSPG.getPartNum()];
+ List points = new ArrayList<>();
+
+ //firstly read out parts begin pos in file
+ for (int j = 0; j < aSPG.getPartNum(); j++) {
+ aSPG.parts[j] = buffer.getInt();
+ }
+
+ //read out coordinates
+ for (int j = 0; j < numPoints; j++) {
+ x = buffer.getDouble();
+ y = buffer.getDouble();
+ PointD aPoint = new PointD();
+ aPoint.X = x;
+ aPoint.Y = y;
+ points.add(aPoint);
+ }
+ aSPG.setPoints(points);
+ aLayer.addShape(aSPG);
+ }
+
+ //Create legend scheme
+ aLayer.setLegendScheme(LegendManage.createSingleSymbolLegendScheme(ShapeTypes.Polygon, new Color(255, 251, 195), 1.0F));
+
+ return aLayer;
+ }
+
+ private static VectorLayer readPolygonMShapes(DataInputStream br, int shapeNum) throws IOException {
+ VectorLayer aLayer = new VectorLayer(ShapeTypes.PolygonM);
+ int RecordNum, ContentLength, aShapeType;
+ double x, y;
+ byte[] bytes;
+ ByteBuffer buffer;
+
+ for (int i = 0; i < shapeNum; i++) {
+ //br.skipBytes(12);
+ bytes = new byte[8];
+ br.read(bytes);
+ buffer = ByteBuffer.wrap(bytes);
+ //br.skipBytes(12);
+ buffer.order(ByteOrder.BIG_ENDIAN);
+ RecordNum = buffer.getInt();
+ ContentLength = buffer.getInt();
+
+ bytes = new byte[ContentLength * 2];
+ br.read(bytes);
+ buffer = ByteBuffer.wrap(bytes);
+ buffer.order(ByteOrder.LITTLE_ENDIAN);
+ aShapeType = buffer.getInt();
+
+ PolygonMShape aSPG = new PolygonMShape();
+ Extent extent = new Extent();
+ extent.minX = buffer.getDouble();
+ extent.minY = buffer.getDouble();
+ extent.maxX = buffer.getDouble();
+ extent.maxY = buffer.getDouble();
+ aSPG.setExtent(extent);
+ aSPG.setPartNum(buffer.getInt());
+ int numPoints = buffer.getInt();
+ aSPG.parts = new int[aSPG.getPartNum()];
+ List points = new ArrayList<>();
+
+ //firstly read out parts begin pos in file
+ for (int j = 0; j < aSPG.getPartNum(); j++) {
+ aSPG.parts[j] = buffer.getInt();
+ }
+
+ //read out coordinates
+ for (int j = 0; j < numPoints; j++) {
+ x = buffer.getDouble();
+ y = buffer.getDouble();
+ PointD aPoint = new PointD();
+ aPoint.X = x;
+ aPoint.Y = y;
+ points.add(aPoint);
+ }
+
+ //Read measure
+ double mmin = buffer.getDouble();
+ double mmax = buffer.getDouble();
+ double[] mArray = new double[numPoints];
+ for (int j = 0; j < numPoints; j++) {
+ mArray[j] = buffer.getDouble();
+ }
+
+ //Get pointM list
+ List pointMs = new ArrayList<>();
+ for (int j = 0; j < numPoints; j++) {
+ pointMs.add(new PointM(points.get(j).X, points.get(j).Y, mArray[j]));
+ }
+
+ aSPG.setPoints(pointMs);
+ aLayer.addShape(aSPG);
+ }
+
+ //Create legend scheme
+ aLayer.setLegendScheme(LegendManage.createSingleSymbolLegendScheme(ShapeTypes.Polygon, new Color(255, 251, 195), 1.0F));
+
+ return aLayer;
+ }
+
+ private static VectorLayer readPolygonZShapes(DataInputStream br, int shapeNum) throws IOException {
+ VectorLayer aLayer = new VectorLayer(ShapeTypes.PolygonZ);
+ int RecordNum, ContentLength, aShapeType;
+ double x, y;
+ byte[] bytes;
+ ByteBuffer buffer;
+
+ for (int i = 0; i < shapeNum; i++) {
+ //br.skipBytes(12);
+ bytes = new byte[8];
+ br.read(bytes);
+ buffer = ByteBuffer.wrap(bytes);
+ //br.skipBytes(12);
+ buffer.order(ByteOrder.BIG_ENDIAN);
+ RecordNum = buffer.getInt();
+ ContentLength = buffer.getInt();
+
+ bytes = new byte[ContentLength * 2];
+ br.read(bytes);
+ buffer = ByteBuffer.wrap(bytes);
+ buffer.order(ByteOrder.LITTLE_ENDIAN);
+ aShapeType = buffer.getInt();
+
+ PolygonZShape aSPG = new PolygonZShape();
+ Extent extent = new Extent();
+ extent.minX = buffer.getDouble();
+ extent.minY = buffer.getDouble();
+ extent.maxX = buffer.getDouble();
+ extent.maxY = buffer.getDouble();
+ aSPG.setExtent(extent);
+ aSPG.setPartNum(buffer.getInt());
+ int numPoints = buffer.getInt();
+ aSPG.parts = new int[aSPG.getPartNum()];
+ List points = new ArrayList<>();
+
+ //firstly read out parts begin pos in file
+ for (int j = 0; j < aSPG.getPartNum(); j++) {
+ aSPG.parts[j] = buffer.getInt();
+ }
+
+ //read out coordinates
+ for (int j = 0; j < numPoints; j++) {
+ x = buffer.getDouble();
+ y = buffer.getDouble();
+ PointD aPoint = new PointD();
+ aPoint.X = x;
+ aPoint.Y = y;
+ points.add(aPoint);
+ }
+
+ //Read Z
+ double zmin = buffer.getDouble();
+ double zmax = buffer.getDouble();
+ double[] zArray = new double[numPoints];
+ for (int j = 0; j < numPoints; j++) {
+ zArray[j] = buffer.getDouble();
+ }
+
+ //Read measure
+ double mmin = buffer.getDouble();
+ double mmax = buffer.getDouble();
+ double[] mArray = new double[numPoints];
+ for (int j = 0; j < numPoints; j++) {
+ mArray[j] = buffer.getDouble();
+ }
+
+ //Get pointZ list
+ List pointZs = new ArrayList<>();
+ for (int j = 0; j < numPoints; j++) {
+ pointZs.add(new PointZ(points.get(j).X, points.get(j).Y, zArray[j], mArray[j]));
+ }
+
+ aSPG.setPoints(pointZs);
+ aLayer.addShape(aSPG);
+ }
+
+ //Create legend scheme
+ aLayer.setLegendScheme(LegendManage.createSingleSymbolLegendScheme(ShapeTypes.Polygon, new Color(255, 251, 195), 1.0F));
+
+ return aLayer;
+ }
+
+ private static void loadShxFile(File shxFile) throws FileNotFoundException, IOException {
+ DataInputStream bridx = new DataInputStream(new BufferedInputStream(new FileInputStream(shxFile)));
+ long BytesSum = shxFile.length(); //Get file byte length
+ int shapeNum = (int) (BytesSum - 100) / 8; //Get total number of records
+ readHeader(bridx);
+
+ int OffSet = 0, ContentLength = 0;
+ for (int i = 0; i < shapeNum; i++) {
+ OffSet = swapByteOrder(bridx.readInt());
+ ContentLength = swapByteOrder(bridx.readInt());
+ }
+
+ bridx.close();
+ }
+
+// /**
+// * Load DBF data file
+// * @param shpFileName Shape file name
+// * @return Attribute table
+// * @throws Exception
+// */
+// public static AttributeTable loadDbfFile(String shpFileName) throws Exception{
+// AttributeTable attrTable = new AttributeTable();
+// attrTable.open(shpFileName);
+// attrTable.fill(attrTable.getNumRecords());
+//
+// return attrTable;
+// }
+
+ /**
+ * Load DBF data file
+ * @param shpFileName Shape file name
+ * @param encoding Encoding
+ * @return Attribute table
+ * @throws Exception
+ */
+ public static AttributeTable loadDbfFile(String shpFileName, String encoding) throws Exception{
+ AttributeTable attrTable = new AttributeTable();
+ attrTable.setEncoding(encoding);
+ attrTable.open(shpFileName);
+ attrTable.fill(attrTable.getNumRecords());
+
+ return attrTable;
+ }
+
+ /**
+ * Load projection file
+ * @param projFile Projection file
+ * @return Projection infomation
+ * @throws FileNotFoundException
+ * @throws IOException
+ */
+ public static ProjectionInfo loadProjFile(File projFile) throws FileNotFoundException, IOException {
+ BufferedReader sr = new BufferedReader(new FileReader(projFile));
+ String line;
+ StringBuilder buffer = new StringBuilder();
+ while ((line = sr.readLine()) != null) {
+ buffer.append(line);
+ }
+
+ String esriString = buffer.toString();
+ sr.close();
+
+ ProjectionInfo projInfo = ProjectionInfo.factoryESRI(esriString);
+
+ return projInfo;
+ }
+
+ /**
+ * Save shape file
+ * @param shpfilepath Shape file path
+ * @param aLayer Vector layer
+ * @return Boolean
+ * @throws java.io.IOException*/
+ public static boolean saveShapeFile(String shpfilepath, VectorLayer aLayer) throws IOException {
+ String shxfilepath = shpfilepath.replace(shpfilepath.substring(shpfilepath.lastIndexOf(".")), ".shx");
+ String dbffilepath = shpfilepath.replace(shpfilepath.substring(shpfilepath.lastIndexOf(".")), ".dbf");
+ String projFilePath = shpfilepath.replace(shpfilepath.substring(shpfilepath.lastIndexOf(".")), ".prj");
+
+ switch (aLayer.getShapeType()) {
+ case Point:
+ case PointZ:
+ case Polyline:
+ case PolylineZ:
+ case Polygon:
+ case PolygonZ:
+ writeShxFile(shxfilepath, aLayer);
+ writeShpFile(shpfilepath, aLayer);
+ writeDbfFile(dbffilepath, aLayer);
+ writeProjFile(projFilePath, aLayer);
+ return true;
+
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * Save shape file
+ * @param shpfilepath Shape file path
+ * @param aLayer Vector layer
+ * @param encoding Encoding
+ * @return Boolean
+ * @throws java.io.IOException*/
+ public static boolean saveShapeFile(String shpfilepath, VectorLayer aLayer, String encoding) throws IOException {
+ String shxfilepath = shpfilepath.replace(shpfilepath.substring(shpfilepath.lastIndexOf(".")), ".shx");
+ String dbffilepath = shpfilepath.replace(shpfilepath.substring(shpfilepath.lastIndexOf(".")), ".dbf");
+ String projFilePath = shpfilepath.replace(shpfilepath.substring(shpfilepath.lastIndexOf(".")), ".prj");
+
+ switch (aLayer.getShapeType()) {
+ case Point:
+ case PointZ:
+ case Polyline:
+ case PolylineZ:
+ case Polygon:
+ case PolygonZ:
+ writeShxFile(shxfilepath, aLayer);
+ writeShpFile(shpfilepath, aLayer);
+ writeDbfFile(dbffilepath, aLayer, encoding);
+ writeProjFile(projFilePath, aLayer);
+ return true;
+
+ default:
+ return false;
+ }
+ }
+
+ private static void writeShpFile(String shpfilepath, VectorLayer aLayer) throws FileNotFoundException, IOException {
+ File shpFile = new File(shpfilepath);
+ EndianDataOutputStream bw = new EndianDataOutputStream(new BufferedOutputStream(new FileOutputStream(shpFile)));
+
+ //Write header
+ int FileLength = getShpFileLength(aLayer);
+ writeHeader(bw, aLayer, FileLength);
+
+ //Write records
+ int RecordNumber;
+
+ for (int i = 0; i < aLayer.getShapeNum(); i++) {
+ Shape aShape = aLayer.getShapes().get(i);
+ RecordNumber = i + 1;
+ writeRecord(bw, RecordNumber, aShape, aLayer.getShapeType());
+ }
+
+ //Close
+ bw.close();
+ }
+
+ private static int getShpFileLength(VectorLayer aLayer) {
+ int fileLength = 50;
+
+ for (int i = 0; i < aLayer.getShapeNum(); i++) {
+ Shape aShape = aLayer.getShapes().get(i);
+ int cLen = getContentLength(aShape, aLayer.getShapeType());
+ fileLength += 4 + cLen;
+ }
+
+ return fileLength;
+ }
+
+ private static int getContentLength(Shape aShape, ShapeTypes aST) {
+ int contentLength = 0;
+ switch (aST) {
+ case Point:
+ contentLength = 2 + 4 * 2;
+ break;
+ case PointZ:
+ contentLength = 2 + 4 * 4;
+ break;
+ case Polyline:
+ PolylineShape aPLS = (PolylineShape) aShape;
+ contentLength = 2 + 4 * 4 + 2 + 2 + 2 * aPLS.getPartNum() + 4 * 2 * aPLS.getPointNum();
+ break;
+ case PolylineZ:
+ PolylineZShape aPLZS = (PolylineZShape) aShape;
+ contentLength = 2 + 4 * 4 + 2 + 2 + 2 * aPLZS.getPartNum() + 4 * 2 * aPLZS.getPointNum()
+ + 4 + 4 + 4 * aPLZS.getPointNum() + 4 + 4 + 4 * aPLZS.getPointNum();
+ break;
+ case Polygon:
+ PolygonShape aPGS = (PolygonShape) aShape;
+ contentLength = 2 + 4 * 4 + 2 + 2 + 2 * aPGS.getPartNum() + 4 * 2 * aPGS.getPointNum();
+ break;
+ case PolygonZ:
+ PolygonZShape aPGZS = (PolygonZShape) aShape;
+ contentLength = 2 + 4 * 4 + 2 + 2 + 2 * aPGZS.getPartNum() + 4 * 2 * aPGZS.getPointNum()
+ + 4 + 4 + 4 * aPGZS.getPointNum() + 4 + 4 + 4 * aPGZS.getPointNum();
+ break;
+ }
+
+ return contentLength;
+ }
+
+ private static void writeRecord(EndianDataOutputStream bw, int RecordNumber, Shape aShape, ShapeTypes aST) throws IOException {
+ int ContentLength, i;
+
+ ContentLength = getContentLength(aShape, aST);
+ bw.writeIntBE(RecordNumber);
+ bw.writeIntBE(ContentLength);
+ bw.writeIntLE(aST.getValue());
+ switch (aST) {
+ case Point:
+ PointShape aPS = (PointShape) aShape;
+ bw.writeDoubleLE(aPS.getPoint().X);
+ bw.writeDoubleLE(aPS.getPoint().Y);
+ break;
+ case Polyline:
+ PolylineShape aPLS = (PolylineShape) aShape;
+ bw.writeDoubleLE(aPLS.getExtent().minX);
+ bw.writeDoubleLE(aPLS.getExtent().minY);
+ bw.writeDoubleLE(aPLS.getExtent().maxX);
+ bw.writeDoubleLE(aPLS.getExtent().maxY);
+ bw.writeIntLE(aPLS.getPartNum());
+ bw.writeIntLE(aPLS.getPointNum());
+ for (i = 0; i < aPLS.getPartNum(); i++) {
+ bw.writeIntLE(aPLS.parts[i]);
+ }
+ for (i = 0; i < aPLS.getPointNum(); i++) {
+ bw.writeDoubleLE((aPLS.getPoints().get(i)).X);
+ bw.writeDoubleLE((aPLS.getPoints().get(i)).Y);
+ }
+ break;
+ case PolylineZ:
+ PolylineZShape aPLZS = (PolylineZShape) aShape;
+ bw.writeDoubleLE(aPLZS.getExtent().minX);
+ bw.writeDoubleLE(aPLZS.getExtent().minY);
+ bw.writeDoubleLE(aPLZS.getExtent().maxX);
+ bw.writeDoubleLE(aPLZS.getExtent().maxY);
+ bw.writeIntLE(aPLZS.getPartNum());
+ bw.writeIntLE(aPLZS.getPointNum());
+ for (i = 0; i < aPLZS.getPartNum(); i++) {
+ bw.writeIntLE(aPLZS.parts[i]);
+ }
+ for (i = 0; i < aPLZS.getPointNum(); i++) {
+ bw.writeDoubleLE((aPLZS.getPoints().get(i)).X);
+ bw.writeDoubleLE((aPLZS.getPoints().get(i)).Y);
+ }
+ bw.writeDoubleLE(aPLZS.getZRange()[0]);
+ bw.writeDoubleLE(aPLZS.getZRange()[1]);
+ for (i = 0; i < aPLZS.getPointNum(); i++) {
+ bw.writeDoubleLE(aPLZS.getZArray()[i]);
+ }
+ bw.writeDoubleLE(aPLZS.getMRange()[0]);
+ bw.writeDoubleLE(aPLZS.getMRange()[1]);
+ for (i = 0; i < aPLZS.getPointNum(); i++) {
+ bw.writeDoubleLE(aPLZS.getMArray()[i]);
+ }
+ break;
+ case Polygon:
+ PolygonShape aPGS = (PolygonShape) aShape;
+ bw.writeDoubleLE(aPGS.getExtent().minX);
+ bw.writeDoubleLE(aPGS.getExtent().minY);
+ bw.writeDoubleLE(aPGS.getExtent().maxX);
+ bw.writeDoubleLE(aPGS.getExtent().maxY);
+ bw.writeIntLE(aPGS.getPartNum());
+ bw.writeIntLE(aPGS.getPointNum());
+ for (i = 0; i < aPGS.getPartNum(); i++) {
+ bw.writeIntLE(aPGS.parts[i]);
+ }
+ for (i = 0; i < aPGS.getPointNum(); i++) {
+ bw.writeDoubleLE((aPGS.getPoints().get(i)).X);
+ bw.writeDoubleLE((aPGS.getPoints().get(i)).Y);
+ }
+ break;
+ case PolygonZ:
+ PolygonZShape aPGZS = (PolygonZShape) aShape;
+ bw.writeDoubleLE(aPGZS.getExtent().minX);
+ bw.writeDoubleLE(aPGZS.getExtent().minY);
+ bw.writeDoubleLE(aPGZS.getExtent().maxX);
+ bw.writeDoubleLE(aPGZS.getExtent().maxY);
+ bw.writeIntLE(aPGZS.getPartNum());
+ bw.writeIntLE(aPGZS.getPointNum());
+ for (i = 0; i < aPGZS.getPartNum(); i++) {
+ bw.writeIntLE(aPGZS.parts[i]);
+ }
+ for (i = 0; i < aPGZS.getPointNum(); i++) {
+ bw.writeDoubleLE((aPGZS.getPoints().get(i)).X);
+ bw.writeDoubleLE((aPGZS.getPoints().get(i)).Y);
+ }
+ bw.writeDoubleLE(aPGZS.getZRange()[0]);
+ bw.writeDoubleLE(aPGZS.getZRange()[1]);
+ for (i = 0; i < aPGZS.getPointNum(); i++) {
+ bw.writeDoubleLE(aPGZS.getZArray()[i]);
+ }
+ bw.writeDoubleLE(aPGZS.getMRange()[0]);
+ bw.writeDoubleLE(aPGZS.getMRange()[1]);
+ for (i = 0; i < aPGZS.getPointNum(); i++) {
+ bw.writeDoubleLE(aPGZS.getMArray()[i]);
+ }
+ break;
+ }
+ }
+
+ private static void writeHeader(EndianDataOutputStream bw, VectorLayer aLayer, int FileLength) throws IOException {
+ int i;
+ int FileCode = 9994;
+ //FileCode = swapByteOrder(FileCode);
+ int Unused = 0;
+ //Unused = swapByteOrder(Unused);
+ //FileLength = swapByteOrder(FileLength);
+ int Version = 1000;
+ int aShapeType = aLayer.getShapeType().getValue();
+
+ bw.writeIntBE(FileCode);
+ for (i = 0; i < 5; i++) {
+ bw.writeIntBE(Unused);
+ }
+ bw.writeIntBE(FileLength);
+ bw.writeIntLE(Version);
+ bw.writeIntLE(aShapeType);
+ bw.writeDoubleLE(aLayer.getExtent().minX);
+ bw.writeDoubleLE(aLayer.getExtent().minY);
+ bw.writeDoubleLE(aLayer.getExtent().maxX);
+ bw.writeDoubleLE(aLayer.getExtent().maxY);
+ for (i = 0; i < 4; i++) {
+ bw.writeDoubleLE(0.0);
+ }
+ }
+
+ private static void writeShxFile(String shxfilepath, VectorLayer aLayer) throws IOException {
+ File shxFile = new File(shxfilepath);
+ EndianDataOutputStream bw = new EndianDataOutputStream(new BufferedOutputStream(new FileOutputStream(shxFile)));
+
+ //Write header
+ int FileLength = aLayer.getShapeNum() * 4 + 50;
+ writeHeader(bw, aLayer, FileLength);
+
+ //Write content
+ int OffSet, ContentLength;
+ OffSet = 50;
+
+ for (int i = 0; i < aLayer.getShapeNum(); i++) {
+ Shape aShape = aLayer.getShapes().get(i);
+ ContentLength = getContentLength(aShape, aLayer.getShapeType());
+
+ bw.writeIntBE(OffSet);
+ bw.writeIntBE(ContentLength);
+
+ OffSet = OffSet + 4 + ContentLength;
+ }
+
+ //Close
+ bw.close();
+ }
+
+ private static void writeDbfFile(String dbffilepath, VectorLayer aLayer) {
+ aLayer.getAttributeTable().saveAs(dbffilepath, true);
+ }
+
+ private static void writeDbfFile(String dbffilepath, VectorLayer aLayer, String encoding) {
+ AttributeTable attTable = aLayer.getAttributeTable();
+ attTable.setEncoding(encoding);
+ attTable.saveAs(dbffilepath, true);
+ }
+
+ private static void writeProjFile(String projFilePath, VectorLayer aLayer) {
+ BufferedWriter sw = null;
+ try {
+ String esriString = aLayer.getProjInfo().toEsriString();
+ sw = new BufferedWriter(new FileWriter(new File(projFilePath)));
+ sw.write(esriString);
+ sw.flush();
+ sw.close();
+ } catch (IOException ex) {
+ Logger.getLogger(ShapeFileManage.class.getName()).log(Level.SEVERE, null, ex);
+ } finally {
+ try {
+ sw.close();
+ } catch (IOException ex) {
+ Logger.getLogger(ShapeFileManage.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+ }
+
+ /**
+ * Swaps the byte order of an int32
+ *
+ * @param i Integer
+ * @return Byte order swapped int
+ */
+ private static int swapByteOrder(int i) {
+ byte[] buffer = intToBytes(i);
+ return ((buffer[3] & 0xff) << 24) | ((buffer[2] & 0xff) << 16)
+ | ((buffer[1] & 0xff) << 8) | (buffer[0] & 0xff);
+ }
+
+ private static byte[] intToBytes(int i) {
+ byte[] result = new byte[4];
+ result[0] = (byte) ((i >> 24) & 0xFF);
+ result[1] = (byte) ((i >> 16) & 0xFF);
+ result[2] = (byte) ((i >> 8) & 0xFF);
+ result[3] = (byte) (i & 0xFF);
+ return result;
+ }
+
+ private static int bytesToInt(byte[] buffer){
+ return ((buffer[3] & 0xff) << 24) | ((buffer[2] & 0xff) << 16)
+ | ((buffer[1] & 0xff) << 8) | (buffer[0] & 0xff);
+ }
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/mapdata/geotiff/GeoTiff.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/mapdata/geotiff/GeoTiff.java
index fc348fb9..5a8ee712 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/mapdata/geotiff/GeoTiff.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/mapdata/geotiff/GeoTiff.java
@@ -28,12 +28,13 @@ import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
-import org.meteoinfo.math.ArrayMath;
+
import org.meteoinfo.data.GridArray;
import org.meteoinfo.data.mapdata.geotiff.compression.CompressionDecoder;
import org.meteoinfo.data.mapdata.geotiff.compression.DeflateCompression;
import org.meteoinfo.data.mapdata.geotiff.compression.LZWCompression;
import org.meteoinfo.global.DataConvert;
+import org.meteoinfo.math.ArrayMath;
import org.meteoinfo.ndarray.util.BigDecimalUtil;
import org.meteoinfo.projection.KnownCoordinateSystems;
import org.meteoinfo.projection.info.ProjectionInfo;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/mapdata/webmap/AbstractTileFactory.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/mapdata/webmap/AbstractTileFactory.java
index e0d1303e..2416282c 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/mapdata/webmap/AbstractTileFactory.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/mapdata/webmap/AbstractTileFactory.java
@@ -1,452 +1,452 @@
-package org.meteoinfo.data.mapdata.webmap;
-
-import java.awt.image.BufferedImage;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.ref.SoftReference;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.PriorityBlockingQueue;
-import java.util.concurrent.ThreadFactory;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.swing.SwingUtilities;
-
-import org.meteoinfo.global.util.GeoUtil;
-import org.meteoinfo.global.util.GraphicsUtilities;
-
-/**
- * The
- * AbstractTileFactory provides a basic implementation for the
- * TileFactory.
- */
-public abstract class AbstractTileFactory extends TileFactory {
-
- private static final Logger LOG = Logger.getLogger(AbstractTileFactory.class.getName());
-
- /**
- * Creates a new instance of DefaultTileFactory using the spcified
- * TileFactoryInfo
- *
- * @param info a TileFactoryInfo to configure this TileFactory
- */
- public AbstractTileFactory(TileFactoryInfo info) {
- super(info);
- }
- //private static final boolean doEagerLoading = true;
- private int threadPoolSize = 4;
- private ExecutorService service;
- //TODO the tile map should be static ALWAYS, regardless of the number
- //of GoogleTileFactories because each tile is, really, a singleton.
- private final Map tileMap = new HashMap<>();
- private TileCache cache = new TileCache();
-
- /**
- * Returns
- *
- * @param pixelCoordinate
- * @return
- */
- //public TilePoint getTileCoordinate(Point2D pixelCoordinate) {
- // return GeoUtil.getTileCoordinate(pixelCoordinate, getInfo());
- //}
- /**
- * Returns the tile that is located at the given tilePoint for this zoom.
- * For example, if getMapSize() returns 10x20 for this zoom, and the
- * tilePoint is (3,5), then the appropriate tile will be located and
- * returned.
- *
- * @param x X index
- * @param y Y index
- * @param zoom Zoom value
- * @return Tile
- */
- @Override
- public Tile getTile(int x, int y, int zoom) {
- return getTile(x, y, zoom, true);
- }
-
- private Tile getTile(int tpx, int tpy, int zoom, boolean eagerLoad) {
- //wrap the tiles horizontally --> mod the X with the max width
- //and use that
- int tileX = tpx;//tilePoint.getX();
- int numTilesWide = (int) getMapSize(zoom).getWidth();
- if (tileX < 0) {
- tileX = numTilesWide - (Math.abs(tileX) % numTilesWide);
- }
-
- tileX = tileX % numTilesWide;
- int tileY = tpy;
- //TilePoint tilePoint = new TilePoint(tileX, tpy);
- String url = getInfo().getTileUrl(tileX, tileY, zoom);//tilePoint);
- //System.out.println("loading: " + url);
-
-
- Tile.Priority pri = Tile.Priority.High;
- if (!eagerLoad) {
- pri = Tile.Priority.Low;
- }
- Tile tile = null;
- //System.out.println("testing for validity: " + tilePoint + " zoom = " + zoom);
- if (!tileMap.containsKey(url)) {
- if (!GeoUtil.isValidTile(tileX, tileY, zoom, getInfo())) {
- tile = new Tile(tileX, tileY, zoom);
- } else {
- tile = new Tile(tileX, tileY, zoom, url, pri, this);
- //load(tile);
- startLoading(tile);
- }
- tileMap.put(url, tile);
- } else {
- tile = tileMap.get(url);
- // if its in the map but is low and isn't loaded yet
- // but we are in high mode
- if (tile.getPriority() == Tile.Priority.Low && eagerLoad && !tile.isLoaded()) {
- //System.out.println("in high mode and want a low");
- //tile.promote();
- promote(tile);
- }
- }
-
- /*
- if (eagerLoad && doEagerLoading) {
- for (int i = 0; i<1; i++) {
- for (int j = 0; j<1; j++) {
- // preload the 4 tiles under the current one
- if(zoom > 0) {
- eagerlyLoad(tilePoint.getX()*2, tilePoint.getY()*2, zoom-1);
- eagerlyLoad(tilePoint.getX()*2+1, tilePoint.getY()*2, zoom-1);
- eagerlyLoad(tilePoint.getX()*2, tilePoint.getY()*2+1, zoom-1);
- eagerlyLoad(tilePoint.getX()*2+1, tilePoint.getY()*2+1, zoom-1);
- }
- }
- }
- }*/
-
-
- return tile;
- }
-
- /*
- private void eagerlyLoad(int x, int y, int zoom) {
- TilePoint t1 = new TilePoint(x,y);
- if(!isLoaded(t1,zoom)) {
- getTile(t1,zoom,false);
- }
- }
- */
- // private boolean isLoaded(int x, int y, int zoom) {
- // String url = getInfo().getTileUrl(zoom,x,y);
- // return tileMap.containsKey(url);
- // }
- public TileCache getTileCache() {
- return cache;
- }
-
- public void setTileCache(TileCache cache) {
- this.cache = cache;
- }
- /**
- * ==== threaded tile loading stuff ===
- */
- /**
- * Thread pool for loading the tiles
- */
- private static final BlockingQueue tileQueue = new PriorityBlockingQueue<>(5,
- new Comparator() {
- @Override
- public int compare(Tile o1, Tile o2) {
- if (o1.getPriority() == Tile.Priority.Low && o2.getPriority() == Tile.Priority.High) {
- return 1;
- }
- if (o1.getPriority() == Tile.Priority.High && o2.getPriority() == Tile.Priority.Low) {
- return -1;
- }
- return 0;
-
- }
-
- @Override
- public boolean equals(Object obj) {
- return obj == this;
- }
- });
-
- /**
- * Subclasses may override this method to provide their own executor
- * services. This method will be called each time a tile needs to be loaded.
- * Implementations should cache the ExecutorService when possible.
- *
- * @return ExecutorService to load tiles with
- */
- protected synchronized ExecutorService getService() {
- if (service == null) {
- //System.out.println("creating an executor service with a threadpool of size " + threadPoolSize);
- service = Executors.newFixedThreadPool(threadPoolSize, new ThreadFactory() {
- private int count = 0;
-
- @Override
- public Thread newThread(Runnable r) {
- Thread t = new Thread(r, "tile-pool-" + count++);
- t.setPriority(Thread.MIN_PRIORITY);
- t.setDaemon(true);
- return t;
- }
- });
- }
- return service;
- }
-
- /**
- * Set the number of threads to use for loading the tiles. This controls the
- * number of threads used by the ExecutorService returned from getService().
- * Note, this method should be called before loading the first tile. Calls
- * after the first tile are loaded will have no effect by default.
- *
- * @param size
- */
- public void setThreadPoolSize(int size) {
- if (size <= 0) {
- throw new IllegalArgumentException("size invalid: " + size + ". The size of the threadpool must be greater than 0.");
- }
- threadPoolSize = size;
- }
-
- @SuppressWarnings("unchecked")
- @Override
- protected synchronized void startLoading(Tile tile) {
- if (tile.isLoading()) {
- System.out.println("already loading. bailing");
- return;
- }
- tile.setLoading(true);
- try {
- tileQueue.put(tile);
- getService().submit(createTileRunner(tile));
- } catch (Exception ex) {
- ex.printStackTrace();
- }
- }
-
- @Override
- public void load(Tile tile) {
- /*
- * 3 strikes and you're out. Attempt to load the url. If it fails,
- * decrement the number of tries left and try again. Log failures.
- * If I run out of try s just get out. This way, if there is some
- * kind of serious failure, I can get out and let other tiles
- * try to load.
- */
- //final Tile tile = tileQueue.remove();
-
- int trys = 3;
- while (!tile.isLoaded() && trys > 0) {
- try {
- BufferedImage img = null;
- URI uri = getURI(tile);
- img = cache.get(uri);
- if (img == null) {
- byte[] bimg = cacheInputStream(uri.toURL());
- img = GraphicsUtilities.loadCompatibleImage(new ByteArrayInputStream(bimg));//ImageIO.read(new URL(tile.url));
- cache.put(uri, bimg, img);
- img = cache.get(uri);
- }
- if (img == null) {
- System.out.println("error loading: " + uri);
- LOG.log(Level.INFO, "Failed to load: " + uri);
- trys--;
- } else {
- final BufferedImage i = img;
- tile.image = new SoftReference<>(i);
- tile.setLoaded(true);
- }
- } catch (OutOfMemoryError memErr) {
- cache.needMoreMemory();
- } catch (Throwable e) {
- LOG.log(Level.SEVERE,
- "Failed to load a tile at url: " + tile.getURL() + ", retrying", e);
- //temp
- System.err.println("Failed to load a tile at url: " + tile.getURL());
- e.printStackTrace();
- ///temp
- Object oldError = tile.getError();
- tile.setError(e);
- tile.firePropertyChangeOnEDT("loadingError", oldError, e);
- if (trys == 0) {
- tile.firePropertyChangeOnEDT("unrecoverableError", null, e);
- } else {
- trys--;
- }
- }
- }
- tile.setLoading(false);
- }
-
- /**
- * Gets the full URI of a tile.
- *
- * @param tile
- * @throws java.net.URISyntaxException
- * @return URI
- */
- protected URI getURI(Tile tile) throws URISyntaxException {
- if (tile.getURL() == null) {
- return null;
- }
- return new URI(tile.getURL());
- }
-
- private byte[] cacheInputStream(URL url) throws IOException {
- InputStream ins = url.openStream();
- ByteArrayOutputStream bout = new ByteArrayOutputStream();
- byte[] buf = new byte[256];
- while (true) {
- int n = ins.read(buf);
- if (n == -1) {
- break;
- }
- bout.write(buf, 0, n);
- }
- return bout.toByteArray();
- }
-
- /**
- * Subclasses can override this if they need custom TileRunners for some
- * reason
- *
- * @param tile Tile
- * @return Runnable
- */
- protected Runnable createTileRunner(Tile tile) {
- return new TileRunner();
- }
-
- /**
- * Increase the priority of this tile so it will be loaded sooner.
- * @param tile Tile
- */
- public synchronized void promote(Tile tile) {
- if (tileQueue.contains(tile)) {
- try {
- tileQueue.remove(tile);
- tile.setPriority(Tile.Priority.High);
- tileQueue.put(tile);
- } catch (Exception ex) {
- ex.printStackTrace();
- }
- }
- }
-
- /**
- * An inner class which actually loads the tiles. Used by the thread queue.
- * Subclasses can override this if necessary.
- */
- private class TileRunner implements Runnable {
- //private Tile tile;
- //private BlockingQueue tileQueue;
-
- //public TileRunner(BlockingQueue tileQueue) {
- //this.tileQueue = tileQueue;
- //this.tile = tile;
- //}
- /**
- * Gets the full URI of a tile.
- *
- * @param tile
- * @throws java.net.URISyntaxException
- * @return
- */
- protected URI getURI(Tile tile) throws URISyntaxException {
- if (tile.getURL() == null) {
- return null;
- }
- return new URI(tile.getURL());
- }
-
- /**
- * implementation of the Runnable interface.
- */
- @Override
- public void run() {
- /*
- * 3 strikes and you're out. Attempt to load the url. If it fails,
- * decrement the number of tries left and try again. Log failures.
- * If I run out of try s just get out. This way, if there is some
- * kind of serious failure, I can get out and let other tiles
- * try to load.
- */
- final Tile tile = tileQueue.remove();
-
- int trys = 3;
- while (!tile.isLoaded() && trys > 0) {
- try {
- BufferedImage img = null;
- URI uri = getURI(tile);
- img = cache.get(uri);
- if (img == null) {
- byte[] bimg = cacheInputStream(uri.toURL());
- img = GraphicsUtilities.loadCompatibleImage(new ByteArrayInputStream(bimg));//ImageIO.read(new URL(tile.url));
- cache.put(uri, bimg, img);
- img = cache.get(uri);
- }
- if (img == null) {
- System.out.println("error loading: " + uri);
- LOG.log(Level.INFO, "Failed to load: " + uri);
- trys--;
- } else {
- final BufferedImage i = img;
- SwingUtilities.invokeAndWait(new Runnable() {
- @Override
- public void run() {
- tile.image = new SoftReference<>(i);
- tile.setLoaded(true);
- }
- });
- }
- } catch (OutOfMemoryError memErr) {
- cache.needMoreMemory();
- } catch (Throwable e) {
- LOG.log(Level.SEVERE,
- "Failed to load a tile at url: " + tile.getURL() + ", retrying", e);
- //temp
- System.err.println("Failed to load a tile at url: " + tile.getURL());
- e.printStackTrace();
- ///temp
- Object oldError = tile.getError();
- tile.setError(e);
- tile.firePropertyChangeOnEDT("loadingError", oldError, e);
- if (trys == 0) {
- tile.firePropertyChangeOnEDT("unrecoverableError", null, e);
- } else {
- trys--;
- }
- }
- }
- tile.setLoading(false);
- }
-
- private byte[] cacheInputStream(URL url) throws IOException {
- InputStream ins = url.openStream();
- ByteArrayOutputStream bout = new ByteArrayOutputStream();
- byte[] buf = new byte[256];
- while (true) {
- int n = ins.read(buf);
- if (n == -1) {
- break;
- }
- bout.write(buf, 0, n);
- }
- return bout.toByteArray();
- }
- }
-}
+package org.meteoinfo.data.mapdata.webmap;
+
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.ref.SoftReference;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.PriorityBlockingQueue;
+import java.util.concurrent.ThreadFactory;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.swing.SwingUtilities;
+
+import org.meteoinfo.common.util.GraphicsUtilities;
+import org.meteoinfo.global.util.GeoUtil;
+
+/**
+ * The
+ * AbstractTileFactory provides a basic implementation for the
+ * TileFactory.
+ */
+public abstract class AbstractTileFactory extends TileFactory {
+
+ private static final Logger LOG = Logger.getLogger(AbstractTileFactory.class.getName());
+
+ /**
+ * Creates a new instance of DefaultTileFactory using the spcified
+ * TileFactoryInfo
+ *
+ * @param info a TileFactoryInfo to configure this TileFactory
+ */
+ public AbstractTileFactory(TileFactoryInfo info) {
+ super(info);
+ }
+ //private static final boolean doEagerLoading = true;
+ private int threadPoolSize = 4;
+ private ExecutorService service;
+ //TODO the tile map should be static ALWAYS, regardless of the number
+ //of GoogleTileFactories because each tile is, really, a singleton.
+ private final Map tileMap = new HashMap<>();
+ private TileCache cache = new TileCache();
+
+ /**
+ * Returns
+ *
+ * @param pixelCoordinate
+ * @return
+ */
+ //public TilePoint getTileCoordinate(Point2D pixelCoordinate) {
+ // return GeoUtil.getTileCoordinate(pixelCoordinate, getInfo());
+ //}
+ /**
+ * Returns the tile that is located at the given tilePoint for this zoom.
+ * For example, if getMapSize() returns 10x20 for this zoom, and the
+ * tilePoint is (3,5), then the appropriate tile will be located and
+ * returned.
+ *
+ * @param x X index
+ * @param y Y index
+ * @param zoom Zoom value
+ * @return Tile
+ */
+ @Override
+ public Tile getTile(int x, int y, int zoom) {
+ return getTile(x, y, zoom, true);
+ }
+
+ private Tile getTile(int tpx, int tpy, int zoom, boolean eagerLoad) {
+ //wrap the tiles horizontally --> mod the X with the max width
+ //and use that
+ int tileX = tpx;//tilePoint.getX();
+ int numTilesWide = (int) getMapSize(zoom).getWidth();
+ if (tileX < 0) {
+ tileX = numTilesWide - (Math.abs(tileX) % numTilesWide);
+ }
+
+ tileX = tileX % numTilesWide;
+ int tileY = tpy;
+ //TilePoint tilePoint = new TilePoint(tileX, tpy);
+ String url = getInfo().getTileUrl(tileX, tileY, zoom);//tilePoint);
+ //System.out.println("loading: " + url);
+
+
+ Tile.Priority pri = Tile.Priority.High;
+ if (!eagerLoad) {
+ pri = Tile.Priority.Low;
+ }
+ Tile tile = null;
+ //System.out.println("testing for validity: " + tilePoint + " zoom = " + zoom);
+ if (!tileMap.containsKey(url)) {
+ if (!GeoUtil.isValidTile(tileX, tileY, zoom, getInfo())) {
+ tile = new Tile(tileX, tileY, zoom);
+ } else {
+ tile = new Tile(tileX, tileY, zoom, url, pri, this);
+ //load(tile);
+ startLoading(tile);
+ }
+ tileMap.put(url, tile);
+ } else {
+ tile = tileMap.get(url);
+ // if its in the map but is low and isn't loaded yet
+ // but we are in high mode
+ if (tile.getPriority() == Tile.Priority.Low && eagerLoad && !tile.isLoaded()) {
+ //System.out.println("in high mode and want a low");
+ //tile.promote();
+ promote(tile);
+ }
+ }
+
+ /*
+ if (eagerLoad && doEagerLoading) {
+ for (int i = 0; i<1; i++) {
+ for (int j = 0; j<1; j++) {
+ // preload the 4 tiles under the current one
+ if(zoom > 0) {
+ eagerlyLoad(tilePoint.getX()*2, tilePoint.getY()*2, zoom-1);
+ eagerlyLoad(tilePoint.getX()*2+1, tilePoint.getY()*2, zoom-1);
+ eagerlyLoad(tilePoint.getX()*2, tilePoint.getY()*2+1, zoom-1);
+ eagerlyLoad(tilePoint.getX()*2+1, tilePoint.getY()*2+1, zoom-1);
+ }
+ }
+ }
+ }*/
+
+
+ return tile;
+ }
+
+ /*
+ private void eagerlyLoad(int x, int y, int zoom) {
+ TilePoint t1 = new TilePoint(x,y);
+ if(!isLoaded(t1,zoom)) {
+ getTile(t1,zoom,false);
+ }
+ }
+ */
+ // private boolean isLoaded(int x, int y, int zoom) {
+ // String url = getInfo().getTileUrl(zoom,x,y);
+ // return tileMap.containsKey(url);
+ // }
+ public TileCache getTileCache() {
+ return cache;
+ }
+
+ public void setTileCache(TileCache cache) {
+ this.cache = cache;
+ }
+ /**
+ * ==== threaded tile loading stuff ===
+ */
+ /**
+ * Thread pool for loading the tiles
+ */
+ private static final BlockingQueue tileQueue = new PriorityBlockingQueue<>(5,
+ new Comparator() {
+ @Override
+ public int compare(Tile o1, Tile o2) {
+ if (o1.getPriority() == Tile.Priority.Low && o2.getPriority() == Tile.Priority.High) {
+ return 1;
+ }
+ if (o1.getPriority() == Tile.Priority.High && o2.getPriority() == Tile.Priority.Low) {
+ return -1;
+ }
+ return 0;
+
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj == this;
+ }
+ });
+
+ /**
+ * Subclasses may override this method to provide their own executor
+ * services. This method will be called each time a tile needs to be loaded.
+ * Implementations should cache the ExecutorService when possible.
+ *
+ * @return ExecutorService to load tiles with
+ */
+ protected synchronized ExecutorService getService() {
+ if (service == null) {
+ //System.out.println("creating an executor service with a threadpool of size " + threadPoolSize);
+ service = Executors.newFixedThreadPool(threadPoolSize, new ThreadFactory() {
+ private int count = 0;
+
+ @Override
+ public Thread newThread(Runnable r) {
+ Thread t = new Thread(r, "tile-pool-" + count++);
+ t.setPriority(Thread.MIN_PRIORITY);
+ t.setDaemon(true);
+ return t;
+ }
+ });
+ }
+ return service;
+ }
+
+ /**
+ * Set the number of threads to use for loading the tiles. This controls the
+ * number of threads used by the ExecutorService returned from getService().
+ * Note, this method should be called before loading the first tile. Calls
+ * after the first tile are loaded will have no effect by default.
+ *
+ * @param size
+ */
+ public void setThreadPoolSize(int size) {
+ if (size <= 0) {
+ throw new IllegalArgumentException("size invalid: " + size + ". The size of the threadpool must be greater than 0.");
+ }
+ threadPoolSize = size;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected synchronized void startLoading(Tile tile) {
+ if (tile.isLoading()) {
+ System.out.println("already loading. bailing");
+ return;
+ }
+ tile.setLoading(true);
+ try {
+ tileQueue.put(tile);
+ getService().submit(createTileRunner(tile));
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ @Override
+ public void load(Tile tile) {
+ /*
+ * 3 strikes and you're out. Attempt to load the url. If it fails,
+ * decrement the number of tries left and try again. Log failures.
+ * If I run out of try s just get out. This way, if there is some
+ * kind of serious failure, I can get out and let other tiles
+ * try to load.
+ */
+ //final Tile tile = tileQueue.remove();
+
+ int trys = 3;
+ while (!tile.isLoaded() && trys > 0) {
+ try {
+ BufferedImage img = null;
+ URI uri = getURI(tile);
+ img = cache.get(uri);
+ if (img == null) {
+ byte[] bimg = cacheInputStream(uri.toURL());
+ img = GraphicsUtilities.loadCompatibleImage(new ByteArrayInputStream(bimg));//ImageIO.read(new URL(tile.url));
+ cache.put(uri, bimg, img);
+ img = cache.get(uri);
+ }
+ if (img == null) {
+ System.out.println("error loading: " + uri);
+ LOG.log(Level.INFO, "Failed to load: " + uri);
+ trys--;
+ } else {
+ final BufferedImage i = img;
+ tile.image = new SoftReference<>(i);
+ tile.setLoaded(true);
+ }
+ } catch (OutOfMemoryError memErr) {
+ cache.needMoreMemory();
+ } catch (Throwable e) {
+ LOG.log(Level.SEVERE,
+ "Failed to load a tile at url: " + tile.getURL() + ", retrying", e);
+ //temp
+ System.err.println("Failed to load a tile at url: " + tile.getURL());
+ e.printStackTrace();
+ ///temp
+ Object oldError = tile.getError();
+ tile.setError(e);
+ tile.firePropertyChangeOnEDT("loadingError", oldError, e);
+ if (trys == 0) {
+ tile.firePropertyChangeOnEDT("unrecoverableError", null, e);
+ } else {
+ trys--;
+ }
+ }
+ }
+ tile.setLoading(false);
+ }
+
+ /**
+ * Gets the full URI of a tile.
+ *
+ * @param tile
+ * @throws java.net.URISyntaxException
+ * @return URI
+ */
+ protected URI getURI(Tile tile) throws URISyntaxException {
+ if (tile.getURL() == null) {
+ return null;
+ }
+ return new URI(tile.getURL());
+ }
+
+ private byte[] cacheInputStream(URL url) throws IOException {
+ InputStream ins = url.openStream();
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ byte[] buf = new byte[256];
+ while (true) {
+ int n = ins.read(buf);
+ if (n == -1) {
+ break;
+ }
+ bout.write(buf, 0, n);
+ }
+ return bout.toByteArray();
+ }
+
+ /**
+ * Subclasses can override this if they need custom TileRunners for some
+ * reason
+ *
+ * @param tile Tile
+ * @return Runnable
+ */
+ protected Runnable createTileRunner(Tile tile) {
+ return new TileRunner();
+ }
+
+ /**
+ * Increase the priority of this tile so it will be loaded sooner.
+ * @param tile Tile
+ */
+ public synchronized void promote(Tile tile) {
+ if (tileQueue.contains(tile)) {
+ try {
+ tileQueue.remove(tile);
+ tile.setPriority(Tile.Priority.High);
+ tileQueue.put(tile);
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ * An inner class which actually loads the tiles. Used by the thread queue.
+ * Subclasses can override this if necessary.
+ */
+ private class TileRunner implements Runnable {
+ //private Tile tile;
+ //private BlockingQueue tileQueue;
+
+ //public TileRunner(BlockingQueue tileQueue) {
+ //this.tileQueue = tileQueue;
+ //this.tile = tile;
+ //}
+ /**
+ * Gets the full URI of a tile.
+ *
+ * @param tile
+ * @throws java.net.URISyntaxException
+ * @return
+ */
+ protected URI getURI(Tile tile) throws URISyntaxException {
+ if (tile.getURL() == null) {
+ return null;
+ }
+ return new URI(tile.getURL());
+ }
+
+ /**
+ * implementation of the Runnable interface.
+ */
+ @Override
+ public void run() {
+ /*
+ * 3 strikes and you're out. Attempt to load the url. If it fails,
+ * decrement the number of tries left and try again. Log failures.
+ * If I run out of try s just get out. This way, if there is some
+ * kind of serious failure, I can get out and let other tiles
+ * try to load.
+ */
+ final Tile tile = tileQueue.remove();
+
+ int trys = 3;
+ while (!tile.isLoaded() && trys > 0) {
+ try {
+ BufferedImage img = null;
+ URI uri = getURI(tile);
+ img = cache.get(uri);
+ if (img == null) {
+ byte[] bimg = cacheInputStream(uri.toURL());
+ img = GraphicsUtilities.loadCompatibleImage(new ByteArrayInputStream(bimg));//ImageIO.read(new URL(tile.url));
+ cache.put(uri, bimg, img);
+ img = cache.get(uri);
+ }
+ if (img == null) {
+ System.out.println("error loading: " + uri);
+ LOG.log(Level.INFO, "Failed to load: " + uri);
+ trys--;
+ } else {
+ final BufferedImage i = img;
+ SwingUtilities.invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ tile.image = new SoftReference<>(i);
+ tile.setLoaded(true);
+ }
+ });
+ }
+ } catch (OutOfMemoryError memErr) {
+ cache.needMoreMemory();
+ } catch (Throwable e) {
+ LOG.log(Level.SEVERE,
+ "Failed to load a tile at url: " + tile.getURL() + ", retrying", e);
+ //temp
+ System.err.println("Failed to load a tile at url: " + tile.getURL());
+ e.printStackTrace();
+ ///temp
+ Object oldError = tile.getError();
+ tile.setError(e);
+ tile.firePropertyChangeOnEDT("loadingError", oldError, e);
+ if (trys == 0) {
+ tile.firePropertyChangeOnEDT("unrecoverableError", null, e);
+ } else {
+ trys--;
+ }
+ }
+ }
+ tile.setLoading(false);
+ }
+
+ private byte[] cacheInputStream(URL url) throws IOException {
+ InputStream ins = url.openStream();
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ byte[] buf = new byte[256];
+ while (true) {
+ int n = ins.read(buf);
+ if (n == -1) {
+ break;
+ }
+ bout.write(buf, 0, n);
+ }
+ return bout.toByteArray();
+ }
+ }
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/mathparser/MathParser.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/mathparser/MathParser.java
index b3489cc1..418d8040 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/mathparser/MathParser.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/mathparser/MathParser.java
@@ -1,331 +1,330 @@
-/*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.meteoinfo.data.mathparser;
-
-import java.beans.Expression;
-import java.io.IOException;
-import java.io.StringReader;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Queue;
-import java.util.Stack;
-import org.meteoinfo.data.meteodata.MeteoDataInfo;
-import org.meteoinfo.global.MIMath;
-
-/**
- *
- * @author yaqiang
- */
-public class MathParser {
- //
-
- private boolean _isGridData;
- private StringBuilder _buffer = new StringBuilder();
- private Stack _symbolStack = new Stack();
- private Queue _expressionQueue = new LinkedList();
- private Map _expressionCache = new HashMap();
- private Stack _calculationStack = new Stack();
- private Stack _parameters = new Stack();
- private List _variables = new ArrayList();
- private StringReader _expressionReader;
- private MeteoDataInfo _meteoDataInfo = null;
- //
- //
-
- /**
- * Constructor
- */
- public MathParser() {
- }
-
- /**
- * Constructor
- *
- * @param aDataInfo MeteoDataInfo
- */
- public MathParser(MeteoDataInfo aDataInfo) {
- _meteoDataInfo = aDataInfo;
- _isGridData = aDataInfo.isGridData();
- _variables = aDataInfo.getDataInfo().getVariableNames();
- }
- //
- //
- //
- //
-
- /**
- * Evaluates the specified expression
- *
- * @param expression The expression to evaluate
- * @return The evaluated result
- */
- public Object evaluate(String expression) throws ParseException, IOException {
- if (expression == null || expression.isEmpty()) {
- throw new java.lang.IllegalArgumentException("expression");
- }
-
- _expressionReader = new StringReader(expression);
- _symbolStack.clear();
- _expressionQueue.clear();
-
- parseExpressionToQueue();
-
- Object result = calculateFromQueue();
-
- //_variables[AnswerVariable] = result;
- return result;
- }
-
- private void parseExpressionToQueue() throws ParseException, IOException {
- int ic;
- char c;
- while ((ic = _expressionReader.read()) != -1) {
- c = (char) ic;
- if (Character.isWhitespace(c)) {
- continue;
- }
- if (tryNumber(c)) {
- continue;
- }
- if (tryString(c)) {
- continue;
- }
- if (tryStartGroup(c)) {
- continue;
- }
- if (tryOperator(c)) {
- continue;
- }
- if (tryEndGroup(c)) {
- continue;
- }
- //if (TryConvert(c))
- // continue;
- throw new ParseException("Invalid character encountered" + c);
- }
-
- processSymbolStack();
- }
-
- private boolean tryNumber(char c) throws IOException, ParseException {
- boolean isNumber = NumberExpression.isNumber(c);
- boolean isNegative = false;
- if (NumberExpression.isNegativeSign(c)) {
- if (_expressionQueue.size() == 0) {
- isNegative = true;
- } else if (_expressionQueue.size() > 0 && _symbolStack.size() > 0) {
- if (((String) _symbolStack.peek()).equals("(")) {
- isNegative = true;
- }
- }
- }
-
- if (!isNumber && !isNegative) {
- return false;
- }
-
- _buffer.setLength(0);
- _buffer.append(c);
-
- _expressionReader.mark(1);
- char p = (char) _expressionReader.read();
- while (NumberExpression.isNumber(p)) {
- _buffer.append(p);
- _expressionReader.mark(1);
- p = (char) _expressionReader.read();
- }
- _expressionReader.reset();
-
- double value;
- try {
- value = Double.parseDouble(_buffer.toString());
- } catch (Exception e) {
- throw new ParseException("Invalid number format: " + _buffer);
- }
-
- NumberExpression expression = new NumberExpression(value);
- _expressionQueue.offer(expression);
-
- return true;
- }
-
- private boolean tryString(char c) throws IOException, ParseException {
- if (!Character.isLetter(c)) {
- return false;
- }
-
- _buffer.setLength(0);
- _buffer.append(c);
-
- _expressionReader.mark(1);
- char p = (char) _expressionReader.read();
- while (Character.isLetterOrDigit(p) || p == '_' || p == '@' || p == '.') {
- _buffer.append(p);
- _expressionReader.mark(1);
- p = (char) _expressionReader.read();
- }
- _expressionReader.reset();
-
- if (_variables.contains(_buffer.toString())) {
- Object value = getVariableValue(_buffer.toString());
- NumberExpression expression = new NumberExpression(value);
- _expressionQueue.offer(expression);
-
- return true;
- }
-
- if (FunctionExpression.isFunction(_buffer.toString())) {
- _symbolStack.push(_buffer.toString());
- return true;
- }
-
- throw new ParseException("Invalid variable: " + _buffer);
- }
-
- private boolean tryStartGroup(char c) {
- if (c != '(') {
- return false;
- }
-
- _symbolStack.push(String.valueOf(c));
- return true;
- }
-
- private boolean tryOperator(char c) throws ParseException {
- if (!OperatorExpression.isSymbol(c)) {
- return false;
- }
-
- boolean repeat;
- String s = String.valueOf(c);
-
- do {
- String p = _symbolStack.size() == 0 ? "" : _symbolStack.peek();
- repeat = false;
- if (_symbolStack.size() == 0) {
- _symbolStack.push(s);
- } else if (p.equals("(")) {
- _symbolStack.push(s);
- } else if (precedence(s) > precedence(p)) {
- _symbolStack.push(s);
- } else {
- IExpression e = getExpressionFromSymbol(_symbolStack.pop());
- _expressionQueue.offer(e);
- repeat = true;
- }
- } while (repeat);
-
- return true;
- }
-
- private boolean tryEndGroup(char c) throws ParseException {
- if (c != ')') {
- return false;
- }
-
- boolean ok = false;
-
- while (_symbolStack.size() > 0) {
- String p = _symbolStack.pop();
- if (p.equals("(")) {
- ok = true;
- break;
- }
-
- IExpression e = getExpressionFromSymbol(p);
- _expressionQueue.offer(e);
- }
-
- if (!ok) {
- throw new ParseException("Unbalance parenthese");
- }
-
- return true;
- }
-
- private void processSymbolStack() throws ParseException {
- while (_symbolStack.size() > 0) {
- String p = _symbolStack.pop();
- if (p.length() == 1 && p.equals("(")) {
- throw new ParseException("Unbalance parenthese");
- }
-
- IExpression e = getExpressionFromSymbol(p);
- _expressionQueue.offer(e);
- }
- }
-
- private static int precedence(String c) {
- String s = c.substring(0, 1);
- if (c.length() == 1 && s.equals("*") || s.equals("/") || s.equals("%")) {
- return 2;
- }
-
- return 1;
- }
-
- private IExpression getExpressionFromSymbol(String p) throws ParseException {
- IExpression e;
-
- if (_expressionCache.containsKey(p)) {
- e = _expressionCache.get(p);
- } else if (OperatorExpression.isSymbol(p)) {
- e = new OperatorExpression(p);
- _expressionCache.put(p, e);
- } else if (FunctionExpression.isFunction(p)) {
- e = new FunctionExpression(p, false);
- _expressionCache.put(p, e);
- } //else if (ConvertExpression.IsConvertExpression(p))
- //{
- // e = new ConvertExpression(p);
- // _expressionCache.Add(p, e);
- //}
- else {
- throw new ParseException("Invalid symbol on stack" + p);
- }
-
- return e;
- }
-
- private Object calculateFromQueue() throws ParseException {
- Object result;
- _calculationStack.clear();
-
- for (IExpression expression : _expressionQueue) {
- if (_calculationStack.size() < expression.getArgumentCount()) {
- throw new ParseException("Not enough numbers" + expression);
- }
-
- _parameters.clear();
- for (int i = 0; i < expression.getArgumentCount(); i++) {
- _parameters.push(_calculationStack.pop());
- }
-
- Object[] parameters = _parameters.toArray();
- MIMath.arrayReverse(parameters);
- _calculationStack.push(expression.evaluate(parameters));
- }
-
- result = _calculationStack.pop();
- return result;
- }
-
- private Object getVariableValue(String varName) {
- if (_meteoDataInfo == null) {
- return 100;
- } else {
- if (_isGridData) {
- return _meteoDataInfo.getGridData(varName);
- } else {
- return _meteoDataInfo.getStationData(varName);
- }
- }
- }
- //
-}
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.meteoinfo.data.mathparser;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Queue;
+import java.util.Stack;
+
+import org.meteoinfo.common.MIMath;
+import org.meteoinfo.data.meteodata.MeteoDataInfo;
+
+/**
+ *
+ * @author yaqiang
+ */
+public class MathParser {
+ //
+
+ private boolean _isGridData;
+ private StringBuilder _buffer = new StringBuilder();
+ private Stack _symbolStack = new Stack();
+ private Queue _expressionQueue = new LinkedList();
+ private Map _expressionCache = new HashMap();
+ private Stack _calculationStack = new Stack();
+ private Stack _parameters = new Stack();
+ private List _variables = new ArrayList();
+ private StringReader _expressionReader;
+ private MeteoDataInfo _meteoDataInfo = null;
+ //
+ //
+
+ /**
+ * Constructor
+ */
+ public MathParser() {
+ }
+
+ /**
+ * Constructor
+ *
+ * @param aDataInfo MeteoDataInfo
+ */
+ public MathParser(MeteoDataInfo aDataInfo) {
+ _meteoDataInfo = aDataInfo;
+ _isGridData = aDataInfo.isGridData();
+ _variables = aDataInfo.getDataInfo().getVariableNames();
+ }
+ //
+ //
+ //
+ //
+
+ /**
+ * Evaluates the specified expression
+ *
+ * @param expression The expression to evaluate
+ * @return The evaluated result
+ */
+ public Object evaluate(String expression) throws ParseException, IOException {
+ if (expression == null || expression.isEmpty()) {
+ throw new java.lang.IllegalArgumentException("expression");
+ }
+
+ _expressionReader = new StringReader(expression);
+ _symbolStack.clear();
+ _expressionQueue.clear();
+
+ parseExpressionToQueue();
+
+ Object result = calculateFromQueue();
+
+ //_variables[AnswerVariable] = result;
+ return result;
+ }
+
+ private void parseExpressionToQueue() throws ParseException, IOException {
+ int ic;
+ char c;
+ while ((ic = _expressionReader.read()) != -1) {
+ c = (char) ic;
+ if (Character.isWhitespace(c)) {
+ continue;
+ }
+ if (tryNumber(c)) {
+ continue;
+ }
+ if (tryString(c)) {
+ continue;
+ }
+ if (tryStartGroup(c)) {
+ continue;
+ }
+ if (tryOperator(c)) {
+ continue;
+ }
+ if (tryEndGroup(c)) {
+ continue;
+ }
+ //if (TryConvert(c))
+ // continue;
+ throw new ParseException("Invalid character encountered" + c);
+ }
+
+ processSymbolStack();
+ }
+
+ private boolean tryNumber(char c) throws IOException, ParseException {
+ boolean isNumber = NumberExpression.isNumber(c);
+ boolean isNegative = false;
+ if (NumberExpression.isNegativeSign(c)) {
+ if (_expressionQueue.size() == 0) {
+ isNegative = true;
+ } else if (_expressionQueue.size() > 0 && _symbolStack.size() > 0) {
+ if (((String) _symbolStack.peek()).equals("(")) {
+ isNegative = true;
+ }
+ }
+ }
+
+ if (!isNumber && !isNegative) {
+ return false;
+ }
+
+ _buffer.setLength(0);
+ _buffer.append(c);
+
+ _expressionReader.mark(1);
+ char p = (char) _expressionReader.read();
+ while (NumberExpression.isNumber(p)) {
+ _buffer.append(p);
+ _expressionReader.mark(1);
+ p = (char) _expressionReader.read();
+ }
+ _expressionReader.reset();
+
+ double value;
+ try {
+ value = Double.parseDouble(_buffer.toString());
+ } catch (Exception e) {
+ throw new ParseException("Invalid number format: " + _buffer);
+ }
+
+ NumberExpression expression = new NumberExpression(value);
+ _expressionQueue.offer(expression);
+
+ return true;
+ }
+
+ private boolean tryString(char c) throws IOException, ParseException {
+ if (!Character.isLetter(c)) {
+ return false;
+ }
+
+ _buffer.setLength(0);
+ _buffer.append(c);
+
+ _expressionReader.mark(1);
+ char p = (char) _expressionReader.read();
+ while (Character.isLetterOrDigit(p) || p == '_' || p == '@' || p == '.') {
+ _buffer.append(p);
+ _expressionReader.mark(1);
+ p = (char) _expressionReader.read();
+ }
+ _expressionReader.reset();
+
+ if (_variables.contains(_buffer.toString())) {
+ Object value = getVariableValue(_buffer.toString());
+ NumberExpression expression = new NumberExpression(value);
+ _expressionQueue.offer(expression);
+
+ return true;
+ }
+
+ if (FunctionExpression.isFunction(_buffer.toString())) {
+ _symbolStack.push(_buffer.toString());
+ return true;
+ }
+
+ throw new ParseException("Invalid variable: " + _buffer);
+ }
+
+ private boolean tryStartGroup(char c) {
+ if (c != '(') {
+ return false;
+ }
+
+ _symbolStack.push(String.valueOf(c));
+ return true;
+ }
+
+ private boolean tryOperator(char c) throws ParseException {
+ if (!OperatorExpression.isSymbol(c)) {
+ return false;
+ }
+
+ boolean repeat;
+ String s = String.valueOf(c);
+
+ do {
+ String p = _symbolStack.size() == 0 ? "" : _symbolStack.peek();
+ repeat = false;
+ if (_symbolStack.size() == 0) {
+ _symbolStack.push(s);
+ } else if (p.equals("(")) {
+ _symbolStack.push(s);
+ } else if (precedence(s) > precedence(p)) {
+ _symbolStack.push(s);
+ } else {
+ IExpression e = getExpressionFromSymbol(_symbolStack.pop());
+ _expressionQueue.offer(e);
+ repeat = true;
+ }
+ } while (repeat);
+
+ return true;
+ }
+
+ private boolean tryEndGroup(char c) throws ParseException {
+ if (c != ')') {
+ return false;
+ }
+
+ boolean ok = false;
+
+ while (_symbolStack.size() > 0) {
+ String p = _symbolStack.pop();
+ if (p.equals("(")) {
+ ok = true;
+ break;
+ }
+
+ IExpression e = getExpressionFromSymbol(p);
+ _expressionQueue.offer(e);
+ }
+
+ if (!ok) {
+ throw new ParseException("Unbalance parenthese");
+ }
+
+ return true;
+ }
+
+ private void processSymbolStack() throws ParseException {
+ while (_symbolStack.size() > 0) {
+ String p = _symbolStack.pop();
+ if (p.length() == 1 && p.equals("(")) {
+ throw new ParseException("Unbalance parenthese");
+ }
+
+ IExpression e = getExpressionFromSymbol(p);
+ _expressionQueue.offer(e);
+ }
+ }
+
+ private static int precedence(String c) {
+ String s = c.substring(0, 1);
+ if (c.length() == 1 && s.equals("*") || s.equals("/") || s.equals("%")) {
+ return 2;
+ }
+
+ return 1;
+ }
+
+ private IExpression getExpressionFromSymbol(String p) throws ParseException {
+ IExpression e;
+
+ if (_expressionCache.containsKey(p)) {
+ e = _expressionCache.get(p);
+ } else if (OperatorExpression.isSymbol(p)) {
+ e = new OperatorExpression(p);
+ _expressionCache.put(p, e);
+ } else if (FunctionExpression.isFunction(p)) {
+ e = new FunctionExpression(p, false);
+ _expressionCache.put(p, e);
+ } //else if (ConvertExpression.IsConvertExpression(p))
+ //{
+ // e = new ConvertExpression(p);
+ // _expressionCache.Add(p, e);
+ //}
+ else {
+ throw new ParseException("Invalid symbol on stack" + p);
+ }
+
+ return e;
+ }
+
+ private Object calculateFromQueue() throws ParseException {
+ Object result;
+ _calculationStack.clear();
+
+ for (IExpression expression : _expressionQueue) {
+ if (_calculationStack.size() < expression.getArgumentCount()) {
+ throw new ParseException("Not enough numbers" + expression);
+ }
+
+ _parameters.clear();
+ for (int i = 0; i < expression.getArgumentCount(); i++) {
+ _parameters.push(_calculationStack.pop());
+ }
+
+ Object[] parameters = _parameters.toArray();
+ MIMath.arrayReverse(parameters);
+ _calculationStack.push(expression.evaluate(parameters));
+ }
+
+ result = _calculationStack.pop();
+ return result;
+ }
+
+ private Object getVariableValue(String varName) {
+ if (_meteoDataInfo == null) {
+ return 100;
+ } else {
+ if (_isGridData) {
+ return _meteoDataInfo.getGridData(varName);
+ } else {
+ return _meteoDataInfo.getStationData(varName);
+ }
+ }
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/DataInfo.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/DataInfo.java
index a047c535..cfb18098 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/DataInfo.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/DataInfo.java
@@ -19,7 +19,7 @@ import java.time.Period;
import java.util.ArrayList;
import java.util.List;
-import org.meteoinfo.global.util.JDateUtil;
+import org.meteoinfo.common.util.JDateUtil;
import org.meteoinfo.ndarray.Array;
import org.meteoinfo.ndarray.Dimension;
import org.meteoinfo.projection.KnownCoordinateSystems;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/DrawMeteoData.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/DrawMeteoData.java
index ddc4d2cf..dbe119ad 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/DrawMeteoData.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/DrawMeteoData.java
@@ -14,6 +14,9 @@
package org.meteoinfo.data.meteodata;
import org.apache.commons.lang3.ArrayUtils;
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.MIMath;
+import org.meteoinfo.common.PointD;
import org.meteoinfo.data.DataMath;
import org.meteoinfo.data.GridData;
import org.meteoinfo.data.StationData;
@@ -21,10 +24,10 @@ import org.meteoinfo.data.dataframe.DataFrame;
import org.meteoinfo.data.mapdata.Field;
import org.meteoinfo.drawing.ContourDraw;
import org.meteoinfo.drawing.Draw;
+import org.meteoinfo.geoprocess.GeometryUtil;
import org.meteoinfo.legend.MarkerType;
import org.meteoinfo.geoprocess.GeoComputation;
-import org.meteoinfo.global.MIMath;
-import org.meteoinfo.global.PointD;
+import org.meteoinfo.math.ArrayUtil;
import org.meteoinfo.ndarray.DataType;
import org.meteoinfo.layer.LayerDrawType;
import org.meteoinfo.layer.VectorLayer;
@@ -45,10 +48,9 @@ import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
-import org.meteoinfo.math.ArrayUtil;
+
import org.meteoinfo.data.GridArray;
import org.meteoinfo.data.XYListDataset;
-import org.meteoinfo.global.Extent;
import org.meteoinfo.layer.ImageLayer;
import org.meteoinfo.layer.RasterLayer;
import org.meteoinfo.layer.WorldFilePara;
@@ -107,7 +109,7 @@ public class DrawMeteoData {
}
aPolyline.setPoints(pList);
aPolyline.setValue(i);
- aPolyline.setExtent(MIMath.getPointsExtent(pList));
+ aPolyline.setExtent(GeometryUtil.getPointsExtent(pList));
int shapeNum = layer.getShapeNum();
try {
@@ -157,7 +159,7 @@ public class DrawMeteoData {
}
aPolyline.setPoints(pList);
aPolyline.setValue(i);
- aPolyline.setExtent(MIMath.getPointsExtent(pList));
+ aPolyline.setExtent(GeometryUtil.getPointsExtent(pList));
int shapeNum = layer.getShapeNum();
try {
@@ -233,7 +235,7 @@ public class DrawMeteoData {
PolylineShape aPolyline = new PolylineShape();
aPolyline.setPoints(ps);
aPolyline.setValue(i);
- aPolyline.setExtent(MIMath.getPointsExtent(ps));
+ aPolyline.setExtent(GeometryUtil.getPointsExtent(ps));
int shapeNum = layer.getShapeNum();
try {
@@ -368,7 +370,7 @@ public class DrawMeteoData {
PolylineShape aPolyline = new PolylineShape();
aPolyline.setPoints(ps);
aPolyline.setValue(k);
- aPolyline.setExtent(MIMath.getPointsExtent(ps));
+ aPolyline.setExtent(GeometryUtil.getPointsExtent(ps));
int shapeNum = layer.getShapeNum();
try {
@@ -509,7 +511,7 @@ public class DrawMeteoData {
PolylineZShape aPolyline = new PolylineZShape();
aPolyline.setPoints(ps);
aPolyline.setValue(0);
- aPolyline.setExtent(MIMath.getPointsExtent(ps));
+ aPolyline.setExtent(GeometryUtil.getPointsExtent(ps));
int shapeNum = layer.getShapeNum();
try {
@@ -621,7 +623,7 @@ public class DrawMeteoData {
PolylineZShape aPolyline = new PolylineZShape();
aPolyline.setPoints(ps);
aPolyline.setValue(0);
- aPolyline.setExtent(MIMath.getPointsExtent(ps));
+ aPolyline.setExtent(GeometryUtil.getPointsExtent(ps));
int shapeNum = layer.getShapeNum();
try {
@@ -740,7 +742,7 @@ public class DrawMeteoData {
}
aPolyline.setPoints(pList);
aPolyline.setValue(aValue);
- aPolyline.setExtent(MIMath.getPointsExtent(pList));
+ aPolyline.setExtent(GeometryUtil.getPointsExtent(pList));
int shapeNum = aLayer.getShapeNum();
try {
@@ -826,7 +828,7 @@ public class DrawMeteoData {
}
aPolyline.setPoints(pList);
aPolyline.setValue(aValue);
- aPolyline.setExtent(MIMath.getPointsExtent(pList));
+ aPolyline.setExtent(GeometryUtil.getPointsExtent(pList));
int shapeNum = aLayer.getShapeNum();
try {
if (aLayer.editInsertShape(aPolyline, shapeNum)) {
@@ -968,7 +970,7 @@ public class DrawMeteoData {
}
PolygonShape aPolygonShape = new PolygonShape();
aPolygonShape.setPoints(pList);
- aPolygonShape.setExtent(MIMath.getPointsExtent(pList));
+ aPolygonShape.setExtent(GeometryUtil.getPointsExtent(pList));
aPolygonShape.lowValue = aValue;
if (aPolygon.HasHoles()) {
for (PolyLine holeLine : aPolygon.HoleLines) {
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/GridDataSetting.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/GridDataSetting.java
index 8b3078c0..c8939246 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/GridDataSetting.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/GridDataSetting.java
@@ -1,36 +1,36 @@
-/* Copyright 2012 Yaqiang Wang,
- * yaqiang.wang@gmail.com
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.data.meteodata;
-
-import org.meteoinfo.global.Extent;
-
-/**
- *
- * @author yaqiang
- */
-public class GridDataSetting {
- ///
- /// Data extent
- ///
-
- public Extent dataExtent = new Extent();
- ///
- /// X number
- ///
- public int xNum;
- ///
- /// Y number
- ///
- public int yNum;
-}
+/* Copyright 2012 Yaqiang Wang,
+ * yaqiang.wang@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ */
+package org.meteoinfo.data.meteodata;
+
+import org.meteoinfo.common.Extent;
+
+/**
+ *
+ * @author yaqiang
+ */
+public class GridDataSetting {
+ ///
+ /// Data extent
+ ///
+
+ public Extent dataExtent = new Extent();
+ ///
+ /// X number
+ ///
+ public int xNum;
+ ///
+ /// Y number
+ ///
+ public int yNum;
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/MeteoDataInfo.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/MeteoDataInfo.java
index 9a603089..90fae8a6 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/MeteoDataInfo.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/MeteoDataInfo.java
@@ -14,6 +14,8 @@
package org.meteoinfo.data.meteodata;
import java.io.File;
+
+import org.meteoinfo.common.MIMath;
import org.meteoinfo.data.GridData;
import org.meteoinfo.data.StationData;
import org.meteoinfo.data.meteodata.arl.ARLDataInfo;
@@ -30,14 +32,15 @@ import java.io.IOException;
import java.time.LocalDateTime;
import java.time.Duration;
import java.util.ArrayList;
+
+import org.meteoinfo.math.ArrayMath;
import org.meteoinfo.projection.info.ProjectionInfo;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
-import org.meteoinfo.math.ArrayMath;
+
import org.meteoinfo.data.meteodata.mm5.MM5DataInfo;
import org.meteoinfo.data.meteodata.mm5.MM5IMDataInfo;
-import org.meteoinfo.global.MIMath;
import org.meteoinfo.data.mathparser.MathParser;
import org.meteoinfo.data.mathparser.ParseException;
import org.meteoinfo.data.meteodata.awx.AWXDataInfo;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/StationModelData.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/StationModelData.java
index eba884f3..b1054aaa 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/StationModelData.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/StationModelData.java
@@ -1,100 +1,101 @@
-/* Copyright 2012 Yaqiang Wang,
- * yaqiang.wang@gmail.com
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.data.meteodata;
-
-import org.meteoinfo.global.Extent;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- *
- * @author yaqiang
- */
-public class StationModelData {
- //
-
- private List _data = new ArrayList<>();
- private Extent _dataExtent = new Extent();
- private double _missingValue = -9999.0;
- //
- //
- //
- //
-
- /**
- * Get data
- *
- * @return Data
- */
- public List getData() {
- return _data;
- }
-
- /**
- * Set data
- *
- * @param value Data
- */
- public void setData(List value) {
- _data = value;
- }
-
- /**
- * Get data extent
- *
- * @return Data extent
- */
- public Extent getDataExtent() {
- return _dataExtent;
- }
-
- /**
- * Set data extent
- *
- * @param value Data extent
- */
- public void setDataExtent(Extent value) {
- _dataExtent = value;
- }
-
- /**
- * Get missing data
- *
- * @return Missing data
- */
- public double getMissingValue() {
- return _missingValue;
- }
-
- /**
- * Set missing data
- *
- * @param value Missing data
- */
- public void setMissingValue(double value) {
- _missingValue = value;
- }
-
- /**
- * Get data number
- *
- * @return Data number
- */
- public int getDataNum() {
- return _data.size();
- }
- //
- //
- //
-}
+/* Copyright 2012 Yaqiang Wang,
+ * yaqiang.wang@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ */
+package org.meteoinfo.data.meteodata;
+
+import org.meteoinfo.common.Extent;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ * @author yaqiang
+ */
+public class StationModelData {
+ //
+
+ private List _data = new ArrayList<>();
+ private Extent _dataExtent = new Extent();
+ private double _missingValue = -9999.0;
+ //
+ //
+ //
+ //
+
+ /**
+ * Get data
+ *
+ * @return Data
+ */
+ public List getData() {
+ return _data;
+ }
+
+ /**
+ * Set data
+ *
+ * @param value Data
+ */
+ public void setData(List value) {
+ _data = value;
+ }
+
+ /**
+ * Get data extent
+ *
+ * @return Data extent
+ */
+ public Extent getDataExtent() {
+ return _dataExtent;
+ }
+
+ /**
+ * Set data extent
+ *
+ * @param value Data extent
+ */
+ public void setDataExtent(Extent value) {
+ _dataExtent = value;
+ }
+
+ /**
+ * Get missing data
+ *
+ * @return Missing data
+ */
+ public double getMissingValue() {
+ return _missingValue;
+ }
+
+ /**
+ * Set missing data
+ *
+ * @param value Missing data
+ */
+ public void setMissingValue(double value) {
+ _missingValue = value;
+ }
+
+ /**
+ * Get data number
+ *
+ * @return Data number
+ */
+ public int getDataNum() {
+ return _data.size();
+ }
+ //
+ //
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/Variable.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/Variable.java
index 5f26701b..eb401e5a 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/Variable.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/Variable.java
@@ -13,13 +13,14 @@
*/
package org.meteoinfo.data.meteodata;
+import org.meteoinfo.common.util.JDateUtil;
import org.meteoinfo.ndarray.DimensionType;
import org.meteoinfo.ndarray.Dimension;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
-import org.meteoinfo.global.util.JDateUtil;
+
import org.meteoinfo.ndarray.DataType;
import org.meteoinfo.ndarray.Range;
import org.meteoinfo.ndarray.Section;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/arl/ARLDataInfo.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/arl/ARLDataInfo.java
index 9b4f938a..61daded8 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/arl/ARLDataInfo.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/arl/ARLDataInfo.java
@@ -13,17 +13,19 @@
*/
package org.meteoinfo.data.meteodata.arl;
-import org.meteoinfo.bak.ArrayMath;
+import org.meteoinfo.common.MIMath;
+import org.meteoinfo.common.util.GlobalUtil;
+import org.meteoinfo.common.util.JDateUtil;
+import org.meteoinfo.math.ArrayMath;
import org.meteoinfo.data.GridData;
import org.meteoinfo.data.meteodata.DataInfo;
-import org.meteoinfo.global.util.JDateUtil;
import org.meteoinfo.ndarray.Dimension;
import org.meteoinfo.ndarray.DimensionType;
import org.meteoinfo.ndarray.util.BigDecimalUtil;
import org.meteoinfo.data.meteodata.IGridDataInfo;
import org.meteoinfo.data.meteodata.Variable;
import org.meteoinfo.global.DataConvert;
-import org.meteoinfo.global.util.GlobalUtil;
+
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
@@ -40,7 +42,6 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import org.meteoinfo.data.GridArray;
import org.meteoinfo.data.meteodata.MeteoDataType;
-import org.meteoinfo.global.MIMath;
import org.locationtech.proj4j.proj.Projection;
import org.meteoinfo.projection.KnownCoordinateSystems;
import org.meteoinfo.projection.info.ProjectionInfo;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/ascii/ASCIIGridDataInfo.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/ascii/ASCIIGridDataInfo.java
index 7d18e0cf..9f4ed6d4 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/ascii/ASCIIGridDataInfo.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/ascii/ASCIIGridDataInfo.java
@@ -13,13 +13,14 @@
*/
package org.meteoinfo.data.meteodata.ascii;
+import org.meteoinfo.common.MIMath;
import org.meteoinfo.data.GridData;
import org.meteoinfo.data.meteodata.DataInfo;
import org.meteoinfo.ndarray.Dimension;
import org.meteoinfo.ndarray.DimensionType;
import org.meteoinfo.data.meteodata.IGridDataInfo;
import org.meteoinfo.data.meteodata.Variable;
-import org.meteoinfo.global.MIMath;
+
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/ascii/LonLatStationDataInfo.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/ascii/LonLatStationDataInfo.java
index df0cb460..ffd5ec4a 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/ascii/LonLatStationDataInfo.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/ascii/LonLatStationDataInfo.java
@@ -13,14 +13,16 @@
*/
package org.meteoinfo.data.meteodata.ascii;
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.MIMath;
+import org.meteoinfo.common.util.GlobalUtil;
import org.meteoinfo.data.StationData;
import org.meteoinfo.data.meteodata.DataInfo;
import org.meteoinfo.data.meteodata.IStationDataInfo;
import org.meteoinfo.data.meteodata.StationInfoData;
import org.meteoinfo.data.meteodata.StationModelData;
import org.meteoinfo.data.meteodata.Variable;
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.global.MIMath;
+
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
@@ -34,8 +36,7 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
import org.meteoinfo.data.meteodata.MeteoDataType;
-import org.meteoinfo.global.util.GlobalUtil;
-import org.meteoinfo.io.FileCharsetDetector;
+import org.meteoinfo.common.io.FileCharsetDetector;
import org.meteoinfo.ndarray.Array;
import org.meteoinfo.data.meteodata.Attribute;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/awx/AWXDataInfo.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/awx/AWXDataInfo.java
index 82e4ce80..aaf3ca6f 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/awx/AWXDataInfo.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/awx/AWXDataInfo.java
@@ -15,6 +15,8 @@ import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
+
+import org.meteoinfo.common.Extent;
import org.meteoinfo.data.GridArray;
import org.meteoinfo.data.GridData;
import org.meteoinfo.data.StationData;
@@ -28,7 +30,6 @@ import org.meteoinfo.data.meteodata.StationInfoData;
import org.meteoinfo.data.meteodata.StationModelData;
import org.meteoinfo.data.meteodata.Variable;
import org.meteoinfo.global.DataConvert;
-import org.meteoinfo.global.Extent;
import org.meteoinfo.layer.WorldFilePara;
import org.meteoinfo.projection.KnownCoordinateSystems;
import org.meteoinfo.projection.info.ProjectionInfo;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/bandraster/GeoTiffDataInfo.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/bandraster/GeoTiffDataInfo.java
index 21139931..1ee41533 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/bandraster/GeoTiffDataInfo.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/bandraster/GeoTiffDataInfo.java
@@ -18,11 +18,12 @@ import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
-import org.meteoinfo.math.ArrayMath;
+
import org.meteoinfo.data.GridArray;
import org.meteoinfo.data.GridData;
import org.meteoinfo.data.mapdata.geotiff.GeoTiff;
import org.meteoinfo.data.meteodata.DataInfo;
+import org.meteoinfo.math.ArrayMath;
import org.meteoinfo.ndarray.Dimension;
import org.meteoinfo.ndarray.DimensionType;
import org.meteoinfo.data.meteodata.IGridDataInfo;
@@ -149,7 +150,7 @@ public class GeoTiffDataInfo extends DataInfo implements IGridDataInfo {
public Array read(String varName, int[] origin, int[] size, int[] stride) {
try {
Array array = read(varName);
- array = ArrayMath.section(array, origin, size, stride);
+ array = ArrayMath.section(array, origin, size, stride);
return array;
} catch (InvalidRangeException ex) {
Logger.getLogger(GeoTiffDataInfo.class.getName()).log(Level.SEVERE, null, ex);
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/grads/GrADSDataInfo.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/grads/GrADSDataInfo.java
index d56d8396..a5b2f57d 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/grads/GrADSDataInfo.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/grads/GrADSDataInfo.java
@@ -13,6 +13,8 @@
*/
package org.meteoinfo.data.meteodata.grads;
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.util.JDateUtil;
import org.meteoinfo.data.GridData;
import org.meteoinfo.data.meteodata.DataInfo;
import org.meteoinfo.ndarray.Dimension;
@@ -20,7 +22,7 @@ import org.meteoinfo.ndarray.DimensionType;
import org.meteoinfo.data.meteodata.IGridDataInfo;
import org.meteoinfo.data.meteodata.Variable;
import org.meteoinfo.global.DataConvert;
-import org.meteoinfo.io.EndianDataOutputStream;
+import org.meteoinfo.common.io.EndianDataOutputStream;
import org.meteoinfo.ndarray.util.BigDecimalUtil;
import org.meteoinfo.projection.KnownCoordinateSystems;
import org.meteoinfo.projection.info.ProjectionInfo;
@@ -51,7 +53,6 @@ import org.meteoinfo.data.meteodata.MeteoDataType;
import org.meteoinfo.data.meteodata.StationInfoData;
import org.meteoinfo.data.meteodata.StationModelData;
import org.meteoinfo.data.meteodata.arl.ARLDataInfo;
-import org.meteoinfo.global.Extent;
import org.meteoinfo.ndarray.Array;
import org.meteoinfo.ndarray.DataType;
import org.meteoinfo.ndarray.IndexIterator;
@@ -59,7 +60,6 @@ import org.meteoinfo.ndarray.InvalidRangeException;
import org.meteoinfo.ndarray.Range;
import org.meteoinfo.ndarray.Section;
import org.meteoinfo.data.meteodata.Attribute;
-import org.meteoinfo.global.util.JDateUtil;
/**
*
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/grib/grib2/GRIB2DataInfo.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/grib/grib2/GRIB2DataInfo.java
index 7c685068..fee51b99 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/grib/grib2/GRIB2DataInfo.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/grib/grib2/GRIB2DataInfo.java
@@ -11,6 +11,8 @@ import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
+
+import org.meteoinfo.common.Bytes2Number;
import org.meteoinfo.data.DataMath;
import org.meteoinfo.data.GridArray;
import org.meteoinfo.data.GridData;
@@ -18,7 +20,6 @@ import org.meteoinfo.data.meteodata.DataInfo;
import org.meteoinfo.data.meteodata.IGridDataInfo;
import org.meteoinfo.data.meteodata.MeteoDataType;
import org.meteoinfo.data.meteodata.Variable;
-import org.meteoinfo.global.Bytes2Number;
import org.meteoinfo.projection.info.ProjectionInfo;
import org.meteoinfo.ndarray.Array;
import org.meteoinfo.data.meteodata.Attribute;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/hysplit/HYSPLITConcDataInfo.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/hysplit/HYSPLITConcDataInfo.java
index 03b5b69a..0bd7d4c8 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/hysplit/HYSPLITConcDataInfo.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/hysplit/HYSPLITConcDataInfo.java
@@ -13,10 +13,10 @@
*/
package org.meteoinfo.data.meteodata.hysplit;
+import org.meteoinfo.common.util.JDateUtil;
import org.meteoinfo.data.meteodata.ascii.ASCIIGridDataInfo;
import org.meteoinfo.data.GridData;
import org.meteoinfo.data.meteodata.DataInfo;
-import org.meteoinfo.global.util.JDateUtil;
import org.meteoinfo.ndarray.Dimension;
import org.meteoinfo.ndarray.DimensionType;
import org.meteoinfo.data.meteodata.IGridDataInfo;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/hysplit/HYSPLITPartDataInfo.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/hysplit/HYSPLITPartDataInfo.java
index 78d28ff7..6304317c 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/hysplit/HYSPLITPartDataInfo.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/hysplit/HYSPLITPartDataInfo.java
@@ -13,13 +13,14 @@
*/
package org.meteoinfo.data.meteodata.hysplit;
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.util.JDateUtil;
import org.meteoinfo.data.StationData;
import org.meteoinfo.data.dataframe.Column;
import org.meteoinfo.data.dataframe.ColumnIndex;
import org.meteoinfo.data.dataframe.DataFrame;
import org.meteoinfo.data.dataframe.Index;
import org.meteoinfo.data.meteodata.DataInfo;
-import org.meteoinfo.global.util.JDateUtil;
import org.meteoinfo.ndarray.DataType;
import org.meteoinfo.ndarray.Dimension;
import org.meteoinfo.ndarray.DimensionType;
@@ -27,7 +28,6 @@ import org.meteoinfo.data.meteodata.IStationDataInfo;
import org.meteoinfo.data.meteodata.StationInfoData;
import org.meteoinfo.data.meteodata.StationModelData;
import org.meteoinfo.data.meteodata.Variable;
-import org.meteoinfo.global.Extent;
import java.io.IOException;
import java.io.RandomAccessFile;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/hysplit/HYSPLITTrajDataInfo.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/hysplit/HYSPLITTrajDataInfo.java
index 1cdad49d..c73b8388 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/hysplit/HYSPLITTrajDataInfo.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/hysplit/HYSPLITTrajDataInfo.java
@@ -13,15 +13,15 @@
*/
package org.meteoinfo.data.meteodata.hysplit;
+import org.meteoinfo.common.PointD;
+import org.meteoinfo.common.util.JDateUtil;
import org.meteoinfo.data.mapdata.Field;
import org.meteoinfo.data.meteodata.DataInfo;
-import org.meteoinfo.global.util.JDateUtil;
+import org.meteoinfo.geoprocess.GeometryUtil;
import org.meteoinfo.ndarray.Dimension;
import org.meteoinfo.ndarray.DimensionType;
import org.meteoinfo.data.meteodata.TrajDataInfo;
import org.meteoinfo.data.meteodata.Variable;
-import org.meteoinfo.global.MIMath;
-import org.meteoinfo.global.PointD;
import java.awt.Color;
import java.io.BufferedReader;
@@ -466,7 +466,7 @@ public class HYSPLITTrajDataInfo extends DataInfo implements TrajDataInfo {
TrajNum += 1;
aPolyline.setValue(TrajNum);
aPolyline.setPoints(PointList.get(i));
- aPolyline.setExtent(MIMath.getPointsExtent(aPolyline.getPoints()));
+ aPolyline.setExtent(GeometryUtil.getPointsExtent(aPolyline.getPoints()));
int shapeNum = aLayer.getShapeNum();
if (aLayer.editInsertShape(aPolyline, shapeNum)) {
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/metar/METARDataInfo.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/metar/METARDataInfo.java
index 9b10def9..f5945877 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/metar/METARDataInfo.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/metar/METARDataInfo.java
@@ -13,9 +13,11 @@
*/
package org.meteoinfo.data.meteodata.metar;
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.MIMath;
+import org.meteoinfo.common.util.JDateUtil;
import org.meteoinfo.data.StationData;
import org.meteoinfo.data.meteodata.DataInfo;
-import org.meteoinfo.global.util.JDateUtil;
import org.meteoinfo.ndarray.Dimension;
import org.meteoinfo.ndarray.DimensionType;
import org.meteoinfo.data.meteodata.IStationDataInfo;
@@ -23,8 +25,7 @@ import org.meteoinfo.data.meteodata.StationInfoData;
import org.meteoinfo.data.meteodata.StationModel;
import org.meteoinfo.data.meteodata.StationModelData;
import org.meteoinfo.data.meteodata.Variable;
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.global.MIMath;
+
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/micaps/MDFSDataInfo.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/micaps/MDFSDataInfo.java
index 05ec3edd..e2bb43a7 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/micaps/MDFSDataInfo.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/micaps/MDFSDataInfo.java
@@ -1,5 +1,7 @@
package org.meteoinfo.data.meteodata.micaps;
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.util.JDateUtil;
import org.meteoinfo.data.GridArray;
import org.meteoinfo.data.GridData;
import org.meteoinfo.data.StationData;
@@ -8,11 +10,7 @@ import org.meteoinfo.data.dataframe.ColumnIndex;
import org.meteoinfo.data.dataframe.DataFrame;
import org.meteoinfo.data.dataframe.Index;
import org.meteoinfo.data.meteodata.*;
-import org.meteoinfo.data.meteodata.awx.AWXDataInfo;
import org.meteoinfo.global.DataConvert;
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.global.util.JDateUtil;
-import org.meteoinfo.math.ArrayMath;
import org.meteoinfo.ndarray.*;
import java.io.IOException;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/micaps/MICAPS11DataInfo.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/micaps/MICAPS11DataInfo.java
index 724725d3..3e588ef3 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/micaps/MICAPS11DataInfo.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/micaps/MICAPS11DataInfo.java
@@ -25,16 +25,17 @@ import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
+
+import org.meteoinfo.common.MIMath;
+import org.meteoinfo.common.util.JDateUtil;
import org.meteoinfo.data.GridArray;
import org.meteoinfo.data.GridData;
import org.meteoinfo.data.meteodata.DataInfo;
-import org.meteoinfo.global.util.JDateUtil;
import org.meteoinfo.ndarray.Dimension;
import org.meteoinfo.ndarray.DimensionType;
import org.meteoinfo.data.meteodata.IGridDataInfo;
import org.meteoinfo.data.meteodata.MeteoDataType;
import org.meteoinfo.data.meteodata.Variable;
-import org.meteoinfo.global.MIMath;
import org.meteoinfo.ndarray.Array;
import org.meteoinfo.ndarray.DataType;
import org.meteoinfo.ndarray.IndexIterator;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/micaps/MICAPS120DataInfo.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/micaps/MICAPS120DataInfo.java
index 80297a21..3440e0f0 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/micaps/MICAPS120DataInfo.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/micaps/MICAPS120DataInfo.java
@@ -13,9 +13,11 @@
*/
package org.meteoinfo.data.meteodata.micaps;
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.util.JDateUtil;
import org.meteoinfo.data.StationData;
import org.meteoinfo.data.meteodata.DataInfo;
-import org.meteoinfo.global.util.JDateUtil;
+import org.meteoinfo.math.ArrayMath;
import org.meteoinfo.ndarray.Dimension;
import org.meteoinfo.ndarray.DimensionType;
import org.meteoinfo.data.meteodata.IStationDataInfo;
@@ -35,13 +37,12 @@ import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
-import org.meteoinfo.math.ArrayMath;
+
import org.meteoinfo.data.dataframe.Column;
import org.meteoinfo.data.dataframe.ColumnIndex;
import org.meteoinfo.data.dataframe.DataFrame;
import org.meteoinfo.data.dataframe.Index;
import org.meteoinfo.data.meteodata.MeteoDataType;
-import org.meteoinfo.global.Extent;
import org.meteoinfo.ndarray.Array;
import org.meteoinfo.ndarray.DataType;
import org.meteoinfo.data.meteodata.Attribute;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/micaps/MICAPS131DataInfo.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/micaps/MICAPS131DataInfo.java
index 781fbec8..8b4078fc 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/micaps/MICAPS131DataInfo.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/micaps/MICAPS131DataInfo.java
@@ -23,10 +23,11 @@ import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
+
+import org.meteoinfo.common.util.JDateUtil;
import org.meteoinfo.data.GridArray;
import org.meteoinfo.data.GridData;
import org.meteoinfo.data.meteodata.DataInfo;
-import org.meteoinfo.global.util.JDateUtil;
import org.meteoinfo.ndarray.Dimension;
import org.meteoinfo.ndarray.DimensionType;
import org.meteoinfo.data.meteodata.IGridDataInfo;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/micaps/MICAPS13DataInfo.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/micaps/MICAPS13DataInfo.java
index b7570e02..6443f3ce 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/micaps/MICAPS13DataInfo.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/micaps/MICAPS13DataInfo.java
@@ -22,17 +22,18 @@ import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
+
+import org.meteoinfo.common.MIMath;
+import org.meteoinfo.common.util.JDateUtil;
import org.meteoinfo.data.GridArray;
import org.meteoinfo.data.GridData;
import org.meteoinfo.data.meteodata.DataInfo;
-import org.meteoinfo.global.util.JDateUtil;
import org.meteoinfo.ndarray.Dimension;
import org.meteoinfo.ndarray.DimensionType;
import org.meteoinfo.data.meteodata.IGridDataInfo;
import org.meteoinfo.data.meteodata.MeteoDataType;
import org.meteoinfo.data.meteodata.Variable;
import org.meteoinfo.global.DataConvert;
-import org.meteoinfo.global.MIMath;
import org.meteoinfo.projection.KnownCoordinateSystems;
import org.meteoinfo.projection.info.ProjectionInfo;
import org.meteoinfo.projection.Reproject;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/micaps/MICAPS1DataInfo.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/micaps/MICAPS1DataInfo.java
index edecc46b..dfd1c1f9 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/micaps/MICAPS1DataInfo.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/micaps/MICAPS1DataInfo.java
@@ -13,9 +13,12 @@
*/
package org.meteoinfo.data.meteodata.micaps;
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.MIMath;
+import org.meteoinfo.common.util.JDateUtil;
import org.meteoinfo.data.StationData;
import org.meteoinfo.data.meteodata.DataInfo;
-import org.meteoinfo.global.util.JDateUtil;
+import org.meteoinfo.math.ArrayMath;
import org.meteoinfo.ndarray.Dimension;
import org.meteoinfo.ndarray.DimensionType;
import org.meteoinfo.data.meteodata.IStationDataInfo;
@@ -23,8 +26,7 @@ import org.meteoinfo.data.meteodata.StationInfoData;
import org.meteoinfo.data.meteodata.StationModel;
import org.meteoinfo.data.meteodata.StationModelData;
import org.meteoinfo.data.meteodata.Variable;
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.global.MIMath;
+
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
@@ -37,7 +39,7 @@ import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
-import org.meteoinfo.math.ArrayMath;
+
import org.meteoinfo.data.dataframe.Column;
import org.meteoinfo.data.dataframe.ColumnIndex;
import org.meteoinfo.data.dataframe.DataFrame;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/micaps/MICAPS2DataInfo.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/micaps/MICAPS2DataInfo.java
index 09c748df..4f58960e 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/micaps/MICAPS2DataInfo.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/micaps/MICAPS2DataInfo.java
@@ -18,9 +18,11 @@ import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
+
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.util.JDateUtil;
import org.meteoinfo.data.StationData;
import org.meteoinfo.data.meteodata.DataInfo;
-import org.meteoinfo.global.util.JDateUtil;
import org.meteoinfo.ndarray.Dimension;
import org.meteoinfo.ndarray.DimensionType;
import org.meteoinfo.data.meteodata.IStationDataInfo;
@@ -29,7 +31,6 @@ import org.meteoinfo.data.meteodata.StationInfoData;
import org.meteoinfo.data.meteodata.StationModel;
import org.meteoinfo.data.meteodata.StationModelData;
import org.meteoinfo.data.meteodata.Variable;
-import org.meteoinfo.global.Extent;
import org.meteoinfo.ndarray.Array;
import org.meteoinfo.ndarray.DataType;
import org.meteoinfo.data.meteodata.Attribute;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/micaps/MICAPS3DataInfo.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/micaps/MICAPS3DataInfo.java
index 8b9e619f..de59ba59 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/micaps/MICAPS3DataInfo.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/micaps/MICAPS3DataInfo.java
@@ -13,16 +13,17 @@
*/
package org.meteoinfo.data.meteodata.micaps;
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.util.JDateUtil;
import org.meteoinfo.data.StationData;
import org.meteoinfo.data.meteodata.DataInfo;
-import org.meteoinfo.global.util.JDateUtil;
import org.meteoinfo.ndarray.Dimension;
import org.meteoinfo.ndarray.DimensionType;
import org.meteoinfo.data.meteodata.IStationDataInfo;
import org.meteoinfo.data.meteodata.StationInfoData;
import org.meteoinfo.data.meteodata.StationModelData;
import org.meteoinfo.data.meteodata.Variable;
-import org.meteoinfo.global.Extent;
+
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/micaps/MICAPS4DataInfo.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/micaps/MICAPS4DataInfo.java
index f08846ab..eaf2fb5f 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/micaps/MICAPS4DataInfo.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/micaps/MICAPS4DataInfo.java
@@ -13,14 +13,15 @@
*/
package org.meteoinfo.data.meteodata.micaps;
+import org.meteoinfo.common.MIMath;
+import org.meteoinfo.common.util.JDateUtil;
import org.meteoinfo.data.GridData;
import org.meteoinfo.data.meteodata.DataInfo;
-import org.meteoinfo.global.util.JDateUtil;
import org.meteoinfo.ndarray.Dimension;
import org.meteoinfo.ndarray.DimensionType;
import org.meteoinfo.data.meteodata.IGridDataInfo;
import org.meteoinfo.data.meteodata.Variable;
-import org.meteoinfo.global.MIMath;
+
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/micaps/MICAPS7DataInfo.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/micaps/MICAPS7DataInfo.java
index 40ff87be..546c19db 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/micaps/MICAPS7DataInfo.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/micaps/MICAPS7DataInfo.java
@@ -25,17 +25,18 @@ import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
+
+import org.meteoinfo.common.PointD;
+import org.meteoinfo.common.util.JDateUtil;
import org.meteoinfo.data.mapdata.Field;
import org.meteoinfo.data.meteodata.DataInfo;
-import org.meteoinfo.global.util.JDateUtil;
+import org.meteoinfo.geoprocess.GeometryUtil;
import org.meteoinfo.ndarray.Dimension;
import org.meteoinfo.ndarray.DimensionType;
import org.meteoinfo.data.meteodata.MeteoDataType;
import org.meteoinfo.data.meteodata.TrajDataInfo;
import org.meteoinfo.data.meteodata.Variable;
import org.meteoinfo.data.meteodata.hysplit.TrajectoryInfo;
-import org.meteoinfo.global.MIMath;
-import org.meteoinfo.global.PointD;
import org.meteoinfo.ndarray.DataType;
import org.meteoinfo.layer.LayerDrawType;
import org.meteoinfo.layer.VectorLayer;
@@ -333,7 +334,7 @@ public class MICAPS7DataInfo extends DataInfo implements TrajDataInfo {
TrajNum += 1;
aPolyline.setValue(TrajNum);
aPolyline.setPoints(PointList.get(i));
- aPolyline.setExtent(MIMath.getPointsExtent(aPolyline.getPoints()));
+ aPolyline.setExtent(GeometryUtil.getPointsExtent(aPolyline.getPoints()));
int shapeNum = aLayer.getShapeNum();
if (aLayer.editInsertShape(aPolyline, shapeNum)) {
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/mm5/MM5DataInfo.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/mm5/MM5DataInfo.java
index e937b760..ccedd421 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/mm5/MM5DataInfo.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/mm5/MM5DataInfo.java
@@ -18,10 +18,11 @@ import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
+
+import org.meteoinfo.common.util.JDateUtil;
import org.meteoinfo.data.GridArray;
import org.meteoinfo.data.GridData;
import org.meteoinfo.data.meteodata.DataInfo;
-import org.meteoinfo.global.util.JDateUtil;
import org.meteoinfo.ndarray.Dimension;
import org.meteoinfo.ndarray.DimensionType;
import org.meteoinfo.data.meteodata.IGridDataInfo;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/mm5/MM5IMDataInfo.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/mm5/MM5IMDataInfo.java
index b09ed482..b04667c5 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/mm5/MM5IMDataInfo.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/mm5/MM5IMDataInfo.java
@@ -16,17 +16,18 @@ import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
+
+import org.meteoinfo.common.util.GlobalUtil;
+import org.meteoinfo.common.util.JDateUtil;
import org.meteoinfo.data.GridArray;
import org.meteoinfo.data.GridData;
import org.meteoinfo.data.meteodata.DataInfo;
-import org.meteoinfo.global.util.JDateUtil;
import org.meteoinfo.ndarray.Dimension;
import org.meteoinfo.ndarray.DimensionType;
import org.meteoinfo.data.meteodata.IGridDataInfo;
import org.meteoinfo.data.meteodata.MeteoDataType;
import org.meteoinfo.data.meteodata.Variable;
import org.meteoinfo.global.DataConvert;
-import org.meteoinfo.global.util.GlobalUtil;
import org.meteoinfo.ndarray.Array;
import org.meteoinfo.data.meteodata.Attribute;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/netcdf/NetCDFDataInfo.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/netcdf/NetCDFDataInfo.java
index 80cff23a..96236b58 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/netcdf/NetCDFDataInfo.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/netcdf/NetCDFDataInfo.java
@@ -13,10 +13,14 @@
*/
package org.meteoinfo.data.meteodata.netcdf;
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.MIMath;
+import org.meteoinfo.common.util.JDateUtil;
import org.meteoinfo.data.GridData;
import org.meteoinfo.data.StationData;
import org.meteoinfo.data.meteodata.DataInfo;
-import org.meteoinfo.global.util.JDateUtil;
+import org.meteoinfo.math.ArrayMath;
+import org.meteoinfo.math.ArrayUtil;
import org.meteoinfo.ndarray.Dimension;
import org.meteoinfo.ndarray.DimensionType;
import org.meteoinfo.data.meteodata.IGridDataInfo;
@@ -24,8 +28,7 @@ import org.meteoinfo.data.meteodata.IStationDataInfo;
import org.meteoinfo.data.meteodata.StationInfoData;
import org.meteoinfo.data.meteodata.StationModelData;
import org.meteoinfo.data.meteodata.Variable;
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.global.MIMath;
+
import java.io.IOException;
import java.text.ParseException;
import java.time.LocalDateTime;
@@ -36,8 +39,7 @@ import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
-import org.meteoinfo.math.ArrayMath;
-import org.meteoinfo.math.ArrayUtil;
+
import org.meteoinfo.data.GridArray;
import org.meteoinfo.data.meteodata.MeteoDataType;
import org.meteoinfo.projection.KnownCoordinateSystems;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/synop/SYNOPDataInfo.java b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/synop/SYNOPDataInfo.java
index 18fdd5ea..461794b6 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/synop/SYNOPDataInfo.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/data/meteodata/synop/SYNOPDataInfo.java
@@ -13,9 +13,11 @@
*/
package org.meteoinfo.data.meteodata.synop;
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.MIMath;
+import org.meteoinfo.common.util.JDateUtil;
import org.meteoinfo.data.StationData;
import org.meteoinfo.data.meteodata.DataInfo;
-import org.meteoinfo.global.util.JDateUtil;
import org.meteoinfo.ndarray.Dimension;
import org.meteoinfo.ndarray.DimensionType;
import org.meteoinfo.data.meteodata.IStationDataInfo;
@@ -23,8 +25,7 @@ import org.meteoinfo.data.meteodata.StationInfoData;
import org.meteoinfo.data.meteodata.StationModel;
import org.meteoinfo.data.meteodata.StationModelData;
import org.meteoinfo.data.meteodata.Variable;
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.global.MIMath;
+
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/drawing/ContourDraw.java b/MeteoInfoLib/src/main/java/org/meteoinfo/drawing/ContourDraw.java
index 67b5dad2..dae1da75 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/drawing/ContourDraw.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/drawing/ContourDraw.java
@@ -13,7 +13,8 @@
*/
package org.meteoinfo.drawing;
-import org.meteoinfo.global.MIMath;
+import org.meteoinfo.common.MIMath;
+
import java.util.List;
/**
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/drawing/Draw.java b/MeteoInfoLib/src/main/java/org/meteoinfo/drawing/Draw.java
index e707ff67..3afaf1b5 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/drawing/Draw.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/drawing/Draw.java
@@ -13,14 +13,14 @@
*/
package org.meteoinfo.drawing;
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.MIMath;
+import org.meteoinfo.common.PointD;
+import org.meteoinfo.common.PointF;
import org.meteoinfo.legend.MarkerType;
import org.meteoinfo.legend.PointStyle;
import org.meteoinfo.geoprocess.Spline;
import org.meteoinfo.global.colors.ColorUtil;
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.global.MIMath;
-import org.meteoinfo.global.PointD;
-import org.meteoinfo.global.PointF;
import org.meteoinfo.legend.BreakTypes;
import org.meteoinfo.legend.ChartBreak;
import org.meteoinfo.legend.LabelBreak;
@@ -60,7 +60,6 @@ import java.util.logging.Logger;
import javax.imageio.ImageIO;
import org.meteoinfo.chart.plot.XAlign;
import org.meteoinfo.chart.plot.YAlign;
-import org.meteoinfo.bak.ArrayMath;
import org.meteoinfo.legend.ArrowBreak;
import org.meteoinfo.legend.ArrowLineBreak;
import org.meteoinfo.legend.ColorBreakCollection;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/geoprocess/BorderPoint.java b/MeteoInfoLib/src/main/java/org/meteoinfo/geoprocess/BorderPoint.java
index 53a6ba9a..2d2b3482 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/geoprocess/BorderPoint.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/geoprocess/BorderPoint.java
@@ -1,45 +1,45 @@
- /* Copyright 2012 Yaqiang Wang,
- * yaqiang.wang@gmail.com
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.geoprocess;
-
-import org.meteoinfo.global.PointD;
-
-/**
- *
- * @author Yaqiang Wang
- */
-public class BorderPoint {
- ///
- /// Identifer
- ///
- public int Id;
- ///
- /// Border index
- ///
- public int BorderIdx;
- ///
- /// Border inner index
- ///
- public int BInnerIdx;
- ///
- /// Point
- ///
- public PointD Point;
- ///
- /// Value
- ///
- public double Value;
-
- public RectPointTypes rectPointType = RectPointTypes.None;
-}
+ /* Copyright 2012 Yaqiang Wang,
+ * yaqiang.wang@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ */
+package org.meteoinfo.geoprocess;
+
+ import org.meteoinfo.common.PointD;
+
+ /**
+ *
+ * @author Yaqiang Wang
+ */
+public class BorderPoint {
+ ///
+ /// Identifer
+ ///
+ public int Id;
+ ///
+ /// Border index
+ ///
+ public int BorderIdx;
+ ///
+ /// Border inner index
+ ///
+ public int BInnerIdx;
+ ///
+ /// Point
+ ///
+ public PointD Point;
+ ///
+ /// Value
+ ///
+ public double Value;
+
+ public RectPointTypes rectPointType = RectPointTypes.None;
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/geoprocess/ClipLine.java b/MeteoInfoLib/src/main/java/org/meteoinfo/geoprocess/ClipLine.java
index d1e3eb73..8a4e29d5 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/geoprocess/ClipLine.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/geoprocess/ClipLine.java
@@ -1,155 +1,155 @@
- /* Copyright 2012 Yaqiang Wang,
- * yaqiang.wang@gmail.com
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.geoprocess;
-
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.global.PointD;
-
-/**
- *
- * @author yaqiang
- */
-public class ClipLine {
- //
-
- private double _value;
- private boolean _isLon;
- private boolean _isLeftOrTop;
- //
- //
-
- /**
- * Constructor
- */
- public ClipLine() {
- _isLon = true;
- _isLeftOrTop = true;
- }
- //
- //
-
- /**
- * Get value
- *
- * @return Value
- */
- public double getValue() {
- return _value;
- }
-
- /**
- * Set value
- *
- * @param value Value
- */
- public void setValue(double value) {
- _value = value;
- }
-
- /**
- * Get if is longitude
- *
- * @return Boolean
- */
- public boolean isLongitude() {
- return _isLon;
- }
-
- /**
- * Set if is longitude
- *
- * @param istrue Boolean
- */
- public void setLongitude(boolean istrue) {
- _isLon = istrue;
- }
-
- /**
- * Get if is left (longitude) or top (latitude)
- *
- * @return Boolean
- */
- public boolean isLeftOrTop() {
- return _isLeftOrTop;
- }
-
- /**
- * Set if is left (longitude) or top (latitude)
- *
- * @param istrue
- */
- public void setLeftOrTop(boolean istrue) {
- _isLeftOrTop = istrue;
- }
- //
- //
-
- /**
- * Determine if a point is inside
- *
- * @param aPoint The Point
- * @return If is inside
- */
- public boolean isInside(PointD aPoint) {
- boolean isIn = false;
- if (_isLon) {
- if (_isLeftOrTop) {
- isIn = (aPoint.X <= _value);
- } else {
- isIn = (aPoint.X >= _value);
- }
- } else {
- if (_isLeftOrTop) {
- isIn = (aPoint.Y >= _value);
- } else {
- isIn = (aPoint.Y <= _value);
- }
- }
-
- return isIn;
- }
-
- /**
- * Determine if an extent is cross
- *
- * @param aExtent The extent
- * @return Is extent cross
- */
- public boolean isExtentCross(Extent aExtent) {
- if (_isLeftOrTop) {
- PointD aPoint = new PointD(aExtent.minX, aExtent.maxY);
- return isInside(aPoint);
- } else {
- PointD aPoint = new PointD(aExtent.maxX, aExtent.minY);
- return isInside(aPoint);
- }
- }
-
- /**
- * Determine if an extent is inside
- *
- * @param aExtent The extent
- * @return Is extent inside
- */
- public boolean isExtentInside(Extent aExtent) {
- if (_isLeftOrTop) {
- PointD aPoint = new PointD(aExtent.maxX, aExtent.minY);
- return isInside(aPoint);
- } else {
- PointD aPoint = new PointD(aExtent.minX, aExtent.maxY);
- return isInside(aPoint);
- }
- }
- //
-}
+ /* Copyright 2012 Yaqiang Wang,
+ * yaqiang.wang@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ */
+package org.meteoinfo.geoprocess;
+
+ import org.meteoinfo.common.Extent;
+ import org.meteoinfo.common.PointD;
+
+ /**
+ *
+ * @author yaqiang
+ */
+public class ClipLine {
+ //
+
+ private double _value;
+ private boolean _isLon;
+ private boolean _isLeftOrTop;
+ //
+ //
+
+ /**
+ * Constructor
+ */
+ public ClipLine() {
+ _isLon = true;
+ _isLeftOrTop = true;
+ }
+ //
+ //
+
+ /**
+ * Get value
+ *
+ * @return Value
+ */
+ public double getValue() {
+ return _value;
+ }
+
+ /**
+ * Set value
+ *
+ * @param value Value
+ */
+ public void setValue(double value) {
+ _value = value;
+ }
+
+ /**
+ * Get if is longitude
+ *
+ * @return Boolean
+ */
+ public boolean isLongitude() {
+ return _isLon;
+ }
+
+ /**
+ * Set if is longitude
+ *
+ * @param istrue Boolean
+ */
+ public void setLongitude(boolean istrue) {
+ _isLon = istrue;
+ }
+
+ /**
+ * Get if is left (longitude) or top (latitude)
+ *
+ * @return Boolean
+ */
+ public boolean isLeftOrTop() {
+ return _isLeftOrTop;
+ }
+
+ /**
+ * Set if is left (longitude) or top (latitude)
+ *
+ * @param istrue
+ */
+ public void setLeftOrTop(boolean istrue) {
+ _isLeftOrTop = istrue;
+ }
+ //
+ //
+
+ /**
+ * Determine if a point is inside
+ *
+ * @param aPoint The Point
+ * @return If is inside
+ */
+ public boolean isInside(PointD aPoint) {
+ boolean isIn = false;
+ if (_isLon) {
+ if (_isLeftOrTop) {
+ isIn = (aPoint.X <= _value);
+ } else {
+ isIn = (aPoint.X >= _value);
+ }
+ } else {
+ if (_isLeftOrTop) {
+ isIn = (aPoint.Y >= _value);
+ } else {
+ isIn = (aPoint.Y <= _value);
+ }
+ }
+
+ return isIn;
+ }
+
+ /**
+ * Determine if an extent is cross
+ *
+ * @param aExtent The extent
+ * @return Is extent cross
+ */
+ public boolean isExtentCross(Extent aExtent) {
+ if (_isLeftOrTop) {
+ PointD aPoint = new PointD(aExtent.minX, aExtent.maxY);
+ return isInside(aPoint);
+ } else {
+ PointD aPoint = new PointD(aExtent.maxX, aExtent.minY);
+ return isInside(aPoint);
+ }
+ }
+
+ /**
+ * Determine if an extent is inside
+ *
+ * @param aExtent The extent
+ * @return Is extent inside
+ */
+ public boolean isExtentInside(Extent aExtent) {
+ if (_isLeftOrTop) {
+ PointD aPoint = new PointD(aExtent.maxX, aExtent.minY);
+ return isInside(aPoint);
+ } else {
+ PointD aPoint = new PointD(aExtent.minX, aExtent.maxY);
+ return isInside(aPoint);
+ }
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/geoprocess/GeoComputation.java b/MeteoInfoLib/src/main/java/org/meteoinfo/geoprocess/GeoComputation.java
index c1242ab5..9d3eb537 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/geoprocess/GeoComputation.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/geoprocess/GeoComputation.java
@@ -13,11 +13,12 @@
*/
package org.meteoinfo.geoprocess;
-import org.meteoinfo.global.Direction;
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.global.MIMath;
-import org.meteoinfo.global.PointD;
+import org.meteoinfo.common.Direction;
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.MIMath;
+import org.meteoinfo.common.PointD;
import org.meteoinfo.map.GridLabel;
+import org.meteoinfo.math.meteo.MeteoMath;
import org.meteoinfo.ndarray.Array;
import org.meteoinfo.ndarray.DataType;
import org.meteoinfo.shape.*;
@@ -28,7 +29,7 @@ import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
-import org.meteoinfo.bak.ArrayMath;
+
import org.meteoinfo.data.mapdata.Field;
import org.meteoinfo.table.DataColumn;
import org.meteoinfo.table.DataRow;
@@ -232,7 +233,7 @@ public class GeoComputation {
*/
public static boolean pointInPolygons(List polygons, PointD aPoint) {
boolean isIn = false;
- Extent ext = MIMath.getExtent(polygons);
+ Extent ext = GeometryUtil.getExtent(polygons);
if (MIMath.pointInExtent(aPoint, ext)) {
for (PolygonShape aPGS : polygons) {
if (pointInPolygon(aPGS, aPoint)) {
@@ -360,7 +361,7 @@ public class GeoComputation {
aExtent.maxX = sp.X + buffer;
aExtent.minY = sp.Y - buffer;
aExtent.maxY = sp.Y + buffer;
- Extent bExtent = MIMath.getPointsExtent(points);
+ Extent bExtent = GeometryUtil.getPointsExtent(points);
double dis;
if (MIMath.isExtentCross(aExtent, bExtent)) {
for (int j = 0; j < points.size(); j++) {
@@ -1347,7 +1348,7 @@ public class GeoComputation {
if (inPolygon.hasHole()) {
for (int h = 0; h < inPolygon.getHoleLines().size(); h++) {
List holePList = (List) inPolygon.getHoleLines().get(h);
- Extent plExtent = MIMath.getPointsExtent(holePList);
+ Extent plExtent = GeometryUtil.getPointsExtent(holePList);
if (!isExtentCross(plExtent, clipObj)) {
continue;
}
@@ -1563,7 +1564,7 @@ public class GeoComputation {
if (inPolygon.hasHole()) {
for (int h = 0; h < inPolygon.getHoleLines().size(); h++) {
List holePList = (List) inPolygon.getHoleLines().get(h);
- Extent plExtent = MIMath.getPointsExtent(holePList);
+ Extent plExtent = GeometryUtil.getPointsExtent(holePList);
if (!isExtentCross(plExtent, extent)) {
continue;
}
@@ -2020,7 +2021,7 @@ public class GeoComputation {
int i, j;
for (i = 0; i < holeList.size(); i++) {
List holePs = holeList.get(i);
- Extent aExtent = MIMath.getPointsExtent(holePs);
+ Extent aExtent = GeometryUtil.getPointsExtent(holePs);
for (j = 0; j < polygonList.size(); j++) {
Polygon aPolygon = polygonList.get(j);
if (aPolygon.getExtent().include(aExtent)) {
@@ -2043,7 +2044,7 @@ public class GeoComputation {
private static boolean isExtentCross(Extent aExtent, Object clipObj) {
if (clipObj instanceof List) {
- Extent bExtent = MIMath.getPointsExtent((List) clipObj);
+ Extent bExtent = GeometryUtil.getPointsExtent((List) clipObj);
return MIMath.isExtentCross(aExtent, bExtent);
}
if (clipObj.getClass() == ClipLine.class) {
@@ -2158,8 +2159,8 @@ public class GeoComputation {
PListA.add(lineA.P2);
PListB.add(lineB.P1);
PListB.add(lineB.P2);
- boundA = MIMath.getPointsExtent(PListA);
- boundB = MIMath.getPointsExtent(PListB);
+ boundA = GeometryUtil.getPointsExtent(PListA);
+ boundB = GeometryUtil.getPointsExtent(PListB);
if (!MIMath.isExtentCross(boundA, boundB)) {
return false;
@@ -2481,7 +2482,7 @@ public class GeoComputation {
} else {
aGL.setLabDirection(Direction.Weast);
}
- aGL.setAnge((float)ArrayMath.uv2ds(p2.X - p1.X, p2.Y - p1.Y)[0]);
+ aGL.setAnge((float)MeteoMath.uv2ds(p2.X - p1.X, p2.Y - p1.Y)[0]);
gridLabels.add(aGL);
p1 = aPList.get(aPList.size() - 1);
@@ -2498,7 +2499,7 @@ public class GeoComputation {
} else {
aGL.setLabDirection(Direction.East);
}
- aGL.setAnge((float)ArrayMath.uv2ds(p2.X - p1.X, p2.Y - p1.Y)[0]);
+ aGL.setAnge((float) MeteoMath.uv2ds(p2.X - p1.X, p2.Y - p1.Y)[0]);
gridLabels.add(aGL);
return gridLabels;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/geoprocess/GeometryUtil.java b/MeteoInfoLib/src/main/java/org/meteoinfo/geoprocess/GeometryUtil.java
index 37408f9f..b26ccbcd 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/geoprocess/GeometryUtil.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/geoprocess/GeometryUtil.java
@@ -10,7 +10,9 @@ import java.util.List;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
-import org.meteoinfo.global.PointD;
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.Extent3D;
+import org.meteoinfo.common.PointD;
import org.meteoinfo.layer.VectorLayer;
import org.meteoinfo.math.ArrayMath;
import org.meteoinfo.ndarray.*;
@@ -22,6 +24,157 @@ import org.meteoinfo.shape.*;
*/
public class GeometryUtil {
+ /**
+ * Get extent from point list
+ *
+ * @param PList point list
+ * @return extent
+ */
+ public static Extent getPointsExtent(List extends PointD> PList) {
+ if (PList.get(0) instanceof PointZ){
+ Extent3D cET = new Extent3D();
+ for (int i = 0; i < PList.size(); i++) {
+ PointZ aP = (PointZ)PList.get(i);
+ if (i == 0) {
+ cET.minX = aP.X;
+ cET.maxX = aP.X;
+ cET.minY = aP.Y;
+ cET.maxY = aP.Y;
+ cET.minZ = aP.Z;
+ cET.maxZ = aP.Z;
+ } else {
+ if (cET.minX > aP.X) {
+ cET.minX = aP.X;
+ } else if (cET.maxX < aP.X) {
+ cET.maxX = aP.X;
+ }
+
+ if (cET.minY > aP.Y) {
+ cET.minY = aP.Y;
+ } else if (cET.maxY < aP.Y) {
+ cET.maxY = aP.Y;
+ }
+
+ if (cET.minZ > aP.Z) {
+ cET.minZ = aP.Z;
+ } else if (cET.maxZ < aP.Z) {
+ cET.maxZ = aP.Z;
+ }
+ }
+ }
+
+ return cET;
+ } else {
+ Extent cET = new Extent();
+ for (int i = 0; i < PList.size(); i++) {
+ PointD aP = PList.get(i);
+ if (i == 0) {
+ cET.minX = aP.X;
+ cET.maxX = aP.X;
+ cET.minY = aP.Y;
+ cET.maxY = aP.Y;
+ } else {
+ if (cET.minX > aP.X) {
+ cET.minX = aP.X;
+ } else if (cET.maxX < aP.X) {
+ cET.maxX = aP.X;
+ }
+
+ if (cET.minY > aP.Y) {
+ cET.minY = aP.Y;
+ } else if (cET.maxY < aP.Y) {
+ cET.maxY = aP.Y;
+ }
+ }
+ }
+
+ return cET;
+ }
+ }
+
+ /**
+ * Get extent of the shapes
+ *
+ * @param shapes
+ * @return Extent
+ */
+ public static Extent getExtent(List extends Shape> shapes) {
+ Extent extent = (Extent) shapes.get(0).getExtent().clone();
+ double minx = extent.minX;
+ double maxx = extent.maxX;
+ double miny = extent.minY;
+ double maxy = extent.maxY;
+ Extent ext;
+ for (int i = 1; i < shapes.size(); i++) {
+ ext = shapes.get(i).getExtent();
+ if (minx > ext.minX) {
+ minx = ext.minX;
+ }
+ if (maxx < ext.maxX) {
+ maxx = ext.maxX;
+ }
+ if (miny > ext.minY) {
+ miny = ext.minY;
+ }
+ if (maxy < ext.maxY) {
+ maxy = ext.maxY;
+ }
+ }
+
+ extent.minX = minx;
+ extent.maxX = maxx;
+ extent.minY = miny;
+ extent.maxY = maxy;
+
+ return extent;
+ }
+
+ /**
+ * Get extent of the points
+ *
+ * @param points
+ * @return Extent
+ */
+ public static Extent3D getExtent(PointZ[] points) {
+ PointZ p = points[0];
+ double minx = p.X;
+ double maxx = p.X;
+ double miny = p.Y;
+ double maxy = p.Y;
+ double minz = p.Z;
+ double maxz = p.Z;
+ for (int i = 1; i < points.length; i++) {
+ if (minx > p.X) {
+ minx = p.M;
+ }
+ if (maxx < p.X) {
+ maxx = p.M;
+ }
+ if (miny > p.Y) {
+ miny = p.Y;
+ }
+ if (maxy < p.Y) {
+ maxy = p.Y;
+ }
+ if (minz > p.Z) {
+ minz = p.Z;
+ }
+ if (maxz < p.Z) {
+ maxz = p.Z;
+ }
+ }
+
+ Extent3D extent = new Extent3D();
+ extent.minX = minx;
+ extent.maxX = maxx;
+ extent.minY = miny;
+ extent.maxY = maxy;
+ extent.minZ = minz;
+ extent.maxZ = maxz;
+
+ return extent;
+ }
+
/**
* Get ellipse coordinate
* @param x0 Center x
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/geoprocess/Spline.java b/MeteoInfoLib/src/main/java/org/meteoinfo/geoprocess/Spline.java
index 249473a2..f618bb26 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/geoprocess/Spline.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/geoprocess/Spline.java
@@ -1,113 +1,114 @@
- /* Copyright 2012 Yaqiang Wang,
- * yaqiang.wang@gmail.com
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.geoprocess;
-
-import org.meteoinfo.global.PointD;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- *
- * @author Yaqiang Wang
- */
-public class Spline {
-
- private static class Vec2 {
-
- public double X, Y;
-
- public Vec2(double x, double y) {
- this.X = x;
- this.Y = y;
- }
-
- public Vec2(PointD p) {
- this.X = p.X;
- this.Y = p.Y;
- }
-
- public PointD toPointD() {
- return new PointD(X, Y);
- }
-
- public Vec2 add(Vec2 v) {
- return new Vec2(this.X + v.X, this.Y + v.Y);
- }
-
- public Vec2 subtract(Vec2 v) {
- return new Vec2(this.X - v.X, this.Y - v.Y);
- }
-
- public Vec2 multiply(float f) {
- return new Vec2(this.X * f, this.Y * f);
- }
-
- public Vec2 divide(float f) {
- return new Vec2(this.X / f, this.Y / f);
- }
- }
-
- private static PointD[] interpolateBezier(PointD p0, PointD p1, PointD p2, PointD p3, int samples) {
- PointD[] result = new PointD[samples];
- Vec2 v0 = new Vec2(p0);
- Vec2 v1 = new Vec2(p1);
- Vec2 v2 = new Vec2(p2);
- Vec2 v3 = new Vec2(p3);
- for (int i = 0; i < samples; i++) {
- float t = (i + 1) / (samples + 1.0f);
- result[i] = (v0.multiply((1 - t) * (1 - t) * (1 - t)).
- add(v1.multiply(3 * (1 - t) * (1 - t) * t)).
- add(v2.multiply(3 * (1 - t) * t * t)).
- add(v3.multiply(t * t * t))).toPointD();
- }
- return result;
- }
-
- private static PointD[] interpolateCardinalSpline(PointD p0, PointD p1, PointD p2, PointD p3, int samples) {
- float tension = 0.5f;
- Vec2 v0 = new Vec2(p0);
- Vec2 v1 = new Vec2(p1);
- Vec2 v2 = new Vec2(p2);
- Vec2 v3 = new Vec2(p3);
-
- PointD u = v2.subtract(v0).multiply(tension / 3).add(v1).toPointD();
- PointD v = v1.subtract(v3).multiply(tension / 3).add(v2).toPointD();
-
- return interpolateBezier(p1, u, v, p2, samples);
- }
-
- /**
- * '基数样条'内插法。 points为通过点,samplesInSegment为两个样本点之间的内插数量。
- *
- * @param points The points
- * @param samplesInSegment Sample in segment
- * @return Splined points
- */
- public static PointD[] cardinalSpline(PointD[] points, int samplesInSegment) {
- List result = new ArrayList<>();
- for (int i = 0; i < points.length - 1; i++) {
- result.add(points[i]);
- PointD[] pds = interpolateCardinalSpline(
- points[Math.max(i - 1, 0)],
- points[i],
- points[i + 1],
- points[Math.min(i + 2, points.length - 1)],
- samplesInSegment);
- result.addAll(Arrays.asList(pds));
- }
- result.add(points[points.length - 1]);
- return (PointD[]) result.toArray(new PointD[result.size()]);
- }
-}
+ /* Copyright 2012 Yaqiang Wang,
+ * yaqiang.wang@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ */
+package org.meteoinfo.geoprocess;
+
+import org.meteoinfo.common.PointD;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ *
+ * @author Yaqiang Wang
+ */
+public class Spline {
+
+ private static class Vec2 {
+
+ public double X, Y;
+
+ public Vec2(double x, double y) {
+ this.X = x;
+ this.Y = y;
+ }
+
+ public Vec2(PointD p) {
+ this.X = p.X;
+ this.Y = p.Y;
+ }
+
+ public PointD toPointD() {
+ return new PointD(X, Y);
+ }
+
+ public Vec2 add(Vec2 v) {
+ return new Vec2(this.X + v.X, this.Y + v.Y);
+ }
+
+ public Vec2 subtract(Vec2 v) {
+ return new Vec2(this.X - v.X, this.Y - v.Y);
+ }
+
+ public Vec2 multiply(float f) {
+ return new Vec2(this.X * f, this.Y * f);
+ }
+
+ public Vec2 divide(float f) {
+ return new Vec2(this.X / f, this.Y / f);
+ }
+ }
+
+ private static PointD[] interpolateBezier(PointD p0, PointD p1, PointD p2, PointD p3, int samples) {
+ PointD[] result = new PointD[samples];
+ Vec2 v0 = new Vec2(p0);
+ Vec2 v1 = new Vec2(p1);
+ Vec2 v2 = new Vec2(p2);
+ Vec2 v3 = new Vec2(p3);
+ for (int i = 0; i < samples; i++) {
+ float t = (i + 1) / (samples + 1.0f);
+ result[i] = (v0.multiply((1 - t) * (1 - t) * (1 - t)).
+ add(v1.multiply(3 * (1 - t) * (1 - t) * t)).
+ add(v2.multiply(3 * (1 - t) * t * t)).
+ add(v3.multiply(t * t * t))).toPointD();
+ }
+ return result;
+ }
+
+ private static PointD[] interpolateCardinalSpline(PointD p0, PointD p1, PointD p2, PointD p3, int samples) {
+ float tension = 0.5f;
+ Vec2 v0 = new Vec2(p0);
+ Vec2 v1 = new Vec2(p1);
+ Vec2 v2 = new Vec2(p2);
+ Vec2 v3 = new Vec2(p3);
+
+ PointD u = v2.subtract(v0).multiply(tension / 3).add(v1).toPointD();
+ PointD v = v1.subtract(v3).multiply(tension / 3).add(v2).toPointD();
+
+ return interpolateBezier(p1, u, v, p2, samples);
+ }
+
+ /**
+ * '基数样条'内插法。 points为通过点,samplesInSegment为两个样本点之间的内插数量。
+ *
+ * @param points The points
+ * @param samplesInSegment Sample in segment
+ * @return Splined points
+ */
+ public static PointD[] cardinalSpline(PointD[] points, int samplesInSegment) {
+ List result = new ArrayList<>();
+ for (int i = 0; i < points.length - 1; i++) {
+ result.add(points[i]);
+ PointD[] pds = interpolateCardinalSpline(
+ points[Math.max(i - 1, 0)],
+ points[i],
+ points[i + 1],
+ points[Math.min(i + 2, points.length - 1)],
+ samplesInSegment);
+ result.addAll(Arrays.asList(pds));
+ }
+ result.add(points[points.length - 1]);
+ return (PointD[]) result.toArray(new PointD[result.size()]);
+ }
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/global/DataConvert.java b/MeteoInfoLib/src/main/java/org/meteoinfo/global/DataConvert.java
index ebd811cb..91a73503 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/global/DataConvert.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/global/DataConvert.java
@@ -29,8 +29,8 @@ import java.util.Date;
import java.util.LinkedList;
import java.util.List;
-import org.meteoinfo.global.util.JDateUtil;
-import org.meteoinfo.global.util.TypeUtils;
+import org.meteoinfo.common.util.JDateUtil;
+import org.meteoinfo.common.util.TypeUtils;
import org.meteoinfo.ndarray.DataType;
/**
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/global/colors/ColorMap.java b/MeteoInfoLib/src/main/java/org/meteoinfo/global/colors/ColorMap.java
index ae4dd02b..5b431617 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/global/colors/ColorMap.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/global/colors/ColorMap.java
@@ -17,7 +17,8 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
-import org.meteoinfo.global.MIMath;
+
+import org.meteoinfo.common.MIMath;
import org.meteoinfo.legend.LegendManage;
/**
@@ -459,7 +460,7 @@ public class ColorMap {
line = line.trim();
strs = line.split("\\s+");
if (strs.length >= 3){
- if (MIMath.isNumeric(strs[0]) && MIMath.isNumeric(strs[1]) &&
+ if (MIMath.isNumeric(strs[0]) && MIMath.isNumeric(strs[1]) &&
MIMath.isNumeric(strs[2])){
if (n == 0){
if (strs[0].contains("."))
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/global/colors/ColorUtil.java b/MeteoInfoLib/src/main/java/org/meteoinfo/global/colors/ColorUtil.java
index e536509e..81978ae4 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/global/colors/ColorUtil.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/global/colors/ColorUtil.java
@@ -1,568 +1,569 @@
- /* Copyright 2012 Yaqiang Wang,
- * yaqiang.wang@gmail.com
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.global.colors;
-
-import java.awt.Color;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import org.meteoinfo.global.MIMath;
-import org.meteoinfo.global.util.GlobalUtil;
-
-/**
- * ColorUtiles class
- *
- * @author Yaqiang
- */
-public class ColorUtil {
- //
-
- private final static Map colorNames;
-
- static {
- // color names.
- colorNames = new HashMap();
- colorNames.put("aliceblue", new Color(0xF0F8FF));
- colorNames.put("antiquewhite", new Color(0xFAEBD7));
- colorNames.put("black", new Color(0x000000));
- colorNames.put("green", new Color(0x008000));
- colorNames.put("silver", new Color(0xC0C0C0));
- colorNames.put("lime", new Color(0x00FF00));
- colorNames.put("gray", new Color(0x808080));
- colorNames.put("darkgray", new Color(0xA9A9A9));
- colorNames.put("olive", new Color(0x808000));
- colorNames.put("white", new Color(0xFFFFFF));
- colorNames.put("yellow", new Color(0xFFFF00));
- colorNames.put("maroon", new Color(0x800000));
- colorNames.put("navy", new Color(0x000080));
- colorNames.put("red", new Color(0xFF0000));
- colorNames.put("blue", new Color(0x0000FF));
- colorNames.put("purple", new Color(0x800080));
- colorNames.put("teal", new Color(0x008080));
- colorNames.put("fuchsia", new Color(0xFF00FF));
- colorNames.put("aqua", new Color(0x00FFFF));
- colorNames.put("transparent", new Color(0, 0, 0, 0));
- }
-
- //
- //
- //
- //
-
- /**
- * Get common color
- *
- * @param idx Index
- * @return Common color
- */
- public static Color getCommonColor(int idx) {
-// if (idx == 0) {
-// idx = 1;
-// }
- if (idx > 11) {
- idx = idx % 11;
- }
-
- switch (idx) {
- case 0:
- return Color.red;
- case 1:
- return Color.blue;
- case 2:
- return Color.green;
- case 3:
- return Color.black;
- case 4:
- return Color.yellow;
- case 5:
- return Color.pink;
- case 6:
- return Color.gray;
- case 7:
- return Color.cyan;
- case 8:
- return Color.magenta;
- case 9:
- return Color.orange;
- case 10:
- return Color.darkGray;
- case 11:
- return Color.lightGray;
- }
-
- return Color.red;
- }
- //
- //
-
- /**
- * Convert a color to hex string
- *
- * @param color a color
- * @return Hex string
- */
- public static String toHexEncoding(Color color) {
- String A, R, G, B;
- StringBuilder sb = new StringBuilder();
-
- A = Integer.toHexString(color.getAlpha());
- R = Integer.toHexString(color.getRed());
- G = Integer.toHexString(color.getGreen());
- B = Integer.toHexString(color.getBlue());
-
- A = A.length() == 1 ? "0" + A : A;
- R = R.length() == 1 ? "0" + R : R;
- G = G.length() == 1 ? "0" + G : G;
- B = B.length() == 1 ? "0" + B : B;
-
- sb.append("0x");
- sb.append(A);
- sb.append(R);
- sb.append(G);
- sb.append(B);
-
- return sb.toString();
- }
-
- /**
- * Parse hex string to color
- *
- * @param c hex string
- * @return Color
- */
- public static Color parseToColor(final String c) {
- //Color convertedColor = (Color) colorNames.get(c.trim().toLowerCase());
- Color convertedColor = Color.white;
- try {
- WebColor webColor = WebColor.valueOf(c.trim());
- convertedColor = WebColor.valueOf(c.trim()).getColor();
- } catch (IllegalArgumentException e) {
- try {
- if (c.length() == 10) {
- String aStr = c.substring(2, 4);
- String cStr = c.substring(0, 2) + c.substring(4);
- int alpha = Integer.parseInt(aStr, 16);
- //int rgb = Integer.parseInt(cStr);
- convertedColor = Color.decode(cStr);
- //convertedColor = new Color(rgb);
- convertedColor = new Color(convertedColor.getRed(), convertedColor.getGreen(), convertedColor.getBlue(), alpha);
- } else {
- //convertedColor = new Color(Integer.parseInt(c, 16));
- convertedColor = Color.decode(c);
- }
- } catch (NumberFormatException ne) {
- // codes to deal with this exception
- //convertedColor = Color.white;
- }
- }
-
- return convertedColor;
- }
-
- /**
- * Modifies an existing brightness level of a color
- *
- * @param c The color
- * @param brightness The brightness
- * @return Adjusted color
- */
- public static Color modifyBrightness(Color c, float brightness) {
- float hsbVals[] = Color.RGBtoHSB(c.getRed(), c.getGreen(), c.getBlue(), null);
- return Color.getHSBColor(hsbVals[0], hsbVals[1], brightness * hsbVals[2]);
- }
-
- /**
- * Convert color to KML color string - AABBGGRR
- *
- * @param color The color
- * @return KML color string
- */
- public static String toKMLColor(Color color) {
- String A, R, G, B;
- StringBuilder sb = new StringBuilder();
-
- A = Integer.toHexString(color.getAlpha()).toUpperCase();
- R = Integer.toHexString(color.getRed()).toUpperCase();
- G = Integer.toHexString(color.getGreen()).toUpperCase();
- B = Integer.toHexString(color.getBlue()).toUpperCase();
-
- A = A.length() == 1 ? "0" + A : A;
- R = R.length() == 1 ? "0" + R : R;
- G = G.length() == 1 ? "0" + G : G;
- B = B.length() == 1 ? "0" + B : B;
-
- //sb.append("0x");
- sb.append(A);
- sb.append(B);
- sb.append(G);
- sb.append(R);
-
- return sb.toString();
- }
-
- /**
- * Get color tables
- *
- * @return Color tables
- * @throws IOException
- */
- public static ColorMap[] getColorTables() throws IOException {
- String fn = GlobalUtil.getAppPath(ColorUtil.class);
- boolean isDebug = java.lang.management.ManagementFactory.getRuntimeMXBean().
- getInputArguments().toString().contains("jdwp");
- if (isDebug) {
- fn = "D:/MyProgram/Distribution/Java/MeteoInfo/MeteoInfo/";
- }
- fn = fn.substring(0, fn.lastIndexOf("/"));
- String path = fn + File.separator + "colormaps";
- File pathDir = new File(path);
- if (!pathDir.isDirectory()) {
- return null;
- }
-
- File[] files = pathDir.listFiles();
- List cts = new ArrayList<>();
- for (File file : files) {
- //InputStream is = ColorUtil.class.getResourceAsStream(pdir + "/" + fileName);
- //System.out.println(file.getAbsolutePath());
- ColorMap ct = new ColorMap();
- ct.readFromFile(file);
- if (ct.getColorCount() > 0) {
- String name = file.getName();
- name = name.substring(0, name.lastIndexOf("."));
- ct.setName(name);
- cts.add(ct);
- }
- }
-
- ColorMap[] ncts = new ColorMap[cts.size()];
- for (int i = 0; i < cts.size(); i++) {
- ncts[i] = cts.get(i);
- }
-
- return ncts;
- }
-
- /**
- * Load color map from rgb file
- * @param fn Color map rgb file path
- * @return Color table
- * @throws java.io.IOException
- */
- public static ColorMap loadColorMap(String fn) throws IOException{
- File ctFile = new File(fn);
- if (!ctFile.isFile())
- return null;
-
- ColorMap ct = new ColorMap();
- ct.readFromFile(fn);
-
- return ct;
- }
-
- /**
- * Load color map from rgb file
- * @param fn Color map rgb file path
- * @param alpha Alpha
- * @return Color table
- * @throws java.io.IOException
- */
- public static ColorMap loadColorMap(String fn, int alpha) throws IOException{
- File ctFile = new File(fn);
- if (!ctFile.isFile())
- return null;
-
- ColorMap ct = new ColorMap();
- ct.readFromFile(fn, alpha);
-
- return ct;
- }
-
- /**
- * Find color table
- * @param cts Color tables
- * @param name Color table name
- * @return Finded color table
- */
- public static ColorMap findColorTable(ColorMap[] cts, String name){
- for (ColorMap ct : cts){
- if (ct.getName().equalsIgnoreCase(name))
- return ct;
- }
-
- return null;
- }
-
- /**
- * Get color tables
- *
- * @return Color tables
- * @throws IOException
- */
- public static ColorMap[] getColorTables_old() throws IOException {
- String pdir = "/images/colortables";
- List fns = new ArrayList<>();
- fns.add("grads_rainbow.rgb");
- fns.add("GHRSST_anomaly.rgb");
- fns.add("amwg256.rgb");
- fns.add("cmp_b2r.rgb");
- fns.add("cmp_flux.rgb");
- fns.add("cmp_haxby.rgb");
- fns.add("matlab_hot.rgb");
- fns.add("matlab_hsv.rgb");
- fns.add("matlab_jet.rgb");
- fns.add("matlab_lines.rgb");
- fns.add("ncl_default.rgb");
- fns.add("ncview_default.ncmap");
- fns.add("rainbow+white+gray.gp");
- fns.add("rainbow.gp");
- fns.add("seaice_1.rgb");
- fns.add("seaice_2.rgb");
-
- List cts = new ArrayList<>();
- for (String fileName : fns) {
- InputStream is = ColorUtil.class.getResourceAsStream(pdir + "/" + fileName);
- ColorMap ct = new ColorMap();
- ct.readFromFile(is);
- cts.add(ct);
- }
-
- ColorMap[] ncts = new ColorMap[cts.size()];
- for (int i = 0; i < cts.size(); i++) {
- ncts[i] = cts.get(i);
- }
-
- return ncts;
- }
-
- /**
- * Create colors from start and end color
- *
- * @param sColor Start color
- * @param eColor End color
- * @param cNum Color number
- * @return Color array
- */
- public static Color[] createColors(Color sColor, Color eColor, int cNum) {
- Color[] colors = new Color[cNum];
- int sR, sG, sB, eR, eG, eB;
- int rStep, gStep, bStep;
- int i;
-
- sR = sColor.getRed();
- sG = sColor.getGreen();
- sB = sColor.getBlue();
- eR = eColor.getRed();
- eG = eColor.getGreen();
- eB = eColor.getBlue();
- rStep = (int) ((eR - sR) / cNum);
- gStep = (int) ((eG - sG) / cNum);
- bStep = (int) ((eB - sB) / cNum);
- for (i = 0; i < colors.length; i++) {
- colors[i] = new Color(sR + i * rStep, sG + i * gStep, sB + i * bStep);
- }
-
- return colors;
- }
-
- /**
- * Create colors
- * @param cm Color map
- * @param min Min value
- * @param max Max value
- * @return Colors
- */
- public static Color[] createColors(ColorMap cm, double min, double max){
- double[] values = MIMath.getIntervalValues(min, max);
- return cm.getColors(values.length + 1);
- }
-
- /**
- * Create colors
- * @param cm Color map
- * @param min Min value
- * @param max Max value
- * @param n Color number
- * @return Colors
- */
- public static Color[] createColors(ColorMap cm, double min, double max, int n){
- double[] values = MIMath.getIntervalValues(min, max, n);
- return cm.getColors(values.length + 1);
- }
-
- /**
- * Create color from start and end color
- *
- * @param sColor Start color
- * @param eColor End color
- * @param p Proportion
- * @return Color
- */
- public static Color createColor(Color sColor, Color eColor, float p) {
- int sR, sG, sB, eR, eG, eB, r, g, b;
-
- sR = sColor.getRed();
- sG = sColor.getGreen();
- sB = sColor.getBlue();
- eR = eColor.getRed();
- eG = eColor.getGreen();
- eB = eColor.getBlue();
- r = (int) (sR + (eR - sR) * p);
- g = (int) (sG + (eG - sG) * p);
- b = (int) (sB + (eB - sB) * p);
-
- return new Color(r, g, b);
- }
-
- /**
- * Create rainbow colors
- *
- * @param cNum Color number
- * @return Rainbow color array
- */
- public static Color[] createRainBowColors(int cNum) {
- if (cNum > 13) {
- //return getRainBowColors_HSL(cNum);
- return getRainBowColors_HSV(cNum);
- }
-
- List colorList = new ArrayList<>();
-
- colorList.add(new Color(160, 0, 200));
- colorList.add(new Color(110, 0, 220));
- colorList.add(new Color(30, 60, 255));
- colorList.add(new Color(0, 160, 255));
- colorList.add(new Color(0, 200, 200));
- colorList.add(new Color(0, 210, 140));
- colorList.add(new Color(0, 220, 0));
- colorList.add(new Color(160, 230, 50));
- colorList.add(new Color(230, 220, 50));
- colorList.add(new Color(230, 175, 45));
- colorList.add(new Color(240, 130, 40));
- colorList.add(new Color(250, 60, 60));
- colorList.add(new Color(240, 0, 130));
-
- switch (cNum) {
- case 12:
- colorList.remove(new Color(0, 210, 140));
- break;
- case 11:
- colorList.remove(new Color(0, 210, 140));
- colorList.remove(new Color(30, 60, 255));
- break;
- case 10:
- colorList.remove(new Color(0, 210, 140));
- colorList.remove(new Color(30, 60, 255));
- colorList.remove(new Color(230, 175, 45));
- break;
- case 9:
- colorList.remove(new Color(0, 210, 140));
- colorList.remove(new Color(30, 60, 255));
- colorList.remove(new Color(230, 175, 45));
- colorList.remove(new Color(160, 230, 50));
- break;
- case 8:
- colorList.remove(new Color(0, 210, 140));
- colorList.remove(new Color(30, 60, 255));
- colorList.remove(new Color(230, 175, 45));
- colorList.remove(new Color(160, 230, 50));
- colorList.remove(new Color(110, 0, 220));
- break;
- case 7:
- colorList.remove(new Color(0, 210, 140));
- colorList.remove(new Color(30, 60, 255));
- colorList.remove(new Color(230, 175, 45));
- colorList.remove(new Color(160, 230, 50));
- colorList.remove(new Color(110, 0, 220));
- colorList.remove(new Color(0, 200, 200));
- break;
- case 6:
- colorList.remove(new Color(0, 210, 140));
- colorList.remove(new Color(30, 60, 255));
- colorList.remove(new Color(230, 175, 45));
- colorList.remove(new Color(160, 230, 50));
- colorList.remove(new Color(110, 0, 220));
- colorList.remove(new Color(0, 200, 200));
- colorList.remove(new Color(240, 130, 40));
- break;
- case 5:
- colorList.remove(new Color(0, 210, 140));
- colorList.remove(new Color(30, 60, 255));
- colorList.remove(new Color(230, 175, 45));
- colorList.remove(new Color(160, 230, 50));
- colorList.remove(new Color(110, 0, 220));
- colorList.remove(new Color(0, 200, 200));
- colorList.remove(new Color(240, 130, 40));
- colorList.remove(new Color(160, 0, 200));
- break;
- }
-
- Color[] colors = new Color[cNum];
- for (int i = 0; i < cNum; i++) {
- colors[i] = colorList.get(i);
- }
-
- return colors;
- }
-
- /**
- * Get rainbow color by HSV/HSB
- *
- * @param cNum Color number
- * @return Rainbow colors
- */
- public static Color[] getRainBowColors_HSV(int cNum) {
- double p = 360.0 / cNum;
- Color[] colors = new Color[cNum];
- for (int i = 0; i < cNum; i++) {
- colors[cNum - i - 1] = Color.getHSBColor((float) (i * p), 1.0f, 1.0f);
- }
-
- return colors;
- }
-
- /**
- * Create a random color
- * @return A random color
- */
- public static Color createRandomColor(){
- Random randomColor = new Random();
- return new Color(randomColor.nextInt(256), randomColor.nextInt(256), randomColor.nextInt(256));
- }
-
- /**
- * Create random colors
- *
- * @param cNum Color number
- * @return The random colors
- */
- public static Color[] createRandomColors(int cNum) {
- Color[] colors = new Color[cNum];
- int i;
- Random randomColor = new Random();
-
- for (i = 0; i < cNum; i++) {
- colors[i] = new Color(randomColor.nextInt(256),
- randomColor.nextInt(256), randomColor.nextInt(256));
- }
-
- return colors;
- }
- //
-}
+ /* Copyright 2012 Yaqiang Wang,
+ * yaqiang.wang@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ */
+package org.meteoinfo.global.colors;
+
+import org.meteoinfo.common.MIMath;
+import org.meteoinfo.common.util.GlobalUtil;
+
+import java.awt.Color;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+
+ /**
+ * ColorUtiles class
+ *
+ * @author Yaqiang
+ */
+public class ColorUtil {
+ //
+
+ private final static Map colorNames;
+
+ static {
+ // color names.
+ colorNames = new HashMap();
+ colorNames.put("aliceblue", new Color(0xF0F8FF));
+ colorNames.put("antiquewhite", new Color(0xFAEBD7));
+ colorNames.put("black", new Color(0x000000));
+ colorNames.put("green", new Color(0x008000));
+ colorNames.put("silver", new Color(0xC0C0C0));
+ colorNames.put("lime", new Color(0x00FF00));
+ colorNames.put("gray", new Color(0x808080));
+ colorNames.put("darkgray", new Color(0xA9A9A9));
+ colorNames.put("olive", new Color(0x808000));
+ colorNames.put("white", new Color(0xFFFFFF));
+ colorNames.put("yellow", new Color(0xFFFF00));
+ colorNames.put("maroon", new Color(0x800000));
+ colorNames.put("navy", new Color(0x000080));
+ colorNames.put("red", new Color(0xFF0000));
+ colorNames.put("blue", new Color(0x0000FF));
+ colorNames.put("purple", new Color(0x800080));
+ colorNames.put("teal", new Color(0x008080));
+ colorNames.put("fuchsia", new Color(0xFF00FF));
+ colorNames.put("aqua", new Color(0x00FFFF));
+ colorNames.put("transparent", new Color(0, 0, 0, 0));
+ }
+
+ //
+ //
+ //
+ //
+
+ /**
+ * Get common color
+ *
+ * @param idx Index
+ * @return Common color
+ */
+ public static Color getCommonColor(int idx) {
+// if (idx == 0) {
+// idx = 1;
+// }
+ if (idx > 11) {
+ idx = idx % 11;
+ }
+
+ switch (idx) {
+ case 0:
+ return Color.red;
+ case 1:
+ return Color.blue;
+ case 2:
+ return Color.green;
+ case 3:
+ return Color.black;
+ case 4:
+ return Color.yellow;
+ case 5:
+ return Color.pink;
+ case 6:
+ return Color.gray;
+ case 7:
+ return Color.cyan;
+ case 8:
+ return Color.magenta;
+ case 9:
+ return Color.orange;
+ case 10:
+ return Color.darkGray;
+ case 11:
+ return Color.lightGray;
+ }
+
+ return Color.red;
+ }
+ //
+ //
+
+ /**
+ * Convert a color to hex string
+ *
+ * @param color a color
+ * @return Hex string
+ */
+ public static String toHexEncoding(Color color) {
+ String A, R, G, B;
+ StringBuilder sb = new StringBuilder();
+
+ A = Integer.toHexString(color.getAlpha());
+ R = Integer.toHexString(color.getRed());
+ G = Integer.toHexString(color.getGreen());
+ B = Integer.toHexString(color.getBlue());
+
+ A = A.length() == 1 ? "0" + A : A;
+ R = R.length() == 1 ? "0" + R : R;
+ G = G.length() == 1 ? "0" + G : G;
+ B = B.length() == 1 ? "0" + B : B;
+
+ sb.append("0x");
+ sb.append(A);
+ sb.append(R);
+ sb.append(G);
+ sb.append(B);
+
+ return sb.toString();
+ }
+
+ /**
+ * Parse hex string to color
+ *
+ * @param c hex string
+ * @return Color
+ */
+ public static Color parseToColor(final String c) {
+ //Color convertedColor = (Color) colorNames.get(c.trim().toLowerCase());
+ Color convertedColor = Color.white;
+ try {
+ WebColor webColor = WebColor.valueOf(c.trim());
+ convertedColor = WebColor.valueOf(c.trim()).getColor();
+ } catch (IllegalArgumentException e) {
+ try {
+ if (c.length() == 10) {
+ String aStr = c.substring(2, 4);
+ String cStr = c.substring(0, 2) + c.substring(4);
+ int alpha = Integer.parseInt(aStr, 16);
+ //int rgb = Integer.parseInt(cStr);
+ convertedColor = Color.decode(cStr);
+ //convertedColor = new Color(rgb);
+ convertedColor = new Color(convertedColor.getRed(), convertedColor.getGreen(), convertedColor.getBlue(), alpha);
+ } else {
+ //convertedColor = new Color(Integer.parseInt(c, 16));
+ convertedColor = Color.decode(c);
+ }
+ } catch (NumberFormatException ne) {
+ // codes to deal with this exception
+ //convertedColor = Color.white;
+ }
+ }
+
+ return convertedColor;
+ }
+
+ /**
+ * Modifies an existing brightness level of a color
+ *
+ * @param c The color
+ * @param brightness The brightness
+ * @return Adjusted color
+ */
+ public static Color modifyBrightness(Color c, float brightness) {
+ float hsbVals[] = Color.RGBtoHSB(c.getRed(), c.getGreen(), c.getBlue(), null);
+ return Color.getHSBColor(hsbVals[0], hsbVals[1], brightness * hsbVals[2]);
+ }
+
+ /**
+ * Convert color to KML color string - AABBGGRR
+ *
+ * @param color The color
+ * @return KML color string
+ */
+ public static String toKMLColor(Color color) {
+ String A, R, G, B;
+ StringBuilder sb = new StringBuilder();
+
+ A = Integer.toHexString(color.getAlpha()).toUpperCase();
+ R = Integer.toHexString(color.getRed()).toUpperCase();
+ G = Integer.toHexString(color.getGreen()).toUpperCase();
+ B = Integer.toHexString(color.getBlue()).toUpperCase();
+
+ A = A.length() == 1 ? "0" + A : A;
+ R = R.length() == 1 ? "0" + R : R;
+ G = G.length() == 1 ? "0" + G : G;
+ B = B.length() == 1 ? "0" + B : B;
+
+ //sb.append("0x");
+ sb.append(A);
+ sb.append(B);
+ sb.append(G);
+ sb.append(R);
+
+ return sb.toString();
+ }
+
+ /**
+ * Get color tables
+ *
+ * @return Color tables
+ * @throws IOException
+ */
+ public static ColorMap[] getColorTables() throws IOException {
+ String fn = GlobalUtil.getAppPath(ColorUtil.class);
+ boolean isDebug = java.lang.management.ManagementFactory.getRuntimeMXBean().
+ getInputArguments().toString().contains("jdwp");
+ if (isDebug) {
+ fn = "D:/MyProgram/Distribution/Java/MeteoInfo/MeteoInfo/";
+ }
+ fn = fn.substring(0, fn.lastIndexOf("/"));
+ String path = fn + File.separator + "colormaps";
+ File pathDir = new File(path);
+ if (!pathDir.isDirectory()) {
+ return null;
+ }
+
+ File[] files = pathDir.listFiles();
+ List cts = new ArrayList<>();
+ for (File file : files) {
+ //InputStream is = ColorUtil.class.getResourceAsStream(pdir + "/" + fileName);
+ //System.out.println(file.getAbsolutePath());
+ ColorMap ct = new ColorMap();
+ ct.readFromFile(file);
+ if (ct.getColorCount() > 0) {
+ String name = file.getName();
+ name = name.substring(0, name.lastIndexOf("."));
+ ct.setName(name);
+ cts.add(ct);
+ }
+ }
+
+ ColorMap[] ncts = new ColorMap[cts.size()];
+ for (int i = 0; i < cts.size(); i++) {
+ ncts[i] = cts.get(i);
+ }
+
+ return ncts;
+ }
+
+ /**
+ * Load color map from rgb file
+ * @param fn Color map rgb file path
+ * @return Color table
+ * @throws java.io.IOException
+ */
+ public static ColorMap loadColorMap(String fn) throws IOException{
+ File ctFile = new File(fn);
+ if (!ctFile.isFile())
+ return null;
+
+ ColorMap ct = new ColorMap();
+ ct.readFromFile(fn);
+
+ return ct;
+ }
+
+ /**
+ * Load color map from rgb file
+ * @param fn Color map rgb file path
+ * @param alpha Alpha
+ * @return Color table
+ * @throws java.io.IOException
+ */
+ public static ColorMap loadColorMap(String fn, int alpha) throws IOException{
+ File ctFile = new File(fn);
+ if (!ctFile.isFile())
+ return null;
+
+ ColorMap ct = new ColorMap();
+ ct.readFromFile(fn, alpha);
+
+ return ct;
+ }
+
+ /**
+ * Find color table
+ * @param cts Color tables
+ * @param name Color table name
+ * @return Finded color table
+ */
+ public static ColorMap findColorTable(ColorMap[] cts, String name){
+ for (ColorMap ct : cts){
+ if (ct.getName().equalsIgnoreCase(name))
+ return ct;
+ }
+
+ return null;
+ }
+
+ /**
+ * Get color tables
+ *
+ * @return Color tables
+ * @throws IOException
+ */
+ public static ColorMap[] getColorTables_old() throws IOException {
+ String pdir = "/images/colortables";
+ List fns = new ArrayList<>();
+ fns.add("grads_rainbow.rgb");
+ fns.add("GHRSST_anomaly.rgb");
+ fns.add("amwg256.rgb");
+ fns.add("cmp_b2r.rgb");
+ fns.add("cmp_flux.rgb");
+ fns.add("cmp_haxby.rgb");
+ fns.add("matlab_hot.rgb");
+ fns.add("matlab_hsv.rgb");
+ fns.add("matlab_jet.rgb");
+ fns.add("matlab_lines.rgb");
+ fns.add("ncl_default.rgb");
+ fns.add("ncview_default.ncmap");
+ fns.add("rainbow+white+gray.gp");
+ fns.add("rainbow.gp");
+ fns.add("seaice_1.rgb");
+ fns.add("seaice_2.rgb");
+
+ List cts = new ArrayList<>();
+ for (String fileName : fns) {
+ InputStream is = ColorUtil.class.getResourceAsStream(pdir + "/" + fileName);
+ ColorMap ct = new ColorMap();
+ ct.readFromFile(is);
+ cts.add(ct);
+ }
+
+ ColorMap[] ncts = new ColorMap[cts.size()];
+ for (int i = 0; i < cts.size(); i++) {
+ ncts[i] = cts.get(i);
+ }
+
+ return ncts;
+ }
+
+ /**
+ * Create colors from start and end color
+ *
+ * @param sColor Start color
+ * @param eColor End color
+ * @param cNum Color number
+ * @return Color array
+ */
+ public static Color[] createColors(Color sColor, Color eColor, int cNum) {
+ Color[] colors = new Color[cNum];
+ int sR, sG, sB, eR, eG, eB;
+ int rStep, gStep, bStep;
+ int i;
+
+ sR = sColor.getRed();
+ sG = sColor.getGreen();
+ sB = sColor.getBlue();
+ eR = eColor.getRed();
+ eG = eColor.getGreen();
+ eB = eColor.getBlue();
+ rStep = (int) ((eR - sR) / cNum);
+ gStep = (int) ((eG - sG) / cNum);
+ bStep = (int) ((eB - sB) / cNum);
+ for (i = 0; i < colors.length; i++) {
+ colors[i] = new Color(sR + i * rStep, sG + i * gStep, sB + i * bStep);
+ }
+
+ return colors;
+ }
+
+ /**
+ * Create colors
+ * @param cm Color map
+ * @param min Min value
+ * @param max Max value
+ * @return Colors
+ */
+ public static Color[] createColors(ColorMap cm, double min, double max){
+ double[] values = MIMath.getIntervalValues(min, max);
+ return cm.getColors(values.length + 1);
+ }
+
+ /**
+ * Create colors
+ * @param cm Color map
+ * @param min Min value
+ * @param max Max value
+ * @param n Color number
+ * @return Colors
+ */
+ public static Color[] createColors(ColorMap cm, double min, double max, int n){
+ double[] values = MIMath.getIntervalValues(min, max, n);
+ return cm.getColors(values.length + 1);
+ }
+
+ /**
+ * Create color from start and end color
+ *
+ * @param sColor Start color
+ * @param eColor End color
+ * @param p Proportion
+ * @return Color
+ */
+ public static Color createColor(Color sColor, Color eColor, float p) {
+ int sR, sG, sB, eR, eG, eB, r, g, b;
+
+ sR = sColor.getRed();
+ sG = sColor.getGreen();
+ sB = sColor.getBlue();
+ eR = eColor.getRed();
+ eG = eColor.getGreen();
+ eB = eColor.getBlue();
+ r = (int) (sR + (eR - sR) * p);
+ g = (int) (sG + (eG - sG) * p);
+ b = (int) (sB + (eB - sB) * p);
+
+ return new Color(r, g, b);
+ }
+
+ /**
+ * Create rainbow colors
+ *
+ * @param cNum Color number
+ * @return Rainbow color array
+ */
+ public static Color[] createRainBowColors(int cNum) {
+ if (cNum > 13) {
+ //return getRainBowColors_HSL(cNum);
+ return getRainBowColors_HSV(cNum);
+ }
+
+ List colorList = new ArrayList<>();
+
+ colorList.add(new Color(160, 0, 200));
+ colorList.add(new Color(110, 0, 220));
+ colorList.add(new Color(30, 60, 255));
+ colorList.add(new Color(0, 160, 255));
+ colorList.add(new Color(0, 200, 200));
+ colorList.add(new Color(0, 210, 140));
+ colorList.add(new Color(0, 220, 0));
+ colorList.add(new Color(160, 230, 50));
+ colorList.add(new Color(230, 220, 50));
+ colorList.add(new Color(230, 175, 45));
+ colorList.add(new Color(240, 130, 40));
+ colorList.add(new Color(250, 60, 60));
+ colorList.add(new Color(240, 0, 130));
+
+ switch (cNum) {
+ case 12:
+ colorList.remove(new Color(0, 210, 140));
+ break;
+ case 11:
+ colorList.remove(new Color(0, 210, 140));
+ colorList.remove(new Color(30, 60, 255));
+ break;
+ case 10:
+ colorList.remove(new Color(0, 210, 140));
+ colorList.remove(new Color(30, 60, 255));
+ colorList.remove(new Color(230, 175, 45));
+ break;
+ case 9:
+ colorList.remove(new Color(0, 210, 140));
+ colorList.remove(new Color(30, 60, 255));
+ colorList.remove(new Color(230, 175, 45));
+ colorList.remove(new Color(160, 230, 50));
+ break;
+ case 8:
+ colorList.remove(new Color(0, 210, 140));
+ colorList.remove(new Color(30, 60, 255));
+ colorList.remove(new Color(230, 175, 45));
+ colorList.remove(new Color(160, 230, 50));
+ colorList.remove(new Color(110, 0, 220));
+ break;
+ case 7:
+ colorList.remove(new Color(0, 210, 140));
+ colorList.remove(new Color(30, 60, 255));
+ colorList.remove(new Color(230, 175, 45));
+ colorList.remove(new Color(160, 230, 50));
+ colorList.remove(new Color(110, 0, 220));
+ colorList.remove(new Color(0, 200, 200));
+ break;
+ case 6:
+ colorList.remove(new Color(0, 210, 140));
+ colorList.remove(new Color(30, 60, 255));
+ colorList.remove(new Color(230, 175, 45));
+ colorList.remove(new Color(160, 230, 50));
+ colorList.remove(new Color(110, 0, 220));
+ colorList.remove(new Color(0, 200, 200));
+ colorList.remove(new Color(240, 130, 40));
+ break;
+ case 5:
+ colorList.remove(new Color(0, 210, 140));
+ colorList.remove(new Color(30, 60, 255));
+ colorList.remove(new Color(230, 175, 45));
+ colorList.remove(new Color(160, 230, 50));
+ colorList.remove(new Color(110, 0, 220));
+ colorList.remove(new Color(0, 200, 200));
+ colorList.remove(new Color(240, 130, 40));
+ colorList.remove(new Color(160, 0, 200));
+ break;
+ }
+
+ Color[] colors = new Color[cNum];
+ for (int i = 0; i < cNum; i++) {
+ colors[i] = colorList.get(i);
+ }
+
+ return colors;
+ }
+
+ /**
+ * Get rainbow color by HSV/HSB
+ *
+ * @param cNum Color number
+ * @return Rainbow colors
+ */
+ public static Color[] getRainBowColors_HSV(int cNum) {
+ double p = 360.0 / cNum;
+ Color[] colors = new Color[cNum];
+ for (int i = 0; i < cNum; i++) {
+ colors[cNum - i - 1] = Color.getHSBColor((float) (i * p), 1.0f, 1.0f);
+ }
+
+ return colors;
+ }
+
+ /**
+ * Create a random color
+ * @return A random color
+ */
+ public static Color createRandomColor(){
+ Random randomColor = new Random();
+ return new Color(randomColor.nextInt(256), randomColor.nextInt(256), randomColor.nextInt(256));
+ }
+
+ /**
+ * Create random colors
+ *
+ * @param cNum Color number
+ * @return The random colors
+ */
+ public static Color[] createRandomColors(int cNum) {
+ Color[] colors = new Color[cNum];
+ int i;
+ Random randomColor = new Random();
+
+ for (i = 0; i < cNum; i++) {
+ colors[i] = new Color(randomColor.nextInt(256),
+ randomColor.nextInt(256), randomColor.nextInt(256));
+ }
+
+ return colors;
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/global/util/DateUtil.java b/MeteoInfoLib/src/main/java/org/meteoinfo/global/util/DateUtil.java
deleted file mode 100644
index f072860c..00000000
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/global/util/DateUtil.java
+++ /dev/null
@@ -1,456 +0,0 @@
-/* Copyright 2012 Yaqiang Wang,
- * yaqiang.wang@gmail.com
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.global.util;
-
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.List;
-
-import org.joda.time.*;
-import org.joda.time.format.DateTimeFormatter;
-import org.meteoinfo.ndarray.util.BigDecimalUtil;
-
-/**
- *
- * @author yaqiang
- */
-public class DateUtil {
- //
- //
- //
- //
- //
- //
- //
-
- /**
- * Add days to a date
- *
- * @param sDate Start date
- * @param days Days
- * @return Added date
- */
- public static Date addDays(Date sDate, float days) {
- Calendar cal = Calendar.getInstance();
- cal.setTime(sDate);
- int intDays = (int) days;
- cal.add(Calendar.DAY_OF_YEAR, intDays);
- int hours = (int) ((days - intDays) * 24);
- cal.add(Calendar.HOUR, hours);
-
- return cal.getTime();
- }
-
- /**
- * Get days of a month
- *
- * @param year The year
- * @param month The month
- * @return The days in the month
- */
- public static int getDaysInMonth(int year, int month) {
- Calendar cal = Calendar.getInstance();
- cal.set(year, month, 1);
-
- return cal.getActualMaximum(Calendar.DAY_OF_MONTH);
- }
-
- /**
- * Get time values - Time delta values of base date
- *
- * @param times Time list
- * @param baseDate Base date
- * @param tDelta Time delta type - days/hours/...
- * @return The time delta values
- */
- public static List getTimeDeltaValues(List times, Date baseDate, String tDelta) {
- List values = new ArrayList<>();
- Calendar cal = Calendar.getInstance();
- cal.setTime(baseDate);
- long sl = cal.getTimeInMillis();
- long el, delta;
- int value;
- for (int i = 0; i < times.size(); i++) {
- cal.setTime(times.get(i));
- el = cal.getTimeInMillis();
- delta = el - sl;
- if (tDelta.equalsIgnoreCase("hours")) {
- value = (int) (delta / (60 * 60 * 1000));
- values.add(value);
- } else if (tDelta.equalsIgnoreCase("days")) {
- value = (int) (delta / (24 * 60 * 60 * 1000));
- values.add(value);
- }
- }
-
- return values;
- }
-
- /**
- * Get time value - Time delta value of base date
- *
- * @param t The time
- * @param baseDate Base date
- * @param tDelta Time delta type - days/hours/...
- * @return The time delta value
- */
- public static int getTimeDeltaValue(Date t, Date baseDate, String tDelta) {
- Calendar cal = Calendar.getInstance();
- cal.setTime(baseDate);
- long sl = cal.getTimeInMillis();
- long el, delta;
- int value = 0;
- cal.setTime(t);
- el = cal.getTimeInMillis();
- delta = el - sl;
- if (tDelta.equalsIgnoreCase("hours")) {
- value = (int) (delta / (60 * 60 * 1000));
- } else if (tDelta.equalsIgnoreCase("days")) {
- value = (int) (delta / (24 * 60 * 60 * 1000));
- }
-
- return value;
- }
-
- /**
- * Get days difference between two dates
- *
- * @param t The time
- * @param baseDate Base date
- * @return The time delta value
- */
- public static int getDays(Date t, Date baseDate) {
- Calendar cal = Calendar.getInstance();
- cal.setTime(baseDate);
- long sl = cal.getTimeInMillis();
- long el, delta;
- cal.setTime(t);
- el = cal.getTimeInMillis();
- delta = el - sl;
- int value = (int) (delta / (24 * 60 * 60 * 1000));
-
- return value;
- }
-
- /**
- * Get hours difference between two dates
- *
- * @param t The time
- * @param baseDate Base date
- * @return The time delta value
- */
- public static int getHours(Date t, Date baseDate) {
- Calendar cal = Calendar.getInstance();
- cal.setTime(baseDate);
- long sl = cal.getTimeInMillis();
- long el, delta;
- cal.setTime(t);
- el = cal.getTimeInMillis();
- delta = el - sl;
- int value = (int) (delta / (60 * 60 * 1000));
-
- return value;
- }
-
- /**
- * Convert OA date to date
- *
- * @param oaDate OA date
- * @return Date
- */
- public static Date fromOADate(double oaDate) {
- Date date = new Date();
- //long t = (long)((oaDate - 25569) * 24 * 3600 * 1000);
- //long t = (long) (oaDate * 1000000);
- long t = (long) BigDecimalUtil.mul(oaDate, 1000000);
- date.setTime(t);
- return date;
- }
-
- /**
- * Convert date to OA date
- *
- * @param date Date
- * @return OA date
- */
- public static double toOADate(Date date) {
- double oaDate = date.getTime();
- //oaDate = oaDate / (24 * 3600 * 1000) + 25569;
- //oaDate = oaDate / 1000000;
- oaDate = BigDecimalUtil.div(oaDate, 1000000);
-
- return oaDate;
- }
-
- /**
- * Date equals
- *
- * @param a Date a
- * @param b Date b
- * @return If equals
- */
- public static boolean equals(Date a, Date b) {
- if (a.getTime() == b.getTime()) {
- return true;
- } else {
- return false;
- }
- }
-
- /**
- * Get day of year
- *
- * @param year Year
- * @param month Month
- * @param day Day
- * @return Day of year
- */
- public static int dayOfYear(int year, int month, int day) {
- Calendar cal = Calendar.getInstance();
- cal.set(year, month, day);
- int doy = cal.get(Calendar.DAY_OF_YEAR);
- return doy;
- }
-
- /**
- * Convert day of year to date
- *
- * @param year Year
- * @param doy Day of year
- * @return The date
- */
- public static Date doy2date(int year, int doy) {
- Calendar cal = Calendar.getInstance();
- cal.set(Calendar.YEAR, year);
- cal.set(Calendar.DAY_OF_YEAR, doy);
- return cal.getTime();
- }
-
- /**
- * Get period type from string
- *
- * @param p Period type string
- * @return PeriodType
- */
- public static PeriodType getPeriodType(String p) {
- PeriodType pt = PeriodType.days();
- switch (p) {
- case "H":
- pt = PeriodType.hours();
- break;
- case "M":
- pt = PeriodType.minutes();
- break;
- case "S":
- pt = PeriodType.seconds();
- break;
- case "m":
- pt = PeriodType.months();
- break;
- case "Y":
- pt = PeriodType.years();
- break;
- }
-
- return pt;
- }
-
- /**
- * Get period from string
- *
- * @param pStr Period string
- * @return Period
- */
- public static ReadablePeriod getPeriod(String pStr) {
- String p;
- int n = 1;
- int idx = 0;
- for (int i = 0; i < pStr.length(); i++) {
- if (Character.isLetter(pStr.charAt(i))){
- break;
- }
- idx += 1;
- }
- if (idx == 0) {
- p = pStr;
- } else {
- p = pStr.substring(idx);
- n = Integer.parseInt(pStr.substring(0, idx));
- }
-
- ReadablePeriod pe;
- switch (p) {
- case "H":
- pe = Hours.hours(n);
- break;
- case "T":
- case "Min":
- pe = Minutes.minutes(n);
- break;
- case "S":
- pe = Seconds.seconds(n);
- break;
- case "D":
- pe = Days.days(n);
- break;
- case "W":
- pe = Weeks.weeks(n);
- break;
- case "M":
- pe = Months.months(n);
- break;
- case "Y":
- pe = Years.years(n);
- break;
- default:
- pe = new Period();
- break;
- }
-
- return pe;
- }
-
- /**
- * Get date format string
- *
- * @param p Period
- * @return Date format string
- */
- public static String getDateFormat(ReadablePeriod p) {
- String df = "yyyy-MM-dd";
- if (p instanceof Hours) {
- df = "yyyy-MM-dd HH";
- } else if (p instanceof Minutes) {
- df = "yyyy-MM-dd HH:mm";
- } else if (p instanceof Seconds) {
- df = "yyyy-MM-dd HH:mm:ss";
- }
-
- return df;
- }
-
- /**
- * Get date time from string
- *
- * @param dts Date time string
- * @return DateTime
- */
- public static DateTime getDateTime(String dts) {
- int year, month, day;
- String dateStr = dts;
- String timeStr = null;
- if (dts.contains(":")) {
- String[] v = dts.split("\\s+");
- dateStr = v[0].trim();
- timeStr = v[1].trim();
- }
- if (dateStr.contains("/")) {
- String[] ymd = dateStr.split("/");
- month = Integer.parseInt(ymd[0]);
- day = Integer.parseInt(ymd[1]);
- year = Integer.parseInt(ymd[2]);
- } else if (dateStr.contains("-")) {
- String[] ymd = dateStr.split("-");
- month = Integer.parseInt(ymd[1]);
- day = Integer.parseInt(ymd[2]);
- year = Integer.parseInt(ymd[0]);
- } else {
- year = Integer.parseInt(dateStr.substring(0, 4));
- month = Integer.parseInt(dateStr.substring(4, 6));
- day = Integer.parseInt(dateStr.substring(6));
- }
- int hour = 0, minute = 0, second = 0;
- if (timeStr != null) {
- String[] hms = timeStr.split(":");
- hour = Integer.parseInt(hms[0]);
- minute = Integer.parseInt(hms[1]);
- second = hms.length == 3 ? Integer.parseInt(hms[2]) : 0;
- }
-
- return new DateTime(year, month, day, hour, minute, second);
- }
-
- /**
- * Get date time from string
- *
- * @param dts Date time string
- * @return DateTime
- */
- public static DateTime getDateTime_(String dts) {
- DateTimeFormatter dtf;
- if (dts.contains(":")) {
- dtf = TypeUtilsBak.getDateTimeFormatter(dts);
- } else {
- dtf = TypeUtilsBak.getDateFormatter(dts);
- }
- DateTime dt = dtf.parseDateTime(dts);
- return dt;
- }
-
- /**
- * Get date time list
- *
- * @param start Start date time
- * @param end End date time
- * @param p Peroid
- * @return Date time list
- */
- public static List getDateTimes(DateTime start, DateTime end, ReadablePeriod p) {
- List dts = new ArrayList<>();
- while (!start.isAfter(end)) {
- dts.add(start);
- start = start.plus(p);
- }
-
- return dts;
- }
-
- /**
- * Get date time list
- *
- * @param start Start date time
- * @param tNum Date time number
- * @param p Peroid
- * @return Date time list
- */
- public static List getDateTimes(DateTime start, int tNum, ReadablePeriod p) {
- List dts = new ArrayList<>();
- for (int i = 0; i < tNum; i++) {
- dts.add(start);
- start = start.plus(p);
- }
-
- return dts;
- }
-
- /**
- * Get date time list
- *
- * @param end End date time
- * @param tNum Date time number
- * @param p Peroid
- * @return Date time list
- */
- public static List getDateTimes(int tNum, DateTime end, ReadablePeriod p) {
- List dts = new ArrayList<>();
- for (int i = 0; i < tNum; i++) {
- dts.add(end);
- end = end.minus(p);
- }
-
- return dts;
- }
- //
-}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/global/util/FontUtil.java b/MeteoInfoLib/src/main/java/org/meteoinfo/global/util/FontUtil.java
index 13bc4c8c..bf2e9fea 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/global/util/FontUtil.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/global/util/FontUtil.java
@@ -1,128 +1,130 @@
- /* Copyright 2012 Yaqiang Wang,
- * yaqiang.wang@gmail.com
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.global.util;
-
-import java.awt.Font;
-import java.awt.FontFormatException;
-import java.awt.GraphicsEnvironment;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import org.meteoinfo.drawing.Draw;
-import org.meteoinfo.legend.MapFrame;
-
-/**
- *
- * @author yaqiang
- */
-public class FontUtil {
-
- /**
- * Get all available fonts (system fonts, weather font and custom fonts)
- *
- * @return Font list
- */
- public static List getAllFonts() {
- List fontList = new ArrayList<>();
-
- //Weather font
- Font weatherFont = getWeatherFont();
- if (weatherFont != null) {
- fontList.add(weatherFont);
- }
-
- //System fonts
- GraphicsEnvironment gEnv = GraphicsEnvironment.getLocalGraphicsEnvironment();
- Font[] fonts = gEnv.getAllFonts();
- for (Font font : fonts) {
- fontList.add(font);
- }
-
- //Custom fonts
- String fn = GlobalUtil.getAppPath(MapFrame.class);
- fn = fn.substring(0, fn.lastIndexOf("/"));
- String path = fn + File.separator + "font";
- File pathDir = new File(path);
- if (pathDir.isDirectory()) {
-
- }
-
- return fontList;
- }
-
- /**
- * Register a font
- * @param font The font
- */
- public static void registerFont(Font font){
- GraphicsEnvironment.getLocalGraphicsEnvironment().registerFont(font);
- }
-
- /**
- * Register a font
- * @param fileName Font file name
- */
- public static void registerFont(String fileName){
- Font font = getFont(fileName);
- if (font != null){
- registerFont(font);
- }
- }
-
- /**
- * Register weather font
- */
- public static void registerWeatherFont(){
- Font weatherFont = getWeatherFont();
- if (weatherFont != null) {
- GraphicsEnvironment.getLocalGraphicsEnvironment().registerFont(weatherFont);
- }
- }
-
- /**
- * Get font from font file - .ttf
- * @param fileName Font file name
- * @return The font
- */
- public static Font getFont(String fileName){
- Font font = null;
- try {
- font = Font.createFont(Font.TRUETYPE_FONT, new File(fileName));
- } catch (FontFormatException | IOException ex) {
- Logger.getLogger(FontUtil.class.getName()).log(Level.SEVERE, null, ex);
- }
- return font;
- }
-
- /**
- * Get weather symbol font
- *
- * @return Weather symbol font
- */
- public static Font getWeatherFont() {
- Font font = null;
- InputStream is = Draw.class.getResourceAsStream("/fonts/WeatherSymbol.ttf");
- try {
- font = Font.createFont(Font.TRUETYPE_FONT, is);
- } catch (FontFormatException | IOException ex) {
- Logger.getLogger(Draw.class.getName()).log(Level.SEVERE, null, ex);
- }
-
- return font;
- }
-}
+ /* Copyright 2012 Yaqiang Wang,
+ * yaqiang.wang@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ */
+package org.meteoinfo.global.util;
+
+import java.awt.Font;
+import java.awt.FontFormatException;
+import java.awt.GraphicsEnvironment;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.meteoinfo.common.util.GlobalUtil;
+import org.meteoinfo.drawing.Draw;
+import org.meteoinfo.legend.MapFrame;
+
+/**
+ *
+ * @author yaqiang
+ */
+public class FontUtil {
+
+ /**
+ * Get all available fonts (system fonts, weather font and custom fonts)
+ *
+ * @return Font list
+ */
+ public static List getAllFonts() {
+ List fontList = new ArrayList<>();
+
+ //Weather font
+ Font weatherFont = getWeatherFont();
+ if (weatherFont != null) {
+ fontList.add(weatherFont);
+ }
+
+ //System fonts
+ GraphicsEnvironment gEnv = GraphicsEnvironment.getLocalGraphicsEnvironment();
+ Font[] fonts = gEnv.getAllFonts();
+ for (Font font : fonts) {
+ fontList.add(font);
+ }
+
+ //Custom fonts
+ String fn = GlobalUtil.getAppPath(MapFrame.class);
+ fn = fn.substring(0, fn.lastIndexOf("/"));
+ String path = fn + File.separator + "font";
+ File pathDir = new File(path);
+ if (pathDir.isDirectory()) {
+
+ }
+
+ return fontList;
+ }
+
+ /**
+ * Register a font
+ * @param font The font
+ */
+ public static void registerFont(Font font){
+ GraphicsEnvironment.getLocalGraphicsEnvironment().registerFont(font);
+ }
+
+ /**
+ * Register a font
+ * @param fileName Font file name
+ */
+ public static void registerFont(String fileName){
+ Font font = getFont(fileName);
+ if (font != null){
+ registerFont(font);
+ }
+ }
+
+ /**
+ * Register weather font
+ */
+ public static void registerWeatherFont(){
+ Font weatherFont = getWeatherFont();
+ if (weatherFont != null) {
+ GraphicsEnvironment.getLocalGraphicsEnvironment().registerFont(weatherFont);
+ }
+ }
+
+ /**
+ * Get font from font file - .ttf
+ * @param fileName Font file name
+ * @return The font
+ */
+ public static Font getFont(String fileName){
+ Font font = null;
+ try {
+ font = Font.createFont(Font.TRUETYPE_FONT, new File(fileName));
+ } catch (FontFormatException | IOException ex) {
+ Logger.getLogger(FontUtil.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ return font;
+ }
+
+ /**
+ * Get weather symbol font
+ *
+ * @return Weather symbol font
+ */
+ public static Font getWeatherFont() {
+ Font font = null;
+ InputStream is = Draw.class.getResourceAsStream("/fonts/WeatherSymbol.ttf");
+ try {
+ font = Font.createFont(Font.TRUETYPE_FONT, is);
+ } catch (FontFormatException | IOException ex) {
+ Logger.getLogger(Draw.class.getName()).log(Level.SEVERE, null, ex);
+ }
+
+ return font;
+ }
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/global/util/GlobalUtil.java b/MeteoInfoLib/src/main/java/org/meteoinfo/global/util/GlobalUtil.java
deleted file mode 100644
index a775450c..00000000
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/global/util/GlobalUtil.java
+++ /dev/null
@@ -1,682 +0,0 @@
- /* Copyright 2012 Yaqiang Wang,
- * yaqiang.wang@gmail.com
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.global.util;
-
-import java.awt.Color;
-import java.awt.Graphics2D;
-import java.awt.Image;
-import java.awt.Toolkit;
-import java.awt.image.BufferedImage;
-import java.awt.image.ColorModel;
-import java.awt.image.FilteredImageSource;
-import java.awt.image.ImageFilter;
-import java.awt.image.ImageProducer;
-import java.awt.image.RGBImageFilter;
-import java.awt.image.WritableRaster;
-import java.io.BufferedReader;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
-
-/**
- * Template
- *
- * @author Yaqiang Wang
- */
-public class GlobalUtil {
- //
- //
- //
- //
- //
- //
- //
-
- /**
- * Get software version
- * @return Software version
- */
- public static String getVersion(){
- String version = GlobalUtil.class.getPackage().getImplementationVersion();
- return version;
- }
-
- /**
- * Get file extension
- *
- * @param filePath The file path
- * @return File extension
- */
- public static String getFileExtension(String filePath) {
- String extension = "";
- String fn = new File(filePath).getName();
- if (fn.contains(".")) {
- String ext = filePath.substring(filePath.lastIndexOf(".") + 1).toLowerCase().trim();
- try {
- extension = ext;
- } catch (IllegalArgumentException e) {
- }
- }
-
- return extension;
- }
-
- /**
- * Get the list of specific file types in a directory
- *
- * @param directory The directory
- * @param ext the file extension
- * @return File name list
- */
- public static List getFiles(String directory, String ext) {
- List fileNames = new ArrayList<>();
- try {
- File f = new File(directory);
- boolean flag = f.isDirectory();
- if (flag) {
- File fs[] = f.listFiles();
- for (int i = 0; i < fs.length; i++) {
- if (!fs[i].isDirectory()) {
- String filename = fs[i].getAbsolutePath();
- if (filename.endsWith(ext.trim())) {
- fileNames.add(filename);
- }
- } else {
- fileNames.addAll(getFiles(fs[i].getAbsolutePath(), ext));
- }
- }
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- return fileNames;
- }
-
- /**
- * Get sub directories
- *
- * @param directory The directory
- * @return Sub directories
- */
- public static List getSubDirectories(String directory) {
- List subDirs = new ArrayList<>();
- File f = new File(directory);
- File fs[] = f.listFiles();
- for (File f1 : fs) {
- if (f1.isDirectory()) {
- subDirs.add(f1.getPath());
- }
- }
-
- return subDirs;
- }
-
- /**
- * Get class names in a jar file
- *
- * @param jarFileName The jar file name
- * @return The class names in the jar file
- * @throws FileNotFoundException
- * @throws IOException
- */
- public static List getClassNames(String jarFileName) throws FileNotFoundException, IOException {
- List classNames = new ArrayList<>();
- ZipInputStream zip = new ZipInputStream(new FileInputStream(jarFileName));
- for (ZipEntry entry = zip.getNextEntry(); entry != null; entry = zip.getNextEntry()) {
- if (entry.getName().endsWith(".class") && !entry.isDirectory()) {
- // This ZipEntry represents a class. Now, what class does it represent?
- StringBuilder className = new StringBuilder();
- for (String part : entry.getName().split("/")) {
- if (className.length() != 0) {
- className.append(".");
- }
- className.append(part);
- if (part.endsWith(".class")) {
- className.setLength(className.length() - ".class".length());
- }
- }
- classNames.add(className.toString());
- }
- }
-
- return classNames;
- }
-
- /**
- * Get the class name which implements IPlugin interface
- *
- * @param jarFileName The jar file name
- * @return The class name which implements IPlugin interface
- */
- public static String getPluginClassName(String jarFileName) {
- String pluginClassName = null;
- try {
- List classNames = getClassNames(jarFileName);
- URL url = new URL("file:" + jarFileName);
- URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{url});
- for (String name : classNames) {
- Class> clazz = urlClassLoader.loadClass(name);
- if (isInterface(clazz, "org.meteoinfo.plugin.IPlugin")) {
- pluginClassName = name;
- break;
- }
- }
- } catch (FileNotFoundException ex) {
- Logger.getLogger(GlobalUtil.class.getName()).log(Level.SEVERE, null, ex);
- } catch (IOException ex) {
- Logger.getLogger(GlobalUtil.class.getName()).log(Level.SEVERE, null, ex);
- } catch (ClassNotFoundException ex) {
- Logger.getLogger(GlobalUtil.class.getName()).log(Level.SEVERE, null, ex);
- }
-
- return pluginClassName;
- }
-
- /**
- * Given a package name, attempts to reflect to find all classes within the
- * package on the local file system.
- *
- * @param packageName
- * @return Class list
- */
- public static List getClassesInPackage(String packageName) {
- List classes = new ArrayList<>();
- String packageNameSlashed = "/" + packageName.replace(".", "/");
- // Get a File object for the package
- URL directoryURL = Thread.currentThread().getContextClassLoader().getResource(packageNameSlashed);
- if (directoryURL == null) {
- System.out.println("Could not retrieve URL resource: " + packageNameSlashed);
- return classes;
- }
-
- String directoryString = directoryURL.getFile();
- if (directoryString == null) {
- System.out.println("Could not find directory for URL resource: " + packageNameSlashed);
- return classes;
- }
-
- File directory = new File(directoryString);
- if (directory.exists()) {
- // Get the list of the files contained in the package
- String[] files = directory.list();
- for (String fileName : files) {
- // We are only interested in .class files
- if (fileName.endsWith(".class")) {
- // Remove the .class extension
- fileName = fileName.substring(0, fileName.length() - 6);
- try {
- classes.add(Class.forName(packageName + "." + fileName));
- } catch (ClassNotFoundException e) {
- System.out.println(packageName + "." + fileName + " does not appear to be a valid class.");
- }
- }
- }
- } else {
- System.out.println(packageName + " does not appear to exist as a valid package on the file system.");
- }
- return classes;
- }
-
- /**
- * Given a package name, attempts to reflect to find all file names within the
- * package on the local file system.
- *
- * @param packageName
- * @return File names
- */
- public static List getFilesInPackage(String packageName) {
- List fns = new ArrayList<>();
- //String packageNameSlashed = "/" + packageName.replace(".", "/");
- String packageNameSlashed = packageName.replace(".", "/");
- // Get a File object for the package
- URL directoryURL = Thread.currentThread().getContextClassLoader().getResource(packageNameSlashed);
- if (directoryURL == null) {
- System.out.println("Could not retrieve URL resource: " + packageNameSlashed);
- return fns;
- }
-
- String directoryString = directoryURL.getFile();
- if (directoryString == null) {
- System.out.println("Could not find directory for URL resource: " + packageNameSlashed);
- return fns;
- }
-
- File directory = new File(directoryString);
- if (directory.exists()) {
- // Get the list of the files contained in the package
- String[] files = directory.list();
- for (String fileName : files) {
- fns.add(fileName);
- }
- } else {
- System.out.println(packageName + " does not appear to exist as a valid package on the file system.");
- }
- return fns;
- }
-
- /**
- * Determine if a class implements a interface
- *
- * @param c The class
- * @param szInterface The interface name
- * @return Boolean
- */
- public static boolean isInterface(Class c, String szInterface) {
- Class[] face = c.getInterfaces();
- for (int i = 0, j = face.length; i < j; i++) {
- if (face[i].getName().equals(szInterface)) {
- return true;
- } else {
- Class[] face1 = face[i].getInterfaces();
- for (int x = 0; x < face1.length; x++) {
- if (face1[x].getName().equals(szInterface)) {
- return true;
- } else if (isInterface(face1[x], szInterface)) {
- return true;
- }
- }
- }
- }
- if (null != c.getSuperclass()) {
- return isInterface(c.getSuperclass(), szInterface);
- }
- return false;
- }
-
- /**
- * Get root path
- *
- * @param aFile The file
- * @return Root path
- */
- public static String getPathRoot(File aFile) {
- File path = aFile.getParentFile();
- String pathRoot = path.toString();
- while (path != null) {
- path = path.getParentFile();
- if (path != null) {
- pathRoot = path.toString();
- }
- }
-
- return pathRoot;
- }
-
- /**
- * Get relative path of the file using project file path
- *
- * @param fileName File path
- * @param projFile Project file path
- * @return Relative path
- * @throws java.io.IOException
- */
- public static String getRelativePath(String fileName, String projFile) throws IOException {
- String RelativePath = "";
- File aFile = new File(fileName);
- File pFile = new File(projFile);
- fileName = aFile.getCanonicalPath();
-
- String layerPathRoot = getPathRoot(aFile);
- String projPathRoot = getPathRoot(pFile);
- if (!layerPathRoot.equalsIgnoreCase(projPathRoot)) {
- RelativePath = fileName;
- } else {
- List aList = new ArrayList<>();
- aList.add(fileName);
- do {
- aList.add("");
- File tempFile = new File(aList.get(aList.size() - 2));
- if (tempFile.exists() && tempFile.getParent() != null) {
- aList.set(aList.size() - 1, tempFile.getParent());
- } else {
- break;
- }
- } while (!"".equals(aList.get(aList.size() - 1)));
-
- List bList = new ArrayList<>();
- bList.add(pFile.getCanonicalPath());
- do {
- bList.add("");
- File tempFile = new File(bList.get(bList.size() - 2));
- if (tempFile.getParent() != null) {
- bList.set(bList.size() - 1, tempFile.getParent());
- } else {
- break;
- }
- } while (!"".equals(bList.get(bList.size() - 1)));
-
- boolean ifExist = false;
- int offSet;
- for (int i = 0; i < aList.size(); i++) {
- for (int j = 0; j < bList.size(); j++) {
- if (aList.get(i).equals(bList.get(j))) {
- for (int k = 1; k < j; k++) {
- RelativePath = RelativePath + ".." + File.separator;
- }
- if (aList.get(i).endsWith(File.separator)) {
- offSet = 0;
- } else {
- offSet = 1;
- }
- RelativePath = RelativePath + fileName.substring(aList.get(i).length() + offSet);
- ifExist = true;
- break;
- }
- }
- if (ifExist) {
- break;
- }
- }
- }
-
- if ("".equals(RelativePath)) {
- RelativePath = fileName;
- }
- return RelativePath;
- }
-
- /**
- * Convert Image to BufferedImage
- *
- * @param image The Image
- * @return The BufferedImage
- */
- public static BufferedImage imageToBufferedImage(Image image) {
-
- BufferedImage bufferedImage = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB);
- Graphics2D g2 = bufferedImage.createGraphics();
- g2.drawImage(image, 0, 0, null);
- g2.dispose();
-
- return bufferedImage;
-
- }
-
- /**
- * Make a color of a image transparent
- *
- * @param im The image
- * @param color The color
- * @return Result image
- */
- public static Image makeColorTransparent(BufferedImage im, final Color color) {
- ImageFilter filter = new RGBImageFilter() {
- // the color we are looking for... Alpha bits are set to opaque
- public int markerRGB = color.getRGB() | 0xFF000000;
-
- @Override
- public final int filterRGB(int x, int y, int rgb) {
- if ((rgb | 0xFF000000) == markerRGB) {
- // Mark the alpha bits as zero - transparent
- return 0x00FFFFFF & rgb;
- } else {
- // nothing to do
- return rgb;
- }
- }
- };
-
- ImageProducer ip = new FilteredImageSource(im.getSource(), filter);
- return Toolkit.getDefaultToolkit().createImage(ip);
- }
-
- /**
- * Get application path by a class
- *
- * @param cls Class
- * @return Application path
- */
- public static String getAppPath(Class cls) {
- if (cls == null) {
- throw new java.lang.IllegalArgumentException("The parameter can not be null!");
- }
-
- ClassLoader loader = cls.getClassLoader();
- //Get class name
- String clsName = cls.getName() + ".class";
- //Get package
- Package pack = cls.getPackage();
- String path = "";
- if (pack != null) {
- String packName = pack.getName();
- //Judge if is Java base class to avoid this condition
- if (packName.startsWith("java.") || packName.startsWith("javax.")) {
- throw new java.lang.IllegalArgumentException("Dont use Java system class!");
- }
- //Remove package name from the class name
- clsName = clsName.substring(packName.length() + 1);
- //Convert package name to path if the package has simple name
- if (!packName.contains(".")) {
- path = packName + "/";
- } else { //Convert package name to path
- int start = 0;
- int end = packName.indexOf(".");
- while (end != -1) {
- path = path + packName.substring(start, end) + "/";
- start = end + 1;
- end = packName.indexOf(".", start);
- }
- path = path + packName.substring(start) + "/";
- }
- }
-
- //Get resource
- java.net.URL url = loader.getResource(path + clsName);
- //Get path
- String realPath = url.getPath();
- //Remove "file:"
- int pos = realPath.indexOf("file:");
- if (pos > -1) {
- realPath = realPath.substring(pos + 5);
- }
- //Remove class info
- pos = realPath.indexOf(path + clsName);
- realPath = realPath.substring(0, pos - 1);
- //Remove JAR package name
- if (realPath.endsWith("!")) {
- realPath = realPath.substring(0, realPath.lastIndexOf("/"));
- }
-
- //Get Chinese path by decode
- try {
- realPath = java.net.URLDecoder.decode(realPath, "utf-8");
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
-
- return realPath;
- }
-
- /**
- * String pad left
- *
- * @param str The string
- * @param length Pad length
- * @param ch Pad char
- * @return Padded string
- */
- public static String padLeft(String str, int length, char ch) {
- for (int i = str.length(); i < length; i++) {
- str = ch + str;
- }
-
- return str;
- }
-
- /**
- * String pad right
- *
- * @param str The string
- * @param length Pad length
- * @param ch Pad char
- * @return Padded string
- */
- public static String padRight(String str, int length, char ch) {
- for (int i = str.length(); i < length; i++) {
- str = str + ch;
- }
-
- return str;
- }
-
- /**
- * Deep clone object
- *
- * @param oldObj Old object
- * @return Cloned object
- * @throws Exception
- */
- public static Object deepCopy(Object oldObj) throws Exception {
- ObjectOutputStream oos = null;
- ObjectInputStream ois = null;
- try {
- ByteArrayOutputStream bos
- = new ByteArrayOutputStream(); // A
- oos = new ObjectOutputStream(bos); // B
- // serialize and pass the object
- oos.writeObject(oldObj); // C
- oos.flush(); // D
- ByteArrayInputStream bin
- = new ByteArrayInputStream(bos.toByteArray()); // E
- ois = new ObjectInputStream(bin); // F
- // return the new object
- return ois.readObject(); // G
- } catch (Exception e) {
- System.out.println("Exception in ObjectCloner = " + e);
- throw (e);
- } finally {
- oos.close();
- ois.close();
- }
- }
-
- /**
- * Deep clone a BufferedIamge
- *
- * @param bi Original image
- * @return Cloned image
- */
- public static BufferedImage deepCopy(BufferedImage bi) {
- ColorModel cm = bi.getColorModel();
- boolean isAlphaPremultiplied = cm.isAlphaPremultiplied();
- WritableRaster raster = bi.copyData(null);
- return new BufferedImage(cm, raster, isAlphaPremultiplied, null);
- }
-
- /**
- * Get default font name
- *
- * @return Default font name
- */
- public static String getDefaultFontName() {
- String[] fontnames = java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
- List fns = Arrays.asList(fontnames);
- String fn = "宋体";
- if (!fns.contains(fn)) {
- fn = "Arial";
- }
-
- if (!fns.contains(fn)) {
- fn = fontnames[0];
- }
-
- return fn;
- }
-
- /**
- * Get separator
- *
- * @param line The string line
- * @return Delimiter string
- */
- public static String getDelimiter(String line) {
- String separator = null;
- if (line.contains(",")) {
- separator = ",";
- } else if (line.contains(";")) {
- separator = ";";
- }
-
- return separator;
- }
-
- /**
- * Get delimiter
- * @param file File
- * @return Delimiter
- * @throws FileNotFoundException
- * @throws IOException
- */
- public static String getDelimiter(File file) throws FileNotFoundException, IOException{
- BufferedReader sr = new BufferedReader(new FileReader(file));
- String line = sr.readLine();
- sr.close();
- return getDelimiter(line);
- }
-
- /**
- * Split a string line by separator
- *
- * @param line The string line
- * @param separator The separator
- * @return Split string array
- */
- public static String[] split(String line, String separator) {
- if (separator == null || separator.equals(" ")) {
- return line.split("\\s+");
- } else {
- String[] strs = line.split(separator);
- List r = new ArrayList<>();
- for (String s : strs){
- r.add(s.trim());
- }
- strs = r.toArray(new String[1]);
- return strs;
- }
- }
-
- /**
- * Capitalize the first character of a string
- * @param str The string
- * @return Capitalized string
- */
- public static String capitalize(String str){
- if(str == null || str.length() == 0)
- return "";
-
- if(str.length() == 1)
- return str.toUpperCase();
-
- char[] charArray = str.toCharArray();
- charArray[0] = Character.toUpperCase(charArray[0]);
- return new String(charArray);
- }
- //
-}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/global/util/TypeUtilsBak.java b/MeteoInfoLib/src/main/java/org/meteoinfo/global/util/TypeUtilsBak.java
deleted file mode 100644
index f323049c..00000000
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/global/util/TypeUtilsBak.java
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.meteoinfo.global.util;
-
-import com.google.common.collect.ImmutableList;
-import org.joda.time.format.DateTimeFormat;
-import org.joda.time.format.DateTimeFormatter;
-import org.joda.time.format.DateTimeFormatterBuilder;
-import org.joda.time.format.ISODateTimeFormat;
-
-import java.time.format.DateTimeParseException;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- *
- * Ported from Tablesaw
- */
-public class TypeUtilsBak {
- // These Strings will convert to true booleans
- public static final List TRUE_STRINGS =
- Arrays.asList("T", "t", "Y", "y", "TRUE", "true", "True", "1");
- // A more restricted set of 'true' strings that is used for column type detection
- public static final List TRUE_STRINGS_FOR_DETECTION =
- Arrays.asList("T", "t", "Y", "y", "TRUE", "true", "True");
- // These Strings will convert to false booleans
- public static final List FALSE_STRINGS =
- Arrays.asList("F", "f", "N", "n", "FALSE", "false", "False", "0");
- // A more restricted set of 'false' strings that is used for column type detection
- public static final List FALSE_STRINGS_FOR_DETECTION =
- Arrays.asList("F", "f", "N", "n", "FALSE", "false", "False");
-
- // Formats that we accept in parsing dates from strings
- // TODO: Add more types, especially dates with month names spelled-out fully.
- private static final DateTimeFormatter dtf1 = DateTimeFormat.forPattern("yyyyMMdd");
- private static final DateTimeFormatter dtf2 = DateTimeFormat.forPattern("MM/dd/yyyy");
- private static final DateTimeFormatter dtf3 = DateTimeFormat.forPattern("MM-dd-yyyy");
- private static final DateTimeFormatter dtf4 = DateTimeFormat.forPattern("MM.dd.yyyy");
- private static final DateTimeFormatter dtf5 = DateTimeFormat.forPattern("yyyy-MM-dd");
- private static final DateTimeFormatter dtf6 = DateTimeFormat.forPattern("yyyy/MM/dd");
- private static final DateTimeFormatter dtf7 = DateTimeFormat.forPattern("dd/MMM/yyyy");
- private static final DateTimeFormatter dtf8 = DateTimeFormat.forPattern("dd-MMM-yyyy");
- private static final DateTimeFormatter dtf9 = DateTimeFormat.forPattern("M/d/yyyy");
- private static final DateTimeFormatter dtf10 = DateTimeFormat.forPattern("M/d/yy");
- private static final DateTimeFormatter dtf11 = DateTimeFormat.forPattern("MMM/dd/yyyy");
- private static final DateTimeFormatter dtf12 = DateTimeFormat.forPattern("MMM-dd-yyyy");
- private static final DateTimeFormatter dtf13 = DateTimeFormat.forPattern("MMM/dd/yy");
- private static final DateTimeFormatter dtf14 = DateTimeFormat.forPattern("MMM-dd-yy");
- private static final DateTimeFormatter dtf15 = DateTimeFormat.forPattern("MMM/dd/yyyy");
- private static final DateTimeFormatter dtf16 = DateTimeFormat.forPattern("MMM/d/yyyy");
- private static final DateTimeFormatter dtf17 = DateTimeFormat.forPattern("MMM-dd-yy");
- private static final DateTimeFormatter dtf18 = DateTimeFormat.forPattern("MMM dd, yyyy");
- private static final DateTimeFormatter dtf19 = DateTimeFormat.forPattern("MMM d, yyyy");
- // A formatter that handles all the date formats defined above
- public static final DateTimeFormatter DATE_FORMATTER =
- new DateTimeFormatterBuilder()
- .append(dtf1)
- .append(dtf2)
- .append(dtf3)
- .append(dtf4)
- .append(dtf5)
- .append(dtf6)
- .append(dtf7)
- .append(dtf8)
- .append(dtf9)
- .append(dtf10)
- .append(dtf11)
- .append(dtf12)
- .append(dtf13)
- .append(dtf14)
- .append(dtf15)
- .append(dtf16)
- .append(dtf17)
- .append(dtf18)
- .append(dtf19)
- .toFormatter();
- private static final DateTimeFormatter dtTimef0 =
- DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss"); // 2014-07-09 13:03:44
- private static final DateTimeFormatter dtTimef2 =
- DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss.S"); // 2014-07-09 13:03:44.7 (as above, but without leading 0 in millis
- private static final DateTimeFormatter dtTimef4 =
- DateTimeFormat.forPattern("dd-MMM-yyyy HH:mm"); // 09-Jul-2014 13:03
- private static final DateTimeFormatter dtTimef5 = ISODateTimeFormat.dateTime();
- private static final DateTimeFormatter dtTimef6; // ISO, with millis appended
- private static final DateTimeFormatter dtTimef7 = // 7/9/14 9:04
- DateTimeFormat.forPattern("M/d/yy H:mm");
- private static final DateTimeFormatter dtTimef8 =
- DateTimeFormat.forPattern("M/d/yyyy h:mm:ss a"); // 7/9/2014 9:04:55 PM
-
- static {
- dtTimef6 = new DateTimeFormatterBuilder()
- .append(ISODateTimeFormat.dateTime())
- .appendLiteral('.')
- .appendPattern("SSS")
- .toFormatter();
- }
-
- // A formatter that handles date time formats defined above
- public static final DateTimeFormatter DATE_TIME_FORMATTER =
- new DateTimeFormatterBuilder()
- .append(dtTimef7)
- .append(dtTimef8)
- .append(dtTimef2)
- .append(dtTimef4)
- .append(dtTimef0)
- .append(dtTimef5)
- .append(dtTimef6)
- .toFormatter();
- private static final DateTimeFormatter timef1 = DateTimeFormat.forPattern("HH:mm:ss.SSS");
- private static final DateTimeFormatter timef2 = DateTimeFormat.forPattern("hh:mm:ss a");
- private static final DateTimeFormatter timef3 = DateTimeFormat.forPattern("h:mm:ss a");
- private static final DateTimeFormatter timef4 = ISODateTimeFormat.dateTime();
- private static final DateTimeFormatter timef5 = DateTimeFormat.forPattern("hh:mm a");
- private static final DateTimeFormatter timef6 = DateTimeFormat.forPattern("h:mm a");
- // A formatter that handles time formats defined above used for type detection.
- // It is more conservative than the converter
- public static final DateTimeFormatter TIME_DETECTION_FORMATTER =
- new DateTimeFormatterBuilder()
- .append(timef5)
- .append(timef2)
- .append(timef3)
- .append(timef1)
- .append(timef4)
- .append(timef6)
- // .append(timef7)
- .toFormatter();
- private static final DateTimeFormatter timef7 = DateTimeFormat.forPattern("HHmm");
- // A formatter that handles time formats defined above
- public static final DateTimeFormatter TIME_FORMATTER =
- new DateTimeFormatterBuilder()
- .append(timef5)
- .append(timef2)
- .append(timef3)
- .append(timef1)
- .append(timef4)
- .append(timef6)
- .append(timef7)
- .toFormatter();
- /**
- * Strings representing missing values in, for example, a CSV file that is being imported
- */
- private static final String missingInd1 = "NaN";
- private static final String missingInd2 = "*";
- private static final String missingInd3 = "NA";
- private static final String missingInd4 = "null";
- public static final ImmutableList MISSING_INDICATORS = ImmutableList.of(
- missingInd1,
- missingInd2,
- missingInd3,
- missingInd4
- );
- /**
- * List of formatters for use in code that selects the correct one for a given Date string
- */
- private static ImmutableList dateFormatters = ImmutableList.of(
- dtf1,
- dtf2,
- dtf3,
- dtf4,
- dtf5,
- dtf6,
- dtf7,
- dtf8,
- dtf9,
- dtf10,
- dtf11,
- dtf12,
- dtf13,
- dtf14,
- dtf15,
- dtf16,
- dtf17,
- dtf18,
- dtf19
- );
- /**
- * List of formatters for use in code that selects the correct one for a given DateTime string
- */
- private static ImmutableList dateTimeFormatters = ImmutableList.of(
- dtTimef0,
- dtTimef2,
- dtTimef4,
- dtTimef5,
- dtTimef6,
- dtTimef7,
- dtTimef8
- );
- /**
- * List of formatters for use in code that selects the correct one for a given Time string
- */
- private static ImmutableList timeFormatters = ImmutableList.of(
- timef1,
- timef2,
- timef3,
- timef4,
- timef5,
- timef6
- );
-
- /**
- * Private constructor to prevent instantiation
- */
- private TypeUtilsBak() {
- }
-
- /**
- * Returns the first DateTimeFormatter to parse the string, which represents a DATE
- *
- * It's intended to be called at the start of a large formatting job so that it picks the write format and is not
- * called again. This is an optimization, because the older version, which will try multiple formatters was too
- * slow for large data sets.
- */
- public static DateTimeFormatter getDateFormatter(String dateValue) {
-
- for (DateTimeFormatter formatter : dateFormatters) {
- try {
- formatter.parseDateTime(dateValue);
- return formatter;
- } catch (DateTimeParseException e) {
- // ignore;
- }
- }
- return DATE_FORMATTER;
- }
-
- /**
- * Returns the first DateTimeFormatter to parse the string, which represents a DATE_TIME
- *
- * It's intended to be called at the start of a large formatting job so that it picks the write format and is not
- * called again. This is an optimization, because the older version, which will try multiple formatters was too
- * slow for large data sets.
- */
- public static DateTimeFormatter getDateTimeFormatter(String dateTimeValue) {
- for (DateTimeFormatter formatter : dateTimeFormatters) {
- if (canParse(formatter, dateTimeValue)) {
- return formatter;
- }
- }
- if (canParse(DATE_FORMATTER, dateTimeValue)) {
- return DATE_FORMATTER;
- }
- if (canParse(DATE_TIME_FORMATTER, dateTimeValue)) {
- return DATE_TIME_FORMATTER;
- }
- throw new IllegalArgumentException("Could not find datetime parser for " + dateTimeValue);
- }
-
- private static boolean canParse(DateTimeFormatter formatter, String dateTimeValue) {
- try {
- formatter.parseDateTime(dateTimeValue);
- return true;
- } catch (DateTimeParseException e) {
- return false;
- }
- }
-
- /**
- * Returns the first DateTimeFormatter to parse the string, which represents a TIME
- *
- * It's intended to be called at the start of a large formatting job so that it picks the write format and is not
- * called again. This is an optimization, because the older version, which will try multiple formatters was too
- * slow for large data sets.
- */
- public static DateTimeFormatter getTimeFormatter(String timeValue) {
- for (DateTimeFormatter formatter : timeFormatters) {
- try {
- formatter.parseDateTime(timeValue);
- return formatter;
- } catch (DateTimeParseException e) {
- // ignore;
- }
- }
- return DATE_FORMATTER;
- }
-
-}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/io/EndianDataInputStream.java b/MeteoInfoLib/src/main/java/org/meteoinfo/io/EndianDataInputStream.java
deleted file mode 100644
index 0284a4c2..00000000
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/io/EndianDataInputStream.java
+++ /dev/null
@@ -1,136 +0,0 @@
- /* Copyright 2012 Yaqiang Wang,
- * yaqiang.wang@gmail.com
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.io;
-
-import java.io.BufferedInputStream;
-import java.io.DataInputStream;
-import java.io.IOException;
-
-/**
- *
- * @author yaqiang - come from OpenJump
- */
-public class EndianDataInputStream {
- private final java.io.DataInputStream inputStream;
- private final byte[] workSpace = new byte[8]; //chars are 16 bits, so we always quash the 1st 8 bits
-
- /** Creates new EndianDataInputStream
- * @param in */
- public EndianDataInputStream(java.io.InputStream in) {
- inputStream = new DataInputStream(new BufferedInputStream(in));
- }
-
- /** close the strea*/
- public void close() throws IOException {
- inputStream.close();
- }
-
- /** read a byte in BigEndian - the same as LE because its only 1 byt*/
- public byte readByteBE() throws IOException {
- return inputStream.readByte();
- }
-
- /** read a byte in LittleEndian - the same as BE because its only 1 byt*/
- public byte readByteLE() throws IOException {
- return inputStream.readByte();
- }
-
- /** read a byte in LittleEndian - the same as BE because its only 1 byte*/
- public void readByteLEnum(byte[] b) throws IOException {
- inputStream.readFully(b);
- }
-
-
- /** read a byte in BigEndian - the same as LE because its only 1 byte. returns int as per java.io.DataStream*/
- public int readUnsignedByteBE() throws IOException {
- return inputStream.readUnsignedByte();
- }
-
- /** read a byte in LittleEndian - the same as BE because its only 1 byte. returns int as per java.io.DataStream*/
- public int readUnsignedByteLE() throws IOException {
- return inputStream.readUnsignedByte();
- }
-
- /** read a 16bit short in BE*/
- public short readShortBE() throws IOException {
- return inputStream.readShort();
- }
-
- /** read a 16bit short in LE*/
- public short readShortLE() throws IOException {
- inputStream.readFully(workSpace, 0, 2);
-
- return (short) (((workSpace[1] & 0xff) << 8) | (workSpace[0] & 0xff));
- }
-
- /** read a 32bit int in BE*/
- public int readIntBE() throws IOException {
- return inputStream.readInt();
- }
-
- /** read a 32bit int in LE*/
- public int readIntLE() throws IOException {
- inputStream.readFully(workSpace, 0, 4);
-
- return ((workSpace[3] & 0xff) << 24) | ((workSpace[2] & 0xff) << 16) |
- ((workSpace[1] & 0xff) << 8) | (workSpace[0] & 0xff);
- }
-
- /** read a 64bit long in BE*/
- public long readLongBE() throws IOException {
- return inputStream.readLong();
- }
-
- /** read a 64bit long in LE*/
- public long readLongLE() throws IOException {
- inputStream.readFully(workSpace, 0, 8);
-
- return ((long) (workSpace[7] & 0xff) << 56) |
- ((long) (workSpace[6] & 0xff) << 48) |
- ((long) (workSpace[5] & 0xff) << 40) |
- ((long) (workSpace[4] & 0xff) << 32) |
- ((long) (workSpace[3] & 0xff) << 24) |
- ((long) (workSpace[2] & 0xff) << 16) |
- ((long) (workSpace[1] & 0xff) << 8) | ((long) (workSpace[0] & 0xff));
- }
-
- /** read a 64bit double in BE*/
- public double readDoubleBE() throws IOException {
- return inputStream.readDouble();
- }
-
- /** read a 64bit double in LE*/
- public double readDoubleLE() throws IOException {
- long l;
-
- inputStream.readFully(workSpace, 0, 8);
- l = ((long) (workSpace[7] & 0xff) << 56) |
- ((long) (workSpace[6] & 0xff) << 48) |
- ((long) (workSpace[5] & 0xff) << 40) |
- ((long) (workSpace[4] & 0xff) << 32) |
- ((long) (workSpace[3] & 0xff) << 24) |
- ((long) (workSpace[2] & 0xff) << 16) |
- ((long) (workSpace[1] & 0xff) << 8) |
- ((long) (workSpace[0] & 0xff));
-
- return Double.longBitsToDouble(l);
- }
-
- /** skip ahead in the stream
- * @param num number of bytes to read ahead
- */
- public int skipBytes(int num) throws IOException {
- return inputStream.skipBytes(num);
- }
-}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/layer/FrmLabelSet.java b/MeteoInfoLib/src/main/java/org/meteoinfo/layer/FrmLabelSet.java
index 5f169b2b..a0af2f98 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/layer/FrmLabelSet.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/layer/FrmLabelSet.java
@@ -5,7 +5,6 @@
package org.meteoinfo.layer;
import org.meteoinfo.data.mapdata.Field;
-import org.meteoinfo.global.MIMath;
import org.meteoinfo.legend.AlignType;
import org.meteoinfo.map.MapView;
import org.meteoinfo.shape.ShapeTypes;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/layer/FrmLayerProperty.java b/MeteoInfoLib/src/main/java/org/meteoinfo/layer/FrmLayerProperty.java
index 82dcc22c..16e2f2e5 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/layer/FrmLayerProperty.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/layer/FrmLayerProperty.java
@@ -5,8 +5,8 @@
package org.meteoinfo.layer;
import com.formdev.flatlaf.extras.FlatSVGIcon;
-import org.meteoinfo.global.GenericFileFilter;
-import org.meteoinfo.global.MIMath;
+import org.meteoinfo.common.GenericFileFilter;
+import org.meteoinfo.common.MIMath;
import org.meteoinfo.ndarray.DataType;
import org.meteoinfo.legend.ColorBreak;
import org.meteoinfo.legend.FrmLegendBreaks;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/layer/ImageLayer.java b/MeteoInfoLib/src/main/java/org/meteoinfo/layer/ImageLayer.java
index ad47c6a6..35c8c7fa 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/layer/ImageLayer.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/layer/ImageLayer.java
@@ -1,890 +1,890 @@
-/* Copyright 2012 Yaqiang Wang,
- * yaqiang.wang@gmail.com
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.layer;
-
-import com.l2fprod.common.beans.BaseBeanInfo;
-import com.l2fprod.common.beans.ExtendedPropertyDescriptor;
-import com.l2fprod.common.beans.editor.ComboBoxPropertyEditor;
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.global.util.GlobalUtil;
-import org.meteoinfo.shape.ShapeTypes;
-import java.awt.Color;
-import java.awt.Image;
-import java.awt.RenderingHints;
-import java.awt.image.BufferedImage;
-import java.awt.image.Raster;
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- *
- * @author Yaqiang Wang
- */
-public class ImageLayer extends MapLayer {
- //
-
- private BufferedImage _image;
- private WorldFilePara _worldFilePara = new WorldFilePara();
- private String _worldFileName;
- private boolean _isSetTransColor;
- private Color _transparencyColor;
- protected Object interp;
- //
- //
-
- /**
- * Constructor
- */
- public ImageLayer() {
- super();
- this.setLayerType(LayerTypes.ImageLayer);
- this.setShapeType(ShapeTypes.Image);
- _isSetTransColor = false;
- _transparencyColor = Color.black;
- this.interp = RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR;
- }
- //
- //
-
- /**
- * Get image
- *
- * @return The image
- */
- public BufferedImage getImage() {
- return _image;
- }
-
- /**
- * Set image
- *
- * @param image The image
- */
- public void setImage(BufferedImage image) {
- _image = image;
- _transparencyColor = new Color(image.getRGB(1, 1));
- }
-
- /**
- * Get world file name of the layer
- *
- * @return World file name
- */
- public String getWorldFileName() {
- return _worldFileName;
- }
-
- /**
- * Set world file name
- *
- * @param name World file name
- */
- public void setWorldFileName(String name) {
- _worldFileName = name;
- }
-
- /**
- * Get world file parameters
- *
- * @return World file parameters
- */
- public WorldFilePara getWorldFilePara() {
- return _worldFilePara;
- }
-
- /**
- * Set world file parameters
- *
- * @param value World file parameters
- */
- public void setWorldFilePara(WorldFilePara value) {
- _worldFilePara = value;
- }
-
- /**
- * Get if set transparency color
- *
- * @return Boolean
- */
- public boolean isUseTransColor() {
- return _isSetTransColor;
- }
-
- /**
- * Set if using transparency color
- *
- * @param istrue Boolean
- */
- public void setUseTransColor(boolean istrue) {
- _isSetTransColor = istrue;
- if (istrue) {
- Image image = GlobalUtil.makeColorTransparent(_image, _transparencyColor);
- _image = GlobalUtil.imageToBufferedImage(image);
- }
- }
-
- /**
- * Get transparency color
- *
- * @return Transparency color
- */
- public Color getTransparencyColor() {
- return _transparencyColor;
- }
-
- /**
- * Set transparency color
- *
- * @param color The color
- */
- public void setTransparencyColor(Color color) {
- _transparencyColor = color;
- if (_isSetTransColor) {
- Image image = GlobalUtil.makeColorTransparent(_image, _transparencyColor);
- _image = GlobalUtil.imageToBufferedImage(image);
- }
- }
-
- /**
- * Get X upper-left
- *
- * @return Upper-left x value
- */
- public double getXUL() {
- return _worldFilePara.xUL;
- }
-
- /**
- * Set upper-left x
- *
- * @param value The value
- * @throws java.io.IOException
- */
- public void setXUL(double value) throws IOException {
- _worldFilePara.xUL = value;
- Extent aExtent = (Extent) this.getExtent().clone();
- aExtent.minX = _worldFilePara.xUL;
- aExtent.maxX = _worldFilePara.xUL + this.getExtent().getWidth();
- this.setExtent(aExtent);
- if (new File(_worldFileName).exists()) {
- writeImageWorldFile(_worldFileName, _worldFilePara);
- }
- }
-
- /**
- * Get y upper-left
- *
- * @return Upper-left y
- */
- public double getYUL() {
- return _worldFilePara.yUL;
- }
-
- /**
- * Set upper-left y
- *
- * @param value The value
- * @throws java.io.IOException
- */
- public void setYUL(double value) throws IOException {
- _worldFilePara.yUL = value;
- Extent aExtent = (Extent) this.getExtent().clone();
- aExtent.maxY = _worldFilePara.yUL;
- aExtent.minY = _worldFilePara.yUL - this.getExtent().getHeight();
- this.setExtent(aExtent);
- if (new File(_worldFileName).exists()) {
- writeImageWorldFile(_worldFileName, _worldFilePara);
- }
- }
-
- /**
- * Get x scale
- *
- * @return The x scale
- */
- public double getXScale() {
- return _worldFilePara.xScale;
- }
-
- /**
- * Set x scale
- *
- * @param value The value
- * @throws java.io.IOException
- */
- public void setXScale(double value) throws IOException {
- _worldFilePara.xScale = value;
- Extent aExtent = (Extent) this.getExtent();
- double width = _image.getWidth() * _worldFilePara.xScale;
- aExtent.maxX = _worldFilePara.xUL + width;
- this.setExtent(aExtent);
- if (new File(_worldFileName).exists()) {
- writeImageWorldFile(_worldFileName, _worldFilePara);
- }
- }
-
- /**
- * Get y scale
- *
- * @return The y scale
- */
- public double getYScale() {
- return _worldFilePara.yScale;
- }
-
- /**
- * Set y scale
- *
- * @param value The y scale value
- * @throws IOException
- */
- public void setYScale(double value) throws IOException {
- _worldFilePara.yScale = value;
- Extent aExtent = (Extent) this.getExtent();
- double height = _image.getHeight() * _worldFilePara.yScale;
- aExtent.minY = _worldFilePara.yUL + height;
- this.setExtent(aExtent);
- if (new File(_worldFileName).exists()) {
- writeImageWorldFile(_worldFileName, _worldFilePara);
- }
- }
-
- /**
- * Get x rotate(shear)
- *
- * @return X rotate
- */
- public double getXRotate() {
- return _worldFilePara.xRotate;
- }
-
- /**
- * Set x rotate(shear)
- *
- * @param value Value
- * @throws IOException
- */
- public void setXRotate(double value) throws IOException {
- _worldFilePara.xRotate = value;
- if (new File(_worldFileName).exists()) {
- writeImageWorldFile(_worldFileName, _worldFilePara);
- }
- }
-
- /**
- * Get y rotate(shear)
- *
- * @return X rotate
- */
- public double getYRotate() {
- return _worldFilePara.yRotate;
- }
-
- /**
- * Set y rotate(shear)
- *
- * @param value Value
- * @throws IOException
- */
- public void setYRotate(double value) throws IOException {
- _worldFilePara.yRotate = value;
- if (new File(_worldFileName).exists()) {
- writeImageWorldFile(_worldFileName, _worldFilePara);
- }
- }
-
- /**
- * Get interpolation
- *
- * @return Interpolation
- */
- public Object getInterpolation() {
- return this.interp;
- }
-
- /**
- * Get interpolation string
- *
- * @return Interpolation string
- */
- public String getInterpolationStr() {
- if (interp == RenderingHints.VALUE_INTERPOLATION_BILINEAR) {
- return "bilinear";
- } else if (interp == RenderingHints.VALUE_INTERPOLATION_BICUBIC) {
- return "bicubic";
- } else {
- return "nearest";
- }
- }
-
- /**
- * Set interpolation object
- *
- * @param value Interpolation object
- */
- public void setInterpolation(Object value) {
- this.interp = value;
- }
-
- /**
- * Set interpolation string
- *
- * @param value Interpolation string
- */
- public void setInterpolation(String value) {
- switch (value) {
- case "nearest":
- this.interp = RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR;
- break;
- case "bilinear":
- this.interp = RenderingHints.VALUE_INTERPOLATION_BILINEAR;
- break;
- case "bicubic":
- this.interp = RenderingHints.VALUE_INTERPOLATION_BICUBIC;
- break;
- }
- }
- //
- //
-
- /**
- * Read image world file
- *
- * @param aIFile Image world file path
- * @throws java.io.FileNotFoundException
- */
- public void readImageWorldFile(String aIFile) throws FileNotFoundException, IOException {
- BufferedReader sr = new BufferedReader(new FileReader(new File(aIFile)));
-
- _worldFilePara.xScale = Double.parseDouble(sr.readLine());
- _worldFilePara.yRotate = Double.parseDouble(sr.readLine());
- _worldFilePara.xRotate = Double.parseDouble(sr.readLine());
- _worldFilePara.yScale = Double.parseDouble(sr.readLine());
- _worldFilePara.xUL = Double.parseDouble(sr.readLine());
- _worldFilePara.yUL = Double.parseDouble(sr.readLine());
- sr.close();
- }
-
- /**
- * Write image world file
- *
- * @param aFile File path
- * @param aWFP WorldFilePara
- * @throws java.io.IOException
- */
- public void writeImageWorldFile(String aFile, WorldFilePara aWFP) throws IOException {
- BufferedWriter sw = new BufferedWriter(new FileWriter(new File(aFile)));
- sw.write(String.valueOf(aWFP.xScale));
- sw.newLine();
- sw.write(String.valueOf(aWFP.yRotate));
- sw.newLine();
- sw.write(String.valueOf(aWFP.xRotate));
- sw.newLine();
- sw.write(String.valueOf(aWFP.yScale));
- sw.newLine();
- sw.write(String.valueOf(aWFP.xUL));
- sw.newLine();
- sw.write(String.valueOf(aWFP.yUL));
- sw.close();
- }
-
- /**
- * Get colors from palette file
- *
- * @param pFile Palette file path
- * @return Colors
- */
- public List getColorsFromPaletteFile(String pFile) {
- BufferedReader sr;
- try {
- sr = new BufferedReader(new InputStreamReader(new FileInputStream(pFile)));
- sr.readLine();
- String aLine = sr.readLine();
- String[] dataArray;
- List colors = new ArrayList<>();
- while (aLine != null) {
- if (aLine.isEmpty()) {
- aLine = sr.readLine();
- continue;
- }
-
- aLine = aLine.trim();
- dataArray = aLine.split("\\s+");
- colors.add(new Color(Integer.parseInt(dataArray[3]), Integer.parseInt(dataArray[2]),
- Integer.parseInt(dataArray[1])));
-
- aLine = sr.readLine();
- }
- sr.close();
-
- return colors;
- } catch (FileNotFoundException ex) {
- Logger.getLogger(ImageLayer.class.getName()).log(Level.SEVERE, null, ex);
- return null;
- } catch (IOException ex) {
- Logger.getLogger(ImageLayer.class.getName()).log(Level.SEVERE, null, ex);
- return null;
- }
- }
-
- /**
- * Set palette
- *
- * @param colors Colors
- */
- public void setPalette(List colors) {
- Raster imageData = _image.getData();
-
- for (int i = 0; i < _image.getWidth(); i++) {
- for (int j = 0; j < _image.getHeight(); j++) {
- _image.setRGB(i, _image.getHeight() - j - 1, colors.get(imageData.getSample(i, j, 0)).getRGB());
- }
- }
- }
-
- /**
- * Set color palette to a image from a palette file
- *
- * @param aFile File path
- */
- public void setPalette(String aFile) {
- List colors = getColorsFromPaletteFile(aFile);
-
- setPalette(colors);
- }
- //
-
- //
- public class ImageLayerBean {
-
- ImageLayerBean() {
- }
-
- //
- /**
- * Get layer type
- *
- * @return Layer type
- */
- public LayerTypes getLayerType() {
- return ImageLayer.this.getLayerType();
- }
-
- /**
- * Set layer type
- *
- * @param lt Layer type
- */
- public void setLayerType(LayerTypes lt) {
- ImageLayer.this.setLayerType(lt);
- }
-
- /**
- * Get layer draw type
- *
- * @return Layer draw type
- */
- public LayerDrawType getLayerDrawType() {
- return ImageLayer.this.getLayerDrawType();
- }
-
- /**
- * Set layer draw type
- *
- * @param ldt Layer draw type
- */
- public void setLayerDrawType(LayerDrawType ldt) {
- ImageLayer.this.setLayerDrawType(ldt);
- }
-
- /**
- * Get file name
- *
- * @return File name
- */
- public String getFileName() {
- return ImageLayer.this.getFileName();
- }
-
- /**
- * Set file name
- *
- * @param fn File name
- */
- public void setFileName(String fn) {
- ImageLayer.this.setFileName(fn);
- }
-
- /**
- * Get layer handle
- *
- * @return Layer handle
- */
- public int getHandle() {
- return ImageLayer.this.getHandle();
- }
-
- /**
- * Get layer name
- *
- * @return Layer name
- */
- public String getLayerName() {
- return ImageLayer.this.getLayerName();
- }
-
- /**
- * Set layer name
- *
- * @param name Layer name
- */
- public void setLayerName(String name) {
- ImageLayer.this.setLayerName(name);
- }
-
- /**
- * Get if is maskout
- *
- * @return If is maskout
- */
- public boolean isMaskout() {
- return ImageLayer.this.isMaskout();
- }
-
- /**
- * Set if maskout
- *
- * @param value If maskout
- */
- public void setMaskout(boolean value) {
- ImageLayer.this.setMaskout(value);
- }
-
- /**
- * Get if is visible
- *
- * @return If is visible
- */
- public boolean isVisible() {
- return ImageLayer.this.isVisible();
- }
-
- /**
- * Set if is visible
- *
- * @param value If is visible
- */
- public void setVisible(boolean value) {
- ImageLayer.this.setVisible(value);
- }
-
- /**
- * Get world file name of the layer
- *
- * @return World file name
- */
- public String getWorldFileName() {
- return _worldFileName;
- }
-
- /**
- * Get if set transparency color
- *
- * @return Boolean
- */
- public boolean isUseTransColor() {
- return _isSetTransColor;
- }
-
- /**
- * Set if using transparency color
- *
- * @param istrue Boolean
- */
- public void setUseTransColor(boolean istrue) {
- _isSetTransColor = istrue;
- if (istrue) {
- Image image = GlobalUtil.makeColorTransparent(_image, _transparencyColor);
- _image = GlobalUtil.imageToBufferedImage(image);
- }
- }
-
- /**
- * Get transparency color
- *
- * @return Transparency color
- */
- public Color getTransparencyColor() {
- return _transparencyColor;
- }
-
- /**
- * Set transparency color
- *
- * @param color The color
- */
- public void setTransparencyColor(Color color) {
- _transparencyColor = color;
- if (_isSetTransColor) {
- Image image = GlobalUtil.makeColorTransparent(_image, _transparencyColor);
- _image = GlobalUtil.imageToBufferedImage(image);
- }
- }
-
- /**
- * Get transparency percent
- *
- * @return Transparency percent
- */
- public int getTransparency() {
- return ImageLayer.this.getTransparency();
- }
-
- /**
- * Set transparency percent
- *
- * @param value Transparency percent
- */
- public void setTransparency(int value) {
- ImageLayer.this.setTransparency(value);
- }
-
- /**
- * Get X upper-left
- *
- * @return Upper-left x value
- */
- public double getXUL() {
- return _worldFilePara.xUL;
- }
-
- /**
- * Set upper-left x
- *
- * @param value The value
- * @throws java.io.IOException
- */
- public void setXUL(double value) throws IOException {
- _worldFilePara.xUL = value;
- Extent aExtent = (Extent) ImageLayer.this.getExtent().clone();
- aExtent.minX = _worldFilePara.xUL;
- aExtent.maxX = _worldFilePara.xUL + ImageLayer.this.getExtent().getWidth();
- ImageLayer.this.setExtent(aExtent);
- if (new File(_worldFileName).exists()) {
- writeImageWorldFile(_worldFileName, _worldFilePara);
- }
- }
-
- /**
- * Get y upper-left
- *
- * @return Upper-left y
- */
- public double getYUL() {
- return _worldFilePara.yUL;
- }
-
- /**
- * Set upper-left y
- *
- * @param value The value
- * @throws java.io.IOException
- */
- public void setYUL(double value) throws IOException {
- _worldFilePara.yUL = value;
- Extent aExtent = (Extent) ImageLayer.this.getExtent().clone();
- aExtent.maxY = _worldFilePara.yUL;
- aExtent.minY = _worldFilePara.yUL - ImageLayer.this.getExtent().getHeight();
- ImageLayer.this.setExtent(aExtent);
- if (new File(_worldFileName).exists()) {
- writeImageWorldFile(_worldFileName, _worldFilePara);
- }
- }
-
- /**
- * Get x scale
- *
- * @return The x scale
- */
- public double getXScale() {
- return _worldFilePara.xScale;
- }
-
- /**
- * Set x scale
- *
- * @param value The value
- * @throws java.io.IOException
- */
- public void setXScale(double value) throws IOException {
- _worldFilePara.xScale = value;
- Extent aExtent = (Extent) ImageLayer.this.getExtent();
- double width = _image.getWidth() * _worldFilePara.xScale;
- aExtent.maxX = _worldFilePara.xUL + width;
- ImageLayer.this.setExtent(aExtent);
- if (new File(_worldFileName).exists()) {
- writeImageWorldFile(_worldFileName, _worldFilePara);
- }
- }
-
- /**
- * Get y scale
- *
- * @return The y scale
- */
- public double getYScale() {
- return _worldFilePara.yScale;
- }
-
- public void setYScale(double value) throws IOException {
- _worldFilePara.yScale = value;
- Extent aExtent = (Extent) ImageLayer.this.getExtent();
- double height = _image.getHeight() * _worldFilePara.yScale;
- aExtent.minY = _worldFilePara.yUL + height;
- ImageLayer.this.setExtent(aExtent);
- if (new File(_worldFileName).exists()) {
- writeImageWorldFile(_worldFileName, _worldFilePara);
- }
- }
-
- /**
- * Get x rotate(shear)
- *
- * @return X rotate
- */
- public double getXRotate() {
- return _worldFilePara.xRotate;
- }
-
- /**
- * Set x rotate(shear)
- *
- * @param value Value
- * @throws IOException
- */
- public void setXRotate(double value) throws IOException {
- _worldFilePara.xRotate = value;
- if (new File(_worldFileName).exists()) {
- writeImageWorldFile(_worldFileName, _worldFilePara);
- }
- }
-
- /**
- * Get y rotate(shear)
- *
- * @return X rotate
- */
- public double getYRotate() {
- return _worldFilePara.yRotate;
- }
-
- /**
- * Set y rotate(shear)
- *
- * @param value Value
- * @throws IOException
- */
- public void setYRotate(double value) throws IOException {
- _worldFilePara.yRotate = value;
- if (new File(_worldFileName).exists()) {
- writeImageWorldFile(_worldFileName, _worldFilePara);
- }
- }
-
- /**
- * Get interpolation
- *
- * @return Interpolation
- */
- public String getInterpolation() {
- if (interp == RenderingHints.VALUE_INTERPOLATION_BILINEAR) {
- return "bilinear";
- } else if (interp == RenderingHints.VALUE_INTERPOLATION_BICUBIC) {
- return "bicubic";
- } else {
- return "nearest";
- }
- }
-
- /**
- * Set interpolation
- *
- * @param value Interpolation
- */
- public void setInterpolation(String value) {
- switch (value) {
- case "nearest":
- interp = RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR;
- break;
- case "bilinear":
- interp = RenderingHints.VALUE_INTERPOLATION_BILINEAR;
- break;
- case "bicubic":
- interp = RenderingHints.VALUE_INTERPOLATION_BICUBIC;
- break;
- }
- }
- //
- }
-
- public static class ImageLayerBeanBeanInfo extends BaseBeanInfo {
-
- public ImageLayerBeanBeanInfo() {
- super(ImageLayerBean.class);
- addProperty("fileName").setCategory("Read only").setReadOnly().setDisplayName("File name");
- addProperty("layerType").setCategory("Read only").setReadOnly().setDisplayName("Layer type");
- addProperty("layerDrawType").setCategory("Read only").setReadOnly().setDisplayName("Layer draw type");
- addProperty("handle").setCategory("Read only").setReadOnly().setDisplayName("Handle");
- addProperty("layerName").setCategory("Editable").setDisplayName("Layer name");
- addProperty("visible").setCategory("Editable").setDisplayName("Visible");
- addProperty("maskout").setCategory("Editable").setDisplayName("Is maskout");
- addProperty("transparency").setCategory("Editable").setDisplayName("Transparency Percent");
- addProperty("useTransColor").setCategory("Editable").setDisplayName("If use transparency color");
- addProperty("transparencyColor").setCategory("Editable").setDisplayName("Transparency color");
- addProperty("xScale").setCategory("Editable").setDisplayName("X scale");
- addProperty("yScale").setCategory("Editable").setDisplayName("Y scale");
- addProperty("xUL").setCategory("Editable").setDisplayName("X upper left");
- addProperty("yUL").setCategory("Editable").setDisplayName("Y upper left");
- addProperty("xRotate").setCategory("Editable").setDisplayName("X rotate");
- addProperty("yRotate").setCategory("Editable").setDisplayName("Y rotate");
- ExtendedPropertyDescriptor e = addProperty("interpolation");
- e.setCategory("Editable").setPropertyEditorClass(InterpolationEditor.class);
- e.setDisplayName("Interpolation");
- }
- }
-
- public static class InterpolationEditor extends ComboBoxPropertyEditor {
-
- public InterpolationEditor() {
- super();
- String[] names = new String[3];
- names[0] = "nearest";
- names[1] = "bilinear";
- names[2] = "bicubic";
- setAvailableValues(names);
- }
- }
- //
-}
+/* Copyright 2012 Yaqiang Wang,
+ * yaqiang.wang@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ */
+package org.meteoinfo.layer;
+
+import com.l2fprod.common.beans.BaseBeanInfo;
+import com.l2fprod.common.beans.ExtendedPropertyDescriptor;
+import com.l2fprod.common.beans.editor.ComboBoxPropertyEditor;
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.util.GlobalUtil;
+import org.meteoinfo.shape.ShapeTypes;
+import java.awt.Color;
+import java.awt.Image;
+import java.awt.RenderingHints;
+import java.awt.image.BufferedImage;
+import java.awt.image.Raster;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ *
+ * @author Yaqiang Wang
+ */
+public class ImageLayer extends MapLayer {
+ //
+
+ private BufferedImage _image;
+ private WorldFilePara _worldFilePara = new WorldFilePara();
+ private String _worldFileName;
+ private boolean _isSetTransColor;
+ private Color _transparencyColor;
+ protected Object interp;
+ //
+ //
+
+ /**
+ * Constructor
+ */
+ public ImageLayer() {
+ super();
+ this.setLayerType(LayerTypes.ImageLayer);
+ this.setShapeType(ShapeTypes.Image);
+ _isSetTransColor = false;
+ _transparencyColor = Color.black;
+ this.interp = RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR;
+ }
+ //
+ //
+
+ /**
+ * Get image
+ *
+ * @return The image
+ */
+ public BufferedImage getImage() {
+ return _image;
+ }
+
+ /**
+ * Set image
+ *
+ * @param image The image
+ */
+ public void setImage(BufferedImage image) {
+ _image = image;
+ _transparencyColor = new Color(image.getRGB(1, 1));
+ }
+
+ /**
+ * Get world file name of the layer
+ *
+ * @return World file name
+ */
+ public String getWorldFileName() {
+ return _worldFileName;
+ }
+
+ /**
+ * Set world file name
+ *
+ * @param name World file name
+ */
+ public void setWorldFileName(String name) {
+ _worldFileName = name;
+ }
+
+ /**
+ * Get world file parameters
+ *
+ * @return World file parameters
+ */
+ public WorldFilePara getWorldFilePara() {
+ return _worldFilePara;
+ }
+
+ /**
+ * Set world file parameters
+ *
+ * @param value World file parameters
+ */
+ public void setWorldFilePara(WorldFilePara value) {
+ _worldFilePara = value;
+ }
+
+ /**
+ * Get if set transparency color
+ *
+ * @return Boolean
+ */
+ public boolean isUseTransColor() {
+ return _isSetTransColor;
+ }
+
+ /**
+ * Set if using transparency color
+ *
+ * @param istrue Boolean
+ */
+ public void setUseTransColor(boolean istrue) {
+ _isSetTransColor = istrue;
+ if (istrue) {
+ Image image = GlobalUtil.makeColorTransparent(_image, _transparencyColor);
+ _image = GlobalUtil.imageToBufferedImage(image);
+ }
+ }
+
+ /**
+ * Get transparency color
+ *
+ * @return Transparency color
+ */
+ public Color getTransparencyColor() {
+ return _transparencyColor;
+ }
+
+ /**
+ * Set transparency color
+ *
+ * @param color The color
+ */
+ public void setTransparencyColor(Color color) {
+ _transparencyColor = color;
+ if (_isSetTransColor) {
+ Image image = GlobalUtil.makeColorTransparent(_image, _transparencyColor);
+ _image = GlobalUtil.imageToBufferedImage(image);
+ }
+ }
+
+ /**
+ * Get X upper-left
+ *
+ * @return Upper-left x value
+ */
+ public double getXUL() {
+ return _worldFilePara.xUL;
+ }
+
+ /**
+ * Set upper-left x
+ *
+ * @param value The value
+ * @throws java.io.IOException
+ */
+ public void setXUL(double value) throws IOException {
+ _worldFilePara.xUL = value;
+ Extent aExtent = (Extent) this.getExtent().clone();
+ aExtent.minX = _worldFilePara.xUL;
+ aExtent.maxX = _worldFilePara.xUL + this.getExtent().getWidth();
+ this.setExtent(aExtent);
+ if (new File(_worldFileName).exists()) {
+ writeImageWorldFile(_worldFileName, _worldFilePara);
+ }
+ }
+
+ /**
+ * Get y upper-left
+ *
+ * @return Upper-left y
+ */
+ public double getYUL() {
+ return _worldFilePara.yUL;
+ }
+
+ /**
+ * Set upper-left y
+ *
+ * @param value The value
+ * @throws java.io.IOException
+ */
+ public void setYUL(double value) throws IOException {
+ _worldFilePara.yUL = value;
+ Extent aExtent = (Extent) this.getExtent().clone();
+ aExtent.maxY = _worldFilePara.yUL;
+ aExtent.minY = _worldFilePara.yUL - this.getExtent().getHeight();
+ this.setExtent(aExtent);
+ if (new File(_worldFileName).exists()) {
+ writeImageWorldFile(_worldFileName, _worldFilePara);
+ }
+ }
+
+ /**
+ * Get x scale
+ *
+ * @return The x scale
+ */
+ public double getXScale() {
+ return _worldFilePara.xScale;
+ }
+
+ /**
+ * Set x scale
+ *
+ * @param value The value
+ * @throws java.io.IOException
+ */
+ public void setXScale(double value) throws IOException {
+ _worldFilePara.xScale = value;
+ Extent aExtent = (Extent) this.getExtent();
+ double width = _image.getWidth() * _worldFilePara.xScale;
+ aExtent.maxX = _worldFilePara.xUL + width;
+ this.setExtent(aExtent);
+ if (new File(_worldFileName).exists()) {
+ writeImageWorldFile(_worldFileName, _worldFilePara);
+ }
+ }
+
+ /**
+ * Get y scale
+ *
+ * @return The y scale
+ */
+ public double getYScale() {
+ return _worldFilePara.yScale;
+ }
+
+ /**
+ * Set y scale
+ *
+ * @param value The y scale value
+ * @throws IOException
+ */
+ public void setYScale(double value) throws IOException {
+ _worldFilePara.yScale = value;
+ Extent aExtent = (Extent) this.getExtent();
+ double height = _image.getHeight() * _worldFilePara.yScale;
+ aExtent.minY = _worldFilePara.yUL + height;
+ this.setExtent(aExtent);
+ if (new File(_worldFileName).exists()) {
+ writeImageWorldFile(_worldFileName, _worldFilePara);
+ }
+ }
+
+ /**
+ * Get x rotate(shear)
+ *
+ * @return X rotate
+ */
+ public double getXRotate() {
+ return _worldFilePara.xRotate;
+ }
+
+ /**
+ * Set x rotate(shear)
+ *
+ * @param value Value
+ * @throws IOException
+ */
+ public void setXRotate(double value) throws IOException {
+ _worldFilePara.xRotate = value;
+ if (new File(_worldFileName).exists()) {
+ writeImageWorldFile(_worldFileName, _worldFilePara);
+ }
+ }
+
+ /**
+ * Get y rotate(shear)
+ *
+ * @return X rotate
+ */
+ public double getYRotate() {
+ return _worldFilePara.yRotate;
+ }
+
+ /**
+ * Set y rotate(shear)
+ *
+ * @param value Value
+ * @throws IOException
+ */
+ public void setYRotate(double value) throws IOException {
+ _worldFilePara.yRotate = value;
+ if (new File(_worldFileName).exists()) {
+ writeImageWorldFile(_worldFileName, _worldFilePara);
+ }
+ }
+
+ /**
+ * Get interpolation
+ *
+ * @return Interpolation
+ */
+ public Object getInterpolation() {
+ return this.interp;
+ }
+
+ /**
+ * Get interpolation string
+ *
+ * @return Interpolation string
+ */
+ public String getInterpolationStr() {
+ if (interp == RenderingHints.VALUE_INTERPOLATION_BILINEAR) {
+ return "bilinear";
+ } else if (interp == RenderingHints.VALUE_INTERPOLATION_BICUBIC) {
+ return "bicubic";
+ } else {
+ return "nearest";
+ }
+ }
+
+ /**
+ * Set interpolation object
+ *
+ * @param value Interpolation object
+ */
+ public void setInterpolation(Object value) {
+ this.interp = value;
+ }
+
+ /**
+ * Set interpolation string
+ *
+ * @param value Interpolation string
+ */
+ public void setInterpolation(String value) {
+ switch (value) {
+ case "nearest":
+ this.interp = RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR;
+ break;
+ case "bilinear":
+ this.interp = RenderingHints.VALUE_INTERPOLATION_BILINEAR;
+ break;
+ case "bicubic":
+ this.interp = RenderingHints.VALUE_INTERPOLATION_BICUBIC;
+ break;
+ }
+ }
+ //
+ //
+
+ /**
+ * Read image world file
+ *
+ * @param aIFile Image world file path
+ * @throws java.io.FileNotFoundException
+ */
+ public void readImageWorldFile(String aIFile) throws FileNotFoundException, IOException {
+ BufferedReader sr = new BufferedReader(new FileReader(new File(aIFile)));
+
+ _worldFilePara.xScale = Double.parseDouble(sr.readLine());
+ _worldFilePara.yRotate = Double.parseDouble(sr.readLine());
+ _worldFilePara.xRotate = Double.parseDouble(sr.readLine());
+ _worldFilePara.yScale = Double.parseDouble(sr.readLine());
+ _worldFilePara.xUL = Double.parseDouble(sr.readLine());
+ _worldFilePara.yUL = Double.parseDouble(sr.readLine());
+ sr.close();
+ }
+
+ /**
+ * Write image world file
+ *
+ * @param aFile File path
+ * @param aWFP WorldFilePara
+ * @throws java.io.IOException
+ */
+ public void writeImageWorldFile(String aFile, WorldFilePara aWFP) throws IOException {
+ BufferedWriter sw = new BufferedWriter(new FileWriter(new File(aFile)));
+ sw.write(String.valueOf(aWFP.xScale));
+ sw.newLine();
+ sw.write(String.valueOf(aWFP.yRotate));
+ sw.newLine();
+ sw.write(String.valueOf(aWFP.xRotate));
+ sw.newLine();
+ sw.write(String.valueOf(aWFP.yScale));
+ sw.newLine();
+ sw.write(String.valueOf(aWFP.xUL));
+ sw.newLine();
+ sw.write(String.valueOf(aWFP.yUL));
+ sw.close();
+ }
+
+ /**
+ * Get colors from palette file
+ *
+ * @param pFile Palette file path
+ * @return Colors
+ */
+ public List getColorsFromPaletteFile(String pFile) {
+ BufferedReader sr;
+ try {
+ sr = new BufferedReader(new InputStreamReader(new FileInputStream(pFile)));
+ sr.readLine();
+ String aLine = sr.readLine();
+ String[] dataArray;
+ List colors = new ArrayList<>();
+ while (aLine != null) {
+ if (aLine.isEmpty()) {
+ aLine = sr.readLine();
+ continue;
+ }
+
+ aLine = aLine.trim();
+ dataArray = aLine.split("\\s+");
+ colors.add(new Color(Integer.parseInt(dataArray[3]), Integer.parseInt(dataArray[2]),
+ Integer.parseInt(dataArray[1])));
+
+ aLine = sr.readLine();
+ }
+ sr.close();
+
+ return colors;
+ } catch (FileNotFoundException ex) {
+ Logger.getLogger(ImageLayer.class.getName()).log(Level.SEVERE, null, ex);
+ return null;
+ } catch (IOException ex) {
+ Logger.getLogger(ImageLayer.class.getName()).log(Level.SEVERE, null, ex);
+ return null;
+ }
+ }
+
+ /**
+ * Set palette
+ *
+ * @param colors Colors
+ */
+ public void setPalette(List colors) {
+ Raster imageData = _image.getData();
+
+ for (int i = 0; i < _image.getWidth(); i++) {
+ for (int j = 0; j < _image.getHeight(); j++) {
+ _image.setRGB(i, _image.getHeight() - j - 1, colors.get(imageData.getSample(i, j, 0)).getRGB());
+ }
+ }
+ }
+
+ /**
+ * Set color palette to a image from a palette file
+ *
+ * @param aFile File path
+ */
+ public void setPalette(String aFile) {
+ List colors = getColorsFromPaletteFile(aFile);
+
+ setPalette(colors);
+ }
+ //
+
+ //
+ public class ImageLayerBean {
+
+ ImageLayerBean() {
+ }
+
+ //
+ /**
+ * Get layer type
+ *
+ * @return Layer type
+ */
+ public LayerTypes getLayerType() {
+ return ImageLayer.this.getLayerType();
+ }
+
+ /**
+ * Set layer type
+ *
+ * @param lt Layer type
+ */
+ public void setLayerType(LayerTypes lt) {
+ ImageLayer.this.setLayerType(lt);
+ }
+
+ /**
+ * Get layer draw type
+ *
+ * @return Layer draw type
+ */
+ public LayerDrawType getLayerDrawType() {
+ return ImageLayer.this.getLayerDrawType();
+ }
+
+ /**
+ * Set layer draw type
+ *
+ * @param ldt Layer draw type
+ */
+ public void setLayerDrawType(LayerDrawType ldt) {
+ ImageLayer.this.setLayerDrawType(ldt);
+ }
+
+ /**
+ * Get file name
+ *
+ * @return File name
+ */
+ public String getFileName() {
+ return ImageLayer.this.getFileName();
+ }
+
+ /**
+ * Set file name
+ *
+ * @param fn File name
+ */
+ public void setFileName(String fn) {
+ ImageLayer.this.setFileName(fn);
+ }
+
+ /**
+ * Get layer handle
+ *
+ * @return Layer handle
+ */
+ public int getHandle() {
+ return ImageLayer.this.getHandle();
+ }
+
+ /**
+ * Get layer name
+ *
+ * @return Layer name
+ */
+ public String getLayerName() {
+ return ImageLayer.this.getLayerName();
+ }
+
+ /**
+ * Set layer name
+ *
+ * @param name Layer name
+ */
+ public void setLayerName(String name) {
+ ImageLayer.this.setLayerName(name);
+ }
+
+ /**
+ * Get if is maskout
+ *
+ * @return If is maskout
+ */
+ public boolean isMaskout() {
+ return ImageLayer.this.isMaskout();
+ }
+
+ /**
+ * Set if maskout
+ *
+ * @param value If maskout
+ */
+ public void setMaskout(boolean value) {
+ ImageLayer.this.setMaskout(value);
+ }
+
+ /**
+ * Get if is visible
+ *
+ * @return If is visible
+ */
+ public boolean isVisible() {
+ return ImageLayer.this.isVisible();
+ }
+
+ /**
+ * Set if is visible
+ *
+ * @param value If is visible
+ */
+ public void setVisible(boolean value) {
+ ImageLayer.this.setVisible(value);
+ }
+
+ /**
+ * Get world file name of the layer
+ *
+ * @return World file name
+ */
+ public String getWorldFileName() {
+ return _worldFileName;
+ }
+
+ /**
+ * Get if set transparency color
+ *
+ * @return Boolean
+ */
+ public boolean isUseTransColor() {
+ return _isSetTransColor;
+ }
+
+ /**
+ * Set if using transparency color
+ *
+ * @param istrue Boolean
+ */
+ public void setUseTransColor(boolean istrue) {
+ _isSetTransColor = istrue;
+ if (istrue) {
+ Image image = GlobalUtil.makeColorTransparent(_image, _transparencyColor);
+ _image = GlobalUtil.imageToBufferedImage(image);
+ }
+ }
+
+ /**
+ * Get transparency color
+ *
+ * @return Transparency color
+ */
+ public Color getTransparencyColor() {
+ return _transparencyColor;
+ }
+
+ /**
+ * Set transparency color
+ *
+ * @param color The color
+ */
+ public void setTransparencyColor(Color color) {
+ _transparencyColor = color;
+ if (_isSetTransColor) {
+ Image image = GlobalUtil.makeColorTransparent(_image, _transparencyColor);
+ _image = GlobalUtil.imageToBufferedImage(image);
+ }
+ }
+
+ /**
+ * Get transparency percent
+ *
+ * @return Transparency percent
+ */
+ public int getTransparency() {
+ return ImageLayer.this.getTransparency();
+ }
+
+ /**
+ * Set transparency percent
+ *
+ * @param value Transparency percent
+ */
+ public void setTransparency(int value) {
+ ImageLayer.this.setTransparency(value);
+ }
+
+ /**
+ * Get X upper-left
+ *
+ * @return Upper-left x value
+ */
+ public double getXUL() {
+ return _worldFilePara.xUL;
+ }
+
+ /**
+ * Set upper-left x
+ *
+ * @param value The value
+ * @throws java.io.IOException
+ */
+ public void setXUL(double value) throws IOException {
+ _worldFilePara.xUL = value;
+ Extent aExtent = (Extent) ImageLayer.this.getExtent().clone();
+ aExtent.minX = _worldFilePara.xUL;
+ aExtent.maxX = _worldFilePara.xUL + ImageLayer.this.getExtent().getWidth();
+ ImageLayer.this.setExtent(aExtent);
+ if (new File(_worldFileName).exists()) {
+ writeImageWorldFile(_worldFileName, _worldFilePara);
+ }
+ }
+
+ /**
+ * Get y upper-left
+ *
+ * @return Upper-left y
+ */
+ public double getYUL() {
+ return _worldFilePara.yUL;
+ }
+
+ /**
+ * Set upper-left y
+ *
+ * @param value The value
+ * @throws java.io.IOException
+ */
+ public void setYUL(double value) throws IOException {
+ _worldFilePara.yUL = value;
+ Extent aExtent = (Extent) ImageLayer.this.getExtent().clone();
+ aExtent.maxY = _worldFilePara.yUL;
+ aExtent.minY = _worldFilePara.yUL - ImageLayer.this.getExtent().getHeight();
+ ImageLayer.this.setExtent(aExtent);
+ if (new File(_worldFileName).exists()) {
+ writeImageWorldFile(_worldFileName, _worldFilePara);
+ }
+ }
+
+ /**
+ * Get x scale
+ *
+ * @return The x scale
+ */
+ public double getXScale() {
+ return _worldFilePara.xScale;
+ }
+
+ /**
+ * Set x scale
+ *
+ * @param value The value
+ * @throws java.io.IOException
+ */
+ public void setXScale(double value) throws IOException {
+ _worldFilePara.xScale = value;
+ Extent aExtent = (Extent) ImageLayer.this.getExtent();
+ double width = _image.getWidth() * _worldFilePara.xScale;
+ aExtent.maxX = _worldFilePara.xUL + width;
+ ImageLayer.this.setExtent(aExtent);
+ if (new File(_worldFileName).exists()) {
+ writeImageWorldFile(_worldFileName, _worldFilePara);
+ }
+ }
+
+ /**
+ * Get y scale
+ *
+ * @return The y scale
+ */
+ public double getYScale() {
+ return _worldFilePara.yScale;
+ }
+
+ public void setYScale(double value) throws IOException {
+ _worldFilePara.yScale = value;
+ Extent aExtent = (Extent) ImageLayer.this.getExtent();
+ double height = _image.getHeight() * _worldFilePara.yScale;
+ aExtent.minY = _worldFilePara.yUL + height;
+ ImageLayer.this.setExtent(aExtent);
+ if (new File(_worldFileName).exists()) {
+ writeImageWorldFile(_worldFileName, _worldFilePara);
+ }
+ }
+
+ /**
+ * Get x rotate(shear)
+ *
+ * @return X rotate
+ */
+ public double getXRotate() {
+ return _worldFilePara.xRotate;
+ }
+
+ /**
+ * Set x rotate(shear)
+ *
+ * @param value Value
+ * @throws IOException
+ */
+ public void setXRotate(double value) throws IOException {
+ _worldFilePara.xRotate = value;
+ if (new File(_worldFileName).exists()) {
+ writeImageWorldFile(_worldFileName, _worldFilePara);
+ }
+ }
+
+ /**
+ * Get y rotate(shear)
+ *
+ * @return X rotate
+ */
+ public double getYRotate() {
+ return _worldFilePara.yRotate;
+ }
+
+ /**
+ * Set y rotate(shear)
+ *
+ * @param value Value
+ * @throws IOException
+ */
+ public void setYRotate(double value) throws IOException {
+ _worldFilePara.yRotate = value;
+ if (new File(_worldFileName).exists()) {
+ writeImageWorldFile(_worldFileName, _worldFilePara);
+ }
+ }
+
+ /**
+ * Get interpolation
+ *
+ * @return Interpolation
+ */
+ public String getInterpolation() {
+ if (interp == RenderingHints.VALUE_INTERPOLATION_BILINEAR) {
+ return "bilinear";
+ } else if (interp == RenderingHints.VALUE_INTERPOLATION_BICUBIC) {
+ return "bicubic";
+ } else {
+ return "nearest";
+ }
+ }
+
+ /**
+ * Set interpolation
+ *
+ * @param value Interpolation
+ */
+ public void setInterpolation(String value) {
+ switch (value) {
+ case "nearest":
+ interp = RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR;
+ break;
+ case "bilinear":
+ interp = RenderingHints.VALUE_INTERPOLATION_BILINEAR;
+ break;
+ case "bicubic":
+ interp = RenderingHints.VALUE_INTERPOLATION_BICUBIC;
+ break;
+ }
+ }
+ //
+ }
+
+ public static class ImageLayerBeanBeanInfo extends BaseBeanInfo {
+
+ public ImageLayerBeanBeanInfo() {
+ super(ImageLayerBean.class);
+ addProperty("fileName").setCategory("Read only").setReadOnly().setDisplayName("File name");
+ addProperty("layerType").setCategory("Read only").setReadOnly().setDisplayName("Layer type");
+ addProperty("layerDrawType").setCategory("Read only").setReadOnly().setDisplayName("Layer draw type");
+ addProperty("handle").setCategory("Read only").setReadOnly().setDisplayName("Handle");
+ addProperty("layerName").setCategory("Editable").setDisplayName("Layer name");
+ addProperty("visible").setCategory("Editable").setDisplayName("Visible");
+ addProperty("maskout").setCategory("Editable").setDisplayName("Is maskout");
+ addProperty("transparency").setCategory("Editable").setDisplayName("Transparency Percent");
+ addProperty("useTransColor").setCategory("Editable").setDisplayName("If use transparency color");
+ addProperty("transparencyColor").setCategory("Editable").setDisplayName("Transparency color");
+ addProperty("xScale").setCategory("Editable").setDisplayName("X scale");
+ addProperty("yScale").setCategory("Editable").setDisplayName("Y scale");
+ addProperty("xUL").setCategory("Editable").setDisplayName("X upper left");
+ addProperty("yUL").setCategory("Editable").setDisplayName("Y upper left");
+ addProperty("xRotate").setCategory("Editable").setDisplayName("X rotate");
+ addProperty("yRotate").setCategory("Editable").setDisplayName("Y rotate");
+ ExtendedPropertyDescriptor e = addProperty("interpolation");
+ e.setCategory("Editable").setPropertyEditorClass(InterpolationEditor.class);
+ e.setDisplayName("Interpolation");
+ }
+ }
+
+ public static class InterpolationEditor extends ComboBoxPropertyEditor {
+
+ public InterpolationEditor() {
+ super();
+ String[] names = new String[3];
+ names[0] = "nearest";
+ names[1] = "bilinear";
+ names[2] = "bicubic";
+ setAvailableValues(names);
+ }
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/layer/LabelSet.java b/MeteoInfoLib/src/main/java/org/meteoinfo/layer/LabelSet.java
index 5963662d..866283a1 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/layer/LabelSet.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/layer/LabelSet.java
@@ -13,12 +13,12 @@
*/
package org.meteoinfo.layer;
+import org.meteoinfo.common.util.GlobalUtil;
import org.meteoinfo.legend.AlignType;
import java.awt.Color;
import java.awt.Font;
-import org.meteoinfo.global.util.GlobalUtil;
-/**
+ /**
* Template
*
* @author Yaqiang Wang
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/layer/MapLayer.java b/MeteoInfoLib/src/main/java/org/meteoinfo/layer/MapLayer.java
index 3b6834c4..ba18247a 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/layer/MapLayer.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/layer/MapLayer.java
@@ -13,7 +13,7 @@
*/
package org.meteoinfo.layer;
-import org.meteoinfo.global.Extent;
+import org.meteoinfo.common.Extent;
import org.meteoinfo.legend.LegendScheme;
import org.meteoinfo.projection.KnownCoordinateSystems;
import org.meteoinfo.projection.info.ProjectionInfo;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/layer/RasterLayer.java b/MeteoInfoLib/src/main/java/org/meteoinfo/layer/RasterLayer.java
index b1c7bcf0..73285c49 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/layer/RasterLayer.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/layer/RasterLayer.java
@@ -15,8 +15,10 @@ package org.meteoinfo.layer;
import com.l2fprod.common.beans.BaseBeanInfo;
import com.l2fprod.common.beans.ExtendedPropertyDescriptor;
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.global.MIMath;
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.GenericFileFilter;
+import org.meteoinfo.common.MIMath;
+import org.meteoinfo.common.util.GlobalUtil;
import org.meteoinfo.legend.LegendScheme;
import org.meteoinfo.shape.ShapeTypes;
import java.awt.Color;
@@ -31,8 +33,6 @@ import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import org.meteoinfo.data.GridArray;
import org.meteoinfo.data.mapdata.MapDataManage;
-import org.meteoinfo.global.GenericFileFilter;
-import org.meteoinfo.global.util.GlobalUtil;
import org.meteoinfo.projection.info.ProjectionInfo;
import org.meteoinfo.ndarray.Index;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/layer/VectorLayer.java b/MeteoInfoLib/src/main/java/org/meteoinfo/layer/VectorLayer.java
index 88404c3c..5ce2f17f 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/layer/VectorLayer.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/layer/VectorLayer.java
@@ -13,14 +13,14 @@
*/
package org.meteoinfo.layer;
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.GenericFileFilter;
+import org.meteoinfo.common.MIMath;
+import org.meteoinfo.common.PointD;
import org.meteoinfo.data.mapdata.AttributeTable;
import org.meteoinfo.data.mapdata.Field;
import org.meteoinfo.data.mapdata.ShapeFileManage;
import org.meteoinfo.geoprocess.GeoComputation;
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.global.GenericFileFilter;
-import org.meteoinfo.global.MIMath;
-import org.meteoinfo.global.PointD;
import org.meteoinfo.global.colors.ColorUtil;
import org.meteoinfo.projection.info.ProjectionInfo;
import org.meteoinfo.table.DataColumn;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/layer/WebMapLayer.java b/MeteoInfoLib/src/main/java/org/meteoinfo/layer/WebMapLayer.java
index 07ccbccf..4f3918e8 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/layer/WebMapLayer.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/layer/WebMapLayer.java
@@ -1,922 +1,919 @@
-/*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.meteoinfo.layer;
-
-//import com.sun.java.swing.Painter;
-import com.l2fprod.common.beans.BaseBeanInfo;
-import com.l2fprod.common.beans.ExtendedPropertyDescriptor;
-import com.l2fprod.common.beans.editor.ComboBoxPropertyEditor;
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.Graphics2D;
-import java.awt.Image;
-import java.awt.Rectangle;
-import java.awt.geom.Point2D;
-import java.awt.image.BufferedImage;
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.List;
-import javax.imageio.ImageIO;
-
-import org.meteoinfo.data.mapdata.webmap.*;
-import org.meteoinfo.data.mapdata.webmap.empty.EmptyTileFactory;
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.global.MIMath;
-import org.meteoinfo.global.PointD;
-import org.meteoinfo.global.util.GeoUtil;
-import org.meteoinfo.projection.KnownCoordinateSystems;
-import org.meteoinfo.projection.Reproject;
-import org.meteoinfo.shape.ShapeTypes;
-
-/**
- *
- * @author wyq
- */
-public class WebMapLayer extends MapLayer {
- //
-
- private final boolean isNegativeYAllowed = true; //maybe rename to isNorthBounded and isSouthBounded?
- /**
- * The zoom level. Generally a value between 1 and 15 (TODO Is this true for
- * all the mapping worlds? What does this mean if some mapping system
- * doesn't support the zoom level?
- */
- private int zoom = 11;
- /**
- * The position, in map coordinates of the center point. This is
- * defined as the distance from the top and left edges of the map in pixels.
- * Dragging the map component will change the center position. Zooming
- * in/out will cause the center to be recalculated so as to remain in the
- * center of the new "map".
- */
- private Point2D center = new Point2D.Double(0, 0);
- /**
- * Indicates whether or not to draw the borders between tiles. Defaults to
- * false.
- *
- * TODO Generally not very nice looking, very much a product of testing
- * Consider whether this should really be a property or not.
- */
- private boolean drawTileBorders = false;
- /**
- * Factory used by this component to grab the tiles necessary for painting
- * the map.
- */
- private TileFactory factory;
- /**
- * The position in latitude/longitude of the "address" being mapped. This is
- * a special coordinate that, when moved, will cause the map to be moved as
- * well. It is separate from "center" in that "center" tracks the current
- * center (in pixels) of the viewport whereas this will not change when
- * panning or zooming. Whenever the addressLocation is changed, however, the
- * map will be repositioned.
- */
- private GeoPosition addressLocation;
- /**
- * Specifies whether panning is enabled. Panning is being able to click and
- * drag the map around to cause it to move
- */
- private boolean panEnabled = true;
- /**
- * Specifies whether zooming is enabled (the mouse wheel, for example,
- * zooms)
- */
- private boolean zoomEnabled = true;
- /**
- * Indicates whether the component should recenter the map when the "middle"
- * mouse button is pressed
- */
- private boolean recenterOnClickEnabled = true;
- /**
- * The overlay to delegate to for painting the "foreground" of the map
- * component. This would include painting waypoints, day/night, etc. Also
- * receives mouse events.
- */
- //private Painter overlay;
- private boolean designTime;
- private double webMapScale = 0.;
- private Image loadingImage;
- private boolean restrictOutsidePanning = false;
- private boolean horizontalWrapped = true;
- private WebMapProvider defaultProvider = WebMapProvider.OpenStreetMap;
- private Graphics2D graphics;
- private int width;
- private int height;
- private List scales = new ArrayList<>();
- //
- //
- // a property change listener which forces repaints when tiles finish loading
- //private TileLoadListener tileLoadListener = new TileLoadListener();
-
-// private final class TileLoadListener implements PropertyChangeListener {
-//
-// @Override
-// public void propertyChange(PropertyChangeEvent evt) {
-// if ("loaded".equals(evt.getPropertyName())
-// && Boolean.TRUE.equals(evt.getNewValue())) {
-// Tile t = (Tile) evt.getSource();
-// if (t.getZoom() == getZoom()) {
-// repaint();
-// /* this optimization doesn't save much and it doesn't work if you
-// * wrap around the world
-// Rectangle viewportBounds = getViewportBounds();
-// TilePoint tilePoint = t.getLocation();
-// Point point = new Point(tilePoint.getX() * getTileFactory().getTileSize(), tilePoint.getY() * getTileFactory().getTileSize());
-// Rectangle tileRect = new Rectangle(point, new Dimension(getTileFactory().getTileSize(), getTileFactory().getTileSize()));
-// if (viewportBounds.intersects(tileRect)) {
-// //convert tileRect from world space to viewport space
-// repaint(new Rectangle(
-// tileRect.x - viewportBounds.x,
-// tileRect.y - viewportBounds.y,
-// tileRect.width,
-// tileRect.height
-// ));
-// }*/
-// }
-// }
-// }
-// }
- //
- //
-
- /**
- * Constructor
- */
- public WebMapLayer() {
- super();
- this.setLayerType(LayerTypes.WebMapLayer);
- this.setShapeType(ShapeTypes.Image);
- this.setLayerDrawType(LayerDrawType.Image);
- this.setLayerName("OpenStreetMap");
- this.setExtent(new Extent(-2.0037508342789244E7, 2.0037508342789244E7, -1.8375854901481014E7, 1.8375854901481014E7));
- factory = new EmptyTileFactory();
-
- // make a dummy loading image
- try {
- URL url = this.getClass().getResource("/images/loading.png");
- this.setLoadingImage(ImageIO.read(url));
- } catch (Throwable ex) {
- System.out.println("could not load 'loading.png'");
- BufferedImage img = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);
- Graphics2D g2 = img.createGraphics();
- g2.setColor(Color.black);
- g2.fillRect(0, 0, 16, 16);
- g2.dispose();
- this.setLoadingImage(img);
- }
- }
- //
- //
-
- /**
- * Gets the current zoom level
- *
- * @return the current zoom level
- */
- public int getZoom() {
- return this.zoom;
- }
-
- /**
- * Set the current zoom level
- *
- * @param zoom the new zoom level
- */
- public void setZoom(int zoom) {
- if (zoom == this.zoom) {
- return;
- }
-
- TileFactoryInfo info = getTileFactory().getInfo();
- // don't repaint if we are out of the valid zoom levels
- if (info != null
- && (zoom < info.getMinimumZoomLevel()
- || zoom > info.getMaximumZoomLevel())) {
- return;
- }
-
- //if(zoom >= 0 && zoom <= 15 && zoom != this.zoom) {
- int oldzoom = this.zoom;
- Point2D oldCenter = getCenter();
- Dimension oldMapSize = getTileFactory().getMapSize(oldzoom);
- this.zoom = zoom;
- //this.firePropertyChange("zoom", oldzoom, zoom);
-
- Dimension mapSize = getTileFactory().getMapSize(zoom);
-
- setCenter(new Point2D.Double(
- oldCenter.getX() * (mapSize.getWidth() / oldMapSize.getWidth()),
- oldCenter.getY() * (mapSize.getHeight() / oldMapSize.getHeight())));
-
- //repaint();
- }
-
- /**
- * Gets the current pixel center of the map. This point is in the global
- * bitmap coordinate system, not as lat/longs.
- *
- * @return the current center of the map as a pixel value
- */
- public Point2D getCenter() {
- return center;
- }
-
- public boolean isRestrictOutsidePanning() {
- return restrictOutsidePanning;
- }
-
- public void setRestrictOutsidePanning(boolean restrictOutsidePanning) {
- this.restrictOutsidePanning = restrictOutsidePanning;
- }
-
- /**
- * Sets the new center of the map in pixel coordinates.
- *
- * @param center the new center of the map in pixel coordinates
- */
- public void setCenter(Point2D center) {
- this.center = center;
-// if(isRestrictOutsidePanning()) {
-// Insets insets = getInsets();
-// int viewportHeight = getHeight() - insets.top - insets.bottom;
-// int viewportWidth = getWidth() - insets.left - insets.right;
-//
-// // don't let the user pan over the top edge
-// Rectangle newVP = calculateViewportBounds(center);
-// if(newVP.getY() < 0) {
-// double centerY = viewportHeight/2;
-// center = new Point2D.Double(center.getX(),centerY);
-// }
-//
-// // don't let the user pan over the left edge
-// if(!isHorizontalWrapped() && newVP.getX() <0) {
-// double centerX = viewportWidth/2;
-// center = new Point2D.Double(centerX, center.getY());
-// }
-//
-// // don't let the user pan over the bottom edge
-// Dimension mapSize = getTileFactory().getMapSize(getZoom());
-// int mapHeight = (int)mapSize.getHeight()*getTileFactory().getTileSize(getZoom());
-// if(newVP.getY() + newVP.getHeight() > mapHeight) {
-// double centerY = mapHeight - viewportHeight/2;
-// center = new Point2D.Double(center.getX(),centerY);
-// }
-//
-// //don't let the user pan over the right edge
-// int mapWidth = (int)mapSize.getWidth()*getTileFactory().getTileSize(getZoom());
-// if(!isHorizontalWrapped() && (newVP.getX() + newVP.getWidth() > mapWidth)) {
-// double centerX = mapWidth - viewportWidth/2;
-// center = new Point2D.Double(centerX, center.getY());
-// }
-//
-// // if map is to small then just center it vert
-// if(mapHeight < newVP.getHeight()) {
-// double centerY = mapHeight/2;//viewportHeight/2;// - mapHeight/2;
-// center = new Point2D.Double(center.getX(),centerY);
-// }
-//
-// // if map is too small then just center it horiz
-// if(!isHorizontalWrapped() && mapWidth < newVP.getWidth()) {
-// double centerX = mapWidth/2;
-// center = new Point2D.Double(centerX, center.getY());
-// }
-// }
-//
-// //joshy: this is an evil hack to force a property change event
-// //i don't know why it doesn't work normally
-// old = new Point(5,6);
-//
-// GeoPosition oldGP = this.getCenterPosition();
- }
-
- /**
- * A property indicating the center position of the map
- *
- * @param geoPosition the new property value
- */
- public void setCenterPosition(GeoPosition geoPosition) {
- GeoPosition oldVal = getCenterPosition();
- setCenter(getTileFactory().geoToPixel(geoPosition, zoom));
- //repaint();
- GeoPosition newVal = getCenterPosition();
- //firePropertyChange("centerPosition", oldVal, newVal);
- }
-
- /**
- * A property indicating the center position of the map
- *
- * @return the current center position
- */
- public GeoPosition getCenterPosition() {
- return getTileFactory().pixelToGeo(getCenter(), zoom);
- }
-
- /**
- * Get the current factory
- *
- * @return the current property value
- */
- public TileFactory getTileFactory() {
- return factory;
- }
-
- /**
- * Set the current tile factory
- *
- * @param factory the new property value
- */
- public void setTileFactory(TileFactory factory) {
- this.factory = factory;
- this.setZoom(factory.getInfo().getDefaultZoomLevel());
- this.setCenterPosition(new GeoPosition(0, 0));
- }
-
- /**
- * Get web map scale
- * @return Web map scale
- */
- public double getWebMapScale() {
- return this.webMapScale;
- }
-
- /**
- * Set web map scale
- * @param value Web map scale
- */
- public void setWebMapScale(double value) {
- this.webMapScale = value;
- }
-
- /**
- * A property for an image which will be display when an image is still
- * loading.
- *
- * @return the current property value
- */
- public Image getLoadingImage() {
- return loadingImage;
- }
-
- /**
- * A property for an image which will be display when an image is still
- * loading.
- *
- * @param loadingImage the new property value
- */
- public void setLoadingImage(Image loadingImage) {
- this.loadingImage = loadingImage;
- }
-
- /**
- * Indicates if the tile borders should be drawn. Mainly used for debugging.
- *
- * @return the value of this property
- */
- public boolean isDrawTileBorders() {
- return drawTileBorders;
- }
-
- /**
- * Set if the tile borders should be drawn. Mainly used for debugging.
- *
- * @param drawTileBorders new value of this drawTileBorders
- */
- public void setDrawTileBorders(boolean drawTileBorders) {
- //boolean old = isDrawTileBorders();
- this.drawTileBorders = drawTileBorders;
- //firePropertyChange("drawTileBorders", old, isDrawTileBorders());
- //repaint();
- }
-
- /**
- * Set web map provider
- * @param prov The web map provider
- */
- public void setWebMapProvider(WebMapProvider prov) {
- TileFactoryInfo info = null;
- switch (prov) {
-// case SwingLabsBlueMarble:
-// setTileFactory(new CylindricalProjectionTileFactory());
-// setZoom(3);
-// return;
- case OpenStreetMap:
- info = new OpenStreetMapInfo();
- break;
- case OpenStreetMapQuestSatellite:
- info = new OpenStreetMapQuestSatelliteInfo();
- break;
- case BingMap:
- info = new BingMapInfo();
- break;
- case BingSatelliteMap:
- info = new BingSatelliteMapInfo();
- break;
- case BingHybridMap:
- info = new BingHybridMapInfo();
- break;
-// case OviMap:
-// info = new OviMapInfo();
-// break;
-// case OviSatelliteMap:
-// info = new OviSatelliteMapInfo();
-// break;
-// case OviTerrainMap:
-// info = new OviTerrainMapInfo();
-// break;
-// case OviHybridMap:
-// info = new OviHybridMapInfo();
-// break;
- case YahooMap:
- info = new YahooMapInfo();
- break;
- case YahooSatelliteMap:
- info = new YahooSatelliteMapInfo();
- break;
- case YahooHybridMap:
- info = new YahooHybridMapInfo();
- break;
- case GoogleMap:
- info = new GoogleMapInfo();
- break;
- case GoogleSatelliteMap:
- info = new GoogleSatelliteMapInfo();
- break;
- case GoogleTerrainMap:
- info = new GoogleTerrainMapInfo();
- break;
- case GoogleHybridMap:
- info = new GoogleHybridMapInfo();
- break;
- case GoogleHybridTerrainMap:
- info = new GoogleHybridTerrainMapInfo();
- break;
-// case BaiduMap:
-// info = new BaiduMapInfo();
-// break;
-// case BaiduSatelliteMap:
-// info = new BaiduSatelliteMapInfo();
-// break;
- case AMap:
- info = new AMapInfo();
- break;
- case ASatelliteMap:
- info = new ASatelliteMapInfo();
- break;
- case AHybridMap:
- info = new AHybridMapInfo();
- break;
- case TencentMap:
- info = new TencentMapInfo();
- break;
- case CMA_CVA_MAP:
- info = new CMACvaMapInfo();
- break;
- case CMA_VEC_MAP:
- info = new CMAVecMapInfo();
- break;
- case CMA_IMG_MAP:
- info = new CMAImgMapInfo();
- break;
-// case ArcGISImage:
-// info = new ArcGISImageInfo();
-// break;
- }
-
- if (info != null) {
- this.defaultProvider = prov;
- this.setLayerName("WebMap_" + info.getName());
- TileFactory tf = new DefaultTileFactory(info);
- setTileFactory(tf);
- //setZoom(11);
- setAddressLocation(new GeoPosition(51.5, 0));
- }
- }
-
- /**
- * Get web map provider
- * @return Web map provider
- */
- public WebMapProvider getWebMapProvider() {
- return this.defaultProvider;
- }
-
- public GeoPosition getAddressLocation() {
- return this.addressLocation;
- }
-
- public void setAddressLocation(GeoPosition pos, int zoom) {
- this.addressLocation = pos;
- setCenter(getTileFactory().geoToPixel(pos, zoom));
- }
-
- public void setAddressLocation(GeoPosition pos) {
- this.addressLocation = pos;
- setCenter(getTileFactory().geoToPixel(addressLocation, getZoom()));
- }
- //
- //
-
- /**
- * Repaint
- */
- public void repaint() {
- Rectangle rect = this.calculateViewportBounds(graphics, width, height);
- this.drawMapTiles(graphics, zoom, rect);
- }
-
- /**
- * Draw the map tiles
- *
- * @param g Graphics2D
- * @param zoom Zoom level to draw at
- * @param width The width
- * @param height The height
- */
- public void drawMapTiles(final Graphics2D g, final int zoom, int width, int height) {
- this.graphics = g;
- this.zoom = zoom;
- this.width = width;
- this.height = height;
- Rectangle rect = this.calculateViewportBounds(g, width, height);
- this.drawMapTiles(g, zoom, rect);
- }
-
- /**
- * Draw the map tiles. This method is for implementation use only.
- *
- * @param g Graphics
- * @param zoom zoom level to draw at
- * @param viewportBounds View bounds
- */
- public void drawMapTiles(final Graphics2D g, final int zoom, final Rectangle viewportBounds) {
- int size = getTileFactory().getTileSize(zoom);
- Dimension mapSize = getTileFactory().getMapSize(zoom);
-
- //calculate the "visible" viewport area in tiles
- int numWide = viewportBounds.width / size + 2;
- int numHigh = viewportBounds.height / size + 2;
-
- //TilePoint topLeftTile = getTileFactory().getTileCoordinate(
- // new Point2D.Double(viewportBounds.x, viewportBounds.y));
- TileFactoryInfo info = getTileFactory().getInfo();
- int tpx = (int) Math.floor(viewportBounds.getX() / info.getTileSize(0));
- int tpy = (int) Math.floor(viewportBounds.getY() / info.getTileSize(0));
- //TilePoint topLeftTile = new TilePoint(tpx, tpy);
-
- //p("top tile = " + topLeftTile);
- //fetch the tiles from the factory and store them in the tiles cache
- //attach the tileLoadListener
- for (int x = 0; x <= numWide; x++) {
- for (int y = 0; y <= numHigh; y++) {
- int itpx = x + tpx;//topLeftTile.getX();
- int itpy = y + tpy;//topLeftTile.getY();
- //TilePoint point = new TilePoint(x + topLeftTile.getX(), y + topLeftTile.getY());
- //only proceed if the specified tile point lies within the area being painted
- //if (g.getClipBounds().intersects(new Rectangle(itpx * size - viewportBounds.x,
- //itpy * size - viewportBounds.y, size, size))) {
- Tile tile = getTileFactory().getTile(itpx, itpy, zoom);
- //tile.addUniquePropertyChangeListener("loaded", tileLoadListener); //this is a filthy hack
- int ox = ((itpx * getTileFactory().getTileSize(zoom)) - viewportBounds.x);
- int oy = ((itpy * getTileFactory().getTileSize(zoom)) - viewportBounds.y);
-
- //if the tile is off the map to the north/south, then just don't paint anything
- if (isTileOnMap(itpx, itpy, mapSize)) {
-// if (isOpaque()) {
-// g.setColor(getBackground());
-// g.fillRect(ox,oy,size,size);
-// }
- } else if (tile.isLoaded()) {
- g.drawImage(tile.getImage(), ox, oy, null);
- }
-// else {
-// int imageX = (getTileFactory().getTileSize(zoom) - getLoadingImage().getWidth(null)) / 2;
-// int imageY = (getTileFactory().getTileSize(zoom) - getLoadingImage().getHeight(null)) / 2;
-// g.setColor(Color.GRAY);
-// g.fillRect(ox, oy, size, size);
-// g.drawImage(getLoadingImage(), ox + imageX, oy + imageY, null);
-// }
- if (isDrawTileBorders()) {
-
- g.setColor(Color.black);
- g.drawRect(ox, oy, size, size);
- g.drawRect(ox + size / 2 - 5, oy + size / 2 - 5, 10, 10);
- g.setColor(Color.white);
- g.drawRect(ox + 1, oy + 1, size, size);
-
- String text = itpx + ", " + itpy + ", " + getZoom();
- g.setColor(Color.BLACK);
- g.drawString(text, ox + 10, oy + 30);
- g.drawString(text, ox + 10 + 2, oy + 30 + 2);
- g.setColor(Color.WHITE);
- g.drawString(text, ox + 10 + 1, oy + 30 + 1);
- }
- //}
- }
- }
- }
-
- /**
- * Draw layer
- * @param g The Graphics2D
- * @param width Canvas width
- * @param height Canvas height
- * @param tll TileLoadListener
- */
- public void drawWebMapLayer(Graphics2D g, int width, int height, TileLoadListener tll) {
- //layer.setZoom(zoom);
- //layer.drawMapTiles(g, zoom, width, height);
- Rectangle viewportBounds = this.calculateViewportBounds(g, width, height);
- int size = this.getTileFactory().getTileSize(zoom);
- Dimension mapSize = this.getTileFactory().getMapSize(zoom);
-
- //calculate the "visible" viewport area in tiles
- int numWide = viewportBounds.width / size + 2;
- int numHigh = viewportBounds.height / size + 2;
-
- //TilePoint topLeftTile = getTileFactory().getTileCoordinate(
- // new Point2D.Double(viewportBounds.x, viewportBounds.y));
- TileFactoryInfo info = this.getTileFactory().getInfo();
- int tpx = (int) Math.floor(viewportBounds.getX() / info.getTileSize(0));
- int tpy = (int) Math.floor(viewportBounds.getY() / info.getTileSize(0));
- //TilePoint topLeftTile = new TilePoint(tpx, tpy);
-
- //p("top tile = " + topLeftTile);
- //fetch the tiles from the factory and store them in the tiles cache
- //attach the TileLoadListener
- //String language = layer.getTileFactory().getInfo().getLanguage();
- for (int x = 0; x <= numWide; x++) {
- for (int y = 0; y <= numHigh; y++) {
- int itpx = x + tpx;//topLeftTile.getX();
- int itpy = y + tpy;//topLeftTile.getY();
- //TilePoint point = new TilePoint(x + topLeftTile.getX(), y + topLeftTile.getY());
- //only proceed if the specified tile point lies within the area being painted
- //if (g.getClipBounds().intersects(new Rectangle(itpx * size - viewportBounds.x,
- //itpy * size - viewportBounds.y, size, size))) {
- Tile tile = this.getTileFactory().getTile(itpx, itpy, zoom);
- tile.addUniquePropertyChangeListener("loaded", tll); //this is a filthy hack
- int ox = ((itpx * this.getTileFactory().getTileSize(zoom)) - viewportBounds.x);
- int oy = ((itpy * this.getTileFactory().getTileSize(zoom)) - viewportBounds.y);
-
- //if the tile is off the map to the north/south, then just don't paint anything
- if (this.isTileOnMap(itpx, itpy, mapSize)) {
-// if (isOpaque()) {
-// g.setColor(getBackground());
-// g.fillRect(ox,oy,size,size);
-// }
- } else if (tile.isLoaded()) {
- g.drawImage(tile.getImage(), ox, oy, null);
- } else {
- int imageX = (this.getTileFactory().getTileSize(zoom) - this.getLoadingImage().getWidth(null)) / 2;
- int imageY = (this.getTileFactory().getTileSize(zoom) - this.getLoadingImage().getHeight(null)) / 2;
- g.setColor(Color.GRAY);
- g.fillRect(ox, oy, size, size);
- g.drawImage(this.getLoadingImage(), ox + imageX, oy + imageY, null);
- }
- if (this.isDrawTileBorders()) {
-
- g.setColor(Color.black);
- g.drawRect(ox, oy, size, size);
- g.drawRect(ox + size / 2 - 5, oy + size / 2 - 5, 10, 10);
- g.setColor(Color.white);
- g.drawRect(ox + 1, oy + 1, size, size);
-
- String text = itpx + ", " + itpy + ", " + this.getZoom();
- g.setColor(Color.BLACK);
- g.drawString(text, ox + 10, oy + 30);
- g.drawString(text, ox + 10 + 2, oy + 30 + 2);
- g.setColor(Color.WHITE);
- g.drawString(text, ox + 10 + 1, oy + 30 + 1);
- }
- //}
- }
- }
- }
-
- private double getWebMapScale(int zoom, int width, int height) {
- Point2D center = this.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, this.getTileFactory().getInfo());
- GeoPosition pos2 = GeoUtil.getPosition(new Point2D.Double(maxx, maxy), zoom, this.getTileFactory().getInfo());
- PointD p1 = Reproject.reprojectPoint(new PointD(pos1.getLongitude(), pos1.getLatitude()),
- KnownCoordinateSystems.geographic.world.WGS1984, this.getProjInfo());
- PointD p2 = Reproject.reprojectPoint(new PointD(pos2.getLongitude(), pos2.getLatitude()),
- KnownCoordinateSystems.geographic.world.WGS1984, this.getProjInfo());
- if (pos2.getLongitude() - pos1.getLongitude() < 360.0) {
- double xlen = p2.X - p1.X;
-// if (pos2.getLongitude() - pos1.getLongitude() > 360)
-// xlen += 2.0037497210840166E7 * 2;
- return (double) width / xlen;
- } else {
- double ylen = Math.abs(p2.Y - p1.Y);
- return (double) height / ylen;
- }
- }
-
- public boolean isTileOnMap(int x, int y, Dimension mapSize) {
- return !isNegativeYAllowed && y < 0 || y >= mapSize.getHeight();
- }
-
- /**
- * Calculate view port bounds
- *
- * @param g Graphic2D
- * @param width The width
- * @param height The height
- * @return View port bounds rectangle
- */
- public Rectangle calculateViewportBounds(Graphics2D g, int width, int height) {
- //calculate the "visible" viewport area in pixels
- //double sx = g.getTransform().getTranslateX();
- //double sy = g.getTransform().getTranslateY();
- double viewportX = (center.getX() - width / 2);
- double viewportY = (center.getY() - height / 2);
- return new Rectangle((int) viewportX, (int) viewportY, width, height);
- }
-
- /**
- * To string
- * @return String
- */
- @Override
- public String getLayerInfo(){
- String str = "Layer name: " + this.getLayerName();
- str += System.getProperty("line.separator") + "Layer file: " + this.getFileName();
- str += System.getProperty("line.separator") + "Layer type: " + this.getLayerType();
- str += System.getProperty("line.separator") + "Data provider: " + this.defaultProvider;
-
- return str;
- }
- //
- //
- public class WebMapLayerBean {
- public WebMapLayerBean(){
-
- }
-
- //
- /**
- * Get layer type
- *
- * @return Layer type
- */
- public LayerTypes getLayerType() {
- return WebMapLayer.this.getLayerType();
- }
-
- /**
- * Get layer draw type
- *
- * @return Layer draw type
- */
- public LayerDrawType getLayerDrawType() {
- return WebMapLayer.this.getLayerDrawType();
- }
-
- /**
- * Get layer handle
- *
- * @return Layer handle
- */
- public int getHandle() {
- return WebMapLayer.this.getHandle();
- }
-
- /**
- * Get layer name
- *
- * @return Layer name
- */
- public String getLayerName() {
- return WebMapLayer.this.getLayerName();
- }
-
- /**
- * Set layer name
- *
- * @param name Layer name
- */
- public void setLayerName(String name) {
- WebMapLayer.this.setLayerName(name);
- }
-
- /**
- * Get web map provider
- * @return The web map provider
- */
- public String getWebMapProvider(){
- return WebMapLayer.this.defaultProvider.toString();
- }
-
- /**
- * Set web map provider
- * @param provider The web map provider
- */
- public void setWebMapProvider(String provider){
- WebMapLayer.this.setWebMapProvider(WebMapProvider.valueOf(provider));
- }
-
- /**
- * Get if is maskout
- *
- * @return If is maskout
- */
- public boolean isMaskout() {
- return WebMapLayer.this.isMaskout();
- }
-
- /**
- * Set if maskout
- *
- * @param value If maskout
- */
- public void setMaskout(boolean value) {
- WebMapLayer.this.setMaskout(value);
- }
-
- /**
- * Get if is visible
- *
- * @return If is visible
- */
- public boolean isVisible() {
- return WebMapLayer.this.isVisible();
- }
-
- /**
- * Set if is visible
- *
- * @param value If is visible
- */
- public void setVisible(boolean value) {
- WebMapLayer.this.setVisible(value);
- }
-
- /**
- * Get language
- * @return The language
- */
- public String getLanguage(){
- return WebMapLayer.this.getTileFactory().getInfo().getLanguage();
- }
-
- /**
- * Set language
- * @param value The language
- */
- public void setLanguage(String value) {
- WebMapLayer.this.getTileFactory().getInfo().setLanguage(value);
- }
-
- //
- }
-
- public static class WebMapLayerBeanBeanInfo extends BaseBeanInfo {
-
- public WebMapLayerBeanBeanInfo() {
- super(WebMapLayer.WebMapLayerBean.class);
- addProperty("layerType").setCategory("Read only").setReadOnly().setDisplayName("Layer type");
- addProperty("layerDrawType").setCategory("Read only").setReadOnly().setDisplayName("Layer draw type");
- addProperty("handle").setCategory("Read only").setReadOnly().setDisplayName("Handle");
- ExtendedPropertyDescriptor e = addProperty("webMapProvider");
- e.setCategory("Editable").setDisplayName("Web Map Provider");
- e.setPropertyEditorClass(WebMapProviderEditor.class);
- e = addProperty("language");
- e.setCategory("Editable").setDisplayName("Language");
- e.setPropertyEditorClass(LanguageEditor.class);
- addProperty("visible").setCategory("Editable").setDisplayName("Visible");
- addProperty("maskout").setCategory("Editable").setDisplayName("Is maskout");
- }
- }
-
- public static class WebMapProviderEditor extends ComboBoxPropertyEditor {
-
- public WebMapProviderEditor() {
- super();
- WebMapProvider[] providers = WebMapProvider.values();
- String[] types = new String[providers.length];
- int i = 0;
- for (WebMapProvider prov : providers) {
- types[i] = prov.toString();
- i += 1;
- }
- setAvailableValues(types);
- }
- }
-
- public static class LanguageEditor extends ComboBoxPropertyEditor {
-
- public LanguageEditor() {
- super();
- String[] langs = new String[]{"en-us", "zh-cn"};
- setAvailableValues(langs);
- }
- }
- //
-}
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.meteoinfo.layer;
+
+//import com.sun.java.swing.Painter;
+import com.l2fprod.common.beans.BaseBeanInfo;
+import com.l2fprod.common.beans.ExtendedPropertyDescriptor;
+import com.l2fprod.common.beans.editor.ComboBoxPropertyEditor;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.Rectangle;
+import java.awt.geom.Point2D;
+import java.awt.image.BufferedImage;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import javax.imageio.ImageIO;
+
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.PointD;
+import org.meteoinfo.data.mapdata.webmap.*;
+import org.meteoinfo.data.mapdata.webmap.empty.EmptyTileFactory;
+import org.meteoinfo.global.util.GeoUtil;
+import org.meteoinfo.projection.KnownCoordinateSystems;
+import org.meteoinfo.projection.Reproject;
+import org.meteoinfo.shape.ShapeTypes;
+
+/**
+ *
+ * @author wyq
+ */
+public class WebMapLayer extends MapLayer {
+ //
+
+ private final boolean isNegativeYAllowed = true; //maybe rename to isNorthBounded and isSouthBounded?
+ /**
+ * The zoom level. Generally a value between 1 and 15 (TODO Is this true for
+ * all the mapping worlds? What does this mean if some mapping system
+ * doesn't support the zoom level?
+ */
+ private int zoom = 11;
+ /**
+ * The position, in map coordinates of the center point. This is
+ * defined as the distance from the top and left edges of the map in pixels.
+ * Dragging the map component will change the center position. Zooming
+ * in/out will cause the center to be recalculated so as to remain in the
+ * center of the new "map".
+ */
+ private Point2D center = new Point2D.Double(0, 0);
+ /**
+ * Indicates whether or not to draw the borders between tiles. Defaults to
+ * false.
+ *
+ * TODO Generally not very nice looking, very much a product of testing
+ * Consider whether this should really be a property or not.
+ */
+ private boolean drawTileBorders = false;
+ /**
+ * Factory used by this component to grab the tiles necessary for painting
+ * the map.
+ */
+ private TileFactory factory;
+ /**
+ * The position in latitude/longitude of the "address" being mapped. This is
+ * a special coordinate that, when moved, will cause the map to be moved as
+ * well. It is separate from "center" in that "center" tracks the current
+ * center (in pixels) of the viewport whereas this will not change when
+ * panning or zooming. Whenever the addressLocation is changed, however, the
+ * map will be repositioned.
+ */
+ private GeoPosition addressLocation;
+ /**
+ * Specifies whether panning is enabled. Panning is being able to click and
+ * drag the map around to cause it to move
+ */
+ private boolean panEnabled = true;
+ /**
+ * Specifies whether zooming is enabled (the mouse wheel, for example,
+ * zooms)
+ */
+ private boolean zoomEnabled = true;
+ /**
+ * Indicates whether the component should recenter the map when the "middle"
+ * mouse button is pressed
+ */
+ private boolean recenterOnClickEnabled = true;
+ /**
+ * The overlay to delegate to for painting the "foreground" of the map
+ * component. This would include painting waypoints, day/night, etc. Also
+ * receives mouse events.
+ */
+ //private Painter overlay;
+ private boolean designTime;
+ private double webMapScale = 0.;
+ private Image loadingImage;
+ private boolean restrictOutsidePanning = false;
+ private boolean horizontalWrapped = true;
+ private WebMapProvider defaultProvider = WebMapProvider.OpenStreetMap;
+ private Graphics2D graphics;
+ private int width;
+ private int height;
+ private List scales = new ArrayList<>();
+ //
+ //
+ // a property change listener which forces repaints when tiles finish loading
+ //private TileLoadListener tileLoadListener = new TileLoadListener();
+
+// private final class TileLoadListener implements PropertyChangeListener {
+//
+// @Override
+// public void propertyChange(PropertyChangeEvent evt) {
+// if ("loaded".equals(evt.getPropertyName())
+// && Boolean.TRUE.equals(evt.getNewValue())) {
+// Tile t = (Tile) evt.getSource();
+// if (t.getZoom() == getZoom()) {
+// repaint();
+// /* this optimization doesn't save much and it doesn't work if you
+// * wrap around the world
+// Rectangle viewportBounds = getViewportBounds();
+// TilePoint tilePoint = t.getLocation();
+// Point point = new Point(tilePoint.getX() * getTileFactory().getTileSize(), tilePoint.getY() * getTileFactory().getTileSize());
+// Rectangle tileRect = new Rectangle(point, new Dimension(getTileFactory().getTileSize(), getTileFactory().getTileSize()));
+// if (viewportBounds.intersects(tileRect)) {
+// //convert tileRect from world space to viewport space
+// repaint(new Rectangle(
+// tileRect.x - viewportBounds.x,
+// tileRect.y - viewportBounds.y,
+// tileRect.width,
+// tileRect.height
+// ));
+// }*/
+// }
+// }
+// }
+// }
+ //
+ //
+
+ /**
+ * Constructor
+ */
+ public WebMapLayer() {
+ super();
+ this.setLayerType(LayerTypes.WebMapLayer);
+ this.setShapeType(ShapeTypes.Image);
+ this.setLayerDrawType(LayerDrawType.Image);
+ this.setLayerName("OpenStreetMap");
+ this.setExtent(new Extent(-2.0037508342789244E7, 2.0037508342789244E7, -1.8375854901481014E7, 1.8375854901481014E7));
+ factory = new EmptyTileFactory();
+
+ // make a dummy loading image
+ try {
+ URL url = this.getClass().getResource("/images/loading.png");
+ this.setLoadingImage(ImageIO.read(url));
+ } catch (Throwable ex) {
+ System.out.println("could not load 'loading.png'");
+ BufferedImage img = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);
+ Graphics2D g2 = img.createGraphics();
+ g2.setColor(Color.black);
+ g2.fillRect(0, 0, 16, 16);
+ g2.dispose();
+ this.setLoadingImage(img);
+ }
+ }
+ //
+ //
+
+ /**
+ * Gets the current zoom level
+ *
+ * @return the current zoom level
+ */
+ public int getZoom() {
+ return this.zoom;
+ }
+
+ /**
+ * Set the current zoom level
+ *
+ * @param zoom the new zoom level
+ */
+ public void setZoom(int zoom) {
+ if (zoom == this.zoom) {
+ return;
+ }
+
+ TileFactoryInfo info = getTileFactory().getInfo();
+ // don't repaint if we are out of the valid zoom levels
+ if (info != null
+ && (zoom < info.getMinimumZoomLevel()
+ || zoom > info.getMaximumZoomLevel())) {
+ return;
+ }
+
+ //if(zoom >= 0 && zoom <= 15 && zoom != this.zoom) {
+ int oldzoom = this.zoom;
+ Point2D oldCenter = getCenter();
+ Dimension oldMapSize = getTileFactory().getMapSize(oldzoom);
+ this.zoom = zoom;
+ //this.firePropertyChange("zoom", oldzoom, zoom);
+
+ Dimension mapSize = getTileFactory().getMapSize(zoom);
+
+ setCenter(new Point2D.Double(
+ oldCenter.getX() * (mapSize.getWidth() / oldMapSize.getWidth()),
+ oldCenter.getY() * (mapSize.getHeight() / oldMapSize.getHeight())));
+
+ //repaint();
+ }
+
+ /**
+ * Gets the current pixel center of the map. This point is in the global
+ * bitmap coordinate system, not as lat/longs.
+ *
+ * @return the current center of the map as a pixel value
+ */
+ public Point2D getCenter() {
+ return center;
+ }
+
+ public boolean isRestrictOutsidePanning() {
+ return restrictOutsidePanning;
+ }
+
+ public void setRestrictOutsidePanning(boolean restrictOutsidePanning) {
+ this.restrictOutsidePanning = restrictOutsidePanning;
+ }
+
+ /**
+ * Sets the new center of the map in pixel coordinates.
+ *
+ * @param center the new center of the map in pixel coordinates
+ */
+ public void setCenter(Point2D center) {
+ this.center = center;
+// if(isRestrictOutsidePanning()) {
+// Insets insets = getInsets();
+// int viewportHeight = getHeight() - insets.top - insets.bottom;
+// int viewportWidth = getWidth() - insets.left - insets.right;
+//
+// // don't let the user pan over the top edge
+// Rectangle newVP = calculateViewportBounds(center);
+// if(newVP.getY() < 0) {
+// double centerY = viewportHeight/2;
+// center = new Point2D.Double(center.getX(),centerY);
+// }
+//
+// // don't let the user pan over the left edge
+// if(!isHorizontalWrapped() && newVP.getX() <0) {
+// double centerX = viewportWidth/2;
+// center = new Point2D.Double(centerX, center.getY());
+// }
+//
+// // don't let the user pan over the bottom edge
+// Dimension mapSize = getTileFactory().getMapSize(getZoom());
+// int mapHeight = (int)mapSize.getHeight()*getTileFactory().getTileSize(getZoom());
+// if(newVP.getY() + newVP.getHeight() > mapHeight) {
+// double centerY = mapHeight - viewportHeight/2;
+// center = new Point2D.Double(center.getX(),centerY);
+// }
+//
+// //don't let the user pan over the right edge
+// int mapWidth = (int)mapSize.getWidth()*getTileFactory().getTileSize(getZoom());
+// if(!isHorizontalWrapped() && (newVP.getX() + newVP.getWidth() > mapWidth)) {
+// double centerX = mapWidth - viewportWidth/2;
+// center = new Point2D.Double(centerX, center.getY());
+// }
+//
+// // if map is to small then just center it vert
+// if(mapHeight < newVP.getHeight()) {
+// double centerY = mapHeight/2;//viewportHeight/2;// - mapHeight/2;
+// center = new Point2D.Double(center.getX(),centerY);
+// }
+//
+// // if map is too small then just center it horiz
+// if(!isHorizontalWrapped() && mapWidth < newVP.getWidth()) {
+// double centerX = mapWidth/2;
+// center = new Point2D.Double(centerX, center.getY());
+// }
+// }
+//
+// //joshy: this is an evil hack to force a property change event
+// //i don't know why it doesn't work normally
+// old = new Point(5,6);
+//
+// GeoPosition oldGP = this.getCenterPosition();
+ }
+
+ /**
+ * A property indicating the center position of the map
+ *
+ * @param geoPosition the new property value
+ */
+ public void setCenterPosition(GeoPosition geoPosition) {
+ GeoPosition oldVal = getCenterPosition();
+ setCenter(getTileFactory().geoToPixel(geoPosition, zoom));
+ //repaint();
+ GeoPosition newVal = getCenterPosition();
+ //firePropertyChange("centerPosition", oldVal, newVal);
+ }
+
+ /**
+ * A property indicating the center position of the map
+ *
+ * @return the current center position
+ */
+ public GeoPosition getCenterPosition() {
+ return getTileFactory().pixelToGeo(getCenter(), zoom);
+ }
+
+ /**
+ * Get the current factory
+ *
+ * @return the current property value
+ */
+ public TileFactory getTileFactory() {
+ return factory;
+ }
+
+ /**
+ * Set the current tile factory
+ *
+ * @param factory the new property value
+ */
+ public void setTileFactory(TileFactory factory) {
+ this.factory = factory;
+ this.setZoom(factory.getInfo().getDefaultZoomLevel());
+ this.setCenterPosition(new GeoPosition(0, 0));
+ }
+
+ /**
+ * Get web map scale
+ * @return Web map scale
+ */
+ public double getWebMapScale() {
+ return this.webMapScale;
+ }
+
+ /**
+ * Set web map scale
+ * @param value Web map scale
+ */
+ public void setWebMapScale(double value) {
+ this.webMapScale = value;
+ }
+
+ /**
+ * A property for an image which will be display when an image is still
+ * loading.
+ *
+ * @return the current property value
+ */
+ public Image getLoadingImage() {
+ return loadingImage;
+ }
+
+ /**
+ * A property for an image which will be display when an image is still
+ * loading.
+ *
+ * @param loadingImage the new property value
+ */
+ public void setLoadingImage(Image loadingImage) {
+ this.loadingImage = loadingImage;
+ }
+
+ /**
+ * Indicates if the tile borders should be drawn. Mainly used for debugging.
+ *
+ * @return the value of this property
+ */
+ public boolean isDrawTileBorders() {
+ return drawTileBorders;
+ }
+
+ /**
+ * Set if the tile borders should be drawn. Mainly used for debugging.
+ *
+ * @param drawTileBorders new value of this drawTileBorders
+ */
+ public void setDrawTileBorders(boolean drawTileBorders) {
+ //boolean old = isDrawTileBorders();
+ this.drawTileBorders = drawTileBorders;
+ //firePropertyChange("drawTileBorders", old, isDrawTileBorders());
+ //repaint();
+ }
+
+ /**
+ * Set web map provider
+ * @param prov The web map provider
+ */
+ public void setWebMapProvider(WebMapProvider prov) {
+ TileFactoryInfo info = null;
+ switch (prov) {
+// case SwingLabsBlueMarble:
+// setTileFactory(new CylindricalProjectionTileFactory());
+// setZoom(3);
+// return;
+ case OpenStreetMap:
+ info = new OpenStreetMapInfo();
+ break;
+ case OpenStreetMapQuestSatellite:
+ info = new OpenStreetMapQuestSatelliteInfo();
+ break;
+ case BingMap:
+ info = new BingMapInfo();
+ break;
+ case BingSatelliteMap:
+ info = new BingSatelliteMapInfo();
+ break;
+ case BingHybridMap:
+ info = new BingHybridMapInfo();
+ break;
+// case OviMap:
+// info = new OviMapInfo();
+// break;
+// case OviSatelliteMap:
+// info = new OviSatelliteMapInfo();
+// break;
+// case OviTerrainMap:
+// info = new OviTerrainMapInfo();
+// break;
+// case OviHybridMap:
+// info = new OviHybridMapInfo();
+// break;
+ case YahooMap:
+ info = new YahooMapInfo();
+ break;
+ case YahooSatelliteMap:
+ info = new YahooSatelliteMapInfo();
+ break;
+ case YahooHybridMap:
+ info = new YahooHybridMapInfo();
+ break;
+ case GoogleMap:
+ info = new GoogleMapInfo();
+ break;
+ case GoogleSatelliteMap:
+ info = new GoogleSatelliteMapInfo();
+ break;
+ case GoogleTerrainMap:
+ info = new GoogleTerrainMapInfo();
+ break;
+ case GoogleHybridMap:
+ info = new GoogleHybridMapInfo();
+ break;
+ case GoogleHybridTerrainMap:
+ info = new GoogleHybridTerrainMapInfo();
+ break;
+// case BaiduMap:
+// info = new BaiduMapInfo();
+// break;
+// case BaiduSatelliteMap:
+// info = new BaiduSatelliteMapInfo();
+// break;
+ case AMap:
+ info = new AMapInfo();
+ break;
+ case ASatelliteMap:
+ info = new ASatelliteMapInfo();
+ break;
+ case AHybridMap:
+ info = new AHybridMapInfo();
+ break;
+ case TencentMap:
+ info = new TencentMapInfo();
+ break;
+ case CMA_CVA_MAP:
+ info = new CMACvaMapInfo();
+ break;
+ case CMA_VEC_MAP:
+ info = new CMAVecMapInfo();
+ break;
+ case CMA_IMG_MAP:
+ info = new CMAImgMapInfo();
+ break;
+// case ArcGISImage:
+// info = new ArcGISImageInfo();
+// break;
+ }
+
+ if (info != null) {
+ this.defaultProvider = prov;
+ this.setLayerName("WebMap_" + info.getName());
+ TileFactory tf = new DefaultTileFactory(info);
+ setTileFactory(tf);
+ //setZoom(11);
+ setAddressLocation(new GeoPosition(51.5, 0));
+ }
+ }
+
+ /**
+ * Get web map provider
+ * @return Web map provider
+ */
+ public WebMapProvider getWebMapProvider() {
+ return this.defaultProvider;
+ }
+
+ public GeoPosition getAddressLocation() {
+ return this.addressLocation;
+ }
+
+ public void setAddressLocation(GeoPosition pos, int zoom) {
+ this.addressLocation = pos;
+ setCenter(getTileFactory().geoToPixel(pos, zoom));
+ }
+
+ public void setAddressLocation(GeoPosition pos) {
+ this.addressLocation = pos;
+ setCenter(getTileFactory().geoToPixel(addressLocation, getZoom()));
+ }
+ //
+ //
+
+ /**
+ * Repaint
+ */
+ public void repaint() {
+ Rectangle rect = this.calculateViewportBounds(graphics, width, height);
+ this.drawMapTiles(graphics, zoom, rect);
+ }
+
+ /**
+ * Draw the map tiles
+ *
+ * @param g Graphics2D
+ * @param zoom Zoom level to draw at
+ * @param width The width
+ * @param height The height
+ */
+ public void drawMapTiles(final Graphics2D g, final int zoom, int width, int height) {
+ this.graphics = g;
+ this.zoom = zoom;
+ this.width = width;
+ this.height = height;
+ Rectangle rect = this.calculateViewportBounds(g, width, height);
+ this.drawMapTiles(g, zoom, rect);
+ }
+
+ /**
+ * Draw the map tiles. This method is for implementation use only.
+ *
+ * @param g Graphics
+ * @param zoom zoom level to draw at
+ * @param viewportBounds View bounds
+ */
+ public void drawMapTiles(final Graphics2D g, final int zoom, final Rectangle viewportBounds) {
+ int size = getTileFactory().getTileSize(zoom);
+ Dimension mapSize = getTileFactory().getMapSize(zoom);
+
+ //calculate the "visible" viewport area in tiles
+ int numWide = viewportBounds.width / size + 2;
+ int numHigh = viewportBounds.height / size + 2;
+
+ //TilePoint topLeftTile = getTileFactory().getTileCoordinate(
+ // new Point2D.Double(viewportBounds.x, viewportBounds.y));
+ TileFactoryInfo info = getTileFactory().getInfo();
+ int tpx = (int) Math.floor(viewportBounds.getX() / info.getTileSize(0));
+ int tpy = (int) Math.floor(viewportBounds.getY() / info.getTileSize(0));
+ //TilePoint topLeftTile = new TilePoint(tpx, tpy);
+
+ //p("top tile = " + topLeftTile);
+ //fetch the tiles from the factory and store them in the tiles cache
+ //attach the tileLoadListener
+ for (int x = 0; x <= numWide; x++) {
+ for (int y = 0; y <= numHigh; y++) {
+ int itpx = x + tpx;//topLeftTile.getX();
+ int itpy = y + tpy;//topLeftTile.getY();
+ //TilePoint point = new TilePoint(x + topLeftTile.getX(), y + topLeftTile.getY());
+ //only proceed if the specified tile point lies within the area being painted
+ //if (g.getClipBounds().intersects(new Rectangle(itpx * size - viewportBounds.x,
+ //itpy * size - viewportBounds.y, size, size))) {
+ Tile tile = getTileFactory().getTile(itpx, itpy, zoom);
+ //tile.addUniquePropertyChangeListener("loaded", tileLoadListener); //this is a filthy hack
+ int ox = ((itpx * getTileFactory().getTileSize(zoom)) - viewportBounds.x);
+ int oy = ((itpy * getTileFactory().getTileSize(zoom)) - viewportBounds.y);
+
+ //if the tile is off the map to the north/south, then just don't paint anything
+ if (isTileOnMap(itpx, itpy, mapSize)) {
+// if (isOpaque()) {
+// g.setColor(getBackground());
+// g.fillRect(ox,oy,size,size);
+// }
+ } else if (tile.isLoaded()) {
+ g.drawImage(tile.getImage(), ox, oy, null);
+ }
+// else {
+// int imageX = (getTileFactory().getTileSize(zoom) - getLoadingImage().getWidth(null)) / 2;
+// int imageY = (getTileFactory().getTileSize(zoom) - getLoadingImage().getHeight(null)) / 2;
+// g.setColor(Color.GRAY);
+// g.fillRect(ox, oy, size, size);
+// g.drawImage(getLoadingImage(), ox + imageX, oy + imageY, null);
+// }
+ if (isDrawTileBorders()) {
+
+ g.setColor(Color.black);
+ g.drawRect(ox, oy, size, size);
+ g.drawRect(ox + size / 2 - 5, oy + size / 2 - 5, 10, 10);
+ g.setColor(Color.white);
+ g.drawRect(ox + 1, oy + 1, size, size);
+
+ String text = itpx + ", " + itpy + ", " + getZoom();
+ g.setColor(Color.BLACK);
+ g.drawString(text, ox + 10, oy + 30);
+ g.drawString(text, ox + 10 + 2, oy + 30 + 2);
+ g.setColor(Color.WHITE);
+ g.drawString(text, ox + 10 + 1, oy + 30 + 1);
+ }
+ //}
+ }
+ }
+ }
+
+ /**
+ * Draw layer
+ * @param g The Graphics2D
+ * @param width Canvas width
+ * @param height Canvas height
+ * @param tll TileLoadListener
+ */
+ public void drawWebMapLayer(Graphics2D g, int width, int height, TileLoadListener tll) {
+ //layer.setZoom(zoom);
+ //layer.drawMapTiles(g, zoom, width, height);
+ Rectangle viewportBounds = this.calculateViewportBounds(g, width, height);
+ int size = this.getTileFactory().getTileSize(zoom);
+ Dimension mapSize = this.getTileFactory().getMapSize(zoom);
+
+ //calculate the "visible" viewport area in tiles
+ int numWide = viewportBounds.width / size + 2;
+ int numHigh = viewportBounds.height / size + 2;
+
+ //TilePoint topLeftTile = getTileFactory().getTileCoordinate(
+ // new Point2D.Double(viewportBounds.x, viewportBounds.y));
+ TileFactoryInfo info = this.getTileFactory().getInfo();
+ int tpx = (int) Math.floor(viewportBounds.getX() / info.getTileSize(0));
+ int tpy = (int) Math.floor(viewportBounds.getY() / info.getTileSize(0));
+ //TilePoint topLeftTile = new TilePoint(tpx, tpy);
+
+ //p("top tile = " + topLeftTile);
+ //fetch the tiles from the factory and store them in the tiles cache
+ //attach the TileLoadListener
+ //String language = layer.getTileFactory().getInfo().getLanguage();
+ for (int x = 0; x <= numWide; x++) {
+ for (int y = 0; y <= numHigh; y++) {
+ int itpx = x + tpx;//topLeftTile.getX();
+ int itpy = y + tpy;//topLeftTile.getY();
+ //TilePoint point = new TilePoint(x + topLeftTile.getX(), y + topLeftTile.getY());
+ //only proceed if the specified tile point lies within the area being painted
+ //if (g.getClipBounds().intersects(new Rectangle(itpx * size - viewportBounds.x,
+ //itpy * size - viewportBounds.y, size, size))) {
+ Tile tile = this.getTileFactory().getTile(itpx, itpy, zoom);
+ tile.addUniquePropertyChangeListener("loaded", tll); //this is a filthy hack
+ int ox = ((itpx * this.getTileFactory().getTileSize(zoom)) - viewportBounds.x);
+ int oy = ((itpy * this.getTileFactory().getTileSize(zoom)) - viewportBounds.y);
+
+ //if the tile is off the map to the north/south, then just don't paint anything
+ if (this.isTileOnMap(itpx, itpy, mapSize)) {
+// if (isOpaque()) {
+// g.setColor(getBackground());
+// g.fillRect(ox,oy,size,size);
+// }
+ } else if (tile.isLoaded()) {
+ g.drawImage(tile.getImage(), ox, oy, null);
+ } else {
+ int imageX = (this.getTileFactory().getTileSize(zoom) - this.getLoadingImage().getWidth(null)) / 2;
+ int imageY = (this.getTileFactory().getTileSize(zoom) - this.getLoadingImage().getHeight(null)) / 2;
+ g.setColor(Color.GRAY);
+ g.fillRect(ox, oy, size, size);
+ g.drawImage(this.getLoadingImage(), ox + imageX, oy + imageY, null);
+ }
+ if (this.isDrawTileBorders()) {
+
+ g.setColor(Color.black);
+ g.drawRect(ox, oy, size, size);
+ g.drawRect(ox + size / 2 - 5, oy + size / 2 - 5, 10, 10);
+ g.setColor(Color.white);
+ g.drawRect(ox + 1, oy + 1, size, size);
+
+ String text = itpx + ", " + itpy + ", " + this.getZoom();
+ g.setColor(Color.BLACK);
+ g.drawString(text, ox + 10, oy + 30);
+ g.drawString(text, ox + 10 + 2, oy + 30 + 2);
+ g.setColor(Color.WHITE);
+ g.drawString(text, ox + 10 + 1, oy + 30 + 1);
+ }
+ //}
+ }
+ }
+ }
+
+ private double getWebMapScale(int zoom, int width, int height) {
+ Point2D center = this.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, this.getTileFactory().getInfo());
+ GeoPosition pos2 = GeoUtil.getPosition(new Point2D.Double(maxx, maxy), zoom, this.getTileFactory().getInfo());
+ PointD p1 = Reproject.reprojectPoint(new PointD(pos1.getLongitude(), pos1.getLatitude()),
+ KnownCoordinateSystems.geographic.world.WGS1984, this.getProjInfo());
+ PointD p2 = Reproject.reprojectPoint(new PointD(pos2.getLongitude(), pos2.getLatitude()),
+ KnownCoordinateSystems.geographic.world.WGS1984, this.getProjInfo());
+ if (pos2.getLongitude() - pos1.getLongitude() < 360.0) {
+ double xlen = p2.X - p1.X;
+// if (pos2.getLongitude() - pos1.getLongitude() > 360)
+// xlen += 2.0037497210840166E7 * 2;
+ return (double) width / xlen;
+ } else {
+ double ylen = Math.abs(p2.Y - p1.Y);
+ return (double) height / ylen;
+ }
+ }
+
+ public boolean isTileOnMap(int x, int y, Dimension mapSize) {
+ return !isNegativeYAllowed && y < 0 || y >= mapSize.getHeight();
+ }
+
+ /**
+ * Calculate view port bounds
+ *
+ * @param g Graphic2D
+ * @param width The width
+ * @param height The height
+ * @return View port bounds rectangle
+ */
+ public Rectangle calculateViewportBounds(Graphics2D g, int width, int height) {
+ //calculate the "visible" viewport area in pixels
+ //double sx = g.getTransform().getTranslateX();
+ //double sy = g.getTransform().getTranslateY();
+ double viewportX = (center.getX() - width / 2);
+ double viewportY = (center.getY() - height / 2);
+ return new Rectangle((int) viewportX, (int) viewportY, width, height);
+ }
+
+ /**
+ * To string
+ * @return String
+ */
+ @Override
+ public String getLayerInfo(){
+ String str = "Layer name: " + this.getLayerName();
+ str += System.getProperty("line.separator") + "Layer file: " + this.getFileName();
+ str += System.getProperty("line.separator") + "Layer type: " + this.getLayerType();
+ str += System.getProperty("line.separator") + "Data provider: " + this.defaultProvider;
+
+ return str;
+ }
+ //
+ //
+ public class WebMapLayerBean {
+ public WebMapLayerBean(){
+
+ }
+
+ //
+ /**
+ * Get layer type
+ *
+ * @return Layer type
+ */
+ public LayerTypes getLayerType() {
+ return WebMapLayer.this.getLayerType();
+ }
+
+ /**
+ * Get layer draw type
+ *
+ * @return Layer draw type
+ */
+ public LayerDrawType getLayerDrawType() {
+ return WebMapLayer.this.getLayerDrawType();
+ }
+
+ /**
+ * Get layer handle
+ *
+ * @return Layer handle
+ */
+ public int getHandle() {
+ return WebMapLayer.this.getHandle();
+ }
+
+ /**
+ * Get layer name
+ *
+ * @return Layer name
+ */
+ public String getLayerName() {
+ return WebMapLayer.this.getLayerName();
+ }
+
+ /**
+ * Set layer name
+ *
+ * @param name Layer name
+ */
+ public void setLayerName(String name) {
+ WebMapLayer.this.setLayerName(name);
+ }
+
+ /**
+ * Get web map provider
+ * @return The web map provider
+ */
+ public String getWebMapProvider(){
+ return WebMapLayer.this.defaultProvider.toString();
+ }
+
+ /**
+ * Set web map provider
+ * @param provider The web map provider
+ */
+ public void setWebMapProvider(String provider){
+ WebMapLayer.this.setWebMapProvider(WebMapProvider.valueOf(provider));
+ }
+
+ /**
+ * Get if is maskout
+ *
+ * @return If is maskout
+ */
+ public boolean isMaskout() {
+ return WebMapLayer.this.isMaskout();
+ }
+
+ /**
+ * Set if maskout
+ *
+ * @param value If maskout
+ */
+ public void setMaskout(boolean value) {
+ WebMapLayer.this.setMaskout(value);
+ }
+
+ /**
+ * Get if is visible
+ *
+ * @return If is visible
+ */
+ public boolean isVisible() {
+ return WebMapLayer.this.isVisible();
+ }
+
+ /**
+ * Set if is visible
+ *
+ * @param value If is visible
+ */
+ public void setVisible(boolean value) {
+ WebMapLayer.this.setVisible(value);
+ }
+
+ /**
+ * Get language
+ * @return The language
+ */
+ public String getLanguage(){
+ return WebMapLayer.this.getTileFactory().getInfo().getLanguage();
+ }
+
+ /**
+ * Set language
+ * @param value The language
+ */
+ public void setLanguage(String value) {
+ WebMapLayer.this.getTileFactory().getInfo().setLanguage(value);
+ }
+
+ //
+ }
+
+ public static class WebMapLayerBeanBeanInfo extends BaseBeanInfo {
+
+ public WebMapLayerBeanBeanInfo() {
+ super(WebMapLayer.WebMapLayerBean.class);
+ addProperty("layerType").setCategory("Read only").setReadOnly().setDisplayName("Layer type");
+ addProperty("layerDrawType").setCategory("Read only").setReadOnly().setDisplayName("Layer draw type");
+ addProperty("handle").setCategory("Read only").setReadOnly().setDisplayName("Handle");
+ ExtendedPropertyDescriptor e = addProperty("webMapProvider");
+ e.setCategory("Editable").setDisplayName("Web Map Provider");
+ e.setPropertyEditorClass(WebMapProviderEditor.class);
+ e = addProperty("language");
+ e.setCategory("Editable").setDisplayName("Language");
+ e.setPropertyEditorClass(LanguageEditor.class);
+ addProperty("visible").setCategory("Editable").setDisplayName("Visible");
+ addProperty("maskout").setCategory("Editable").setDisplayName("Is maskout");
+ }
+ }
+
+ public static class WebMapProviderEditor extends ComboBoxPropertyEditor {
+
+ public WebMapProviderEditor() {
+ super();
+ WebMapProvider[] providers = WebMapProvider.values();
+ String[] types = new String[providers.length];
+ int i = 0;
+ for (WebMapProvider prov : providers) {
+ types[i] = prov.toString();
+ i += 1;
+ }
+ setAvailableValues(types);
+ }
+ }
+
+ public static class LanguageEditor extends ComboBoxPropertyEditor {
+
+ public LanguageEditor() {
+ super();
+ String[] langs = new String[]{"en-us", "zh-cn"};
+ setAvailableValues(langs);
+ }
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/layout/LayoutChart.java b/MeteoInfoLib/src/main/java/org/meteoinfo/layout/LayoutChart.java
index 22cbaf9b..3eb65f45 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/layout/LayoutChart.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/layout/LayoutChart.java
@@ -1,78 +1,78 @@
-/*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.meteoinfo.layout;
-
-import java.awt.Graphics2D;
-import java.awt.geom.Rectangle2D;
-import org.meteoinfo.chart.Chart;
-import org.meteoinfo.global.PointF;
-
-/**
- *
- * @author yaqiang
- */
-public class LayoutChart extends LayoutElement {
-
- //
- private Chart chart;
- //
- //
-
- /**
- * Constructor
- */
- public LayoutChart() {
- super();
- this.setElementType(ElementType.LayoutChart);
- this.setResizeAbility(ResizeAbility.ResizeAll);
- this.setWidth(200);
- this.setHeight(150);
- }
- //
- //
-
- /**
- * Get chart
- *
- * @return The chart
- */
- public Chart getChart() {
- return chart;
- }
-
- /**
- * Set chart
- *
- * @param value The chart
- */
- public void setChart(Chart value) {
- chart = value;
- }
- //
- //
-
- @Override
- public void paint(Graphics2D g) {
- }
-
- @Override
- public void paintOnLayout(Graphics2D g, PointF pageLocation, float zoom) {
- if (chart == null)
- return;
-
- PointF aP = pageToScreen(this.getLeft(), this.getTop(), pageLocation, zoom);
- Rectangle2D area = new Rectangle2D.Double(aP.X, aP.Y, this.getWidth() * zoom, this.getHeight() * zoom);
- chart.draw(g, area);
- }
-
- @Override
- public void moveUpdate() {
- }
-
- @Override
- public void resizeUpdate() {
- }
- //
-}
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.meteoinfo.layout;
+
+import java.awt.Graphics2D;
+import java.awt.geom.Rectangle2D;
+import org.meteoinfo.chart.Chart;
+import org.meteoinfo.common.PointF;
+
+/**
+ *
+ * @author yaqiang
+ */
+public class LayoutChart extends LayoutElement {
+
+ //
+ private Chart chart;
+ //
+ //
+
+ /**
+ * Constructor
+ */
+ public LayoutChart() {
+ super();
+ this.setElementType(ElementType.LayoutChart);
+ this.setResizeAbility(ResizeAbility.ResizeAll);
+ this.setWidth(200);
+ this.setHeight(150);
+ }
+ //
+ //
+
+ /**
+ * Get chart
+ *
+ * @return The chart
+ */
+ public Chart getChart() {
+ return chart;
+ }
+
+ /**
+ * Set chart
+ *
+ * @param value The chart
+ */
+ public void setChart(Chart value) {
+ chart = value;
+ }
+ //
+ //
+
+ @Override
+ public void paint(Graphics2D g) {
+ }
+
+ @Override
+ public void paintOnLayout(Graphics2D g, PointF pageLocation, float zoom) {
+ if (chart == null)
+ return;
+
+ PointF aP = pageToScreen(this.getLeft(), this.getTop(), pageLocation, zoom);
+ Rectangle2D area = new Rectangle2D.Double(aP.X, aP.Y, this.getWidth() * zoom, this.getHeight() * zoom);
+ chart.draw(g, area);
+ }
+
+ @Override
+ public void moveUpdate() {
+ }
+
+ @Override
+ public void resizeUpdate() {
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/layout/LayoutElement.java b/MeteoInfoLib/src/main/java/org/meteoinfo/layout/LayoutElement.java
index 80748a4b..c6d234eb 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/layout/LayoutElement.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/layout/LayoutElement.java
@@ -1,370 +1,371 @@
- /* Copyright 2012 Yaqiang Wang,
- * yaqiang.wang@gmail.com
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.layout;
-
-import org.meteoinfo.global.event.ILocationChangedListener;
-import org.meteoinfo.global.event.ISizeChangedListener;
-import org.meteoinfo.global.event.LocationChangedEvent;
-import org.meteoinfo.global.event.SizeChangedEvent;
-import org.meteoinfo.global.PointF;
-import java.awt.Color;
-import java.awt.Graphics2D;
-import java.awt.Rectangle;
-import javax.swing.event.EventListenerList;
-
-/**
- *
- * @author yaqiang
- */
-public abstract class LayoutElement {
- //
-
- public void addLocationChangedListener(ILocationChangedListener listener) {
- this._listeners.add(ILocationChangedListener.class, listener);
- }
-
- public void removeLocationChangedListener(ILocationChangedListener listener) {
- this._listeners.remove(ILocationChangedListener.class, listener);
- }
-
- public void fireLocationChangedEvent() {
- fireLocationChangedEvent(new LocationChangedEvent(this));
- }
-
- private void fireLocationChangedEvent(LocationChangedEvent event) {
- Object[] listeners = _listeners.getListenerList();
- for (int i = 0; i < listeners.length; i = i + 2) {
- if (listeners[i] == ILocationChangedListener.class) {
- ((ILocationChangedListener) listeners[i + 1]).locationChangedEvent(event);
- }
- }
- }
-
- public void addSizeChangedListener(ISizeChangedListener listener) {
- this._listeners.add(ISizeChangedListener.class, listener);
- }
-
- public void removeSizeChangedListener(ISizeChangedListener listener) {
- this._listeners.remove(ISizeChangedListener.class, listener);
- }
-
- public void fireSizeChangedEvent() {
- fireSizeChangedEvent(new SizeChangedEvent(this));
- }
-
- private void fireSizeChangedEvent(SizeChangedEvent event) {
- Object[] listeners = _listeners.getListenerList();
- for (int i = 0; i < listeners.length; i = i + 2) {
- if (listeners[i] == ISizeChangedListener.class) {
- ((ISizeChangedListener) listeners[i + 1]).sizeChangedEvent(event);
- }
- }
- }
- //
- //
- private final EventListenerList _listeners = new EventListenerList();
- private int _left;
- private int _top;
- private int _width;
- private int _height;
- private ElementType _elementType;
- private Color _foreColor;
- private Color _backColor;
- private boolean _selected;
- private ResizeAbility _resizeAbility;
- private boolean _visible = true;
- private boolean drawBackColor = false;
- //
- //
-
- public LayoutElement() {
- _foreColor = Color.black;
- _backColor = Color.white;
- _selected = false;
- _resizeAbility = ResizeAbility.None;
- }
- //
- //
-
- /**
- * Get if visible
- *
- * @return Boolean
- */
- public boolean isVisible() {
- return _visible;
- }
-
- /**
- * Set if visible
- *
- * @param istrue Boolean
- */
- public void setVisible(boolean istrue) {
- _visible = istrue;
- }
-
- /**
- * Get left
- *
- * @return Left
- */
- public int getLeft() {
- return _left;
- }
-
- /**
- * Set left
- *
- * @param left
- */
- public void setLeft(int left) {
- _left = left;
- this.fireLocationChangedEvent();
- }
-
- /**
- * Get top
- *
- * @return Top
- */
- public int getTop() {
- return _top;
- }
-
- /**
- * Set top
- *
- * @param top Top
- */
- public void setTop(int top) {
- _top = top;
- this.fireLocationChangedEvent();
- }
-
- /**
- * Get width
- *
- * @return Width
- */
- public int getWidth() {
- return _width;
- }
-
- /**
- * Set width
- *
- * @param width Width
- */
- public void setWidth(int width) {
- _width = width;
- this.fireSizeChangedEvent();
- }
-
- /**
- * Get height
- *
- * @return Height
- */
- public int getHeight() {
- return _height;
- }
-
- /**
- * Set height
- *
- * @param height Height
- */
- public void setHeight(int height) {
- _height = height;
- this.fireSizeChangedEvent();
- }
-
- /**
- * Get right
- *
- * @return Right
- */
- public int getRight() {
- return _left + _width;
- }
-
- /**
- * Get bottom
- *
- * @return Bottom
- */
- public int getBottom() {
- return _top + _height;
- }
-
- /**
- * Get bounds rectangle
- *
- * @return Bounds rectangle
- */
- public Rectangle getBounds() {
- return new Rectangle(_left, _top, _width, _height);
- }
-
- /**
- * Get element type
- *
- * @return The element type
- */
- public ElementType getElementType() {
- return _elementType;
- }
-
- /**
- * Set element type
- *
- * @param type Element type
- */
- public void setElementType(ElementType type) {
- _elementType = type;
- }
-
- /**
- * Get foreground color
- *
- * @return Foreground color
- */
- public Color getForeColor() {
- return _foreColor;
- }
-
- /**
- * Set foreground color
- *
- * @param color Foreground color
- */
- public void setForeColor(Color color) {
- _foreColor = color;
- }
-
- /**
- * Get background color
- *
- * @return Background color
- */
- public Color getBackColor() {
- return _backColor;
- }
-
- /**
- * Set background color
- *
- * @param color Background color
- */
- public void setBackColor(Color color) {
- _backColor = color;
- }
-
- /**
- * Get if is selected
- *
- * @return Boolean
- */
- public boolean isSelected() {
- return _selected;
- }
-
- /**
- * Set if is selected
- *
- * @param istrue Boolean
- */
- public void setSelected(boolean istrue) {
- _selected = istrue;
- }
-
- /**
- * Get resize ability
- *
- * @return Resize ability
- */
- public ResizeAbility getResizeAbility() {
- return _resizeAbility;
- }
-
- /**
- * Set resize ability
- *
- * @param ra Resize ability
- */
- public void setResizeAbility(ResizeAbility ra) {
- _resizeAbility = ra;
- }
-
- /**
- * Get is draw backcolor
- * @return Boolean
- */
- public boolean isDrawBackColor(){
- return drawBackColor;
- }
-
- /**
- * Set is draw backcolor
- * @param value Boolean
- */
- public void setDrawBackColor(boolean value){
- drawBackColor = value;
- }
- //
- //
-
- /**
- * Paint method
- *
- * @param g Graphics2D
- */
- public abstract void paint(Graphics2D g);
-
- /**
- * Paint on layout method
- *
- * @param g Grahpics2D
- * @param pageLocation Page location
- * @param zoom Zoom
- */
- public abstract void paintOnLayout(Graphics2D g, PointF pageLocation, float zoom);
-
- /**
- * Move update method
- */
- public abstract void moveUpdate();
-
- /**
- * Resize update method
- */
- public abstract void resizeUpdate();
-
- /**
- * Page to screen
- *
- * @param pageX Page X
- * @param pageY Page Y
- * @param pageLocation Page location
- * @param zoom Zoom
- * @return Screen point
- */
- public PointF pageToScreen(float pageX, float pageY, PointF pageLocation, float zoom) {
- float x = pageX * zoom + pageLocation.X;
- float y = pageY * zoom + pageLocation.Y;
- return (new PointF(x, y));
- }
- //
-}
+ /* Copyright 2012 Yaqiang Wang,
+ * yaqiang.wang@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ */
+package org.meteoinfo.layout;
+
+import org.meteoinfo.common.PointF;
+import org.meteoinfo.global.event.ILocationChangedListener;
+import org.meteoinfo.global.event.ISizeChangedListener;
+import org.meteoinfo.global.event.LocationChangedEvent;
+import org.meteoinfo.global.event.SizeChangedEvent;
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import javax.swing.event.EventListenerList;
+
+/**
+ *
+ * @author yaqiang
+ */
+public abstract class LayoutElement {
+ //
+
+ public void addLocationChangedListener(ILocationChangedListener listener) {
+ this._listeners.add(ILocationChangedListener.class, listener);
+ }
+
+ public void removeLocationChangedListener(ILocationChangedListener listener) {
+ this._listeners.remove(ILocationChangedListener.class, listener);
+ }
+
+ public void fireLocationChangedEvent() {
+ fireLocationChangedEvent(new LocationChangedEvent(this));
+ }
+
+ private void fireLocationChangedEvent(LocationChangedEvent event) {
+ Object[] listeners = _listeners.getListenerList();
+ for (int i = 0; i < listeners.length; i = i + 2) {
+ if (listeners[i] == ILocationChangedListener.class) {
+ ((ILocationChangedListener) listeners[i + 1]).locationChangedEvent(event);
+ }
+ }
+ }
+
+ public void addSizeChangedListener(ISizeChangedListener listener) {
+ this._listeners.add(ISizeChangedListener.class, listener);
+ }
+
+ public void removeSizeChangedListener(ISizeChangedListener listener) {
+ this._listeners.remove(ISizeChangedListener.class, listener);
+ }
+
+ public void fireSizeChangedEvent() {
+ fireSizeChangedEvent(new SizeChangedEvent(this));
+ }
+
+ private void fireSizeChangedEvent(SizeChangedEvent event) {
+ Object[] listeners = _listeners.getListenerList();
+ for (int i = 0; i < listeners.length; i = i + 2) {
+ if (listeners[i] == ISizeChangedListener.class) {
+ ((ISizeChangedListener) listeners[i + 1]).sizeChangedEvent(event);
+ }
+ }
+ }
+ //
+ //
+ private final EventListenerList _listeners = new EventListenerList();
+ private int _left;
+ private int _top;
+ private int _width;
+ private int _height;
+ private ElementType _elementType;
+ private Color _foreColor;
+ private Color _backColor;
+ private boolean _selected;
+ private ResizeAbility _resizeAbility;
+ private boolean _visible = true;
+ private boolean drawBackColor = false;
+ //
+ //
+
+ public LayoutElement() {
+ _foreColor = Color.black;
+ _backColor = Color.white;
+ _selected = false;
+ _resizeAbility = ResizeAbility.None;
+ }
+ //
+ //
+
+ /**
+ * Get if visible
+ *
+ * @return Boolean
+ */
+ public boolean isVisible() {
+ return _visible;
+ }
+
+ /**
+ * Set if visible
+ *
+ * @param istrue Boolean
+ */
+ public void setVisible(boolean istrue) {
+ _visible = istrue;
+ }
+
+ /**
+ * Get left
+ *
+ * @return Left
+ */
+ public int getLeft() {
+ return _left;
+ }
+
+ /**
+ * Set left
+ *
+ * @param left
+ */
+ public void setLeft(int left) {
+ _left = left;
+ this.fireLocationChangedEvent();
+ }
+
+ /**
+ * Get top
+ *
+ * @return Top
+ */
+ public int getTop() {
+ return _top;
+ }
+
+ /**
+ * Set top
+ *
+ * @param top Top
+ */
+ public void setTop(int top) {
+ _top = top;
+ this.fireLocationChangedEvent();
+ }
+
+ /**
+ * Get width
+ *
+ * @return Width
+ */
+ public int getWidth() {
+ return _width;
+ }
+
+ /**
+ * Set width
+ *
+ * @param width Width
+ */
+ public void setWidth(int width) {
+ _width = width;
+ this.fireSizeChangedEvent();
+ }
+
+ /**
+ * Get height
+ *
+ * @return Height
+ */
+ public int getHeight() {
+ return _height;
+ }
+
+ /**
+ * Set height
+ *
+ * @param height Height
+ */
+ public void setHeight(int height) {
+ _height = height;
+ this.fireSizeChangedEvent();
+ }
+
+ /**
+ * Get right
+ *
+ * @return Right
+ */
+ public int getRight() {
+ return _left + _width;
+ }
+
+ /**
+ * Get bottom
+ *
+ * @return Bottom
+ */
+ public int getBottom() {
+ return _top + _height;
+ }
+
+ /**
+ * Get bounds rectangle
+ *
+ * @return Bounds rectangle
+ */
+ public Rectangle getBounds() {
+ return new Rectangle(_left, _top, _width, _height);
+ }
+
+ /**
+ * Get element type
+ *
+ * @return The element type
+ */
+ public ElementType getElementType() {
+ return _elementType;
+ }
+
+ /**
+ * Set element type
+ *
+ * @param type Element type
+ */
+ public void setElementType(ElementType type) {
+ _elementType = type;
+ }
+
+ /**
+ * Get foreground color
+ *
+ * @return Foreground color
+ */
+ public Color getForeColor() {
+ return _foreColor;
+ }
+
+ /**
+ * Set foreground color
+ *
+ * @param color Foreground color
+ */
+ public void setForeColor(Color color) {
+ _foreColor = color;
+ }
+
+ /**
+ * Get background color
+ *
+ * @return Background color
+ */
+ public Color getBackColor() {
+ return _backColor;
+ }
+
+ /**
+ * Set background color
+ *
+ * @param color Background color
+ */
+ public void setBackColor(Color color) {
+ _backColor = color;
+ }
+
+ /**
+ * Get if is selected
+ *
+ * @return Boolean
+ */
+ public boolean isSelected() {
+ return _selected;
+ }
+
+ /**
+ * Set if is selected
+ *
+ * @param istrue Boolean
+ */
+ public void setSelected(boolean istrue) {
+ _selected = istrue;
+ }
+
+ /**
+ * Get resize ability
+ *
+ * @return Resize ability
+ */
+ public ResizeAbility getResizeAbility() {
+ return _resizeAbility;
+ }
+
+ /**
+ * Set resize ability
+ *
+ * @param ra Resize ability
+ */
+ public void setResizeAbility(ResizeAbility ra) {
+ _resizeAbility = ra;
+ }
+
+ /**
+ * Get is draw backcolor
+ * @return Boolean
+ */
+ public boolean isDrawBackColor(){
+ return drawBackColor;
+ }
+
+ /**
+ * Set is draw backcolor
+ * @param value Boolean
+ */
+ public void setDrawBackColor(boolean value){
+ drawBackColor = value;
+ }
+ //
+ //
+
+ /**
+ * Paint method
+ *
+ * @param g Graphics2D
+ */
+ public abstract void paint(Graphics2D g);
+
+ /**
+ * Paint on layout method
+ *
+ * @param g Grahpics2D
+ * @param pageLocation Page location
+ * @param zoom Zoom
+ */
+ public abstract void paintOnLayout(Graphics2D g, PointF pageLocation, float zoom);
+
+ /**
+ * Move update method
+ */
+ public abstract void moveUpdate();
+
+ /**
+ * Resize update method
+ */
+ public abstract void resizeUpdate();
+
+ /**
+ * Page to screen
+ *
+ * @param pageX Page X
+ * @param pageY Page Y
+ * @param pageLocation Page location
+ * @param zoom Zoom
+ * @return Screen point
+ */
+ public PointF pageToScreen(float pageX, float pageY, PointF pageLocation, float zoom) {
+ float x = pageX * zoom + pageLocation.X;
+ float y = pageY * zoom + pageLocation.Y;
+ return (new PointF(x, y));
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/layout/LayoutGraphic.java b/MeteoInfoLib/src/main/java/org/meteoinfo/layout/LayoutGraphic.java
index 9f9db4bc..7bf08f98 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/layout/LayoutGraphic.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/layout/LayoutGraphic.java
@@ -1,554 +1,554 @@
-/* Copyright 2012 Yaqiang Wang,
- * yaqiang.wang@gmail.com
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.layout;
-
-import org.meteoinfo.drawing.Draw;
-import org.meteoinfo.global.event.IMapViewUpdatedListener;
-import org.meteoinfo.global.event.ISizeChangedListener;
-import org.meteoinfo.global.event.MapViewUpdatedEvent;
-import org.meteoinfo.global.event.SizeChangedEvent;
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.global.PointD;
-import org.meteoinfo.global.PointF;
-import org.meteoinfo.layer.LayerDrawType;
-import org.meteoinfo.layer.LayerTypes;
-import org.meteoinfo.layer.MapLayer;
-import org.meteoinfo.layer.VectorLayer;
-import org.meteoinfo.legend.BreakTypes;
-import org.meteoinfo.legend.LabelBreak;
-import org.meteoinfo.legend.PointBreak;
-import org.meteoinfo.legend.PolygonBreak;
-import org.meteoinfo.legend.PolylineBreak;
-import org.meteoinfo.legend.VectorBreak;
-import org.meteoinfo.shape.Graphic;
-import org.meteoinfo.shape.PointShape;
-import org.meteoinfo.shape.ShapeTypes;
-import org.meteoinfo.shape.WindArrow;
-import java.awt.Dimension;
-import java.awt.Font;
-import java.awt.FontMetrics;
-import java.awt.Graphics2D;
-import java.awt.Rectangle;
-import java.awt.RenderingHints;
-import java.awt.image.BufferedImage;
-import java.util.ArrayList;
-import java.util.List;
-import org.meteoinfo.global.DataConvert;
-import org.meteoinfo.shape.EllipseShape;
-
-/**
- *
- * @author yaqiang
- */
-public class LayoutGraphic extends LayoutElement {
-//
-
- private MapLayout _mapLayout;
- private LayoutMap _layoutMap;
- private Graphic _graphic;
- private boolean _updatingSize = false;
- private boolean _isTitle = false;
- private boolean _isPaint;
- private boolean _antiAlias = true;
- //
- //
-
- /**
- * Constructor
- *
- * @param aGraphic Graphic
- * @param aMapLayout MapLayout
- */
- public LayoutGraphic(Graphic aGraphic, MapLayout aMapLayout) {
- super();
- this.setElementType(ElementType.LayoutGraphic);
- this.setResizeAbility(ResizeAbility.ResizeAll);
-
- _mapLayout = aMapLayout;
- _isPaint = true;
- this.setGraphic(aGraphic);
- if (_graphic.getLegend() != null) {
- if (_graphic.getLegend().getBreakType() == BreakTypes.LabelBreak) {
- ((LabelBreak) _graphic.getLegend()).addSizeChangedListener(new ISizeChangedListener() {
- @Override
- public void sizeChangedEvent(SizeChangedEvent event) {
- updateControlSize();
- }
- });
- }
- }
- }
-
- /**
- * Constructor
- *
- * @param aGraphic Graphic
- * @param aMapLayout MapLayout
- * @param aLayoutMap LayoutMap
- */
- public LayoutGraphic(Graphic aGraphic, MapLayout aMapLayout, LayoutMap aLayoutMap) {
- super();
- this.setElementType(ElementType.LayoutGraphic);
- this.setResizeAbility(ResizeAbility.ResizeAll);
-
- _mapLayout = aMapLayout;
- _isPaint = true;
- this.setGraphic(aGraphic);
- if (_graphic.getLegend() != null) {
- if (_graphic.getLegend().getBreakType() == BreakTypes.LabelBreak) {
- ((LabelBreak) _graphic.getLegend()).addSizeChangedListener(new ISizeChangedListener() {
- @Override
- public void sizeChangedEvent(SizeChangedEvent event) {
- updateControlSize();
- }
- });
- }
- }
-
- _layoutMap = aLayoutMap;
- _layoutMap.addMapViewUpdatedListener(new IMapViewUpdatedListener() {
- @Override
- public void mapViewUpdatedEvent(MapViewUpdatedEvent event) {
- if (_graphic.getLegend().getBreakType() == BreakTypes.VectorBreak) {
- for (int i = 0; i < _layoutMap.getMapFrame().getMapView().getLayerNum(); i++) {
- MapLayer aLayer = _layoutMap.getMapFrame().getMapView().getLayers().
- get(_layoutMap.getMapFrame().getMapView().getLayerNum() - 1 - i);
- if (aLayer.getLayerType() == LayerTypes.VectorLayer) {
- if (aLayer.isVisible() && aLayer.getLayerDrawType() == LayerDrawType.Vector) {
- setVisible(true);
- float zoom = ((VectorLayer) aLayer).getDrawingZoom();
- ((VectorBreak) _graphic.getLegend()).setZoom(zoom);
-// float max = 30.0f / zoom;
-// WindArraw aWA = (WindArraw) _graphic.getShape();
-// int llen = 5;
-// for (i = 10; i <= 100; i += 5) {
-// if (max < i) {
-// llen = i - 5;
-// break;
-// }
-// }
-// aWA.length = llen;
-// aWA.size = 5;
-// aWA.setValue(0);
- updateControlSize();
- break;
- }
- }
- }
- }
- }
- });
- }
- //
- //
-
- public Graphic getGraphic() {
- return _graphic;
- }
-
- public void setGraphic(Graphic graphic) {
- _graphic = graphic;
- if (_graphic.getShape() != null) {
- switch (_graphic.getShape().getShapeType()) {
- case Point:
- if (_graphic.getLegend().getBreakType() == BreakTypes.PointBreak) {
- this.setResizeAbility(ResizeAbility.SameWidthHeight);
- } else if (_graphic.getLegend().getBreakType() == BreakTypes.LabelBreak) {
- this.setResizeAbility(ResizeAbility.None);
- }
- break;
- case Circle:
- this.setResizeAbility(ResizeAbility.SameWidthHeight);
- break;
- case WindArraw:
- this.setResizeAbility(ResizeAbility.None);
- break;
- default:
- this.setResizeAbility(ResizeAbility.ResizeAll);
- break;
- }
- updateControlSize();
- }
- }
-
- /**
- * Get if is title
- *
- * @return If is title
- */
- public boolean isTitle() {
- return _isTitle;
- }
-
- /**
- * Set if is title
- *
- * @param istrue Boolean
- */
- public void setIsTitle(boolean istrue) {
- _isTitle = istrue;
- }
-
- /**
- * Get if paint
- *
- * @return If paint
- */
- public boolean isPaint() {
- return _isPaint;
- }
-
- /**
- * Set if paint
- *
- * @param istrue If paint
- */
- public void setIsPaint(boolean istrue) {
- _isPaint = istrue;
- }
-
- //
- //
- /**
- * Set label text
- *
- * @param text Label text
- */
- public void setLabelText(String text) {
- switch (_graphic.getShape().getShapeType()) {
- case Point:
- if (_graphic.getLegend().getBreakType() == BreakTypes.LabelBreak) {
- ((LabelBreak) _graphic.getLegend()).setText(text);
- updateControlSize();
- }
- break;
- }
- }
-
- /**
- * Update control size
- */
- public void updateControlSize() {
- if (_graphic.getShape() == null) {
- return;
- }
-
- _updatingSize = true;
-
- switch (_graphic.getShape().getShapeType()) {
- case Point:
- PointShape aPS = (PointShape) _graphic.getShape();
- this.setLeft((int) aPS.getPoint().X);
- this.setTop((int) aPS.getPoint().Y);
- if (_graphic.getLegend().getBreakType() == BreakTypes.PointBreak) {
- PointBreak aPB = (PointBreak) _graphic.getLegend();
- this.setLeft(this.getLeft() - (int) (aPB.getSize() / 2));
- this.setTop(this.getTop() - (int) (aPB.getSize() / 2));
- this.setWidth((int) Math.ceil(aPB.getSize()));
- this.setHeight((int) Math.ceil(aPB.getSize()));
- } else if (_graphic.getLegend().getBreakType() == BreakTypes.LabelBreak) {
- LabelBreak aLB = (LabelBreak) _graphic.getLegend();
- //FontMetrics metrics = _mapLayout.getGraphics().getFontMetrics(aLB.getFont());
- BufferedImage image = new BufferedImage(_mapLayout.getPageBounds().width, _mapLayout.getPageBounds().height, BufferedImage.TYPE_INT_ARGB);
- Graphics2D g = (Graphics2D)image.getGraphics();
- g.setFont(aLB.getFont());
- Dimension aSF = Draw.getStringDimension(aLB.getText(), g);
- //FontMetrics metrics = image.getGraphics().getFontMetrics(aLB.getFont());
- //Dimension aSF = new Dimension(metrics.stringWidth(aLB.getText()), metrics.getHeight());
- this.setLeft(this.getLeft() - (int) (aSF.width / 2));
- this.setTop(this.getTop() - (int) (aSF.height * 2 / 3));
- this.setWidth((int) Math.ceil(aSF.width));
- this.setHeight((int) Math.ceil(aSF.getHeight()));
- }
- break;
- case WindArraw:
- WindArrow aWA = (WindArrow)_graphic.getShape();
- this.setLeft((int)aWA.getPoint().X);
- this.setTop((int)aWA.getPoint().Y);
- if (aWA.length == 0){
- aWA.length = 20;
- }
- this.setWidth((int)(aWA.length * ((VectorBreak)_graphic.getLegend()).getZoom()));
- this.setHeight(20);
- break;
- case Polyline:
- case Polygon:
- case Rectangle:
- case Circle:
- case CurveLine:
- case CurvePolygon:
- case Ellipse:
- Extent extent = _graphic.getShape().getExtent();
- this.setLeft((int) Math.ceil(extent.minX));
- this.setTop((int) Math.ceil(extent.minY));
- this.setWidth((int) Math.ceil(extent.getWidth()));
- this.setHeight((int) Math.ceil((extent.getHeight())));
- break;
- }
-
- _updatingSize = false;
- }
-
- /**
- * Vertice edited update
- *
- * @param vIdx Vertice index
- * @param newX New x
- * @param newY New y
- */
- public void verticeEditUpdate(int vIdx, double newX, double newY) {
- List points = (List) _graphic.getShape().getPoints();
- switch (_graphic.getShape().getShapeType()) {
- case Polygon:
- case CurvePolygon:
- case Rectangle:
- int last = points.size() - 1;
- if (vIdx == 0) {
- if (points.get(0).X == points.get(last).X && points.get(0).Y == points.get(last).Y) {
- points.get(last).X = newX;
- points.get(last).Y = newY;
- }
- } else if (vIdx == last) {
- if (points.get(0).X == points.get(last).X && points.get(0).Y == points.get(last).Y) {
- points.get(0).X = newX;
- points.get(0).Y = newY;
- }
- }
- break;
- }
-
- PointD aP = points.get(vIdx);
- aP.X = newX;
- aP.Y = newY;
- _graphic.getShape().setPoints(points);
- updateControlSize();
- }
-
- @Override
- public void paint(Graphics2D g) {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- @Override
- public void paintOnLayout(Graphics2D g, PointF pageLocation, float zoom) {
- if (this.isDrawBackColor()){
- PointF aP = pageToScreen(this.getLeft(), this.getTop(), pageLocation, zoom);
- Rectangle rect = new Rectangle((int) aP.X, (int) aP.Y, (int) (this.getWidth() * zoom), (int) (this.getHeight() * zoom));
- g.setColor(this.getBackColor());
- g.fill(rect);
- }
-
- //Draw graphics
- if (_antiAlias) {
- g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
- } else {
- g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
- }
- paintGraphics(g, pageLocation, zoom);
- }
-
- /**
- * Paint graphics
- *
- * @param g Graphics2D
- * @param pageLocation page location
- * @param zoom Zoom
- */
- public void paintGraphics(Graphics2D g, PointF pageLocation, float zoom) {
- switch (_graphic.getShape().getShapeType()) {
- case Point:
- PointD dPoint = _graphic.getShape().getPoints().get(0);
- PointF aPoint = pageToScreen((float) dPoint.X, (float) dPoint.Y, pageLocation, zoom);
- if (_graphic.getLegend().getBreakType() == BreakTypes.PointBreak) {
- PointBreak aPB = (PointBreak) ((PointBreak) _graphic.getLegend()).clone();
- float size = aPB.getSize();
- aPB.setSize(aPB.getSize() * zoom);
- g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
- Draw.drawPoint(aPoint, aPB, g);
- aPB.setSize(size);
- if (!_antiAlias) {
- g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
- }
- } else if (_graphic.getLegend().getBreakType() == BreakTypes.LabelBreak) {
- LabelBreak aLB = (LabelBreak) ((LabelBreak) _graphic.getLegend()).clone();
- Font font = new Font(aLB.getFont().getFontName(), aLB.getFont().getStyle(), aLB.getFont().getSize());
- aLB.setFont(new Font(font.getFontName(), font.getStyle(), (int) (font.getSize() * zoom)));
- Rectangle rect = new Rectangle();
- Draw.drawLabelPoint(aPoint, aLB, g, rect);
- aLB.setFont(font);
- }
- break;
- case WindArraw:
- dPoint = _graphic.getShape().getPoints().get(0);
- aPoint = pageToScreen((float) dPoint.X, (float) dPoint.Y, pageLocation, zoom);
- WindArrow aArraw = (WindArrow) _graphic.getShape();
- VectorBreak aVB = (VectorBreak) _graphic.getLegend();
- Draw.drawArraw(aVB.getColor(), aPoint, aArraw, g, aVB.getZoom() * zoom);
- Font drawFont = new Font("Arial", Font.PLAIN, (int) (12 * zoom));
- FontMetrics metrics = g.getFontMetrics(drawFont);
- String drawStr = DataConvert.removeTailingZeros(String.valueOf(aArraw.length));
- Dimension fsize = new Dimension(metrics.stringWidth(drawStr), metrics.getHeight());
- g.setColor(aVB.getColor());
- g.setFont(drawFont);
- g.drawString(drawStr, aPoint.X, aPoint.Y + fsize.height);
- break;
- case Polyline:
- case Polygon:
- case Rectangle:
- case Circle:
- case CurveLine:
- case CurvePolygon:
- case Ellipse:
- List pList = (List) _graphic.getShape().getPoints();
- PointF[] points = new PointF[pList.size()];
- for (int i = 0; i < pList.size(); i++) {
- points[i] = pageToScreen((float) pList.get(i).X, (float) pList.get(i).Y, pageLocation, zoom);
- }
-
- switch (_graphic.getShape().getShapeType()) {
- case Polyline:
- PolylineBreak aPLB = (PolylineBreak) ((PolylineBreak) _graphic.getLegend()).clone();
- float size = aPLB.getWidth();
- aPLB.setWidth(size * zoom);
- Draw.drawPolyline(points, (PolylineBreak) _graphic.getLegend(), g);
- aPLB.setWidth(size);
- break;
- case Polygon:
- case Rectangle:
- PolygonBreak aPGB = (PolygonBreak) ((PolygonBreak) _graphic.getLegend()).clone();
- size = aPGB.getOutlineSize();
- aPGB.setOutlineSize(size * zoom);
- Draw.drawPolygon(points, (PolygonBreak) _graphic.getLegend(), g);
- aPGB.setOutlineSize(size);
- break;
- case Circle:
- aPGB = (PolygonBreak) ((PolygonBreak) _graphic.getLegend()).clone();
- size = aPGB.getOutlineSize();
- aPGB.setOutlineSize(size * zoom);
- Draw.drawCircle(points, (PolygonBreak) _graphic.getLegend(), g);
- aPGB.setOutlineSize(size);
- break;
- case CurveLine:
- aPLB = (PolylineBreak) ((PolylineBreak) _graphic.getLegend()).clone();
- size = aPLB.getWidth();
- aPLB.setWidth(size * zoom);
- Draw.drawCurveLine(points, (PolylineBreak) _graphic.getLegend(), g);
- aPLB.setWidth(size);
- break;
- case CurvePolygon:
- aPGB = (PolygonBreak) ((PolygonBreak) _graphic.getLegend()).clone();
- size = aPGB.getOutlineSize();
- aPGB.setOutlineSize(size * zoom);
- Draw.drawCurvePolygon(points, (PolygonBreak) _graphic.getLegend(), g);
- aPGB.setOutlineSize(size);
- break;
- case Ellipse:
- aPGB = (PolygonBreak) ((PolygonBreak) _graphic.getLegend()).clone();
- size = aPGB.getOutlineSize();
- aPGB.setOutlineSize(size * zoom);
- float angle = ((EllipseShape)_graphic.getShape()).getAngle();
- Draw.drawEllipse(points, angle, (PolygonBreak) _graphic.getLegend(), g);
- aPGB.setOutlineSize(size);
- break;
- }
- break;
- }
- }
-
- @Override
- public void moveUpdate() {
- if (_graphic.getShape() != null) {
- List points = (List) _graphic.getShape().getPoints();
- Extent aExtent = _graphic.getShape().getExtent();
- double minX = aExtent.minX;
- double minY = aExtent.minY;
- if (_graphic.getShape().getShapeType() == ShapeTypes.Point) {
- minX -= this.getWidth() / 2;
- if (_graphic.getLegend().getBreakType() == BreakTypes.PointBreak)
- minY -= this.getHeight() / 2;
- else if (_graphic.getLegend().getBreakType() == BreakTypes.LabelBreak)
- minY -= this.getHeight() * 2 / 3;
- }
- int shiftX = this.getLeft() - (int) minX;
- int shiftY = this.getTop() - (int) minY;
- for (int i = 0; i < points.size(); i++) {
- PointD aP = points.get(i);
- aP.X += shiftX;
- aP.Y += shiftY;
- }
- _graphic.getShape().setPoints(points);
- }
- }
-
- @Override
- public void resizeUpdate() {
- if (_graphic.getShape() != null) {
- switch (_graphic.getShape().getShapeType()) {
- case Point:
- if (_graphic.getLegend().getBreakType() == BreakTypes.PointBreak) {
- PointBreak aPB = (PointBreak) _graphic.getLegend();
- aPB.setSize(this.getWidth());
- updateControlSize();
- }
- break;
- case Polyline:
- case Polygon:
- case CurveLine:
- case CurvePolygon:
- moveUpdate();
- List points = (List) _graphic.getShape().getPoints();
- Extent aExtent = _graphic.getShape().getExtent();
- int deltaX = this.getWidth() - (int) aExtent.getWidth();
- int deltaY = this.getHeight() - (int) aExtent.getHeight();
-
- for (int i = 0; i < points.size(); i++) {
- PointD aP = points.get(i);
- aP.X = aP.X + deltaX * (aP.X - aExtent.minX) / aExtent.getWidth();
- aP.Y = aP.Y + deltaY * (aP.Y - aExtent.minY) / aExtent.getHeight();
- }
- _graphic.getShape().setPoints(points);
- break;
- case Rectangle:
- case Ellipse:
- points = new ArrayList<>();
- points.add(new PointD(this.getLeft(), this.getTop()));
- points.add(new PointD(this.getLeft(), this.getBottom()));
- points.add(new PointD(this.getRight(), this.getBottom()));
- points.add(new PointD(this.getRight(), this.getTop()));
- if (_graphic.getShape().getShapeType() == ShapeTypes.Rectangle) {
- points.add((PointD) points.get(0).clone());
- }
- _graphic.getShape().setPoints(points);
- break;
- case Circle:
- points = new ArrayList<>();
- points.add(new PointD(this.getLeft(), this.getTop() + this.getWidth() / 2));
- points.add(new PointD(this.getLeft() + this.getWidth() / 2, this.getTop()));
- points.add(new PointD(this.getLeft() + this.getWidth(), this.getTop() + this.getWidth() / 2));
- points.add(new PointD(this.getLeft() + this.getWidth() / 2, this.getTop() + this.getWidth()));
- _graphic.getShape().setPoints(points);
- break;
- }
- }
- }
-
- @Override
- public void fireLocationChangedEvent() {
- super.fireLocationChangedEvent();
-
- if (!this._updatingSize)
- this.moveUpdate();
- }
- //
-}
+/* Copyright 2012 Yaqiang Wang,
+ * yaqiang.wang@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ */
+package org.meteoinfo.layout;
+
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.PointD;
+import org.meteoinfo.common.PointF;
+import org.meteoinfo.drawing.Draw;
+import org.meteoinfo.global.event.IMapViewUpdatedListener;
+import org.meteoinfo.global.event.ISizeChangedListener;
+import org.meteoinfo.global.event.MapViewUpdatedEvent;
+import org.meteoinfo.global.event.SizeChangedEvent;
+import org.meteoinfo.layer.LayerDrawType;
+import org.meteoinfo.layer.LayerTypes;
+import org.meteoinfo.layer.MapLayer;
+import org.meteoinfo.layer.VectorLayer;
+import org.meteoinfo.legend.BreakTypes;
+import org.meteoinfo.legend.LabelBreak;
+import org.meteoinfo.legend.PointBreak;
+import org.meteoinfo.legend.PolygonBreak;
+import org.meteoinfo.legend.PolylineBreak;
+import org.meteoinfo.legend.VectorBreak;
+import org.meteoinfo.shape.Graphic;
+import org.meteoinfo.shape.PointShape;
+import org.meteoinfo.shape.ShapeTypes;
+import org.meteoinfo.shape.WindArrow;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.image.BufferedImage;
+import java.util.ArrayList;
+import java.util.List;
+import org.meteoinfo.global.DataConvert;
+import org.meteoinfo.shape.EllipseShape;
+
+/**
+ *
+ * @author yaqiang
+ */
+public class LayoutGraphic extends LayoutElement {
+//
+
+ private MapLayout _mapLayout;
+ private LayoutMap _layoutMap;
+ private Graphic _graphic;
+ private boolean _updatingSize = false;
+ private boolean _isTitle = false;
+ private boolean _isPaint;
+ private boolean _antiAlias = true;
+ //
+ //
+
+ /**
+ * Constructor
+ *
+ * @param aGraphic Graphic
+ * @param aMapLayout MapLayout
+ */
+ public LayoutGraphic(Graphic aGraphic, MapLayout aMapLayout) {
+ super();
+ this.setElementType(ElementType.LayoutGraphic);
+ this.setResizeAbility(ResizeAbility.ResizeAll);
+
+ _mapLayout = aMapLayout;
+ _isPaint = true;
+ this.setGraphic(aGraphic);
+ if (_graphic.getLegend() != null) {
+ if (_graphic.getLegend().getBreakType() == BreakTypes.LabelBreak) {
+ ((LabelBreak) _graphic.getLegend()).addSizeChangedListener(new ISizeChangedListener() {
+ @Override
+ public void sizeChangedEvent(SizeChangedEvent event) {
+ updateControlSize();
+ }
+ });
+ }
+ }
+ }
+
+ /**
+ * Constructor
+ *
+ * @param aGraphic Graphic
+ * @param aMapLayout MapLayout
+ * @param aLayoutMap LayoutMap
+ */
+ public LayoutGraphic(Graphic aGraphic, MapLayout aMapLayout, LayoutMap aLayoutMap) {
+ super();
+ this.setElementType(ElementType.LayoutGraphic);
+ this.setResizeAbility(ResizeAbility.ResizeAll);
+
+ _mapLayout = aMapLayout;
+ _isPaint = true;
+ this.setGraphic(aGraphic);
+ if (_graphic.getLegend() != null) {
+ if (_graphic.getLegend().getBreakType() == BreakTypes.LabelBreak) {
+ ((LabelBreak) _graphic.getLegend()).addSizeChangedListener(new ISizeChangedListener() {
+ @Override
+ public void sizeChangedEvent(SizeChangedEvent event) {
+ updateControlSize();
+ }
+ });
+ }
+ }
+
+ _layoutMap = aLayoutMap;
+ _layoutMap.addMapViewUpdatedListener(new IMapViewUpdatedListener() {
+ @Override
+ public void mapViewUpdatedEvent(MapViewUpdatedEvent event) {
+ if (_graphic.getLegend().getBreakType() == BreakTypes.VectorBreak) {
+ for (int i = 0; i < _layoutMap.getMapFrame().getMapView().getLayerNum(); i++) {
+ MapLayer aLayer = _layoutMap.getMapFrame().getMapView().getLayers().
+ get(_layoutMap.getMapFrame().getMapView().getLayerNum() - 1 - i);
+ if (aLayer.getLayerType() == LayerTypes.VectorLayer) {
+ if (aLayer.isVisible() && aLayer.getLayerDrawType() == LayerDrawType.Vector) {
+ setVisible(true);
+ float zoom = ((VectorLayer) aLayer).getDrawingZoom();
+ ((VectorBreak) _graphic.getLegend()).setZoom(zoom);
+// float max = 30.0f / zoom;
+// WindArraw aWA = (WindArraw) _graphic.getShape();
+// int llen = 5;
+// for (i = 10; i <= 100; i += 5) {
+// if (max < i) {
+// llen = i - 5;
+// break;
+// }
+// }
+// aWA.length = llen;
+// aWA.size = 5;
+// aWA.setValue(0);
+ updateControlSize();
+ break;
+ }
+ }
+ }
+ }
+ }
+ });
+ }
+ //
+ //
+
+ public Graphic getGraphic() {
+ return _graphic;
+ }
+
+ public void setGraphic(Graphic graphic) {
+ _graphic = graphic;
+ if (_graphic.getShape() != null) {
+ switch (_graphic.getShape().getShapeType()) {
+ case Point:
+ if (_graphic.getLegend().getBreakType() == BreakTypes.PointBreak) {
+ this.setResizeAbility(ResizeAbility.SameWidthHeight);
+ } else if (_graphic.getLegend().getBreakType() == BreakTypes.LabelBreak) {
+ this.setResizeAbility(ResizeAbility.None);
+ }
+ break;
+ case Circle:
+ this.setResizeAbility(ResizeAbility.SameWidthHeight);
+ break;
+ case WindArraw:
+ this.setResizeAbility(ResizeAbility.None);
+ break;
+ default:
+ this.setResizeAbility(ResizeAbility.ResizeAll);
+ break;
+ }
+ updateControlSize();
+ }
+ }
+
+ /**
+ * Get if is title
+ *
+ * @return If is title
+ */
+ public boolean isTitle() {
+ return _isTitle;
+ }
+
+ /**
+ * Set if is title
+ *
+ * @param istrue Boolean
+ */
+ public void setIsTitle(boolean istrue) {
+ _isTitle = istrue;
+ }
+
+ /**
+ * Get if paint
+ *
+ * @return If paint
+ */
+ public boolean isPaint() {
+ return _isPaint;
+ }
+
+ /**
+ * Set if paint
+ *
+ * @param istrue If paint
+ */
+ public void setIsPaint(boolean istrue) {
+ _isPaint = istrue;
+ }
+
+ //
+ //
+ /**
+ * Set label text
+ *
+ * @param text Label text
+ */
+ public void setLabelText(String text) {
+ switch (_graphic.getShape().getShapeType()) {
+ case Point:
+ if (_graphic.getLegend().getBreakType() == BreakTypes.LabelBreak) {
+ ((LabelBreak) _graphic.getLegend()).setText(text);
+ updateControlSize();
+ }
+ break;
+ }
+ }
+
+ /**
+ * Update control size
+ */
+ public void updateControlSize() {
+ if (_graphic.getShape() == null) {
+ return;
+ }
+
+ _updatingSize = true;
+
+ switch (_graphic.getShape().getShapeType()) {
+ case Point:
+ PointShape aPS = (PointShape) _graphic.getShape();
+ this.setLeft((int) aPS.getPoint().X);
+ this.setTop((int) aPS.getPoint().Y);
+ if (_graphic.getLegend().getBreakType() == BreakTypes.PointBreak) {
+ PointBreak aPB = (PointBreak) _graphic.getLegend();
+ this.setLeft(this.getLeft() - (int) (aPB.getSize() / 2));
+ this.setTop(this.getTop() - (int) (aPB.getSize() / 2));
+ this.setWidth((int) Math.ceil(aPB.getSize()));
+ this.setHeight((int) Math.ceil(aPB.getSize()));
+ } else if (_graphic.getLegend().getBreakType() == BreakTypes.LabelBreak) {
+ LabelBreak aLB = (LabelBreak) _graphic.getLegend();
+ //FontMetrics metrics = _mapLayout.getGraphics().getFontMetrics(aLB.getFont());
+ BufferedImage image = new BufferedImage(_mapLayout.getPageBounds().width, _mapLayout.getPageBounds().height, BufferedImage.TYPE_INT_ARGB);
+ Graphics2D g = (Graphics2D)image.getGraphics();
+ g.setFont(aLB.getFont());
+ Dimension aSF = Draw.getStringDimension(aLB.getText(), g);
+ //FontMetrics metrics = image.getGraphics().getFontMetrics(aLB.getFont());
+ //Dimension aSF = new Dimension(metrics.stringWidth(aLB.getText()), metrics.getHeight());
+ this.setLeft(this.getLeft() - (int) (aSF.width / 2));
+ this.setTop(this.getTop() - (int) (aSF.height * 2 / 3));
+ this.setWidth((int) Math.ceil(aSF.width));
+ this.setHeight((int) Math.ceil(aSF.getHeight()));
+ }
+ break;
+ case WindArraw:
+ WindArrow aWA = (WindArrow)_graphic.getShape();
+ this.setLeft((int)aWA.getPoint().X);
+ this.setTop((int)aWA.getPoint().Y);
+ if (aWA.length == 0){
+ aWA.length = 20;
+ }
+ this.setWidth((int)(aWA.length * ((VectorBreak)_graphic.getLegend()).getZoom()));
+ this.setHeight(20);
+ break;
+ case Polyline:
+ case Polygon:
+ case Rectangle:
+ case Circle:
+ case CurveLine:
+ case CurvePolygon:
+ case Ellipse:
+ Extent extent = _graphic.getShape().getExtent();
+ this.setLeft((int) Math.ceil(extent.minX));
+ this.setTop((int) Math.ceil(extent.minY));
+ this.setWidth((int) Math.ceil(extent.getWidth()));
+ this.setHeight((int) Math.ceil((extent.getHeight())));
+ break;
+ }
+
+ _updatingSize = false;
+ }
+
+ /**
+ * Vertice edited update
+ *
+ * @param vIdx Vertice index
+ * @param newX New x
+ * @param newY New y
+ */
+ public void verticeEditUpdate(int vIdx, double newX, double newY) {
+ List points = (List) _graphic.getShape().getPoints();
+ switch (_graphic.getShape().getShapeType()) {
+ case Polygon:
+ case CurvePolygon:
+ case Rectangle:
+ int last = points.size() - 1;
+ if (vIdx == 0) {
+ if (points.get(0).X == points.get(last).X && points.get(0).Y == points.get(last).Y) {
+ points.get(last).X = newX;
+ points.get(last).Y = newY;
+ }
+ } else if (vIdx == last) {
+ if (points.get(0).X == points.get(last).X && points.get(0).Y == points.get(last).Y) {
+ points.get(0).X = newX;
+ points.get(0).Y = newY;
+ }
+ }
+ break;
+ }
+
+ PointD aP = points.get(vIdx);
+ aP.X = newX;
+ aP.Y = newY;
+ _graphic.getShape().setPoints(points);
+ updateControlSize();
+ }
+
+ @Override
+ public void paint(Graphics2D g) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void paintOnLayout(Graphics2D g, PointF pageLocation, float zoom) {
+ if (this.isDrawBackColor()){
+ PointF aP = pageToScreen(this.getLeft(), this.getTop(), pageLocation, zoom);
+ Rectangle rect = new Rectangle((int) aP.X, (int) aP.Y, (int) (this.getWidth() * zoom), (int) (this.getHeight() * zoom));
+ g.setColor(this.getBackColor());
+ g.fill(rect);
+ }
+
+ //Draw graphics
+ if (_antiAlias) {
+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ } else {
+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
+ }
+ paintGraphics(g, pageLocation, zoom);
+ }
+
+ /**
+ * Paint graphics
+ *
+ * @param g Graphics2D
+ * @param pageLocation page location
+ * @param zoom Zoom
+ */
+ public void paintGraphics(Graphics2D g, PointF pageLocation, float zoom) {
+ switch (_graphic.getShape().getShapeType()) {
+ case Point:
+ PointD dPoint = _graphic.getShape().getPoints().get(0);
+ PointF aPoint = pageToScreen((float) dPoint.X, (float) dPoint.Y, pageLocation, zoom);
+ if (_graphic.getLegend().getBreakType() == BreakTypes.PointBreak) {
+ PointBreak aPB = (PointBreak) ((PointBreak) _graphic.getLegend()).clone();
+ float size = aPB.getSize();
+ aPB.setSize(aPB.getSize() * zoom);
+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ Draw.drawPoint(aPoint, aPB, g);
+ aPB.setSize(size);
+ if (!_antiAlias) {
+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ }
+ } else if (_graphic.getLegend().getBreakType() == BreakTypes.LabelBreak) {
+ LabelBreak aLB = (LabelBreak) ((LabelBreak) _graphic.getLegend()).clone();
+ Font font = new Font(aLB.getFont().getFontName(), aLB.getFont().getStyle(), aLB.getFont().getSize());
+ aLB.setFont(new Font(font.getFontName(), font.getStyle(), (int) (font.getSize() * zoom)));
+ Rectangle rect = new Rectangle();
+ Draw.drawLabelPoint(aPoint, aLB, g, rect);
+ aLB.setFont(font);
+ }
+ break;
+ case WindArraw:
+ dPoint = _graphic.getShape().getPoints().get(0);
+ aPoint = pageToScreen((float) dPoint.X, (float) dPoint.Y, pageLocation, zoom);
+ WindArrow aArraw = (WindArrow) _graphic.getShape();
+ VectorBreak aVB = (VectorBreak) _graphic.getLegend();
+ Draw.drawArraw(aVB.getColor(), aPoint, aArraw, g, aVB.getZoom() * zoom);
+ Font drawFont = new Font("Arial", Font.PLAIN, (int) (12 * zoom));
+ FontMetrics metrics = g.getFontMetrics(drawFont);
+ String drawStr = DataConvert.removeTailingZeros(String.valueOf(aArraw.length));
+ Dimension fsize = new Dimension(metrics.stringWidth(drawStr), metrics.getHeight());
+ g.setColor(aVB.getColor());
+ g.setFont(drawFont);
+ g.drawString(drawStr, aPoint.X, aPoint.Y + fsize.height);
+ break;
+ case Polyline:
+ case Polygon:
+ case Rectangle:
+ case Circle:
+ case CurveLine:
+ case CurvePolygon:
+ case Ellipse:
+ List pList = (List) _graphic.getShape().getPoints();
+ PointF[] points = new PointF[pList.size()];
+ for (int i = 0; i < pList.size(); i++) {
+ points[i] = pageToScreen((float) pList.get(i).X, (float) pList.get(i).Y, pageLocation, zoom);
+ }
+
+ switch (_graphic.getShape().getShapeType()) {
+ case Polyline:
+ PolylineBreak aPLB = (PolylineBreak) ((PolylineBreak) _graphic.getLegend()).clone();
+ float size = aPLB.getWidth();
+ aPLB.setWidth(size * zoom);
+ Draw.drawPolyline(points, (PolylineBreak) _graphic.getLegend(), g);
+ aPLB.setWidth(size);
+ break;
+ case Polygon:
+ case Rectangle:
+ PolygonBreak aPGB = (PolygonBreak) ((PolygonBreak) _graphic.getLegend()).clone();
+ size = aPGB.getOutlineSize();
+ aPGB.setOutlineSize(size * zoom);
+ Draw.drawPolygon(points, (PolygonBreak) _graphic.getLegend(), g);
+ aPGB.setOutlineSize(size);
+ break;
+ case Circle:
+ aPGB = (PolygonBreak) ((PolygonBreak) _graphic.getLegend()).clone();
+ size = aPGB.getOutlineSize();
+ aPGB.setOutlineSize(size * zoom);
+ Draw.drawCircle(points, (PolygonBreak) _graphic.getLegend(), g);
+ aPGB.setOutlineSize(size);
+ break;
+ case CurveLine:
+ aPLB = (PolylineBreak) ((PolylineBreak) _graphic.getLegend()).clone();
+ size = aPLB.getWidth();
+ aPLB.setWidth(size * zoom);
+ Draw.drawCurveLine(points, (PolylineBreak) _graphic.getLegend(), g);
+ aPLB.setWidth(size);
+ break;
+ case CurvePolygon:
+ aPGB = (PolygonBreak) ((PolygonBreak) _graphic.getLegend()).clone();
+ size = aPGB.getOutlineSize();
+ aPGB.setOutlineSize(size * zoom);
+ Draw.drawCurvePolygon(points, (PolygonBreak) _graphic.getLegend(), g);
+ aPGB.setOutlineSize(size);
+ break;
+ case Ellipse:
+ aPGB = (PolygonBreak) ((PolygonBreak) _graphic.getLegend()).clone();
+ size = aPGB.getOutlineSize();
+ aPGB.setOutlineSize(size * zoom);
+ float angle = ((EllipseShape)_graphic.getShape()).getAngle();
+ Draw.drawEllipse(points, angle, (PolygonBreak) _graphic.getLegend(), g);
+ aPGB.setOutlineSize(size);
+ break;
+ }
+ break;
+ }
+ }
+
+ @Override
+ public void moveUpdate() {
+ if (_graphic.getShape() != null) {
+ List points = (List) _graphic.getShape().getPoints();
+ Extent aExtent = _graphic.getShape().getExtent();
+ double minX = aExtent.minX;
+ double minY = aExtent.minY;
+ if (_graphic.getShape().getShapeType() == ShapeTypes.Point) {
+ minX -= this.getWidth() / 2;
+ if (_graphic.getLegend().getBreakType() == BreakTypes.PointBreak)
+ minY -= this.getHeight() / 2;
+ else if (_graphic.getLegend().getBreakType() == BreakTypes.LabelBreak)
+ minY -= this.getHeight() * 2 / 3;
+ }
+ int shiftX = this.getLeft() - (int) minX;
+ int shiftY = this.getTop() - (int) minY;
+ for (int i = 0; i < points.size(); i++) {
+ PointD aP = points.get(i);
+ aP.X += shiftX;
+ aP.Y += shiftY;
+ }
+ _graphic.getShape().setPoints(points);
+ }
+ }
+
+ @Override
+ public void resizeUpdate() {
+ if (_graphic.getShape() != null) {
+ switch (_graphic.getShape().getShapeType()) {
+ case Point:
+ if (_graphic.getLegend().getBreakType() == BreakTypes.PointBreak) {
+ PointBreak aPB = (PointBreak) _graphic.getLegend();
+ aPB.setSize(this.getWidth());
+ updateControlSize();
+ }
+ break;
+ case Polyline:
+ case Polygon:
+ case CurveLine:
+ case CurvePolygon:
+ moveUpdate();
+ List points = (List) _graphic.getShape().getPoints();
+ Extent aExtent = _graphic.getShape().getExtent();
+ int deltaX = this.getWidth() - (int) aExtent.getWidth();
+ int deltaY = this.getHeight() - (int) aExtent.getHeight();
+
+ for (int i = 0; i < points.size(); i++) {
+ PointD aP = points.get(i);
+ aP.X = aP.X + deltaX * (aP.X - aExtent.minX) / aExtent.getWidth();
+ aP.Y = aP.Y + deltaY * (aP.Y - aExtent.minY) / aExtent.getHeight();
+ }
+ _graphic.getShape().setPoints(points);
+ break;
+ case Rectangle:
+ case Ellipse:
+ points = new ArrayList<>();
+ points.add(new PointD(this.getLeft(), this.getTop()));
+ points.add(new PointD(this.getLeft(), this.getBottom()));
+ points.add(new PointD(this.getRight(), this.getBottom()));
+ points.add(new PointD(this.getRight(), this.getTop()));
+ if (_graphic.getShape().getShapeType() == ShapeTypes.Rectangle) {
+ points.add((PointD) points.get(0).clone());
+ }
+ _graphic.getShape().setPoints(points);
+ break;
+ case Circle:
+ points = new ArrayList<>();
+ points.add(new PointD(this.getLeft(), this.getTop() + this.getWidth() / 2));
+ points.add(new PointD(this.getLeft() + this.getWidth() / 2, this.getTop()));
+ points.add(new PointD(this.getLeft() + this.getWidth(), this.getTop() + this.getWidth() / 2));
+ points.add(new PointD(this.getLeft() + this.getWidth() / 2, this.getTop() + this.getWidth()));
+ _graphic.getShape().setPoints(points);
+ break;
+ }
+ }
+ }
+
+ @Override
+ public void fireLocationChangedEvent() {
+ super.fireLocationChangedEvent();
+
+ if (!this._updatingSize)
+ this.moveUpdate();
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/layout/LayoutLegend.java b/MeteoInfoLib/src/main/java/org/meteoinfo/layout/LayoutLegend.java
index 0d5b4ed8..362088c8 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/layout/LayoutLegend.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/layout/LayoutLegend.java
@@ -1,2145 +1,2145 @@
-/* Copyright 2012 Yaqiang Wang,
- * yaqiang.wang@gmail.com
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.layout;
-
-import org.meteoinfo.drawing.Draw;
-import org.meteoinfo.global.event.IMapViewUpdatedListener;
-import org.meteoinfo.global.event.MapViewUpdatedEvent;
-import org.meteoinfo.global.PointF;
-import org.meteoinfo.layer.LayerDrawType;
-import org.meteoinfo.layer.LayerTypes;
-import org.meteoinfo.layer.MapLayer;
-import org.meteoinfo.layer.VectorLayer;
-import org.meteoinfo.legend.ChartBreak;
-import org.meteoinfo.legend.ColorBreak;
-import org.meteoinfo.legend.LegendScheme;
-import org.meteoinfo.legend.LegendType;
-import org.meteoinfo.legend.PointBreak;
-import org.meteoinfo.legend.PolygonBreak;
-import org.meteoinfo.legend.PolylineBreak;
-import org.meteoinfo.shape.ShapeTypes;
-import com.l2fprod.common.beans.BaseBeanInfo;
-import com.l2fprod.common.beans.ExtendedPropertyDescriptor;
-import com.l2fprod.common.beans.editor.ComboBoxPropertyEditor;
-import java.awt.BasicStroke;
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.Font;
-import java.awt.FontMetrics;
-import java.awt.Graphics2D;
-import java.awt.Polygon;
-import java.awt.Rectangle;
-import java.awt.RenderingHints;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Line2D;
-import java.awt.image.BufferedImage;
-import java.util.ArrayList;
-import java.util.List;
-import org.meteoinfo.global.DataConvert;
-import org.meteoinfo.legend.ChartTypes;
-
-/**
- *
- * @author Yaqiang Wang
- */
-public class LayoutLegend extends LayoutElement {
- //
-
- private MapLayout _mapLayout;
- private static LayoutMap _layoutMap;
- private MapLayer _legendLayer;
- private boolean forceDrawOutline;
- private boolean _isAntiAlias;
- private LayerUpdateTypes _layerUpdateType;
- private LegendStyles _legendStyle;
- private String _title;
- private Font _font;
- private Font _titleFont;
- private boolean _drawNeatLine;
- private Color _neatLineColor;
- private float _neatLineSize;
- private float _breakSpace;
- private float _topSpace;
- private float _leftSpace;
- private float _vBarWidth;
- private float _hBarHeight;
- private int _columnNum = 1;
- private boolean drawChartBreaks = true;
- private boolean drawPieLabel = false;
- //
- //
-
- /**
- * Constructor
- *
- * @param mapLayout Map layout
- * @param layoutMap Layout map
- */
- public LayoutLegend(MapLayout mapLayout, LayoutMap layoutMap) {
- super();
- this.setElementType(ElementType.LayoutLegend);
- this.setResizeAbility(ResizeAbility.ResizeAll);
-
- _mapLayout = mapLayout;
- _layoutMap = layoutMap;
- _layoutMap.addMapViewUpdatedListener(new IMapViewUpdatedListener() {
- @Override
- public void mapViewUpdatedEvent(MapViewUpdatedEvent event) {
- onMapViewUpdated(event);
- }
- });
- _isAntiAlias = true;
- this.forceDrawOutline = true;
- _layerUpdateType = LayerUpdateTypes.FirstMeteoLayer;
- _legendStyle = LegendStyles.Normal;
- _title = "";
- _drawNeatLine = false;
- _neatLineColor = Color.black;
- _neatLineSize = 1;
- _breakSpace = 3;
- _topSpace = 5;
- _leftSpace = 5;
- _vBarWidth = 10;
- _hBarHeight = 10;
- _font = new Font("宋体", Font.PLAIN, 12);
- _titleFont = new Font("Arial", Font.PLAIN, 12);
- }
-
- //
- //
- public void onMapViewUpdated(MapViewUpdatedEvent e) {
- if (_layoutMap.getMapFrame().getMapView().getLayerNum() == 0) {
- return;
- }
-
- switch (_layerUpdateType) {
- case FirstExpandedLayer:
- for (int i = 0; i < _layoutMap.getMapFrame().getMapView().getLayerNum(); i++) {
- MapLayer aLayer = _layoutMap.getMapFrame().getMapView().getLayers().
- get(_layoutMap.getMapFrame().getMapView().getLayerNum() - 1 - i);
- if (aLayer.hasLegendScheme()) {
- if (aLayer.isVisible() && aLayer.isExpanded() && aLayer.getLegendScheme().getLegendType() != LegendType.SingleSymbol) {
- this.setVisible(true);
- this.setLegendLayer(aLayer);
- break;
- }
- }
- }
- break;
- case FirstMeteoLayer:
- for (int i = 0; i < _layoutMap.getMapFrame().getMapView().getLayerNum(); i++) {
- MapLayer aLayer = _layoutMap.getMapFrame().getMapView().getLayers().
- get(_layoutMap.getMapFrame().getMapView().getLayerNum() - 1 - i);
- if (aLayer.hasLegendScheme()) {
- if (aLayer.isVisible() && aLayer.getLayerDrawType() != LayerDrawType.Map
- && aLayer.getLegendScheme().getLegendType() != LegendType.SingleSymbol) {
- this.setVisible(true);
- this.setLegendLayer(aLayer);
- break;
- }
- }
- }
- break;
- case LastAddedLayer:
- if (_layoutMap.getMapFrame().getMapView().getLastAddedLayer().hasLegendScheme()) {
- this.setVisible(true);
- this.setLegendLayer(_layoutMap.getMapFrame().getMapView().getLastAddedLayer());
- }
- break;
- }
-
- updateLegendSize();
- }
- //
- //
-
- /**
- * Get layout map
- *
- * @return The layout map
- */
- public LayoutMap getLayoutMap() {
- return _layoutMap;
- }
-
- /**
- * Get legend layer
- *
- * @return The legend alyer
- */
- public MapLayer getLegendLayer() {
- return _legendLayer;
- }
-
- /**
- * Set legend layer
- *
- * @param layer The legend layer
- */
- public void setLegendLayer(MapLayer layer) {
- if (layer == null) {
- return;
- }
-
- _legendLayer = layer;
- String aStr = _legendLayer.getLayerName();
- if (aStr.contains("_")) {
- aStr = aStr.split("_")[1];
- }
- _title = aStr;
- updateLegendSize();
- }
-
- /**
- * Get legend layer name
- *
- * @return Legend layer name
- */
- public String getLayerName() {
- if (_legendLayer != null) {
- return _legendLayer.getLayerName();
- } else {
- return "";
- }
- }
-
- /**
- * Set legend layer name
- *
- * @param name Layer name
- */
- public void setLayerName(String name) {
- MapLayer aLayer = _layoutMap.getMapFrame().getMapView().getLayer(name);
- if (aLayer != null) {
- _legendLayer = aLayer;
- }
- }
-
- /**
- * Get if force to draw polygon outline - for normal legend
- *
- * @return Boolean
- */
- public boolean isForceDrawOutline() {
- return this.forceDrawOutline;
- }
-
- /**
- * Set if force to draw polygon outline - for normal legend
- *
- * @param value Boolean
- */
- public void setForceDrawOutline(boolean value) {
- this.forceDrawOutline = value;
- }
-
- /**
- * Get layer update type
- *
- * @return Layer update type
- */
- public LayerUpdateTypes getLayerUpdateType() {
- return _layerUpdateType;
- }
-
- /**
- * Set layer update type
- *
- * @param type Layer update type
- */
- public void setLayerUpdateType(LayerUpdateTypes type) {
- _layerUpdateType = type;
- }
-
- /**
- * Get legend style
- *
- * @return Legend style
- */
- public LegendStyles getLegendStyle() {
- return _legendStyle;
- }
-
- /**
- * Set legend style
- *
- * @param style Legend style
- */
- public void setLegendStyle(LegendStyles style) {
- _legendStyle = style;
- if (this.isVisible()) {
- updateLegendSize();
- }
- }
-
- /**
- * Get title
- *
- * @return The title
- */
- public String getTitle() {
- return _title;
- }
-
- /**
- * Set title
- *
- * @param title The title
- */
- public void setTitle(String title) {
- _title = title;
- updateLegendSize();
- }
-
- /**
- * Get if draw neat line
- *
- * @return If draw neat line
- */
- public boolean isDrawNeatLine() {
- return _drawNeatLine;
- }
-
- /**
- * Set if draw neat line
- *
- * @param istrue If draw neat line
- */
- public void setDrawNeatLine(boolean istrue) {
- _drawNeatLine = istrue;
- }
-
- /**
- * Get neat line color
- *
- * @return Neat line color
- */
- public Color getNeatLineColor() {
- return _neatLineColor;
- }
-
- /**
- * Set neat line color
- *
- * @param color Neat line color
- */
- public void setNeatLineColor(Color color) {
- _neatLineColor = color;
- }
-
- /**
- * Get neat line size
- *
- * @return Neat line size
- */
- public float getNeatLineSize() {
- return _neatLineSize;
- }
-
- /**
- * Set neat line size
- *
- * @param size Neat line size
- */
- public void setNeatLineSize(float size) {
- _neatLineSize = size;
- }
-
- /**
- * Get font
- *
- * @return The font
- */
- public Font getFont() {
- return _font;
- }
-
- /**
- * Set font
- *
- * @param font The font
- */
- public void setFont(Font font) {
- _font = font;
- _titleFont = new Font(_font.getFontName(), Font.PLAIN, _font.getSize() + 2);
- updateLegendSize();
- }
-
- /**
- * Get column number
- *
- * @return Column number
- */
- public int getColumnNumber() {
- return _columnNum;
- }
-
- /**
- * Set column number
- *
- * @param value Column number
- */
- public void setColumnNumber(int value) {
- _columnNum = value;
- }
-
- /**
- * Get if draw chart breaks
- *
- * @return Boolean
- */
- public boolean isDrawChartBreaks() {
- return this.drawChartBreaks;
- }
-
- /**
- * Set if draw chart breaks
- *
- * @param value Boolean
- */
- public void setDrawChartBreaks(boolean value) {
- this.drawChartBreaks = value;
- }
-
- /**
- * Get if draw pie label
- *
- * @return Boolean
- */
- public boolean isDrawPieLabel() {
- return this.drawPieLabel;
- }
-
- /**
- * Set if draw pie label
- *
- * @param value Boolean
- */
- public void setDrawPieLabel(boolean value) {
- this.drawPieLabel = value;
- }
-
- //
- //
- /**
- * Paint graphics
- *
- * @param g Graphics2D
- * @param pageLocation Page location
- * @param zoom Zoom
- */
- public void paintGraphics(Graphics2D g, PointF pageLocation, float zoom) {
- if (_legendLayer == null) {
- return;
- }
-
- if (_legendLayer.getLayerType() == LayerTypes.ImageLayer) {
- return;
- }
-
- AffineTransform oldMatrix = g.getTransform();
- PointF aP = pageToScreen(this.getLeft(), this.getTop(), pageLocation, zoom);
- g.translate(aP.X, aP.Y);
- g.scale(zoom, zoom);
- if (this._isAntiAlias) {
- g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
- } else {
- g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
- }
-
- //Draw background color
- if (this.isDrawBackColor()) {
- g.setColor(this.getBackColor());
- g.fill(new Rectangle.Float(0, 0, this.getWidth() * zoom, this.getHeight() * zoom));
- }
-
- int gap = this.getTickGap(g);
- switch (_legendStyle) {
- case Bar_Horizontal:
- if (gap > 1) {
- drawHorizontalBarLegend_Ex(g, zoom);
- } else {
- drawHorizontalBarLegend(g, zoom);
- }
- break;
- case Bar_Vertical:
- if (gap > 1) {
- drawVerticalBarLegend_Ex(g, zoom);
- } else {
- drawVerticalBarLegend(g, zoom);
- }
- break;
- case Normal:
- drawNormalLegend(g, zoom);
- break;
- }
-
- //Draw neatline
- if (_drawNeatLine) {
- Rectangle.Float mapRect = new Rectangle.Float(_neatLineSize - 1, _neatLineSize - 1,
- (this.getWidth() - _neatLineSize) * zoom, (this.getHeight() - _neatLineSize) * zoom);
- g.setColor(_neatLineColor);
- g.setStroke(new BasicStroke(_neatLineSize));
- g.draw(mapRect);
- }
-
- g.setTransform(oldMatrix);
- }
-
- private void drawChartLegend(Graphics2D g, float zoom, PointF aPoint, boolean drawBreaks) {
- VectorLayer aLayer = (VectorLayer) _legendLayer;
- ChartBreak aCB = ((ChartBreak) aLayer.getChartPoints().get(0).getLegend()).getSampleChartBreak();
-
- //Draw chart symbol
- aPoint.X = 5;
- aPoint.Y += aCB.getHeight();
- switch (aCB.getChartType()) {
- case BarChart:
- Draw.drawBarChartSymbol(aPoint, aCB, g, true);
- break;
- case PieChart:
- if (this.drawChartBreaks) {
- Draw.drawPieChartSymbol(aPoint, aCB, g, null);
- } else {
- List rStrs = new ArrayList<>();
- for (int i = 0; i < aCB.getItemNum(); i++) {
- rStrs.add(aCB.getLegendScheme().getLegendBreaks().get(i).getCaption());
- }
- Draw.drawPieChartSymbol(aPoint, aCB, g, rStrs);
- }
- aPoint.Y += aCB.getHeight();
- break;
- }
- aPoint.Y += _breakSpace;
-
- //Draw breaks
- if (drawBreaks) {
- LegendScheme aLS = aCB.getLegendScheme();
- drawNormalLegend(g, zoom, aLS, aPoint, false);
- }
- }
-
- private void drawNormalLegend(Graphics2D g, float zoom) {
- boolean drawChart = false;
- if (_legendLayer.getLayerType() == LayerTypes.VectorLayer) {
- if (((VectorLayer) _legendLayer).getChartSet().isDrawCharts()) {
- drawChart = true;
- }
- }
-
- PointF aP = new PointF(0, 0);
-// if (!drawChart) {
-// LegendScheme aLS = _legendLayer.getLegendScheme();
-// drawNormalLegend(g, zoom, aLS, aP, true);
-// float height = getBreakHeight(g) * zoom;
-// aP.Y += height + _breakSpace;
-// }
-
- LegendScheme aLS = _legendLayer.getLegendScheme();
- drawNormalLegend(g, zoom, aLS, aP, true);
- float height = getBreakHeight(g) * zoom;
- aP.Y += height + _breakSpace;
-
- //Draw chart legend
- if (drawChart) {
- drawChartLegend(g, zoom, aP, this.drawChartBreaks);
- }
- }
-
- private void drawNormalLegend(Graphics2D g, float zoom, LegendScheme aLS, PointF aP, boolean drawTitle) {
- String caption = "";
- Dimension aSF;
- float leftSpace = _leftSpace * zoom;
- float topSpace = _topSpace * zoom;
- float breakSpace = _breakSpace * zoom;
- float height = getBreakHeight(g) * zoom;
- float width = height * 2;
- float colWidth = getBreakHeight(g) * 2 + getLabelWidth(g) + 10;
-
- //Draw title
- if (drawTitle) {
- Font tFont = new Font(_titleFont.getFontName(), _titleFont.getStyle(), (int) (_titleFont.getSize() * zoom));
- String Title = _title;
- aP.X = leftSpace;
- aP.Y = leftSpace;
- FontMetrics metrics = g.getFontMetrics(tFont);
- aSF = new Dimension(metrics.stringWidth(Title), metrics.getHeight());
- float titleHeight = aSF.height;
- g.setColor(this.getForeColor());
- g.setFont(tFont);
- g.drawString(_title, aP.X, aP.Y + aSF.height * 3 / 4);
- aP.Y += titleHeight + breakSpace - height / 2;
- }
-
- //Set columns
- int[] rowNums = new int[_columnNum];
- int ave = aLS.getVisibleBreakNum() / _columnNum;
- int num = 0;
- int i;
- for (i = 1; i < _columnNum; i++) {
- rowNums[i] = ave;
- num += ave;
- }
- rowNums[0] = aLS.getVisibleBreakNum() - num;
-
- //Draw legend
- Font lFont = new Font(this.getFont().getFontName(), this.getFont().getStyle(), (int) (this.getFont().getSize() * zoom));
- float sX = aP.X;
- float sY = aP.Y;
- i = 0;
- for (int col = 0; col < _columnNum; col++) {
- aP.X = width / 2 + leftSpace + col * colWidth;
- aP.Y = sY;
- for (int row = 0; row < rowNums[col]; row++) {
- if (!aLS.getLegendBreaks().get(i).isDrawShape()) {
- i += 1;
- row -= 1;
- continue;
- }
-
- aP.Y += height + breakSpace;
- //boolean isVisible = true;
- switch (aLS.getShapeType()) {
- case Point:
- PointBreak aPB = (PointBreak) ((PointBreak) aLS.getLegendBreaks().get(i)).clone();
- caption = aPB.getCaption();
- aPB.setSize(aPB.getSize() * zoom);
- Draw.drawPoint((PointF) aP.clone(), aPB, g);
- break;
- case Polyline:
- case PolylineZ:
- PolylineBreak aPLB = (PolylineBreak) aLS.getLegendBreaks().get(i);
- caption = aPLB.getCaption();
- Draw.drawPolylineSymbol((PointF) aP.clone(), width, height, aPLB, g);
- break;
- case Polygon:
- PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(i);
- caption = aPGB.getCaption();
- if (this.forceDrawOutline) {
- aPGB = (PolygonBreak) aPGB.clone();
- aPGB.setDrawOutline(true);
- }
- Draw.drawPolygonSymbol((PointF) aP.clone(), width, height, aPGB, g);
- break;
- case Image:
- ColorBreak aCB = aLS.getLegendBreaks().get(i);
- caption = aCB.getCaption();
- Draw.drawPolygonSymbol((PointF) aP.clone(), aCB.getColor(), Color.black, width,
- height, true, true, g);
- break;
- }
-
- PointF sP = new PointF(0, 0);
- sP.X = aP.X + width / 2;
- sP.Y = aP.Y;
- FontMetrics metrics = g.getFontMetrics(lFont);
- aSF = new Dimension(metrics.stringWidth(caption), metrics.getHeight());
- g.setColor(this.getForeColor());
- g.setFont(lFont);
- //g.drawString(caption, sP.X + 5, sP.Y + aSF.height / 3);
- g.drawString(caption, sP.X + 5, sP.Y + aSF.height / 4);
-
- i += 1;
- }
- }
- }
-
- /**
- * Update tick gap
- *
- * @param g Graphics2D
- */
- private int getTickGap(Graphics2D g) {
- double len;
- int n = this._legendLayer.getLegendScheme().getBreakNum();
- int nn;
- if (this.getLegendStyle() == LegendStyles.Bar_Horizontal) {
- len = this.getWidth();
- int labLen = this.getLabelWidth(g);
- nn = (int) ((len * 0.8) / labLen);
- } else {
- len = this.getHeight();
- FontMetrics metrics = g.getFontMetrics(this._font);
- nn = (int) (len / metrics.getHeight());
- }
- if (nn == 0) {
- nn = 1;
- }
- return n / nn + 1;
- }
-
- private void drawVerticalBarLegend(Graphics2D g, float zoom) {
- LegendScheme aLS = _legendLayer.getLegendScheme();
- PointF aP = new PointF(0, 0);
- PointF sP = new PointF(0, 0);
- boolean DrawShape = true, DrawFill = true, DrawOutline = true;
- Color FillColor = Color.red, OutlineColor = this.getForeColor();
- String caption = "";
- Dimension aSF;
-
- int bNum = aLS.getBreakNum();
- if (aLS.getLegendBreaks().get(bNum - 1).isNoData()) {
- bNum -= 1;
- }
-
- _vBarWidth = this.getWidth() - this.getLabelWidth(g) - 5;
- float width = _vBarWidth * zoom;
- float height = (this.getHeight() - 5) * zoom / bNum;
- Font lFont = new Font(this.getFont().getFontName(), this.getFont().getStyle(), (int) (this.getFont().getSize() * zoom));
-
- boolean order = true;
- if (aLS.getBreakNum() > 1) {
- try {
- double v1 = Double.parseDouble(aLS.getLegendBreaks().get(0).getEndValue().toString());
- double v2 = Double.parseDouble(aLS.getLegendBreaks().get(1).getEndValue().toString());
- if (v2 < v1) {
- order = false;
- }
- } catch (Exception e) {
-
- }
- }
-
- int idx;
- for (int i = 0; i < bNum; i++) {
- if (order) {
- idx = bNum - i - 1;
- } else {
- idx = i;
- }
- switch (aLS.getShapeType()) {
- case Point:
- PointBreak aPB = (PointBreak) aLS.getLegendBreaks().get(idx);
- DrawShape = aPB.isDrawShape();
- DrawFill = aPB.isDrawFill();
- FillColor = aPB.getColor();
- if (aLS.getLegendType() == LegendType.UniqueValue) {
- caption = aPB.getCaption();
- } else if (!order) {
- caption = DataConvert.removeTailingZeros(aPB.getEndValue().toString());
- } else {
- caption = DataConvert.removeTailingZeros(aPB.getStartValue().toString());
- }
- break;
- case Polyline:
- case PolylineZ:
- PolylineBreak aPLB = (PolylineBreak) aLS.getLegendBreaks().get(idx);
- DrawShape = aPLB.getDrawPolyline();
- FillColor = aPLB.getColor();
- if (aLS.getLegendType() == LegendType.UniqueValue) {
- caption = aPLB.getCaption();
- } else if (!order) {
- caption = DataConvert.removeTailingZeros(aPLB.getEndValue().toString());
- } else {
- caption = DataConvert.removeTailingZeros(aPLB.getStartValue().toString());
- }
- break;
- case Polygon:
- PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx);
- DrawShape = aPGB.isDrawShape();
- DrawFill = aPGB.isDrawFill();
- FillColor = aPGB.getColor();
- if (aLS.getLegendType() == LegendType.UniqueValue) {
- caption = aPGB.getCaption();
- } else if (!order) {
- caption = DataConvert.removeTailingZeros(aPGB.getEndValue().toString());
- } else {
- caption = DataConvert.removeTailingZeros(aPGB.getStartValue().toString());
- }
- break;
- case Image:
- ColorBreak aCB = aLS.getLegendBreaks().get(idx);
- DrawShape = true;
- DrawFill = true;
- FillColor = aCB.getColor();
- if (aLS.getLegendType() == LegendType.UniqueValue) {
- caption = aCB.getCaption();
- } else if (!order) {
- caption = DataConvert.removeTailingZeros(aCB.getEndValue().toString());
- } else {
- caption = DataConvert.removeTailingZeros(aCB.getStartValue().toString());
- }
- break;
- }
-
- aP.X = width / 2;
- aP.Y = i * height + height / 2;
-
- if (aLS.getLegendType() == LegendType.UniqueValue) {
- if (DrawShape) {
- if (aLS.getShapeType() == ShapeTypes.Polygon) {
- PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
- aPGB.setDrawOutline(true);
- aPGB.setOutlineColor(Color.black);
- Draw.drawPolygonSymbol((PointF) aP.clone(), width, height, aPGB, g);
- } else {
- Draw.drawPolygonSymbol((PointF) aP.clone(), FillColor, OutlineColor, width,
- height, DrawFill, DrawOutline, g);
- }
- }
-
- sP.X = aP.X + width / 2 + 5;
- sP.Y = aP.Y;
- FontMetrics metrics = g.getFontMetrics(lFont);
- aSF = new Dimension(metrics.stringWidth(caption), metrics.getHeight());
- g.setColor(this.getForeColor());
- g.setFont(lFont);
- g.drawString(caption, sP.X, sP.Y + aSF.height / 2);
- } else {
- if (DrawShape) {
- if (i == 0) {
- PointF[] Points = new PointF[4];
- Points[0] = new PointF();
- Points[0].X = aP.X;
- Points[0].Y = 0;
- Points[1] = new PointF();
- Points[1].X = 0;
- Points[1].Y = height;
- Points[2] = new PointF();
- Points[2].X = width;
- Points[2].Y = height;
- Points[3] = new PointF();
- Points[3].X = aP.X;
- Points[3].Y = 0;
- if (aLS.getShapeType() == ShapeTypes.Polygon) {
- PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
- aPGB.setDrawOutline(true);
- aPGB.setOutlineColor(Color.black);
- Draw.drawPolygon(Points, aPGB, g);
- } else {
- Draw.drawPolygon(Points, FillColor, OutlineColor, DrawFill, DrawOutline, g);
- }
- } else if (i == bNum - 1) {
- PointF[] Points = new PointF[4];
- Points[0] = new PointF();
- Points[0].X = 0;
- Points[0].Y = i * height;
- Points[1] = new PointF();
- Points[1].X = width;
- Points[1].Y = i * height;
- Points[2] = new PointF();
- Points[2].X = aP.X;
- Points[2].Y = i * height + height;
- Points[3] = new PointF();
- Points[3].X = 0;
- Points[3].Y = i * height;
- if (aLS.getShapeType() == ShapeTypes.Polygon) {
- PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
- aPGB.setDrawOutline(true);
- aPGB.setOutlineColor(Color.black);
- Draw.drawPolygon(Points, aPGB, g);
- } else {
- Draw.drawPolygon(Points, FillColor, OutlineColor, DrawFill, DrawOutline, g);
- }
- } else if (aLS.getShapeType() == ShapeTypes.Polygon) {
- PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
- aPGB.setDrawOutline(true);
- aPGB.setOutlineColor(Color.black);
- Draw.drawPolygonSymbol((PointF) aP.clone(), width, height, aPGB, g);
- } else {
- Draw.drawPolygonSymbol((PointF) aP.clone(), FillColor, OutlineColor, width,
- height, DrawFill, DrawOutline, g);
- }
- }
-
- sP.X = aP.X + width / 2 + 5;
- sP.Y = aP.Y + height / 2;
- if (i < bNum - 1) {
- FontMetrics metrics = g.getFontMetrics(lFont);
- aSF = new Dimension(metrics.stringWidth(caption), metrics.getHeight());
- g.setColor(this.getForeColor());
- g.setFont(lFont);
- g.drawString(caption, sP.X, sP.Y + aSF.height / 2);
- }
- }
- }
- }
-
- private void drawVerticalBarLegend_Ex(Graphics2D g, float zoom) {
- LegendScheme aLS = _legendLayer.getLegendScheme();
- PointF aP = new PointF(0, 0);
- PointF sP = new PointF(0, 0);
- boolean DrawShape = true, DrawFill = true, DrawOutline = false;
- Color FillColor = Color.red, OutlineColor = this.getForeColor();
- String caption;
- Dimension aSF;
-
- int bNum = aLS.getBreakNum();
- if (aLS.getLegendBreaks().get(bNum - 1).isNoData()) {
- bNum -= 1;
- }
-
- int tickGap = this.getTickGap(g);
- List labelIdxs = new ArrayList<>();
- int sIdx = (bNum % tickGap) / 2;
- int labNum = bNum - 1;
- if (aLS.getLegendType() == LegendType.UniqueValue) {
- labNum += 1;
- }
- while (sIdx < labNum) {
- labelIdxs.add(sIdx);
- sIdx += tickGap;
- }
-
- _vBarWidth = this.getWidth() - this.getLabelWidth(g) - 5;
- float width = _vBarWidth;
- //float width = _vBarWidth * zoom;
- _hBarHeight = (float) this.getHeight() / bNum;
- float height = _hBarHeight;
- //float height = (this.getHeight() - 5) * zoom / bNum;
- //Font lFont = new Font(this.getFont().getFontName(), this.getFont().getStyle(), (int) (this.getFont().getSize() * zoom));
-
- boolean order = true;
- if (aLS.getBreakNum() > 1) {
- try {
- double v1 = Double.parseDouble(aLS.getLegendBreaks().get(0).getEndValue().toString());
- double v2 = Double.parseDouble(aLS.getLegendBreaks().get(1).getEndValue().toString());
- if (v2 < v1) {
- order = false;
- }
- } catch (Exception e) {
-
- }
- }
- int idx;
- for (int i = 0; i < bNum; i++) {
- if (order) {
- idx = bNum - i - 1;
- } else {
- idx = i;
- }
- switch (aLS.getShapeType()) {
- case Point:
- PointBreak aPB = (PointBreak) aLS.getLegendBreaks().get(idx);
- DrawShape = aPB.isDrawShape();
- DrawFill = aPB.isDrawFill();
- FillColor = aPB.getColor();
- break;
- case Polyline:
- case PolylineZ:
- PolylineBreak aPLB = (PolylineBreak) aLS.getLegendBreaks().get(idx);
- DrawShape = aPLB.getDrawPolyline();
- FillColor = aPLB.getColor();
- break;
- case Polygon:
- PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx);
- DrawShape = aPGB.isDrawShape();
- DrawFill = aPGB.isDrawFill();
- FillColor = aPGB.getColor();
- break;
- case Image:
- ColorBreak aCB = aLS.getLegendBreaks().get(idx);
- DrawShape = true;
- DrawFill = true;
- FillColor = aCB.getColor();
- break;
- }
-
- aP.X = width / 2;
- aP.Y = i * height + height / 2;
-
- if (aLS.getLegendType() == LegendType.UniqueValue) {
- if (DrawShape) {
- if (aLS.getShapeType() == ShapeTypes.Polygon) {
- PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
- aPGB.setDrawOutline(DrawOutline);
- aPGB.setOutlineColor(Color.black);
- Draw.drawPolygonSymbol((PointF) aP.clone(), width, height, aPGB, g);
- } else {
- Draw.drawPolygonSymbol((PointF) aP.clone(), FillColor, OutlineColor, width,
- height, DrawFill, DrawOutline, g);
- }
- }
- } else if (DrawShape) {
- if (i == 0) {
- PointF[] Points = new PointF[4];
- Points[0] = new PointF();
- Points[0].X = aP.X;
- Points[0].Y = 0;
- Points[1] = new PointF();
- Points[1].X = 0;
- Points[1].Y = height;
- Points[2] = new PointF();
- Points[2].X = width;
- Points[2].Y = height;
- Points[3] = new PointF();
- Points[3].X = aP.X;
- Points[3].Y = 0;
- if (aLS.getShapeType() == ShapeTypes.Polygon) {
- PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
- aPGB.setDrawOutline(DrawOutline);
- aPGB.setOutlineColor(Color.black);
- Draw.drawPolygon(Points, aPGB, g);
- } else {
- Draw.drawPolygon(Points, FillColor, OutlineColor, DrawFill, DrawOutline, g);
- }
- } else if (i == bNum - 1) {
- PointF[] Points = new PointF[4];
- Points[0] = new PointF();
- Points[0].X = 0;
- Points[0].Y = i * height;
- Points[1] = new PointF();
- Points[1].X = width;
- Points[1].Y = i * height;
- Points[2] = new PointF();
- Points[2].X = aP.X;
- Points[2].Y = i * height + height;
- Points[3] = new PointF();
- Points[3].X = 0;
- Points[3].Y = i * height;
- if (aLS.getShapeType() == ShapeTypes.Polygon) {
- PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
- aPGB.setDrawOutline(DrawOutline);
- aPGB.setOutlineColor(Color.black);
- Draw.drawPolygon(Points, aPGB, g);
- } else {
- Draw.drawPolygon(Points, FillColor, OutlineColor, DrawFill, DrawOutline, g);
- }
- } else if (aLS.getShapeType() == ShapeTypes.Polygon) {
- PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
- aPGB.setDrawOutline(DrawOutline);
- aPGB.setOutlineColor(Color.black);
- Draw.drawPolygonSymbol((PointF) aP.clone(), width, height, aPGB, g);
- } else {
- Draw.drawPolygonSymbol((PointF) aP.clone(), FillColor, OutlineColor, width,
- height, DrawFill, DrawOutline, g);
- }
- }
- }
-
- //Draw neatline
- g.setColor(Color.black);
- if (aLS.getLegendType() == LegendType.UniqueValue) {
- g.draw(new Rectangle.Float(0, 0, this._vBarWidth, this._hBarHeight * bNum));
- } else {
- Polygon p = new Polygon();
- p.addPoint((int) (width / 2), 0);
- p.addPoint(0, (int) height);
- p.addPoint(0, (int) (height * (bNum - 1)));
- p.addPoint((int) (width / 2), (int) (height * bNum));
- p.addPoint((int) width, (int) (height * (bNum - 1)));
- p.addPoint((int) width, (int) height);
- g.drawPolygon(p);
- }
- //Draw ticks
- aP.Y = this.getHeight() + _hBarHeight / 2;
- int labLen = (int) (this._vBarWidth / 3);
- if (labLen < 5) {
- labLen = 5;
- if (this._vBarWidth < 5) {
- labLen = (int) this._vBarWidth;
- }
- }
-
- for (int i = 0; i < bNum; i++) {
- if (order) {
- idx = i;
- } else {
- idx = bNum - i - 1;
- }
- ColorBreak cb = aLS.getLegendBreaks().get(idx);
- if (aLS.getLegendType() == LegendType.UniqueValue) {
- caption = cb.getCaption();
- } else {
- caption = DataConvert.removeTailingZeros(cb.getEndValue().toString());
- }
-
- aP.X = _vBarWidth / 2;
- aP.Y = aP.Y - _hBarHeight;
-
- if (aLS.getLegendType() == LegendType.UniqueValue) {
- if (labelIdxs.contains(idx)) {
- sP.X = aP.X + _vBarWidth / 2 + 5;
- sP.Y = aP.Y;
- FontMetrics metrics = g.getFontMetrics(this._font);
- aSF = new Dimension(metrics.stringWidth(caption), metrics.getHeight());
- g.setColor(Color.black);
- g.setFont(this._font);
- //g.drawString(caption, sP.X, sP.Y + aSF.height / 4);
- Draw.drawString(g, caption, sP.X, sP.Y + aSF.height / 4);
- }
- } else if (labelIdxs.contains(idx)) {
- //g.setColor(Color.black);
- sP.X = aP.X + _vBarWidth / 2;
- sP.Y = aP.Y - _hBarHeight / 2;
- g.draw(new Line2D.Float(sP.X - labLen, sP.Y, sP.X, sP.Y));
- sP.X = sP.X + 5;
- if (i < bNum - 1) {
- FontMetrics metrics = g.getFontMetrics(this._font);
- aSF = new Dimension(metrics.stringWidth(caption), metrics.getHeight());
- g.setFont(this._font);
- //g.drawString(caption, sP.X, sP.Y + aSF.height / 4);
- Draw.drawString(g, caption, sP.X, sP.Y + aSF.height / 4);
- }
- }
- }
- }
-
- private void drawHorizontalBarLegend(Graphics2D g, float zoom) {
- LegendScheme aLS = _legendLayer.getLegendScheme();
- PointF aP = new PointF(0, 0);
- PointF sP = new PointF(0, 0);
- float width, height;
- boolean DrawShape = true, DrawFill = true, DrawOutline = true;
- Color FillColor = Color.red, OutlineColor = this.getForeColor();
- String caption = "";
- Dimension aSF;
-
- int bNum = aLS.getBreakNum();
- if (aLS.getLegendBreaks().get(bNum - 1).isNoData()) {
- bNum -= 1;
- }
-
- Font lFont = new Font(this.getFont().getFontName(), this.getFont().getStyle(), (int) (this.getFont().getSize() * zoom));
- FontMetrics metrics = g.getFontMetrics(lFont);
- _vBarWidth = this.getHeight() - metrics.getHeight() - 5;
- width = (this.getWidth() - 5) * zoom / bNum;
- height = _vBarWidth * zoom;
-
- for (int i = 0; i < bNum; i++) {
- switch (aLS.getShapeType()) {
- case Point:
- PointBreak aPB = (PointBreak) aLS.getLegendBreaks().get(i);
- DrawShape = aPB.isDrawShape();
- DrawFill = aPB.isDrawFill();
- FillColor = aPB.getColor();
- if (aLS.getLegendType() == LegendType.UniqueValue) {
- caption = aPB.getCaption();
- } else {
- caption = DataConvert.removeTailingZeros(aPB.getEndValue().toString());
- }
- break;
- case Polyline:
- case PolylineZ:
- PolylineBreak aPLB = (PolylineBreak) aLS.getLegendBreaks().get(i);
- DrawShape = aPLB.getDrawPolyline();
- FillColor = aPLB.getColor();
- if (aLS.getLegendType() == LegendType.UniqueValue) {
- caption = aPLB.getCaption();
- } else {
- caption = DataConvert.removeTailingZeros(aPLB.getEndValue().toString());
- }
- break;
- case Polygon:
- PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(i);
- DrawShape = aPGB.isDrawShape();
- DrawFill = aPGB.isDrawFill();
- FillColor = aPGB.getColor();
- if (aLS.getLegendType() == LegendType.UniqueValue) {
- caption = aPGB.getCaption();
- } else {
- caption = DataConvert.removeTailingZeros(aPGB.getEndValue().toString());
- }
- break;
- case Image:
- ColorBreak aCB = aLS.getLegendBreaks().get(i);
- DrawShape = true;
- DrawFill = true;
- FillColor = aCB.getColor();
- if (aLS.getLegendType() == LegendType.UniqueValue) {
- caption = aCB.getCaption();
- } else {
- caption = DataConvert.removeTailingZeros(aCB.getEndValue().toString());
- }
- break;
- }
-
- aP.X = i * width + width / 2;
- aP.Y = height / 2;
-
- if (aLS.getLegendType() == LegendType.UniqueValue) {
- if (DrawShape) {
- if (aLS.getShapeType() == ShapeTypes.Polygon) {
- PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(i).clone();
- aPGB.setDrawOutline(true);
- aPGB.setOutlineColor(Color.black);
- Draw.drawPolygonSymbol((PointF) aP.clone(), width, height, aPGB, g);
- } else {
- Draw.drawPolygonSymbol((PointF) aP.clone(), FillColor, OutlineColor, width,
- height, DrawFill, DrawOutline, g);
- }
- }
-
- sP.X = aP.X;
- sP.Y = aP.Y + height / 2;
- //FontMetrics metrics = g.getFontMetrics(lFont);
- aSF = new Dimension(metrics.stringWidth(caption), metrics.getHeight());
- g.setColor(this.getForeColor());
- g.setFont(lFont);
- g.drawString(caption, sP.X - aSF.width / 2, sP.Y + aSF.height);
- } else {
- if (DrawShape) {
- if (i == 0) {
- PointF[] Points = new PointF[4];
- Points[0] = new PointF();
- Points[0].X = 0;
- Points[0].Y = aP.Y;
- Points[1] = new PointF();
- Points[1].X = width;
- Points[1].Y = 0;
- Points[2] = new PointF();
- Points[2].X = width;
- Points[2].Y = height;
- Points[3] = new PointF();
- Points[3].X = 0;
- Points[3].Y = aP.Y;
- if (aLS.getShapeType() == ShapeTypes.Polygon) {
- PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(i).clone();
- aPGB.setDrawOutline(true);
- aPGB.setOutlineColor(Color.black);
- Draw.drawPolygon(Points, aPGB, g);
- } else {
- Draw.drawPolygon(Points, FillColor, OutlineColor, DrawFill, DrawOutline, g);
- }
- } else if (i == bNum - 1) {
- PointF[] Points = new PointF[4];
- Points[0] = new PointF();
- Points[0].X = i * width;
- Points[0].Y = height;
- Points[1] = new PointF();
- Points[1].X = i * width;
- Points[1].Y = 0;
- Points[2] = new PointF();
- Points[2].X = i * width + width;
- Points[2].Y = aP.Y;
- Points[3] = new PointF();
- Points[3].X = i * width;
- Points[3].Y = height;
- if (aLS.getShapeType() == ShapeTypes.Polygon) {
- PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(i).clone();
- aPGB.setDrawOutline(true);
- aPGB.setOutlineColor(Color.black);
- Draw.drawPolygon(Points, aPGB, g);
- } else {
- Draw.drawPolygon(Points, FillColor, OutlineColor, DrawFill, DrawOutline, g);
- }
- } else if (aLS.getShapeType() == ShapeTypes.Polygon) {
- PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(i).clone();
- aPGB.setDrawOutline(true);
- aPGB.setOutlineColor(Color.black);
- Draw.drawPolygonSymbol((PointF) aP.clone(), width, height, aPGB, g);
- } else {
- Draw.drawPolygonSymbol((PointF) aP.clone(), FillColor, OutlineColor, width,
- height, DrawFill, DrawOutline, g);
- }
- }
-
- sP.X = aP.X + width / 2;
- sP.Y = aP.Y + height / 2;
- if (i < bNum - 1) {
- //FontMetrics metrics = g.getFontMetrics(lFont);
- aSF = new Dimension(metrics.stringWidth(caption), metrics.getHeight());
- g.setColor(this.getForeColor());
- g.setFont(lFont);
- g.drawString(caption, sP.X - aSF.width / 2, sP.Y + aSF.height);
- }
- }
- }
- }
-
- private void drawHorizontalBarLegend_Ex(Graphics2D g, float zoom) {
- LegendScheme aLS = _legendLayer.getLegendScheme();
- PointF aP = new PointF(0, 0);
- PointF sP = new PointF(0, 0);
- float width, height;
- boolean DrawShape = true, DrawFill = true, DrawOutline = false;
- Color FillColor = Color.red, OutlineColor = this.getForeColor();
- String caption = "";
- Dimension aSF;
-
- int bNum = aLS.getBreakNum();
- if (aLS.getLegendBreaks().get(bNum - 1).isNoData()) {
- bNum -= 1;
- }
-
- int tickGap = this.getTickGap(g);
- List labelIdxs = new ArrayList<>();
- int sIdx = (bNum % tickGap) / 2;
- int labNum = bNum - 1;
- if (aLS.getLegendType() == LegendType.UniqueValue) {
- labNum += 1;
- }
- while (sIdx < labNum) {
- labelIdxs.add(sIdx);
- sIdx += tickGap;
- }
-
- Font lFont = new Font(this.getFont().getFontName(), this.getFont().getStyle(), (int) (this.getFont().getSize() * zoom));
- FontMetrics metrics = g.getFontMetrics(lFont);
- _vBarWidth = this.getHeight() - metrics.getHeight() - 5;
- //width = (this.getWidth() - 5) * zoom / bNum;
- width = this.getWidth() / bNum;
- //height = _vBarWidth * zoom;
- height = _vBarWidth;
- int idx;
- for (int i = 0; i < bNum; i++) {
- switch (aLS.getShapeType()) {
- case Point:
- PointBreak aPB = (PointBreak) aLS.getLegendBreaks().get(i);
- DrawShape = aPB.isDrawShape();
- DrawFill = aPB.isDrawFill();
- FillColor = aPB.getColor();
- break;
- case Polyline:
- case PolylineZ:
- PolylineBreak aPLB = (PolylineBreak) aLS.getLegendBreaks().get(i);
- DrawShape = aPLB.getDrawPolyline();
- FillColor = aPLB.getColor();
- break;
- case Polygon:
- PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(i);
- DrawShape = aPGB.isDrawShape();
- DrawFill = aPGB.isDrawFill();
- FillColor = aPGB.getColor();
- break;
- case Image:
- ColorBreak aCB = aLS.getLegendBreaks().get(i);
- DrawShape = true;
- DrawFill = true;
- FillColor = aCB.getColor();
- break;
- }
-
- aP.X = i * width + width / 2;
- aP.Y = height / 2;
-
- if (aLS.getLegendType() == LegendType.UniqueValue) {
- if (DrawShape) {
- if (aLS.getShapeType() == ShapeTypes.Polygon) {
- PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(i).clone();
- aPGB.setDrawOutline(DrawOutline);
- aPGB.setOutlineColor(Color.black);
- Draw.drawPolygonSymbol((PointF) aP.clone(), width, height, aPGB, g);
- } else {
- Draw.drawPolygonSymbol((PointF) aP.clone(), FillColor, OutlineColor, width,
- height, DrawFill, DrawOutline, g);
- }
- }
- } else if (DrawShape) {
- if (i == 0) {
- PointF[] Points = new PointF[4];
- Points[0] = new PointF();
- Points[0].X = 0;
- Points[0].Y = aP.Y;
- Points[1] = new PointF();
- Points[1].X = width;
- Points[1].Y = 0;
- Points[2] = new PointF();
- Points[2].X = width;
- Points[2].Y = height;
- Points[3] = new PointF();
- Points[3].X = 0;
- Points[3].Y = aP.Y;
- if (aLS.getShapeType() == ShapeTypes.Polygon) {
- PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(i).clone();
- aPGB.setDrawOutline(DrawOutline);
- aPGB.setOutlineColor(Color.black);
- Draw.drawPolygon(Points, aPGB, g);
- } else {
- Draw.drawPolygon(Points, FillColor, OutlineColor, DrawFill, DrawOutline, g);
- }
- } else if (i == bNum - 1) {
- PointF[] Points = new PointF[4];
- Points[0] = new PointF();
- Points[0].X = i * width;
- Points[0].Y = height;
- Points[1] = new PointF();
- Points[1].X = i * width;
- Points[1].Y = 0;
- Points[2] = new PointF();
- Points[2].X = i * width + width;
- Points[2].Y = aP.Y;
- Points[3] = new PointF();
- Points[3].X = i * width;
- Points[3].Y = height;
- if (aLS.getShapeType() == ShapeTypes.Polygon) {
- PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(i).clone();
- aPGB.setDrawOutline(DrawOutline);
- aPGB.setOutlineColor(Color.black);
- Draw.drawPolygon(Points, aPGB, g);
- } else {
- Draw.drawPolygon(Points, FillColor, OutlineColor, DrawFill, DrawOutline, g);
- }
- } else if (aLS.getShapeType() == ShapeTypes.Polygon) {
- PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(i).clone();
- aPGB.setDrawOutline(DrawOutline);
- aPGB.setOutlineColor(Color.black);
- Draw.drawPolygonSymbol((PointF) aP.clone(), width, height, aPGB, g);
- } else {
- Draw.drawPolygonSymbol((PointF) aP.clone(), FillColor, OutlineColor, width,
- height, DrawFill, DrawOutline, g);
- }
- }
- }
-
- //Draw neatline
- g.setColor(Color.black);
- if (aLS.getLegendType() == LegendType.UniqueValue) {
- g.draw(new Rectangle.Float(0, 0, width * bNum, height));
- } else {
- float extendw = width;
-// if (this.autoExtendFrac)
-// extendw = _hBarHeight;
- Polygon p = new Polygon();
- p.addPoint((int) (width - extendw), (int) (height / 2));
- p.addPoint((int) width, 0);
- p.addPoint((int) (width * (bNum - 1)), 0);
- p.addPoint((int) (width * (bNum - 1) + extendw), (int) (height / 2));
- p.addPoint((int) (width * (bNum - 1)), (int) height);
- p.addPoint((int) width, (int) height);
- g.drawPolygon(p);
- }
- //Draw tick and label
- aP.X = -_vBarWidth / 2;
- int labLen = (int) (this._hBarHeight / 3);
- if (labLen < 5) {
- labLen = 5;
- if (this._hBarHeight < 5) {
- labLen = (int) this._hBarHeight;
- }
- }
- for (int i = 0; i < bNum; i++) {
- idx = i;
- ColorBreak cb = aLS.getLegendBreaks().get(idx);
- if (aLS.getLegendType() == LegendType.UniqueValue) {
- caption = cb.getCaption();
- } else {
- caption = DataConvert.removeTailingZeros(cb.getEndValue().toString());
- }
-
- aP.X += width;
- aP.Y = height / 2;
-
- if (aLS.getLegendType() == LegendType.UniqueValue) {
- if (labelIdxs.contains(idx)) {
- sP.X = aP.X;
- sP.Y = aP.Y + height / 2 + 5;
- metrics = g.getFontMetrics(this._font);
- aSF = new Dimension(metrics.stringWidth(caption), metrics.getHeight());
- g.setColor(Color.black);
- g.setFont(this._font);
- //g.drawString(caption, sP.X, sP.Y + aSF.height / 4);
- Draw.drawString(g, caption, sP.X - aSF.width / 2, sP.Y + aSF.height * 3 / 4);
- }
- } else if (labelIdxs.contains(idx)) {
- //g.setColor(Color.black);
- sP.X = aP.X + _vBarWidth / 2;
- sP.Y = aP.Y + height / 2;
- g.draw(new Line2D.Float(sP.X, sP.Y, sP.X, sP.Y - labLen));
- sP.Y = sP.Y + 5;
- if (i < bNum - 1) {
- metrics = g.getFontMetrics(this._font);
- aSF = new Dimension(metrics.stringWidth(caption), metrics.getHeight());
- g.setFont(this._font);
- //g.drawString(caption, sP.X, sP.Y + aSF.height / 4);
- Draw.drawString(g, caption, sP.X - aSF.width / 2, sP.Y + aSF.height * 3 / 4);
- }
- }
- }
- }
-
- private int getLabelWidth(Graphics2D g) {
- LegendScheme aLS = _legendLayer.getLegendScheme();
- float width = 0;
- String caption = "";
- Dimension aSF;
- int bNum = aLS.getBreakNum();
- FontMetrics metrics = g.getFontMetrics(_font);
- if (_legendStyle == LegendStyles.Normal) {
- aSF = new Dimension(metrics.stringWidth(_title), metrics.getHeight());
- width = aSF.width;
- } else if (aLS.getLegendBreaks().get(bNum - 1).isNoData()) {
- bNum -= 1;
- }
- for (int i = 0; i < bNum; i++) {
- switch (aLS.getShapeType()) {
- case Point:
- PointBreak aPB = (PointBreak) aLS.getLegendBreaks().get(i);
- if (aLS.getLegendType() == LegendType.GraduatedColor && _legendStyle != LegendStyles.Normal) {
- caption = DataConvert.removeTailingZeros(aPB.getEndValue().toString());
- } else {
- caption = aPB.getCaption();
- }
- break;
- case Polyline:
- PolylineBreak aPLB = (PolylineBreak) aLS.getLegendBreaks().get(i);
- if (aLS.getLegendType() == LegendType.GraduatedColor && _legendStyle != LegendStyles.Normal) {
- caption = DataConvert.removeTailingZeros(aPLB.getEndValue().toString());
- } else {
- caption = aPLB.getCaption();
- }
- break;
- case Polygon:
- PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(i);
- if (aLS.getLegendType() == LegendType.GraduatedColor && _legendStyle != LegendStyles.Normal) {
- caption = DataConvert.removeTailingZeros(aPGB.getEndValue().toString());
- } else {
- caption = aPGB.getCaption();
- }
- break;
- case Image:
- ColorBreak aCB = aLS.getLegendBreaks().get(i);
- if (aLS.getLegendType() == LegendType.GraduatedColor && _legendStyle != LegendStyles.Normal) {
- caption = DataConvert.removeTailingZeros(aCB.getEndValue().toString());
- } else {
- caption = aCB.getCaption();
- }
- break;
- }
-
- boolean isValid = true;
- switch (aLS.getLegendType()) {
- case GraduatedColor:
- if (_legendStyle != LegendStyles.Normal) {
- if (i == bNum - 1) {
- isValid = false;
- }
- }
- break;
- }
- if (isValid) {
- float labwidth = metrics.stringWidth(caption);
- if (width < labwidth) {
- width = labwidth;
- }
- }
- }
-
- if (_legendStyle == LegendStyles.Normal) {
- if (_legendLayer.getLayerType() == LayerTypes.VectorLayer) {
- if (((VectorLayer) _legendLayer).getChartSet().isDrawCharts()) {
- ChartBreak aCB = ((ChartBreak) ((VectorLayer) _legendLayer).getChartPoints().get(0).getLegend()).getSampleChartBreak();
- if (aCB.getChartType() == ChartTypes.BarChart) {
- LegendScheme ls = aCB.getLegendScheme();
- for (ColorBreak cb : ls.getLegendBreaks()) {
- float labwidth = metrics.stringWidth(cb.getCaption());
- if (width < labwidth) {
- width = metrics.stringWidth(cb.getCaption());
- }
- }
- }
- }
- }
- }
-
- return (int) width;
- }
-
- private int getBreakHeight(Graphics2D g) {
- String title = _title;
- if ("".equals(title.trim())) {
- title = "Temp";
- }
-
- FontMetrics metrics = g.getFontMetrics(_font);
- Dimension aSF = new Dimension(metrics.stringWidth(title), metrics.getHeight());
- return aSF.height;
- }
-
- private int getTitleHeight(Graphics2D g) {
- FontMetrics metrics = g.getFontMetrics(_titleFont);
- Dimension aSF = new Dimension(metrics.stringWidth(_title), metrics.getHeight());
- return aSF.height;
- }
-
- /**
- * Update legend control size
- */
- public void updateLegendSize() {
- if (this._legendStyle != LegendStyles.Normal) {
- return;
- }
-
- if (_legendLayer != null) {
- if (_legendLayer.getLegendScheme() == null) {
- return;
- }
-
- //Graphics2D g = (Graphics2D) _mapLayout.getGraphics();
- BufferedImage image = new BufferedImage(_mapLayout.getPageBounds().width, _mapLayout.getPageBounds().height, BufferedImage.TYPE_INT_ARGB);
- Graphics2D g = image.createGraphics();
- int bNum = _legendLayer.getLegendScheme().getBreakNum();
- if (_legendLayer.getLegendScheme().getLegendBreaks().get(bNum - 1).isNoData()) {
- bNum -= 1;
- }
-
- int w = this.getWidth();
- int h = this.getHeight();
- int nw, nh;
- switch (_legendStyle) {
- case Bar_Vertical:
- nw = 10 + getLabelWidth(g) + 5;
- nh = bNum * 20;
- if (nw > w) {
- this.setWidth(nw);
- }
- if (nh > h) {
- this.setHeight(bNum * 20);
- }
- break;
- case Bar_Horizontal:
- nw = bNum * 30;
- nh = 30;
- if (nw > w) {
- this.setWidth(nw);
- }
- if (nh > h) {
- this.setHeight(bNum * 20);
- }
- break;
- case Normal:
- int aHeight = getBreakHeight(g);
- int colWidth = aHeight * 2 + getLabelWidth(g) + 15;
- this.setWidth(colWidth * _columnNum);
-
- //Set columns
- int[] rowNums = new int[_columnNum];
- int ave = _legendLayer.getLegendScheme().getVisibleBreakNum() / _columnNum;
- int num = 0;
- int i;
- for (i = 1; i < _columnNum; i++) {
- rowNums[i] = ave;
- num += ave;
- }
- rowNums[0] = _legendLayer.getLegendScheme().getVisibleBreakNum() - num;
-
- this.setHeight((int) (rowNums[0] * (aHeight + _breakSpace)
- + getTitleHeight(g) + _breakSpace * 2 + aHeight / 2 + 5));
- if (_legendLayer.getLayerType() == LayerTypes.VectorLayer) {
- VectorLayer aLayer = (VectorLayer) _legendLayer;
- if (aLayer.getChartSet().isDrawCharts()) {
- ChartBreak aCB = ((ChartBreak) aLayer.getChartPoints().get(0).getLegend()).getSampleChartBreak();
- this.setHeight(this.getHeight() + (int) (_breakSpace * 2 + aCB.getHeight()
- + aCB.getLegendScheme().getBreakNum() * (aHeight + _breakSpace) + aHeight / 2 + 5));
- }
- }
- break;
- }
- }
- }
-
- @Override
- public void paint(Graphics2D g) {
- //throw new UnsupportedOperationException("Not supported yet.");
- }
-
- @Override
- public void paintOnLayout(Graphics2D g, PointF pageLocation, float zoom) {
- if (this.isVisible()) {
- paintGraphics(g, pageLocation, zoom);
- }
- }
-
- @Override
- public void moveUpdate() {
- }
-
- @Override
- public void resizeUpdate() {
- }
-
- /**
- * Get layer names
- *
- * @return Layer names
- */
- public static List getLayerNames() {
- List layerNames = new ArrayList<>();
- for (MapLayer aLayer : _layoutMap.getMapFrame().getMapView().getLayers()) {
- if (aLayer.getLayerType() == LayerTypes.VectorLayer || aLayer.getLayerType() == LayerTypes.RasterLayer) {
- layerNames.add(aLayer.getLayerName());
- }
- }
-
- return layerNames;
- }
- //
-
- //
- public class LayoutLegendBean {
-
- LayoutLegendBean() {
- }
-
- //
- /**
- * Get layout map
- *
- * @return The layout map
- */
- public LayoutMap getLayoutMap() {
- return _layoutMap;
- }
-
- /**
- * Get legend layer
- *
- * @return The legend alyer
- */
- public MapLayer getLegendLayer() {
- return _legendLayer;
- }
-
- /**
- * Set legend layer
- *
- * @param layer The legend layer
- */
- public void setLegendLayer(MapLayer layer) {
- _legendLayer = layer;
- String aStr = _legendLayer.getLayerName();
- if (aStr.contains("_")) {
- aStr = aStr.split("_")[1];
- }
- _title = aStr;
- updateLegendSize();
- }
-
- /**
- * Get legend layer name
- *
- * @return Legend layer name
- */
- public String getLayerName() {
- if (_legendLayer != null) {
- return _legendLayer.getLayerName();
- } else {
- return null;
- }
- }
-
- /**
- * Set legend layer name
- *
- * @param name Layer name
- */
- public void setLayerName(String name) {
- MapLayer aLayer = _layoutMap.getMapFrame().getMapView().getLayer(name);
- if (aLayer != null) {
- this.setLegendLayer(aLayer);
- }
- }
-
- /**
- * Get if force to draw polygon outline - for normal legend
- *
- * @return Boolean
- */
- public boolean isForceDrawOutline() {
- return forceDrawOutline;
- }
-
- /**
- * Set if force to draw polygon outline - for normal legend
- *
- * @param value Boolean
- */
- public void setForceDrawOutline(boolean value) {
- forceDrawOutline = value;
- }
-
- /**
- * Get layer update type string
- *
- * @return Layer update type string
- */
- public String getLayerUpdateType() {
- return _layerUpdateType.toString();
- }
-
- /**
- * Set layer update type
- *
- * @param typeStr Layer update type string
- */
- public void setLayerUpdateType(String typeStr) {
- _layerUpdateType = LayerUpdateTypes.valueOf(typeStr);
- }
-
- /**
- * Get legend style string
- *
- * @return Legend style string
- */
- public String getLegendStyle() {
- return _legendStyle.toString();
- }
-
- /**
- * Set legend style
- *
- * @param style Legend style string
- */
- public void setLegendStyle(String style) {
- _legendStyle = LegendStyles.valueOf(style);
- if (isVisible()) {
- updateLegendSize();
- }
- }
-
- /**
- * Get title
- *
- * @return The title
- */
- public String getTitle() {
- return _title;
- }
-
- /**
- * Set title
- *
- * @param title The title
- */
- public void setTitle(String title) {
- _title = title;
- updateLegendSize();
- }
-
- /**
- * Get if draw neat line
- *
- * @return If draw neat line
- */
- public boolean isDrawNeatLine() {
- return _drawNeatLine;
- }
-
- /**
- * Set if draw neat line
- *
- * @param istrue If draw neat line
- */
- public void setDrawNeatLine(boolean istrue) {
- _drawNeatLine = istrue;
- }
-
- /**
- * Get neat line color
- *
- * @return Neat line color
- */
- public Color getNeatLineColor() {
- return _neatLineColor;
- }
-
- /**
- * Set neat line color
- *
- * @param color Neat line color
- */
- public void setNeatLineColor(Color color) {
- _neatLineColor = color;
- }
-
- /**
- * Get neat line size
- *
- * @return Neat line size
- */
- public float getNeatLineSize() {
- return _neatLineSize;
- }
-
- /**
- * Set neat line size
- *
- * @param size Neat line size
- */
- public void setNeatLineSize(float size) {
- _neatLineSize = size;
- }
-
- /**
- * Get font
- *
- * @return The font
- */
- public Font getFont() {
- return _font;
- }
-
- /**
- * Set font
- *
- * @param font The font
- */
- public void setFont(Font font) {
- _font = font;
- _titleFont = new Font(_font.getFontName(), Font.PLAIN, _font.getSize() + 2);
- updateLegendSize();
- }
-
- /**
- * Get column number
- *
- * @return Column number
- */
- public int getColumnNumber() {
- return _columnNum;
- }
-
- /**
- * Set column number
- *
- * @param value Column number
- */
- public void setColumnNumber(int value) {
- _columnNum = value;
- if (isVisible()) {
- updateLegendSize();
- }
- }
-
- /**
- * Get is draw chart breaks
- *
- * @return Boolean
- */
- public boolean isDrawChartBreaks() {
- return drawChartBreaks;
- }
-
- /**
- * Set if draw chart breaks
- *
- * @param value Boolean
- */
- public void setDrawChartBreaks(boolean value) {
- drawChartBreaks = value;
- }
-
- /**
- * Get is draw backcolor
- *
- * @return Boolean
- */
- public boolean isDrawBackColor() {
- return LayoutLegend.this.isDrawBackColor();
- }
-
- /**
- * Set is draw backcolor
- *
- * @param value Boolean
- */
- public void setDrawBackColor(boolean value) {
- LayoutLegend.this.setDrawBackColor(value);
- }
-
- /**
- * Get background color
- *
- * @return Background color
- */
- public Color getBackColor() {
- return LayoutLegend.this.getBackColor();
- }
-
- /**
- * Set background color
- *
- * @param c Background color
- */
- public void setBackColor(Color c) {
- LayoutLegend.this.setBackColor(c);
- }
-
- /**
- * Get foreground color
- *
- * @return Foreground color
- */
- public Color getForeColor() {
- return LayoutLegend.this.getForeColor();
- }
-
- /**
- * Set foreground color
- *
- * @param c Foreground color
- */
- public void setForeColor(Color c) {
- LayoutLegend.this.setForeColor(c);
- }
-
- /**
- * Get left
- *
- * @return Left
- */
- public int getLeft() {
- return LayoutLegend.this.getLeft();
- }
-
- /**
- * Set left
- *
- * @param left Left
- */
- public void setLeft(int left) {
- LayoutLegend.this.setLeft(left);
- }
-
- /**
- * Get top
- *
- * @return Top
- */
- public int getTop() {
- return LayoutLegend.this.getTop();
- }
-
- /**
- * Set top
- *
- * @param top Top
- */
- public void setTop(int top) {
- LayoutLegend.this.setTop(top);
- }
-
- /**
- * Get width
- *
- * @return Width
- */
- public int getWidth() {
- return LayoutLegend.this.getWidth();
- }
-
- /**
- * Set width
- *
- * @param value Width
- */
- public void setWidth(int value) {
- LayoutLegend.this.setWidth(value);
- }
-
- /**
- * Get height
- *
- * @return Height
- */
- public int getHeight() {
- return LayoutLegend.this.getHeight();
- }
-
- /**
- * Set height
- *
- * @param value Height
- */
- public void setHeight(int value) {
- LayoutLegend.this.setHeight(value);
- }
-
- /**
- * Get bar width
- *
- * @return Bar width
- */
- public float getBarWidth() {
- return LayoutLegend.this._vBarWidth;
- }
-
- /**
- * Set bar width
- *
- * @param value Bar width
- */
- public void setBarWidth(float value) {
- LayoutLegend.this._vBarWidth = value;
- }
- //
- }
-
- public static class LayoutLegendBeanBeanInfo extends BaseBeanInfo {
-
- public LayoutLegendBeanBeanInfo() {
- super(LayoutLegendBean.class);
- ExtendedPropertyDescriptor e = addProperty("layerName");
- e.setCategory("General").setPropertyEditorClass(LayerNameEditor.class);
- e.setDisplayName("Layer Name");
- e.setShortDescription("The name of the layer of this legend");
- e = addProperty("layerUpdateType");
- e.setCategory("General").setDisplayName("Layer Update Type");
- e.setPropertyEditorClass(LayerUpdateTypeEditor.class);
- e = addProperty("legendStyle");
- e.setCategory("General").setDisplayName("Legend Style");
- e.setPropertyEditorClass(LegendStyleEditor.class);
- addProperty("title").setCategory("General").setDisplayName("Title");
- addProperty("font").setCategory("General").setDisplayName("Font");
- addProperty("drawBackColor").setCategory("General").setDisplayName("Draw Background");
- addProperty("backColor").setCategory("General").setDisplayName("Background");
- addProperty("foreColor").setCategory("General").setDisplayName("Foreground");
- addProperty("columnNumber").setCategory("General").setDisplayName("Column Number");
- addProperty("forceDrawOutline").setCategory("General").setDisplayName("Force Draw Outline");
- addProperty("drawNeatLine").setCategory("Neat Line").setDisplayName("Draw Neat Line");
- addProperty("neatLineColor").setCategory("Neat Line").setDisplayName("Neat Line Color");
- addProperty("neatLineSize").setCategory("Neat Line").setDisplayName("Neat Line Size");
- addProperty("drawChartBreaks").setCategory("Chart").setDisplayName("Draw Chart Breaks");
- //addProperty("drawPieLabel").setCategory("Chart").setDisplayName("Draw Pie label");
- addProperty("left").setCategory("Location").setDisplayName("Left");
- addProperty("top").setCategory("Location").setDisplayName("Top");
- addProperty("width").setCategory("Location").setDisplayName("Width");
- addProperty("height").setCategory("Location").setDisplayName("Height");
- //addProperty("barWidth").setCategory("ColorBar").setDisplayName("Bar Width");
- }
- }
-
- public static class LayerNameEditor extends ComboBoxPropertyEditor {
-
- public LayerNameEditor() {
- super();
- String[] names = (String[]) getLayerNames().toArray(new String[0]);
- setAvailableValues(names);
-// Icon[] icons = new Icon[4];
-// Arrays.fill(icons, UIManager.getIcon("Tree.openIcon"));
-// setAvailableIcons(icons);
- }
- }
-
- public static class LayerUpdateTypeEditor extends ComboBoxPropertyEditor {
-
- public LayerUpdateTypeEditor() {
- super();
- LayerUpdateTypes[] lutypes = LayerUpdateTypes.values();
- String[] types = new String[lutypes.length];
- int i = 0;
- for (LayerUpdateTypes type : lutypes) {
- types[i] = type.toString();
- i += 1;
- }
- setAvailableValues(types);
- }
- }
-
- public static class LegendStyleEditor extends ComboBoxPropertyEditor {
-
- public LegendStyleEditor() {
- super();
- LegendStyles[] styles = LegendStyles.values();
- String[] values = new String[styles.length];
- int i = 0;
- for (LegendStyles s : styles) {
- values[i] = s.toString();
- i += 1;
- }
- setAvailableValues(values);
- }
- }
- //
-}
+/* Copyright 2012 Yaqiang Wang,
+ * yaqiang.wang@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ */
+package org.meteoinfo.layout;
+
+import org.meteoinfo.common.PointF;
+import org.meteoinfo.drawing.Draw;
+import org.meteoinfo.global.event.IMapViewUpdatedListener;
+import org.meteoinfo.global.event.MapViewUpdatedEvent;
+import org.meteoinfo.layer.LayerDrawType;
+import org.meteoinfo.layer.LayerTypes;
+import org.meteoinfo.layer.MapLayer;
+import org.meteoinfo.layer.VectorLayer;
+import org.meteoinfo.legend.ChartBreak;
+import org.meteoinfo.legend.ColorBreak;
+import org.meteoinfo.legend.LegendScheme;
+import org.meteoinfo.legend.LegendType;
+import org.meteoinfo.legend.PointBreak;
+import org.meteoinfo.legend.PolygonBreak;
+import org.meteoinfo.legend.PolylineBreak;
+import org.meteoinfo.shape.ShapeTypes;
+import com.l2fprod.common.beans.BaseBeanInfo;
+import com.l2fprod.common.beans.ExtendedPropertyDescriptor;
+import com.l2fprod.common.beans.editor.ComboBoxPropertyEditor;
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics2D;
+import java.awt.Polygon;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Line2D;
+import java.awt.image.BufferedImage;
+import java.util.ArrayList;
+import java.util.List;
+import org.meteoinfo.global.DataConvert;
+import org.meteoinfo.legend.ChartTypes;
+
+/**
+ *
+ * @author Yaqiang Wang
+ */
+public class LayoutLegend extends LayoutElement {
+ //
+
+ private MapLayout _mapLayout;
+ private static LayoutMap _layoutMap;
+ private MapLayer _legendLayer;
+ private boolean forceDrawOutline;
+ private boolean _isAntiAlias;
+ private LayerUpdateTypes _layerUpdateType;
+ private LegendStyles _legendStyle;
+ private String _title;
+ private Font _font;
+ private Font _titleFont;
+ private boolean _drawNeatLine;
+ private Color _neatLineColor;
+ private float _neatLineSize;
+ private float _breakSpace;
+ private float _topSpace;
+ private float _leftSpace;
+ private float _vBarWidth;
+ private float _hBarHeight;
+ private int _columnNum = 1;
+ private boolean drawChartBreaks = true;
+ private boolean drawPieLabel = false;
+ //
+ //
+
+ /**
+ * Constructor
+ *
+ * @param mapLayout Map layout
+ * @param layoutMap Layout map
+ */
+ public LayoutLegend(MapLayout mapLayout, LayoutMap layoutMap) {
+ super();
+ this.setElementType(ElementType.LayoutLegend);
+ this.setResizeAbility(ResizeAbility.ResizeAll);
+
+ _mapLayout = mapLayout;
+ _layoutMap = layoutMap;
+ _layoutMap.addMapViewUpdatedListener(new IMapViewUpdatedListener() {
+ @Override
+ public void mapViewUpdatedEvent(MapViewUpdatedEvent event) {
+ onMapViewUpdated(event);
+ }
+ });
+ _isAntiAlias = true;
+ this.forceDrawOutline = true;
+ _layerUpdateType = LayerUpdateTypes.FirstMeteoLayer;
+ _legendStyle = LegendStyles.Normal;
+ _title = "";
+ _drawNeatLine = false;
+ _neatLineColor = Color.black;
+ _neatLineSize = 1;
+ _breakSpace = 3;
+ _topSpace = 5;
+ _leftSpace = 5;
+ _vBarWidth = 10;
+ _hBarHeight = 10;
+ _font = new Font("宋体", Font.PLAIN, 12);
+ _titleFont = new Font("Arial", Font.PLAIN, 12);
+ }
+
+ //
+ //
+ public void onMapViewUpdated(MapViewUpdatedEvent e) {
+ if (_layoutMap.getMapFrame().getMapView().getLayerNum() == 0) {
+ return;
+ }
+
+ switch (_layerUpdateType) {
+ case FirstExpandedLayer:
+ for (int i = 0; i < _layoutMap.getMapFrame().getMapView().getLayerNum(); i++) {
+ MapLayer aLayer = _layoutMap.getMapFrame().getMapView().getLayers().
+ get(_layoutMap.getMapFrame().getMapView().getLayerNum() - 1 - i);
+ if (aLayer.hasLegendScheme()) {
+ if (aLayer.isVisible() && aLayer.isExpanded() && aLayer.getLegendScheme().getLegendType() != LegendType.SingleSymbol) {
+ this.setVisible(true);
+ this.setLegendLayer(aLayer);
+ break;
+ }
+ }
+ }
+ break;
+ case FirstMeteoLayer:
+ for (int i = 0; i < _layoutMap.getMapFrame().getMapView().getLayerNum(); i++) {
+ MapLayer aLayer = _layoutMap.getMapFrame().getMapView().getLayers().
+ get(_layoutMap.getMapFrame().getMapView().getLayerNum() - 1 - i);
+ if (aLayer.hasLegendScheme()) {
+ if (aLayer.isVisible() && aLayer.getLayerDrawType() != LayerDrawType.Map
+ && aLayer.getLegendScheme().getLegendType() != LegendType.SingleSymbol) {
+ this.setVisible(true);
+ this.setLegendLayer(aLayer);
+ break;
+ }
+ }
+ }
+ break;
+ case LastAddedLayer:
+ if (_layoutMap.getMapFrame().getMapView().getLastAddedLayer().hasLegendScheme()) {
+ this.setVisible(true);
+ this.setLegendLayer(_layoutMap.getMapFrame().getMapView().getLastAddedLayer());
+ }
+ break;
+ }
+
+ updateLegendSize();
+ }
+ //
+ //
+
+ /**
+ * Get layout map
+ *
+ * @return The layout map
+ */
+ public LayoutMap getLayoutMap() {
+ return _layoutMap;
+ }
+
+ /**
+ * Get legend layer
+ *
+ * @return The legend alyer
+ */
+ public MapLayer getLegendLayer() {
+ return _legendLayer;
+ }
+
+ /**
+ * Set legend layer
+ *
+ * @param layer The legend layer
+ */
+ public void setLegendLayer(MapLayer layer) {
+ if (layer == null) {
+ return;
+ }
+
+ _legendLayer = layer;
+ String aStr = _legendLayer.getLayerName();
+ if (aStr.contains("_")) {
+ aStr = aStr.split("_")[1];
+ }
+ _title = aStr;
+ updateLegendSize();
+ }
+
+ /**
+ * Get legend layer name
+ *
+ * @return Legend layer name
+ */
+ public String getLayerName() {
+ if (_legendLayer != null) {
+ return _legendLayer.getLayerName();
+ } else {
+ return "";
+ }
+ }
+
+ /**
+ * Set legend layer name
+ *
+ * @param name Layer name
+ */
+ public void setLayerName(String name) {
+ MapLayer aLayer = _layoutMap.getMapFrame().getMapView().getLayer(name);
+ if (aLayer != null) {
+ _legendLayer = aLayer;
+ }
+ }
+
+ /**
+ * Get if force to draw polygon outline - for normal legend
+ *
+ * @return Boolean
+ */
+ public boolean isForceDrawOutline() {
+ return this.forceDrawOutline;
+ }
+
+ /**
+ * Set if force to draw polygon outline - for normal legend
+ *
+ * @param value Boolean
+ */
+ public void setForceDrawOutline(boolean value) {
+ this.forceDrawOutline = value;
+ }
+
+ /**
+ * Get layer update type
+ *
+ * @return Layer update type
+ */
+ public LayerUpdateTypes getLayerUpdateType() {
+ return _layerUpdateType;
+ }
+
+ /**
+ * Set layer update type
+ *
+ * @param type Layer update type
+ */
+ public void setLayerUpdateType(LayerUpdateTypes type) {
+ _layerUpdateType = type;
+ }
+
+ /**
+ * Get legend style
+ *
+ * @return Legend style
+ */
+ public LegendStyles getLegendStyle() {
+ return _legendStyle;
+ }
+
+ /**
+ * Set legend style
+ *
+ * @param style Legend style
+ */
+ public void setLegendStyle(LegendStyles style) {
+ _legendStyle = style;
+ if (this.isVisible()) {
+ updateLegendSize();
+ }
+ }
+
+ /**
+ * Get title
+ *
+ * @return The title
+ */
+ public String getTitle() {
+ return _title;
+ }
+
+ /**
+ * Set title
+ *
+ * @param title The title
+ */
+ public void setTitle(String title) {
+ _title = title;
+ updateLegendSize();
+ }
+
+ /**
+ * Get if draw neat line
+ *
+ * @return If draw neat line
+ */
+ public boolean isDrawNeatLine() {
+ return _drawNeatLine;
+ }
+
+ /**
+ * Set if draw neat line
+ *
+ * @param istrue If draw neat line
+ */
+ public void setDrawNeatLine(boolean istrue) {
+ _drawNeatLine = istrue;
+ }
+
+ /**
+ * Get neat line color
+ *
+ * @return Neat line color
+ */
+ public Color getNeatLineColor() {
+ return _neatLineColor;
+ }
+
+ /**
+ * Set neat line color
+ *
+ * @param color Neat line color
+ */
+ public void setNeatLineColor(Color color) {
+ _neatLineColor = color;
+ }
+
+ /**
+ * Get neat line size
+ *
+ * @return Neat line size
+ */
+ public float getNeatLineSize() {
+ return _neatLineSize;
+ }
+
+ /**
+ * Set neat line size
+ *
+ * @param size Neat line size
+ */
+ public void setNeatLineSize(float size) {
+ _neatLineSize = size;
+ }
+
+ /**
+ * Get font
+ *
+ * @return The font
+ */
+ public Font getFont() {
+ return _font;
+ }
+
+ /**
+ * Set font
+ *
+ * @param font The font
+ */
+ public void setFont(Font font) {
+ _font = font;
+ _titleFont = new Font(_font.getFontName(), Font.PLAIN, _font.getSize() + 2);
+ updateLegendSize();
+ }
+
+ /**
+ * Get column number
+ *
+ * @return Column number
+ */
+ public int getColumnNumber() {
+ return _columnNum;
+ }
+
+ /**
+ * Set column number
+ *
+ * @param value Column number
+ */
+ public void setColumnNumber(int value) {
+ _columnNum = value;
+ }
+
+ /**
+ * Get if draw chart breaks
+ *
+ * @return Boolean
+ */
+ public boolean isDrawChartBreaks() {
+ return this.drawChartBreaks;
+ }
+
+ /**
+ * Set if draw chart breaks
+ *
+ * @param value Boolean
+ */
+ public void setDrawChartBreaks(boolean value) {
+ this.drawChartBreaks = value;
+ }
+
+ /**
+ * Get if draw pie label
+ *
+ * @return Boolean
+ */
+ public boolean isDrawPieLabel() {
+ return this.drawPieLabel;
+ }
+
+ /**
+ * Set if draw pie label
+ *
+ * @param value Boolean
+ */
+ public void setDrawPieLabel(boolean value) {
+ this.drawPieLabel = value;
+ }
+
+ //
+ //
+ /**
+ * Paint graphics
+ *
+ * @param g Graphics2D
+ * @param pageLocation Page location
+ * @param zoom Zoom
+ */
+ public void paintGraphics(Graphics2D g, PointF pageLocation, float zoom) {
+ if (_legendLayer == null) {
+ return;
+ }
+
+ if (_legendLayer.getLayerType() == LayerTypes.ImageLayer) {
+ return;
+ }
+
+ AffineTransform oldMatrix = g.getTransform();
+ PointF aP = pageToScreen(this.getLeft(), this.getTop(), pageLocation, zoom);
+ g.translate(aP.X, aP.Y);
+ g.scale(zoom, zoom);
+ if (this._isAntiAlias) {
+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ } else {
+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
+ }
+
+ //Draw background color
+ if (this.isDrawBackColor()) {
+ g.setColor(this.getBackColor());
+ g.fill(new Rectangle.Float(0, 0, this.getWidth() * zoom, this.getHeight() * zoom));
+ }
+
+ int gap = this.getTickGap(g);
+ switch (_legendStyle) {
+ case Bar_Horizontal:
+ if (gap > 1) {
+ drawHorizontalBarLegend_Ex(g, zoom);
+ } else {
+ drawHorizontalBarLegend(g, zoom);
+ }
+ break;
+ case Bar_Vertical:
+ if (gap > 1) {
+ drawVerticalBarLegend_Ex(g, zoom);
+ } else {
+ drawVerticalBarLegend(g, zoom);
+ }
+ break;
+ case Normal:
+ drawNormalLegend(g, zoom);
+ break;
+ }
+
+ //Draw neatline
+ if (_drawNeatLine) {
+ Rectangle.Float mapRect = new Rectangle.Float(_neatLineSize - 1, _neatLineSize - 1,
+ (this.getWidth() - _neatLineSize) * zoom, (this.getHeight() - _neatLineSize) * zoom);
+ g.setColor(_neatLineColor);
+ g.setStroke(new BasicStroke(_neatLineSize));
+ g.draw(mapRect);
+ }
+
+ g.setTransform(oldMatrix);
+ }
+
+ private void drawChartLegend(Graphics2D g, float zoom, PointF aPoint, boolean drawBreaks) {
+ VectorLayer aLayer = (VectorLayer) _legendLayer;
+ ChartBreak aCB = ((ChartBreak) aLayer.getChartPoints().get(0).getLegend()).getSampleChartBreak();
+
+ //Draw chart symbol
+ aPoint.X = 5;
+ aPoint.Y += aCB.getHeight();
+ switch (aCB.getChartType()) {
+ case BarChart:
+ Draw.drawBarChartSymbol(aPoint, aCB, g, true);
+ break;
+ case PieChart:
+ if (this.drawChartBreaks) {
+ Draw.drawPieChartSymbol(aPoint, aCB, g, null);
+ } else {
+ List rStrs = new ArrayList<>();
+ for (int i = 0; i < aCB.getItemNum(); i++) {
+ rStrs.add(aCB.getLegendScheme().getLegendBreaks().get(i).getCaption());
+ }
+ Draw.drawPieChartSymbol(aPoint, aCB, g, rStrs);
+ }
+ aPoint.Y += aCB.getHeight();
+ break;
+ }
+ aPoint.Y += _breakSpace;
+
+ //Draw breaks
+ if (drawBreaks) {
+ LegendScheme aLS = aCB.getLegendScheme();
+ drawNormalLegend(g, zoom, aLS, aPoint, false);
+ }
+ }
+
+ private void drawNormalLegend(Graphics2D g, float zoom) {
+ boolean drawChart = false;
+ if (_legendLayer.getLayerType() == LayerTypes.VectorLayer) {
+ if (((VectorLayer) _legendLayer).getChartSet().isDrawCharts()) {
+ drawChart = true;
+ }
+ }
+
+ PointF aP = new PointF(0, 0);
+// if (!drawChart) {
+// LegendScheme aLS = _legendLayer.getLegendScheme();
+// drawNormalLegend(g, zoom, aLS, aP, true);
+// float height = getBreakHeight(g) * zoom;
+// aP.Y += height + _breakSpace;
+// }
+
+ LegendScheme aLS = _legendLayer.getLegendScheme();
+ drawNormalLegend(g, zoom, aLS, aP, true);
+ float height = getBreakHeight(g) * zoom;
+ aP.Y += height + _breakSpace;
+
+ //Draw chart legend
+ if (drawChart) {
+ drawChartLegend(g, zoom, aP, this.drawChartBreaks);
+ }
+ }
+
+ private void drawNormalLegend(Graphics2D g, float zoom, LegendScheme aLS, PointF aP, boolean drawTitle) {
+ String caption = "";
+ Dimension aSF;
+ float leftSpace = _leftSpace * zoom;
+ float topSpace = _topSpace * zoom;
+ float breakSpace = _breakSpace * zoom;
+ float height = getBreakHeight(g) * zoom;
+ float width = height * 2;
+ float colWidth = getBreakHeight(g) * 2 + getLabelWidth(g) + 10;
+
+ //Draw title
+ if (drawTitle) {
+ Font tFont = new Font(_titleFont.getFontName(), _titleFont.getStyle(), (int) (_titleFont.getSize() * zoom));
+ String Title = _title;
+ aP.X = leftSpace;
+ aP.Y = leftSpace;
+ FontMetrics metrics = g.getFontMetrics(tFont);
+ aSF = new Dimension(metrics.stringWidth(Title), metrics.getHeight());
+ float titleHeight = aSF.height;
+ g.setColor(this.getForeColor());
+ g.setFont(tFont);
+ g.drawString(_title, aP.X, aP.Y + aSF.height * 3 / 4);
+ aP.Y += titleHeight + breakSpace - height / 2;
+ }
+
+ //Set columns
+ int[] rowNums = new int[_columnNum];
+ int ave = aLS.getVisibleBreakNum() / _columnNum;
+ int num = 0;
+ int i;
+ for (i = 1; i < _columnNum; i++) {
+ rowNums[i] = ave;
+ num += ave;
+ }
+ rowNums[0] = aLS.getVisibleBreakNum() - num;
+
+ //Draw legend
+ Font lFont = new Font(this.getFont().getFontName(), this.getFont().getStyle(), (int) (this.getFont().getSize() * zoom));
+ float sX = aP.X;
+ float sY = aP.Y;
+ i = 0;
+ for (int col = 0; col < _columnNum; col++) {
+ aP.X = width / 2 + leftSpace + col * colWidth;
+ aP.Y = sY;
+ for (int row = 0; row < rowNums[col]; row++) {
+ if (!aLS.getLegendBreaks().get(i).isDrawShape()) {
+ i += 1;
+ row -= 1;
+ continue;
+ }
+
+ aP.Y += height + breakSpace;
+ //boolean isVisible = true;
+ switch (aLS.getShapeType()) {
+ case Point:
+ PointBreak aPB = (PointBreak) ((PointBreak) aLS.getLegendBreaks().get(i)).clone();
+ caption = aPB.getCaption();
+ aPB.setSize(aPB.getSize() * zoom);
+ Draw.drawPoint((PointF) aP.clone(), aPB, g);
+ break;
+ case Polyline:
+ case PolylineZ:
+ PolylineBreak aPLB = (PolylineBreak) aLS.getLegendBreaks().get(i);
+ caption = aPLB.getCaption();
+ Draw.drawPolylineSymbol((PointF) aP.clone(), width, height, aPLB, g);
+ break;
+ case Polygon:
+ PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(i);
+ caption = aPGB.getCaption();
+ if (this.forceDrawOutline) {
+ aPGB = (PolygonBreak) aPGB.clone();
+ aPGB.setDrawOutline(true);
+ }
+ Draw.drawPolygonSymbol((PointF) aP.clone(), width, height, aPGB, g);
+ break;
+ case Image:
+ ColorBreak aCB = aLS.getLegendBreaks().get(i);
+ caption = aCB.getCaption();
+ Draw.drawPolygonSymbol((PointF) aP.clone(), aCB.getColor(), Color.black, width,
+ height, true, true, g);
+ break;
+ }
+
+ PointF sP = new PointF(0, 0);
+ sP.X = aP.X + width / 2;
+ sP.Y = aP.Y;
+ FontMetrics metrics = g.getFontMetrics(lFont);
+ aSF = new Dimension(metrics.stringWidth(caption), metrics.getHeight());
+ g.setColor(this.getForeColor());
+ g.setFont(lFont);
+ //g.drawString(caption, sP.X + 5, sP.Y + aSF.height / 3);
+ g.drawString(caption, sP.X + 5, sP.Y + aSF.height / 4);
+
+ i += 1;
+ }
+ }
+ }
+
+ /**
+ * Update tick gap
+ *
+ * @param g Graphics2D
+ */
+ private int getTickGap(Graphics2D g) {
+ double len;
+ int n = this._legendLayer.getLegendScheme().getBreakNum();
+ int nn;
+ if (this.getLegendStyle() == LegendStyles.Bar_Horizontal) {
+ len = this.getWidth();
+ int labLen = this.getLabelWidth(g);
+ nn = (int) ((len * 0.8) / labLen);
+ } else {
+ len = this.getHeight();
+ FontMetrics metrics = g.getFontMetrics(this._font);
+ nn = (int) (len / metrics.getHeight());
+ }
+ if (nn == 0) {
+ nn = 1;
+ }
+ return n / nn + 1;
+ }
+
+ private void drawVerticalBarLegend(Graphics2D g, float zoom) {
+ LegendScheme aLS = _legendLayer.getLegendScheme();
+ PointF aP = new PointF(0, 0);
+ PointF sP = new PointF(0, 0);
+ boolean DrawShape = true, DrawFill = true, DrawOutline = true;
+ Color FillColor = Color.red, OutlineColor = this.getForeColor();
+ String caption = "";
+ Dimension aSF;
+
+ int bNum = aLS.getBreakNum();
+ if (aLS.getLegendBreaks().get(bNum - 1).isNoData()) {
+ bNum -= 1;
+ }
+
+ _vBarWidth = this.getWidth() - this.getLabelWidth(g) - 5;
+ float width = _vBarWidth * zoom;
+ float height = (this.getHeight() - 5) * zoom / bNum;
+ Font lFont = new Font(this.getFont().getFontName(), this.getFont().getStyle(), (int) (this.getFont().getSize() * zoom));
+
+ boolean order = true;
+ if (aLS.getBreakNum() > 1) {
+ try {
+ double v1 = Double.parseDouble(aLS.getLegendBreaks().get(0).getEndValue().toString());
+ double v2 = Double.parseDouble(aLS.getLegendBreaks().get(1).getEndValue().toString());
+ if (v2 < v1) {
+ order = false;
+ }
+ } catch (Exception e) {
+
+ }
+ }
+
+ int idx;
+ for (int i = 0; i < bNum; i++) {
+ if (order) {
+ idx = bNum - i - 1;
+ } else {
+ idx = i;
+ }
+ switch (aLS.getShapeType()) {
+ case Point:
+ PointBreak aPB = (PointBreak) aLS.getLegendBreaks().get(idx);
+ DrawShape = aPB.isDrawShape();
+ DrawFill = aPB.isDrawFill();
+ FillColor = aPB.getColor();
+ if (aLS.getLegendType() == LegendType.UniqueValue) {
+ caption = aPB.getCaption();
+ } else if (!order) {
+ caption = DataConvert.removeTailingZeros(aPB.getEndValue().toString());
+ } else {
+ caption = DataConvert.removeTailingZeros(aPB.getStartValue().toString());
+ }
+ break;
+ case Polyline:
+ case PolylineZ:
+ PolylineBreak aPLB = (PolylineBreak) aLS.getLegendBreaks().get(idx);
+ DrawShape = aPLB.getDrawPolyline();
+ FillColor = aPLB.getColor();
+ if (aLS.getLegendType() == LegendType.UniqueValue) {
+ caption = aPLB.getCaption();
+ } else if (!order) {
+ caption = DataConvert.removeTailingZeros(aPLB.getEndValue().toString());
+ } else {
+ caption = DataConvert.removeTailingZeros(aPLB.getStartValue().toString());
+ }
+ break;
+ case Polygon:
+ PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx);
+ DrawShape = aPGB.isDrawShape();
+ DrawFill = aPGB.isDrawFill();
+ FillColor = aPGB.getColor();
+ if (aLS.getLegendType() == LegendType.UniqueValue) {
+ caption = aPGB.getCaption();
+ } else if (!order) {
+ caption = DataConvert.removeTailingZeros(aPGB.getEndValue().toString());
+ } else {
+ caption = DataConvert.removeTailingZeros(aPGB.getStartValue().toString());
+ }
+ break;
+ case Image:
+ ColorBreak aCB = aLS.getLegendBreaks().get(idx);
+ DrawShape = true;
+ DrawFill = true;
+ FillColor = aCB.getColor();
+ if (aLS.getLegendType() == LegendType.UniqueValue) {
+ caption = aCB.getCaption();
+ } else if (!order) {
+ caption = DataConvert.removeTailingZeros(aCB.getEndValue().toString());
+ } else {
+ caption = DataConvert.removeTailingZeros(aCB.getStartValue().toString());
+ }
+ break;
+ }
+
+ aP.X = width / 2;
+ aP.Y = i * height + height / 2;
+
+ if (aLS.getLegendType() == LegendType.UniqueValue) {
+ if (DrawShape) {
+ if (aLS.getShapeType() == ShapeTypes.Polygon) {
+ PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
+ aPGB.setDrawOutline(true);
+ aPGB.setOutlineColor(Color.black);
+ Draw.drawPolygonSymbol((PointF) aP.clone(), width, height, aPGB, g);
+ } else {
+ Draw.drawPolygonSymbol((PointF) aP.clone(), FillColor, OutlineColor, width,
+ height, DrawFill, DrawOutline, g);
+ }
+ }
+
+ sP.X = aP.X + width / 2 + 5;
+ sP.Y = aP.Y;
+ FontMetrics metrics = g.getFontMetrics(lFont);
+ aSF = new Dimension(metrics.stringWidth(caption), metrics.getHeight());
+ g.setColor(this.getForeColor());
+ g.setFont(lFont);
+ g.drawString(caption, sP.X, sP.Y + aSF.height / 2);
+ } else {
+ if (DrawShape) {
+ if (i == 0) {
+ PointF[] Points = new PointF[4];
+ Points[0] = new PointF();
+ Points[0].X = aP.X;
+ Points[0].Y = 0;
+ Points[1] = new PointF();
+ Points[1].X = 0;
+ Points[1].Y = height;
+ Points[2] = new PointF();
+ Points[2].X = width;
+ Points[2].Y = height;
+ Points[3] = new PointF();
+ Points[3].X = aP.X;
+ Points[3].Y = 0;
+ if (aLS.getShapeType() == ShapeTypes.Polygon) {
+ PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
+ aPGB.setDrawOutline(true);
+ aPGB.setOutlineColor(Color.black);
+ Draw.drawPolygon(Points, aPGB, g);
+ } else {
+ Draw.drawPolygon(Points, FillColor, OutlineColor, DrawFill, DrawOutline, g);
+ }
+ } else if (i == bNum - 1) {
+ PointF[] Points = new PointF[4];
+ Points[0] = new PointF();
+ Points[0].X = 0;
+ Points[0].Y = i * height;
+ Points[1] = new PointF();
+ Points[1].X = width;
+ Points[1].Y = i * height;
+ Points[2] = new PointF();
+ Points[2].X = aP.X;
+ Points[2].Y = i * height + height;
+ Points[3] = new PointF();
+ Points[3].X = 0;
+ Points[3].Y = i * height;
+ if (aLS.getShapeType() == ShapeTypes.Polygon) {
+ PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
+ aPGB.setDrawOutline(true);
+ aPGB.setOutlineColor(Color.black);
+ Draw.drawPolygon(Points, aPGB, g);
+ } else {
+ Draw.drawPolygon(Points, FillColor, OutlineColor, DrawFill, DrawOutline, g);
+ }
+ } else if (aLS.getShapeType() == ShapeTypes.Polygon) {
+ PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
+ aPGB.setDrawOutline(true);
+ aPGB.setOutlineColor(Color.black);
+ Draw.drawPolygonSymbol((PointF) aP.clone(), width, height, aPGB, g);
+ } else {
+ Draw.drawPolygonSymbol((PointF) aP.clone(), FillColor, OutlineColor, width,
+ height, DrawFill, DrawOutline, g);
+ }
+ }
+
+ sP.X = aP.X + width / 2 + 5;
+ sP.Y = aP.Y + height / 2;
+ if (i < bNum - 1) {
+ FontMetrics metrics = g.getFontMetrics(lFont);
+ aSF = new Dimension(metrics.stringWidth(caption), metrics.getHeight());
+ g.setColor(this.getForeColor());
+ g.setFont(lFont);
+ g.drawString(caption, sP.X, sP.Y + aSF.height / 2);
+ }
+ }
+ }
+ }
+
+ private void drawVerticalBarLegend_Ex(Graphics2D g, float zoom) {
+ LegendScheme aLS = _legendLayer.getLegendScheme();
+ PointF aP = new PointF(0, 0);
+ PointF sP = new PointF(0, 0);
+ boolean DrawShape = true, DrawFill = true, DrawOutline = false;
+ Color FillColor = Color.red, OutlineColor = this.getForeColor();
+ String caption;
+ Dimension aSF;
+
+ int bNum = aLS.getBreakNum();
+ if (aLS.getLegendBreaks().get(bNum - 1).isNoData()) {
+ bNum -= 1;
+ }
+
+ int tickGap = this.getTickGap(g);
+ List labelIdxs = new ArrayList<>();
+ int sIdx = (bNum % tickGap) / 2;
+ int labNum = bNum - 1;
+ if (aLS.getLegendType() == LegendType.UniqueValue) {
+ labNum += 1;
+ }
+ while (sIdx < labNum) {
+ labelIdxs.add(sIdx);
+ sIdx += tickGap;
+ }
+
+ _vBarWidth = this.getWidth() - this.getLabelWidth(g) - 5;
+ float width = _vBarWidth;
+ //float width = _vBarWidth * zoom;
+ _hBarHeight = (float) this.getHeight() / bNum;
+ float height = _hBarHeight;
+ //float height = (this.getHeight() - 5) * zoom / bNum;
+ //Font lFont = new Font(this.getFont().getFontName(), this.getFont().getStyle(), (int) (this.getFont().getSize() * zoom));
+
+ boolean order = true;
+ if (aLS.getBreakNum() > 1) {
+ try {
+ double v1 = Double.parseDouble(aLS.getLegendBreaks().get(0).getEndValue().toString());
+ double v2 = Double.parseDouble(aLS.getLegendBreaks().get(1).getEndValue().toString());
+ if (v2 < v1) {
+ order = false;
+ }
+ } catch (Exception e) {
+
+ }
+ }
+ int idx;
+ for (int i = 0; i < bNum; i++) {
+ if (order) {
+ idx = bNum - i - 1;
+ } else {
+ idx = i;
+ }
+ switch (aLS.getShapeType()) {
+ case Point:
+ PointBreak aPB = (PointBreak) aLS.getLegendBreaks().get(idx);
+ DrawShape = aPB.isDrawShape();
+ DrawFill = aPB.isDrawFill();
+ FillColor = aPB.getColor();
+ break;
+ case Polyline:
+ case PolylineZ:
+ PolylineBreak aPLB = (PolylineBreak) aLS.getLegendBreaks().get(idx);
+ DrawShape = aPLB.getDrawPolyline();
+ FillColor = aPLB.getColor();
+ break;
+ case Polygon:
+ PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx);
+ DrawShape = aPGB.isDrawShape();
+ DrawFill = aPGB.isDrawFill();
+ FillColor = aPGB.getColor();
+ break;
+ case Image:
+ ColorBreak aCB = aLS.getLegendBreaks().get(idx);
+ DrawShape = true;
+ DrawFill = true;
+ FillColor = aCB.getColor();
+ break;
+ }
+
+ aP.X = width / 2;
+ aP.Y = i * height + height / 2;
+
+ if (aLS.getLegendType() == LegendType.UniqueValue) {
+ if (DrawShape) {
+ if (aLS.getShapeType() == ShapeTypes.Polygon) {
+ PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
+ aPGB.setDrawOutline(DrawOutline);
+ aPGB.setOutlineColor(Color.black);
+ Draw.drawPolygonSymbol((PointF) aP.clone(), width, height, aPGB, g);
+ } else {
+ Draw.drawPolygonSymbol((PointF) aP.clone(), FillColor, OutlineColor, width,
+ height, DrawFill, DrawOutline, g);
+ }
+ }
+ } else if (DrawShape) {
+ if (i == 0) {
+ PointF[] Points = new PointF[4];
+ Points[0] = new PointF();
+ Points[0].X = aP.X;
+ Points[0].Y = 0;
+ Points[1] = new PointF();
+ Points[1].X = 0;
+ Points[1].Y = height;
+ Points[2] = new PointF();
+ Points[2].X = width;
+ Points[2].Y = height;
+ Points[3] = new PointF();
+ Points[3].X = aP.X;
+ Points[3].Y = 0;
+ if (aLS.getShapeType() == ShapeTypes.Polygon) {
+ PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
+ aPGB.setDrawOutline(DrawOutline);
+ aPGB.setOutlineColor(Color.black);
+ Draw.drawPolygon(Points, aPGB, g);
+ } else {
+ Draw.drawPolygon(Points, FillColor, OutlineColor, DrawFill, DrawOutline, g);
+ }
+ } else if (i == bNum - 1) {
+ PointF[] Points = new PointF[4];
+ Points[0] = new PointF();
+ Points[0].X = 0;
+ Points[0].Y = i * height;
+ Points[1] = new PointF();
+ Points[1].X = width;
+ Points[1].Y = i * height;
+ Points[2] = new PointF();
+ Points[2].X = aP.X;
+ Points[2].Y = i * height + height;
+ Points[3] = new PointF();
+ Points[3].X = 0;
+ Points[3].Y = i * height;
+ if (aLS.getShapeType() == ShapeTypes.Polygon) {
+ PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
+ aPGB.setDrawOutline(DrawOutline);
+ aPGB.setOutlineColor(Color.black);
+ Draw.drawPolygon(Points, aPGB, g);
+ } else {
+ Draw.drawPolygon(Points, FillColor, OutlineColor, DrawFill, DrawOutline, g);
+ }
+ } else if (aLS.getShapeType() == ShapeTypes.Polygon) {
+ PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(idx).clone();
+ aPGB.setDrawOutline(DrawOutline);
+ aPGB.setOutlineColor(Color.black);
+ Draw.drawPolygonSymbol((PointF) aP.clone(), width, height, aPGB, g);
+ } else {
+ Draw.drawPolygonSymbol((PointF) aP.clone(), FillColor, OutlineColor, width,
+ height, DrawFill, DrawOutline, g);
+ }
+ }
+ }
+
+ //Draw neatline
+ g.setColor(Color.black);
+ if (aLS.getLegendType() == LegendType.UniqueValue) {
+ g.draw(new Rectangle.Float(0, 0, this._vBarWidth, this._hBarHeight * bNum));
+ } else {
+ Polygon p = new Polygon();
+ p.addPoint((int) (width / 2), 0);
+ p.addPoint(0, (int) height);
+ p.addPoint(0, (int) (height * (bNum - 1)));
+ p.addPoint((int) (width / 2), (int) (height * bNum));
+ p.addPoint((int) width, (int) (height * (bNum - 1)));
+ p.addPoint((int) width, (int) height);
+ g.drawPolygon(p);
+ }
+ //Draw ticks
+ aP.Y = this.getHeight() + _hBarHeight / 2;
+ int labLen = (int) (this._vBarWidth / 3);
+ if (labLen < 5) {
+ labLen = 5;
+ if (this._vBarWidth < 5) {
+ labLen = (int) this._vBarWidth;
+ }
+ }
+
+ for (int i = 0; i < bNum; i++) {
+ if (order) {
+ idx = i;
+ } else {
+ idx = bNum - i - 1;
+ }
+ ColorBreak cb = aLS.getLegendBreaks().get(idx);
+ if (aLS.getLegendType() == LegendType.UniqueValue) {
+ caption = cb.getCaption();
+ } else {
+ caption = DataConvert.removeTailingZeros(cb.getEndValue().toString());
+ }
+
+ aP.X = _vBarWidth / 2;
+ aP.Y = aP.Y - _hBarHeight;
+
+ if (aLS.getLegendType() == LegendType.UniqueValue) {
+ if (labelIdxs.contains(idx)) {
+ sP.X = aP.X + _vBarWidth / 2 + 5;
+ sP.Y = aP.Y;
+ FontMetrics metrics = g.getFontMetrics(this._font);
+ aSF = new Dimension(metrics.stringWidth(caption), metrics.getHeight());
+ g.setColor(Color.black);
+ g.setFont(this._font);
+ //g.drawString(caption, sP.X, sP.Y + aSF.height / 4);
+ Draw.drawString(g, caption, sP.X, sP.Y + aSF.height / 4);
+ }
+ } else if (labelIdxs.contains(idx)) {
+ //g.setColor(Color.black);
+ sP.X = aP.X + _vBarWidth / 2;
+ sP.Y = aP.Y - _hBarHeight / 2;
+ g.draw(new Line2D.Float(sP.X - labLen, sP.Y, sP.X, sP.Y));
+ sP.X = sP.X + 5;
+ if (i < bNum - 1) {
+ FontMetrics metrics = g.getFontMetrics(this._font);
+ aSF = new Dimension(metrics.stringWidth(caption), metrics.getHeight());
+ g.setFont(this._font);
+ //g.drawString(caption, sP.X, sP.Y + aSF.height / 4);
+ Draw.drawString(g, caption, sP.X, sP.Y + aSF.height / 4);
+ }
+ }
+ }
+ }
+
+ private void drawHorizontalBarLegend(Graphics2D g, float zoom) {
+ LegendScheme aLS = _legendLayer.getLegendScheme();
+ PointF aP = new PointF(0, 0);
+ PointF sP = new PointF(0, 0);
+ float width, height;
+ boolean DrawShape = true, DrawFill = true, DrawOutline = true;
+ Color FillColor = Color.red, OutlineColor = this.getForeColor();
+ String caption = "";
+ Dimension aSF;
+
+ int bNum = aLS.getBreakNum();
+ if (aLS.getLegendBreaks().get(bNum - 1).isNoData()) {
+ bNum -= 1;
+ }
+
+ Font lFont = new Font(this.getFont().getFontName(), this.getFont().getStyle(), (int) (this.getFont().getSize() * zoom));
+ FontMetrics metrics = g.getFontMetrics(lFont);
+ _vBarWidth = this.getHeight() - metrics.getHeight() - 5;
+ width = (this.getWidth() - 5) * zoom / bNum;
+ height = _vBarWidth * zoom;
+
+ for (int i = 0; i < bNum; i++) {
+ switch (aLS.getShapeType()) {
+ case Point:
+ PointBreak aPB = (PointBreak) aLS.getLegendBreaks().get(i);
+ DrawShape = aPB.isDrawShape();
+ DrawFill = aPB.isDrawFill();
+ FillColor = aPB.getColor();
+ if (aLS.getLegendType() == LegendType.UniqueValue) {
+ caption = aPB.getCaption();
+ } else {
+ caption = DataConvert.removeTailingZeros(aPB.getEndValue().toString());
+ }
+ break;
+ case Polyline:
+ case PolylineZ:
+ PolylineBreak aPLB = (PolylineBreak) aLS.getLegendBreaks().get(i);
+ DrawShape = aPLB.getDrawPolyline();
+ FillColor = aPLB.getColor();
+ if (aLS.getLegendType() == LegendType.UniqueValue) {
+ caption = aPLB.getCaption();
+ } else {
+ caption = DataConvert.removeTailingZeros(aPLB.getEndValue().toString());
+ }
+ break;
+ case Polygon:
+ PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(i);
+ DrawShape = aPGB.isDrawShape();
+ DrawFill = aPGB.isDrawFill();
+ FillColor = aPGB.getColor();
+ if (aLS.getLegendType() == LegendType.UniqueValue) {
+ caption = aPGB.getCaption();
+ } else {
+ caption = DataConvert.removeTailingZeros(aPGB.getEndValue().toString());
+ }
+ break;
+ case Image:
+ ColorBreak aCB = aLS.getLegendBreaks().get(i);
+ DrawShape = true;
+ DrawFill = true;
+ FillColor = aCB.getColor();
+ if (aLS.getLegendType() == LegendType.UniqueValue) {
+ caption = aCB.getCaption();
+ } else {
+ caption = DataConvert.removeTailingZeros(aCB.getEndValue().toString());
+ }
+ break;
+ }
+
+ aP.X = i * width + width / 2;
+ aP.Y = height / 2;
+
+ if (aLS.getLegendType() == LegendType.UniqueValue) {
+ if (DrawShape) {
+ if (aLS.getShapeType() == ShapeTypes.Polygon) {
+ PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(i).clone();
+ aPGB.setDrawOutline(true);
+ aPGB.setOutlineColor(Color.black);
+ Draw.drawPolygonSymbol((PointF) aP.clone(), width, height, aPGB, g);
+ } else {
+ Draw.drawPolygonSymbol((PointF) aP.clone(), FillColor, OutlineColor, width,
+ height, DrawFill, DrawOutline, g);
+ }
+ }
+
+ sP.X = aP.X;
+ sP.Y = aP.Y + height / 2;
+ //FontMetrics metrics = g.getFontMetrics(lFont);
+ aSF = new Dimension(metrics.stringWidth(caption), metrics.getHeight());
+ g.setColor(this.getForeColor());
+ g.setFont(lFont);
+ g.drawString(caption, sP.X - aSF.width / 2, sP.Y + aSF.height);
+ } else {
+ if (DrawShape) {
+ if (i == 0) {
+ PointF[] Points = new PointF[4];
+ Points[0] = new PointF();
+ Points[0].X = 0;
+ Points[0].Y = aP.Y;
+ Points[1] = new PointF();
+ Points[1].X = width;
+ Points[1].Y = 0;
+ Points[2] = new PointF();
+ Points[2].X = width;
+ Points[2].Y = height;
+ Points[3] = new PointF();
+ Points[3].X = 0;
+ Points[3].Y = aP.Y;
+ if (aLS.getShapeType() == ShapeTypes.Polygon) {
+ PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(i).clone();
+ aPGB.setDrawOutline(true);
+ aPGB.setOutlineColor(Color.black);
+ Draw.drawPolygon(Points, aPGB, g);
+ } else {
+ Draw.drawPolygon(Points, FillColor, OutlineColor, DrawFill, DrawOutline, g);
+ }
+ } else if (i == bNum - 1) {
+ PointF[] Points = new PointF[4];
+ Points[0] = new PointF();
+ Points[0].X = i * width;
+ Points[0].Y = height;
+ Points[1] = new PointF();
+ Points[1].X = i * width;
+ Points[1].Y = 0;
+ Points[2] = new PointF();
+ Points[2].X = i * width + width;
+ Points[2].Y = aP.Y;
+ Points[3] = new PointF();
+ Points[3].X = i * width;
+ Points[3].Y = height;
+ if (aLS.getShapeType() == ShapeTypes.Polygon) {
+ PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(i).clone();
+ aPGB.setDrawOutline(true);
+ aPGB.setOutlineColor(Color.black);
+ Draw.drawPolygon(Points, aPGB, g);
+ } else {
+ Draw.drawPolygon(Points, FillColor, OutlineColor, DrawFill, DrawOutline, g);
+ }
+ } else if (aLS.getShapeType() == ShapeTypes.Polygon) {
+ PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(i).clone();
+ aPGB.setDrawOutline(true);
+ aPGB.setOutlineColor(Color.black);
+ Draw.drawPolygonSymbol((PointF) aP.clone(), width, height, aPGB, g);
+ } else {
+ Draw.drawPolygonSymbol((PointF) aP.clone(), FillColor, OutlineColor, width,
+ height, DrawFill, DrawOutline, g);
+ }
+ }
+
+ sP.X = aP.X + width / 2;
+ sP.Y = aP.Y + height / 2;
+ if (i < bNum - 1) {
+ //FontMetrics metrics = g.getFontMetrics(lFont);
+ aSF = new Dimension(metrics.stringWidth(caption), metrics.getHeight());
+ g.setColor(this.getForeColor());
+ g.setFont(lFont);
+ g.drawString(caption, sP.X - aSF.width / 2, sP.Y + aSF.height);
+ }
+ }
+ }
+ }
+
+ private void drawHorizontalBarLegend_Ex(Graphics2D g, float zoom) {
+ LegendScheme aLS = _legendLayer.getLegendScheme();
+ PointF aP = new PointF(0, 0);
+ PointF sP = new PointF(0, 0);
+ float width, height;
+ boolean DrawShape = true, DrawFill = true, DrawOutline = false;
+ Color FillColor = Color.red, OutlineColor = this.getForeColor();
+ String caption = "";
+ Dimension aSF;
+
+ int bNum = aLS.getBreakNum();
+ if (aLS.getLegendBreaks().get(bNum - 1).isNoData()) {
+ bNum -= 1;
+ }
+
+ int tickGap = this.getTickGap(g);
+ List labelIdxs = new ArrayList<>();
+ int sIdx = (bNum % tickGap) / 2;
+ int labNum = bNum - 1;
+ if (aLS.getLegendType() == LegendType.UniqueValue) {
+ labNum += 1;
+ }
+ while (sIdx < labNum) {
+ labelIdxs.add(sIdx);
+ sIdx += tickGap;
+ }
+
+ Font lFont = new Font(this.getFont().getFontName(), this.getFont().getStyle(), (int) (this.getFont().getSize() * zoom));
+ FontMetrics metrics = g.getFontMetrics(lFont);
+ _vBarWidth = this.getHeight() - metrics.getHeight() - 5;
+ //width = (this.getWidth() - 5) * zoom / bNum;
+ width = this.getWidth() / bNum;
+ //height = _vBarWidth * zoom;
+ height = _vBarWidth;
+ int idx;
+ for (int i = 0; i < bNum; i++) {
+ switch (aLS.getShapeType()) {
+ case Point:
+ PointBreak aPB = (PointBreak) aLS.getLegendBreaks().get(i);
+ DrawShape = aPB.isDrawShape();
+ DrawFill = aPB.isDrawFill();
+ FillColor = aPB.getColor();
+ break;
+ case Polyline:
+ case PolylineZ:
+ PolylineBreak aPLB = (PolylineBreak) aLS.getLegendBreaks().get(i);
+ DrawShape = aPLB.getDrawPolyline();
+ FillColor = aPLB.getColor();
+ break;
+ case Polygon:
+ PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(i);
+ DrawShape = aPGB.isDrawShape();
+ DrawFill = aPGB.isDrawFill();
+ FillColor = aPGB.getColor();
+ break;
+ case Image:
+ ColorBreak aCB = aLS.getLegendBreaks().get(i);
+ DrawShape = true;
+ DrawFill = true;
+ FillColor = aCB.getColor();
+ break;
+ }
+
+ aP.X = i * width + width / 2;
+ aP.Y = height / 2;
+
+ if (aLS.getLegendType() == LegendType.UniqueValue) {
+ if (DrawShape) {
+ if (aLS.getShapeType() == ShapeTypes.Polygon) {
+ PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(i).clone();
+ aPGB.setDrawOutline(DrawOutline);
+ aPGB.setOutlineColor(Color.black);
+ Draw.drawPolygonSymbol((PointF) aP.clone(), width, height, aPGB, g);
+ } else {
+ Draw.drawPolygonSymbol((PointF) aP.clone(), FillColor, OutlineColor, width,
+ height, DrawFill, DrawOutline, g);
+ }
+ }
+ } else if (DrawShape) {
+ if (i == 0) {
+ PointF[] Points = new PointF[4];
+ Points[0] = new PointF();
+ Points[0].X = 0;
+ Points[0].Y = aP.Y;
+ Points[1] = new PointF();
+ Points[1].X = width;
+ Points[1].Y = 0;
+ Points[2] = new PointF();
+ Points[2].X = width;
+ Points[2].Y = height;
+ Points[3] = new PointF();
+ Points[3].X = 0;
+ Points[3].Y = aP.Y;
+ if (aLS.getShapeType() == ShapeTypes.Polygon) {
+ PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(i).clone();
+ aPGB.setDrawOutline(DrawOutline);
+ aPGB.setOutlineColor(Color.black);
+ Draw.drawPolygon(Points, aPGB, g);
+ } else {
+ Draw.drawPolygon(Points, FillColor, OutlineColor, DrawFill, DrawOutline, g);
+ }
+ } else if (i == bNum - 1) {
+ PointF[] Points = new PointF[4];
+ Points[0] = new PointF();
+ Points[0].X = i * width;
+ Points[0].Y = height;
+ Points[1] = new PointF();
+ Points[1].X = i * width;
+ Points[1].Y = 0;
+ Points[2] = new PointF();
+ Points[2].X = i * width + width;
+ Points[2].Y = aP.Y;
+ Points[3] = new PointF();
+ Points[3].X = i * width;
+ Points[3].Y = height;
+ if (aLS.getShapeType() == ShapeTypes.Polygon) {
+ PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(i).clone();
+ aPGB.setDrawOutline(DrawOutline);
+ aPGB.setOutlineColor(Color.black);
+ Draw.drawPolygon(Points, aPGB, g);
+ } else {
+ Draw.drawPolygon(Points, FillColor, OutlineColor, DrawFill, DrawOutline, g);
+ }
+ } else if (aLS.getShapeType() == ShapeTypes.Polygon) {
+ PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(i).clone();
+ aPGB.setDrawOutline(DrawOutline);
+ aPGB.setOutlineColor(Color.black);
+ Draw.drawPolygonSymbol((PointF) aP.clone(), width, height, aPGB, g);
+ } else {
+ Draw.drawPolygonSymbol((PointF) aP.clone(), FillColor, OutlineColor, width,
+ height, DrawFill, DrawOutline, g);
+ }
+ }
+ }
+
+ //Draw neatline
+ g.setColor(Color.black);
+ if (aLS.getLegendType() == LegendType.UniqueValue) {
+ g.draw(new Rectangle.Float(0, 0, width * bNum, height));
+ } else {
+ float extendw = width;
+// if (this.autoExtendFrac)
+// extendw = _hBarHeight;
+ Polygon p = new Polygon();
+ p.addPoint((int) (width - extendw), (int) (height / 2));
+ p.addPoint((int) width, 0);
+ p.addPoint((int) (width * (bNum - 1)), 0);
+ p.addPoint((int) (width * (bNum - 1) + extendw), (int) (height / 2));
+ p.addPoint((int) (width * (bNum - 1)), (int) height);
+ p.addPoint((int) width, (int) height);
+ g.drawPolygon(p);
+ }
+ //Draw tick and label
+ aP.X = -_vBarWidth / 2;
+ int labLen = (int) (this._hBarHeight / 3);
+ if (labLen < 5) {
+ labLen = 5;
+ if (this._hBarHeight < 5) {
+ labLen = (int) this._hBarHeight;
+ }
+ }
+ for (int i = 0; i < bNum; i++) {
+ idx = i;
+ ColorBreak cb = aLS.getLegendBreaks().get(idx);
+ if (aLS.getLegendType() == LegendType.UniqueValue) {
+ caption = cb.getCaption();
+ } else {
+ caption = DataConvert.removeTailingZeros(cb.getEndValue().toString());
+ }
+
+ aP.X += width;
+ aP.Y = height / 2;
+
+ if (aLS.getLegendType() == LegendType.UniqueValue) {
+ if (labelIdxs.contains(idx)) {
+ sP.X = aP.X;
+ sP.Y = aP.Y + height / 2 + 5;
+ metrics = g.getFontMetrics(this._font);
+ aSF = new Dimension(metrics.stringWidth(caption), metrics.getHeight());
+ g.setColor(Color.black);
+ g.setFont(this._font);
+ //g.drawString(caption, sP.X, sP.Y + aSF.height / 4);
+ Draw.drawString(g, caption, sP.X - aSF.width / 2, sP.Y + aSF.height * 3 / 4);
+ }
+ } else if (labelIdxs.contains(idx)) {
+ //g.setColor(Color.black);
+ sP.X = aP.X + _vBarWidth / 2;
+ sP.Y = aP.Y + height / 2;
+ g.draw(new Line2D.Float(sP.X, sP.Y, sP.X, sP.Y - labLen));
+ sP.Y = sP.Y + 5;
+ if (i < bNum - 1) {
+ metrics = g.getFontMetrics(this._font);
+ aSF = new Dimension(metrics.stringWidth(caption), metrics.getHeight());
+ g.setFont(this._font);
+ //g.drawString(caption, sP.X, sP.Y + aSF.height / 4);
+ Draw.drawString(g, caption, sP.X - aSF.width / 2, sP.Y + aSF.height * 3 / 4);
+ }
+ }
+ }
+ }
+
+ private int getLabelWidth(Graphics2D g) {
+ LegendScheme aLS = _legendLayer.getLegendScheme();
+ float width = 0;
+ String caption = "";
+ Dimension aSF;
+ int bNum = aLS.getBreakNum();
+ FontMetrics metrics = g.getFontMetrics(_font);
+ if (_legendStyle == LegendStyles.Normal) {
+ aSF = new Dimension(metrics.stringWidth(_title), metrics.getHeight());
+ width = aSF.width;
+ } else if (aLS.getLegendBreaks().get(bNum - 1).isNoData()) {
+ bNum -= 1;
+ }
+ for (int i = 0; i < bNum; i++) {
+ switch (aLS.getShapeType()) {
+ case Point:
+ PointBreak aPB = (PointBreak) aLS.getLegendBreaks().get(i);
+ if (aLS.getLegendType() == LegendType.GraduatedColor && _legendStyle != LegendStyles.Normal) {
+ caption = DataConvert.removeTailingZeros(aPB.getEndValue().toString());
+ } else {
+ caption = aPB.getCaption();
+ }
+ break;
+ case Polyline:
+ PolylineBreak aPLB = (PolylineBreak) aLS.getLegendBreaks().get(i);
+ if (aLS.getLegendType() == LegendType.GraduatedColor && _legendStyle != LegendStyles.Normal) {
+ caption = DataConvert.removeTailingZeros(aPLB.getEndValue().toString());
+ } else {
+ caption = aPLB.getCaption();
+ }
+ break;
+ case Polygon:
+ PolygonBreak aPGB = (PolygonBreak) aLS.getLegendBreaks().get(i);
+ if (aLS.getLegendType() == LegendType.GraduatedColor && _legendStyle != LegendStyles.Normal) {
+ caption = DataConvert.removeTailingZeros(aPGB.getEndValue().toString());
+ } else {
+ caption = aPGB.getCaption();
+ }
+ break;
+ case Image:
+ ColorBreak aCB = aLS.getLegendBreaks().get(i);
+ if (aLS.getLegendType() == LegendType.GraduatedColor && _legendStyle != LegendStyles.Normal) {
+ caption = DataConvert.removeTailingZeros(aCB.getEndValue().toString());
+ } else {
+ caption = aCB.getCaption();
+ }
+ break;
+ }
+
+ boolean isValid = true;
+ switch (aLS.getLegendType()) {
+ case GraduatedColor:
+ if (_legendStyle != LegendStyles.Normal) {
+ if (i == bNum - 1) {
+ isValid = false;
+ }
+ }
+ break;
+ }
+ if (isValid) {
+ float labwidth = metrics.stringWidth(caption);
+ if (width < labwidth) {
+ width = labwidth;
+ }
+ }
+ }
+
+ if (_legendStyle == LegendStyles.Normal) {
+ if (_legendLayer.getLayerType() == LayerTypes.VectorLayer) {
+ if (((VectorLayer) _legendLayer).getChartSet().isDrawCharts()) {
+ ChartBreak aCB = ((ChartBreak) ((VectorLayer) _legendLayer).getChartPoints().get(0).getLegend()).getSampleChartBreak();
+ if (aCB.getChartType() == ChartTypes.BarChart) {
+ LegendScheme ls = aCB.getLegendScheme();
+ for (ColorBreak cb : ls.getLegendBreaks()) {
+ float labwidth = metrics.stringWidth(cb.getCaption());
+ if (width < labwidth) {
+ width = metrics.stringWidth(cb.getCaption());
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return (int) width;
+ }
+
+ private int getBreakHeight(Graphics2D g) {
+ String title = _title;
+ if ("".equals(title.trim())) {
+ title = "Temp";
+ }
+
+ FontMetrics metrics = g.getFontMetrics(_font);
+ Dimension aSF = new Dimension(metrics.stringWidth(title), metrics.getHeight());
+ return aSF.height;
+ }
+
+ private int getTitleHeight(Graphics2D g) {
+ FontMetrics metrics = g.getFontMetrics(_titleFont);
+ Dimension aSF = new Dimension(metrics.stringWidth(_title), metrics.getHeight());
+ return aSF.height;
+ }
+
+ /**
+ * Update legend control size
+ */
+ public void updateLegendSize() {
+ if (this._legendStyle != LegendStyles.Normal) {
+ return;
+ }
+
+ if (_legendLayer != null) {
+ if (_legendLayer.getLegendScheme() == null) {
+ return;
+ }
+
+ //Graphics2D g = (Graphics2D) _mapLayout.getGraphics();
+ BufferedImage image = new BufferedImage(_mapLayout.getPageBounds().width, _mapLayout.getPageBounds().height, BufferedImage.TYPE_INT_ARGB);
+ Graphics2D g = image.createGraphics();
+ int bNum = _legendLayer.getLegendScheme().getBreakNum();
+ if (_legendLayer.getLegendScheme().getLegendBreaks().get(bNum - 1).isNoData()) {
+ bNum -= 1;
+ }
+
+ int w = this.getWidth();
+ int h = this.getHeight();
+ int nw, nh;
+ switch (_legendStyle) {
+ case Bar_Vertical:
+ nw = 10 + getLabelWidth(g) + 5;
+ nh = bNum * 20;
+ if (nw > w) {
+ this.setWidth(nw);
+ }
+ if (nh > h) {
+ this.setHeight(bNum * 20);
+ }
+ break;
+ case Bar_Horizontal:
+ nw = bNum * 30;
+ nh = 30;
+ if (nw > w) {
+ this.setWidth(nw);
+ }
+ if (nh > h) {
+ this.setHeight(bNum * 20);
+ }
+ break;
+ case Normal:
+ int aHeight = getBreakHeight(g);
+ int colWidth = aHeight * 2 + getLabelWidth(g) + 15;
+ this.setWidth(colWidth * _columnNum);
+
+ //Set columns
+ int[] rowNums = new int[_columnNum];
+ int ave = _legendLayer.getLegendScheme().getVisibleBreakNum() / _columnNum;
+ int num = 0;
+ int i;
+ for (i = 1; i < _columnNum; i++) {
+ rowNums[i] = ave;
+ num += ave;
+ }
+ rowNums[0] = _legendLayer.getLegendScheme().getVisibleBreakNum() - num;
+
+ this.setHeight((int) (rowNums[0] * (aHeight + _breakSpace)
+ + getTitleHeight(g) + _breakSpace * 2 + aHeight / 2 + 5));
+ if (_legendLayer.getLayerType() == LayerTypes.VectorLayer) {
+ VectorLayer aLayer = (VectorLayer) _legendLayer;
+ if (aLayer.getChartSet().isDrawCharts()) {
+ ChartBreak aCB = ((ChartBreak) aLayer.getChartPoints().get(0).getLegend()).getSampleChartBreak();
+ this.setHeight(this.getHeight() + (int) (_breakSpace * 2 + aCB.getHeight()
+ + aCB.getLegendScheme().getBreakNum() * (aHeight + _breakSpace) + aHeight / 2 + 5));
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ @Override
+ public void paint(Graphics2D g) {
+ //throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void paintOnLayout(Graphics2D g, PointF pageLocation, float zoom) {
+ if (this.isVisible()) {
+ paintGraphics(g, pageLocation, zoom);
+ }
+ }
+
+ @Override
+ public void moveUpdate() {
+ }
+
+ @Override
+ public void resizeUpdate() {
+ }
+
+ /**
+ * Get layer names
+ *
+ * @return Layer names
+ */
+ public static List getLayerNames() {
+ List layerNames = new ArrayList<>();
+ for (MapLayer aLayer : _layoutMap.getMapFrame().getMapView().getLayers()) {
+ if (aLayer.getLayerType() == LayerTypes.VectorLayer || aLayer.getLayerType() == LayerTypes.RasterLayer) {
+ layerNames.add(aLayer.getLayerName());
+ }
+ }
+
+ return layerNames;
+ }
+ //
+
+ //
+ public class LayoutLegendBean {
+
+ LayoutLegendBean() {
+ }
+
+ //
+ /**
+ * Get layout map
+ *
+ * @return The layout map
+ */
+ public LayoutMap getLayoutMap() {
+ return _layoutMap;
+ }
+
+ /**
+ * Get legend layer
+ *
+ * @return The legend alyer
+ */
+ public MapLayer getLegendLayer() {
+ return _legendLayer;
+ }
+
+ /**
+ * Set legend layer
+ *
+ * @param layer The legend layer
+ */
+ public void setLegendLayer(MapLayer layer) {
+ _legendLayer = layer;
+ String aStr = _legendLayer.getLayerName();
+ if (aStr.contains("_")) {
+ aStr = aStr.split("_")[1];
+ }
+ _title = aStr;
+ updateLegendSize();
+ }
+
+ /**
+ * Get legend layer name
+ *
+ * @return Legend layer name
+ */
+ public String getLayerName() {
+ if (_legendLayer != null) {
+ return _legendLayer.getLayerName();
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Set legend layer name
+ *
+ * @param name Layer name
+ */
+ public void setLayerName(String name) {
+ MapLayer aLayer = _layoutMap.getMapFrame().getMapView().getLayer(name);
+ if (aLayer != null) {
+ this.setLegendLayer(aLayer);
+ }
+ }
+
+ /**
+ * Get if force to draw polygon outline - for normal legend
+ *
+ * @return Boolean
+ */
+ public boolean isForceDrawOutline() {
+ return forceDrawOutline;
+ }
+
+ /**
+ * Set if force to draw polygon outline - for normal legend
+ *
+ * @param value Boolean
+ */
+ public void setForceDrawOutline(boolean value) {
+ forceDrawOutline = value;
+ }
+
+ /**
+ * Get layer update type string
+ *
+ * @return Layer update type string
+ */
+ public String getLayerUpdateType() {
+ return _layerUpdateType.toString();
+ }
+
+ /**
+ * Set layer update type
+ *
+ * @param typeStr Layer update type string
+ */
+ public void setLayerUpdateType(String typeStr) {
+ _layerUpdateType = LayerUpdateTypes.valueOf(typeStr);
+ }
+
+ /**
+ * Get legend style string
+ *
+ * @return Legend style string
+ */
+ public String getLegendStyle() {
+ return _legendStyle.toString();
+ }
+
+ /**
+ * Set legend style
+ *
+ * @param style Legend style string
+ */
+ public void setLegendStyle(String style) {
+ _legendStyle = LegendStyles.valueOf(style);
+ if (isVisible()) {
+ updateLegendSize();
+ }
+ }
+
+ /**
+ * Get title
+ *
+ * @return The title
+ */
+ public String getTitle() {
+ return _title;
+ }
+
+ /**
+ * Set title
+ *
+ * @param title The title
+ */
+ public void setTitle(String title) {
+ _title = title;
+ updateLegendSize();
+ }
+
+ /**
+ * Get if draw neat line
+ *
+ * @return If draw neat line
+ */
+ public boolean isDrawNeatLine() {
+ return _drawNeatLine;
+ }
+
+ /**
+ * Set if draw neat line
+ *
+ * @param istrue If draw neat line
+ */
+ public void setDrawNeatLine(boolean istrue) {
+ _drawNeatLine = istrue;
+ }
+
+ /**
+ * Get neat line color
+ *
+ * @return Neat line color
+ */
+ public Color getNeatLineColor() {
+ return _neatLineColor;
+ }
+
+ /**
+ * Set neat line color
+ *
+ * @param color Neat line color
+ */
+ public void setNeatLineColor(Color color) {
+ _neatLineColor = color;
+ }
+
+ /**
+ * Get neat line size
+ *
+ * @return Neat line size
+ */
+ public float getNeatLineSize() {
+ return _neatLineSize;
+ }
+
+ /**
+ * Set neat line size
+ *
+ * @param size Neat line size
+ */
+ public void setNeatLineSize(float size) {
+ _neatLineSize = size;
+ }
+
+ /**
+ * Get font
+ *
+ * @return The font
+ */
+ public Font getFont() {
+ return _font;
+ }
+
+ /**
+ * Set font
+ *
+ * @param font The font
+ */
+ public void setFont(Font font) {
+ _font = font;
+ _titleFont = new Font(_font.getFontName(), Font.PLAIN, _font.getSize() + 2);
+ updateLegendSize();
+ }
+
+ /**
+ * Get column number
+ *
+ * @return Column number
+ */
+ public int getColumnNumber() {
+ return _columnNum;
+ }
+
+ /**
+ * Set column number
+ *
+ * @param value Column number
+ */
+ public void setColumnNumber(int value) {
+ _columnNum = value;
+ if (isVisible()) {
+ updateLegendSize();
+ }
+ }
+
+ /**
+ * Get is draw chart breaks
+ *
+ * @return Boolean
+ */
+ public boolean isDrawChartBreaks() {
+ return drawChartBreaks;
+ }
+
+ /**
+ * Set if draw chart breaks
+ *
+ * @param value Boolean
+ */
+ public void setDrawChartBreaks(boolean value) {
+ drawChartBreaks = value;
+ }
+
+ /**
+ * Get is draw backcolor
+ *
+ * @return Boolean
+ */
+ public boolean isDrawBackColor() {
+ return LayoutLegend.this.isDrawBackColor();
+ }
+
+ /**
+ * Set is draw backcolor
+ *
+ * @param value Boolean
+ */
+ public void setDrawBackColor(boolean value) {
+ LayoutLegend.this.setDrawBackColor(value);
+ }
+
+ /**
+ * Get background color
+ *
+ * @return Background color
+ */
+ public Color getBackColor() {
+ return LayoutLegend.this.getBackColor();
+ }
+
+ /**
+ * Set background color
+ *
+ * @param c Background color
+ */
+ public void setBackColor(Color c) {
+ LayoutLegend.this.setBackColor(c);
+ }
+
+ /**
+ * Get foreground color
+ *
+ * @return Foreground color
+ */
+ public Color getForeColor() {
+ return LayoutLegend.this.getForeColor();
+ }
+
+ /**
+ * Set foreground color
+ *
+ * @param c Foreground color
+ */
+ public void setForeColor(Color c) {
+ LayoutLegend.this.setForeColor(c);
+ }
+
+ /**
+ * Get left
+ *
+ * @return Left
+ */
+ public int getLeft() {
+ return LayoutLegend.this.getLeft();
+ }
+
+ /**
+ * Set left
+ *
+ * @param left Left
+ */
+ public void setLeft(int left) {
+ LayoutLegend.this.setLeft(left);
+ }
+
+ /**
+ * Get top
+ *
+ * @return Top
+ */
+ public int getTop() {
+ return LayoutLegend.this.getTop();
+ }
+
+ /**
+ * Set top
+ *
+ * @param top Top
+ */
+ public void setTop(int top) {
+ LayoutLegend.this.setTop(top);
+ }
+
+ /**
+ * Get width
+ *
+ * @return Width
+ */
+ public int getWidth() {
+ return LayoutLegend.this.getWidth();
+ }
+
+ /**
+ * Set width
+ *
+ * @param value Width
+ */
+ public void setWidth(int value) {
+ LayoutLegend.this.setWidth(value);
+ }
+
+ /**
+ * Get height
+ *
+ * @return Height
+ */
+ public int getHeight() {
+ return LayoutLegend.this.getHeight();
+ }
+
+ /**
+ * Set height
+ *
+ * @param value Height
+ */
+ public void setHeight(int value) {
+ LayoutLegend.this.setHeight(value);
+ }
+
+ /**
+ * Get bar width
+ *
+ * @return Bar width
+ */
+ public float getBarWidth() {
+ return LayoutLegend.this._vBarWidth;
+ }
+
+ /**
+ * Set bar width
+ *
+ * @param value Bar width
+ */
+ public void setBarWidth(float value) {
+ LayoutLegend.this._vBarWidth = value;
+ }
+ //
+ }
+
+ public static class LayoutLegendBeanBeanInfo extends BaseBeanInfo {
+
+ public LayoutLegendBeanBeanInfo() {
+ super(LayoutLegendBean.class);
+ ExtendedPropertyDescriptor e = addProperty("layerName");
+ e.setCategory("General").setPropertyEditorClass(LayerNameEditor.class);
+ e.setDisplayName("Layer Name");
+ e.setShortDescription("The name of the layer of this legend");
+ e = addProperty("layerUpdateType");
+ e.setCategory("General").setDisplayName("Layer Update Type");
+ e.setPropertyEditorClass(LayerUpdateTypeEditor.class);
+ e = addProperty("legendStyle");
+ e.setCategory("General").setDisplayName("Legend Style");
+ e.setPropertyEditorClass(LegendStyleEditor.class);
+ addProperty("title").setCategory("General").setDisplayName("Title");
+ addProperty("font").setCategory("General").setDisplayName("Font");
+ addProperty("drawBackColor").setCategory("General").setDisplayName("Draw Background");
+ addProperty("backColor").setCategory("General").setDisplayName("Background");
+ addProperty("foreColor").setCategory("General").setDisplayName("Foreground");
+ addProperty("columnNumber").setCategory("General").setDisplayName("Column Number");
+ addProperty("forceDrawOutline").setCategory("General").setDisplayName("Force Draw Outline");
+ addProperty("drawNeatLine").setCategory("Neat Line").setDisplayName("Draw Neat Line");
+ addProperty("neatLineColor").setCategory("Neat Line").setDisplayName("Neat Line Color");
+ addProperty("neatLineSize").setCategory("Neat Line").setDisplayName("Neat Line Size");
+ addProperty("drawChartBreaks").setCategory("Chart").setDisplayName("Draw Chart Breaks");
+ //addProperty("drawPieLabel").setCategory("Chart").setDisplayName("Draw Pie label");
+ addProperty("left").setCategory("Location").setDisplayName("Left");
+ addProperty("top").setCategory("Location").setDisplayName("Top");
+ addProperty("width").setCategory("Location").setDisplayName("Width");
+ addProperty("height").setCategory("Location").setDisplayName("Height");
+ //addProperty("barWidth").setCategory("ColorBar").setDisplayName("Bar Width");
+ }
+ }
+
+ public static class LayerNameEditor extends ComboBoxPropertyEditor {
+
+ public LayerNameEditor() {
+ super();
+ String[] names = (String[]) getLayerNames().toArray(new String[0]);
+ setAvailableValues(names);
+// Icon[] icons = new Icon[4];
+// Arrays.fill(icons, UIManager.getIcon("Tree.openIcon"));
+// setAvailableIcons(icons);
+ }
+ }
+
+ public static class LayerUpdateTypeEditor extends ComboBoxPropertyEditor {
+
+ public LayerUpdateTypeEditor() {
+ super();
+ LayerUpdateTypes[] lutypes = LayerUpdateTypes.values();
+ String[] types = new String[lutypes.length];
+ int i = 0;
+ for (LayerUpdateTypes type : lutypes) {
+ types[i] = type.toString();
+ i += 1;
+ }
+ setAvailableValues(types);
+ }
+ }
+
+ public static class LegendStyleEditor extends ComboBoxPropertyEditor {
+
+ public LegendStyleEditor() {
+ super();
+ LegendStyles[] styles = LegendStyles.values();
+ String[] values = new String[styles.length];
+ int i = 0;
+ for (LegendStyles s : styles) {
+ values[i] = s.toString();
+ i += 1;
+ }
+ setAvailableValues(values);
+ }
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/layout/LayoutMap.java b/MeteoInfoLib/src/main/java/org/meteoinfo/layout/LayoutMap.java
index d933b3ee..d6816b72 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/layout/LayoutMap.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/layout/LayoutMap.java
@@ -1,1548 +1,1548 @@
-/* Copyright 2012 Yaqiang Wang,
- * yaqiang.wang@gmail.com
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.layout;
-
-import com.l2fprod.common.beans.BaseBeanInfo;
-import com.l2fprod.common.beans.ExtendedPropertyDescriptor;
-import com.l2fprod.common.beans.editor.ComboBoxPropertyEditor;
-import org.meteoinfo.global.event.ILayersUpdatedListener;
-import org.meteoinfo.global.event.IMapViewUpdatedListener;
-import org.meteoinfo.global.event.LayersUpdatedEvent;
-import org.meteoinfo.global.event.MapViewUpdatedEvent;
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.global.MIMath;
-import org.meteoinfo.global.PointF;
-import org.meteoinfo.legend.GridLabelPosition;
-import org.meteoinfo.legend.LineStyles;
-import org.meteoinfo.legend.MapFrame;
-import org.meteoinfo.map.GridLabel;
-import java.awt.BasicStroke;
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.Font;
-import java.awt.FontMetrics;
-import java.awt.Graphics2D;
-import java.awt.Rectangle;
-import java.awt.geom.Line2D;
-import java.util.ArrayList;
-import java.util.List;
-import javax.swing.event.EventListenerList;
-import org.meteoinfo.data.mapdata.webmap.TileLoadListener;
-
-/**
- *
- * @author yaqiang
- */
-public class LayoutMap extends LayoutElement {
- //
-
- public void addMapViewUpdatedListener(IMapViewUpdatedListener listener) {
- this._listeners.add(IMapViewUpdatedListener.class, listener);
- }
-
- public void removeMapViewUpdatedListener(IMapViewUpdatedListener listener) {
- this._listeners.remove(IMapViewUpdatedListener.class, listener);
- }
-
- public void fireMapViewUpdatedEvent() {
- fireMapViewUpdatedEvent(new MapViewUpdatedEvent(this));
- }
-
- private void fireMapViewUpdatedEvent(MapViewUpdatedEvent event) {
- Object[] listeners = _listeners.getListenerList();
- for (int i = 0; i < listeners.length; i = i + 2) {
- if (listeners[i] == IMapViewUpdatedListener.class) {
- ((IMapViewUpdatedListener) listeners[i + 1]).mapViewUpdatedEvent(event);
- }
- }
- }
- //
- //
- private EventListenerList _listeners = new EventListenerList();
- private MapFrame _mapFrame = null;
- private boolean _drawDegreeSymbol = false;
- private final TileLoadListener tileLoadListener;
- //
- //
-
- /**
- * Constructor
- *
- * @param mapFrame MapFrame
- * @param tll TileLoadListener
- */
- public LayoutMap(MapFrame mapFrame, TileLoadListener tll) {
- super();
- this.setElementType(ElementType.LayoutMap);
- this.setResizeAbility(ResizeAbility.ResizeAll);
- this.setMapFrame(mapFrame);
- this.tileLoadListener = tll;
- }
- //
- //
-
- public MapFrame getMapFrame() {
- return _mapFrame;
- }
-
- public void setMapFrame(MapFrame mf) {
- _mapFrame = mf;
- _mapFrame.addMapViewUpdatedListener(new IMapViewUpdatedListener() {
- @Override
- public void mapViewUpdatedEvent(MapViewUpdatedEvent event) {
- fireMapViewUpdatedEvent();
- }
- });
-
- _mapFrame.addLayersUpdatedListener(new ILayersUpdatedListener() {
- @Override
- public void layersUpdatedEvent(LayersUpdatedEvent event) {
- fireMapViewUpdatedEvent();
- }
- });
- }
-
- /**
- * Get left
- *
- * @return Left
- */
- @Override
- public int getLeft() {
- return _mapFrame.getLayoutBounds().x;
- }
-
- /**
- * Set left
- *
- * @param left Left
- */
- @Override
- public void setLeft(int left) {
- _mapFrame.setLayoutBounds(new Rectangle(left, _mapFrame.getLayoutBounds().y, _mapFrame.getLayoutBounds().width,
- _mapFrame.getLayoutBounds().height));
- }
-
- /**
- * Get top
- *
- * @return Top
- */
- @Override
- public int getTop() {
- return _mapFrame.getLayoutBounds().y;
- }
-
- /**
- * Set top
- *
- * @param top Top
- */
- @Override
- public void setTop(int top) {
- _mapFrame.setLayoutBounds(new Rectangle(_mapFrame.getLayoutBounds().x, top, _mapFrame.getLayoutBounds().width,
- _mapFrame.getLayoutBounds().height));
- }
-
- /**
- * Get width
- *
- * @return Width
- */
- @Override
- public int getWidth() {
- return _mapFrame.getLayoutBounds().width;
- }
-
- /**
- * Set width
- *
- * @param width Width
- */
- @Override
- public void setWidth(int width) {
- _mapFrame.setLayoutBounds(new Rectangle(_mapFrame.getLayoutBounds().x, _mapFrame.getLayoutBounds().y, width,
- _mapFrame.getLayoutBounds().height));
- }
-
- /**
- * Get height
- *
- * @return Height
- */
- @Override
- public int getHeight() {
- return _mapFrame.getLayoutBounds().height;
- }
-
- /**
- * Set height
- *
- * @param height Height
- */
- @Override
- public void setHeight(int height) {
- _mapFrame.setLayoutBounds(new Rectangle(_mapFrame.getLayoutBounds().x, _mapFrame.getLayoutBounds().y,
- _mapFrame.getLayoutBounds().width, height));
- }
-
- /**
- * Get bounds rectangle
- *
- * @return The bounds rectangle
- */
- @Override
- public Rectangle getBounds() {
- return _mapFrame.getLayoutBounds();
- }
-
- /**
- * Set bounds rectangle
- *
- * @param rect Bounds rectangle
- */
- public void setBounds(Rectangle rect) {
- _mapFrame.setLayoutBounds(rect);
- }
-
- /**
- * Get background color
- *
- * @return Background color
- */
- @Override
- public Color getBackColor() {
- return _mapFrame.getBackColor();
- }
-
- /**
- * Set background color
- *
- * @param color Background color
- */
- @Override
- public void setBackColor(Color color) {
- _mapFrame.setBackColor(color);
- }
-
- /**
- * Get foreground color
- *
- * @return Foreground color
- */
- @Override
- public Color getForeColor() {
- return _mapFrame.getForeColor();
- }
-
- /**
- * Set foreground color
- *
- * @param color
- */
- @Override
- public void setForeColor(Color color) {
- _mapFrame.setForeColor(color);
- }
-
- /**
- * Get if draw map view neat line
- *
- * @return Boolean
- */
- public boolean isDrawNeatLine() {
- return _mapFrame.isDrawNeatLine();
- }
-
- /**
- * Set if draw map view neat line
- *
- * @param istrue Boolean
- */
- public void setDrawNeatLine(boolean istrue) {
- _mapFrame.setDrawNeatLine(istrue);
- }
-
- /**
- * Get map view neat line color
- *
- * @return Neat line color
- */
- public Color getNeatLineColor() {
- return _mapFrame.getNeatLineColor();
- }
-
- /**
- * Set map view neat line color
- *
- * @param color Neat line color
- */
- public void setNeatLineColor(Color color) {
- _mapFrame.setNeatLineColor(color);
- }
-
- /**
- * Get map view neat line size
- *
- * @return Neat line size
- */
- public float getNeatLineSize() {
- return _mapFrame.getNeatLineSize();
- }
-
- /**
- * Set map view neat line size
- *
- * @param size Neat line size
- */
- public void setNeatLineSize(float size) {
- _mapFrame.setNeatLineSize(size);
- }
-
- /**
- * Get grid line color
- *
- * @return Grid line color
- */
- public Color getGridLineColor() {
- return _mapFrame.getGridLineColor();
- }
-
- /**
- * Set grid line color
- *
- * @param color Grid line color
- */
- public void setGridLineColor(Color color) {
- _mapFrame.setGridLineColor(color);
- }
-
- /**
- * Get grid line size
- *
- * @return Grid line size
- */
- public float getGridLineSize() {
- return _mapFrame.getGridLineSize();
- }
-
- /**
- * Set grid line size
- *
- * @param size Grid line size
- */
- public void setGridLineSize(float size) {
- _mapFrame.setGridLineSize(size);
- }
-
- /**
- * Get grid line style
- *
- * @return Grid line style
- */
- public LineStyles getGridLineStyle() {
- return _mapFrame.getGridLineStyle();
- }
-
- /**
- * Set grid line style
- *
- * @param style Grid line style
- */
- public void setGridLineStyle(LineStyles style) {
- _mapFrame.setGridLineStyle(style);
- }
-
- /**
- * Get if draw grid labels
- *
- * @return If draw grid labels
- */
- public boolean isDrawGridLabel() {
- return _mapFrame.isDrawGridLabel();
- }
-
- /**
- * Set if draw grid labels
- *
- * @param istrue Boolean
- */
- public void setDrawGridLabel(boolean istrue) {
- _mapFrame.setDrawGridLabel(istrue);
- }
-
- /**
- * Get if draw grid tick line inside
- *
- * @return Booelan
- */
- public boolean isInsideTickLine() {
- return _mapFrame.isInsideTickLine();
- }
-
- /**
- * Set if draw grid tick line inside
- *
- * @param istrue Boolean
- */
- public void setInsideTickLine(boolean istrue) {
- _mapFrame.setInsideTickLine(istrue);
- }
-
- /**
- * Get grid tick line length
- *
- * @return Grid tick line length
- */
- public int getTickLineLength() {
- return _mapFrame.getTickLineLength();
- }
-
- /**
- * Set grid tick line length
- *
- * @param value Tick line length value
- */
- public void setTickLineLength(int value) {
- _mapFrame.setTickLineLength(value);
- }
-
- /**
- * Get grid label shift
- *
- * @return Grid label shift
- */
- public int getGridLabelShift() {
- return _mapFrame.getGridLabelShift();
- }
-
- /**
- * Set grid label shift
- *
- * @param value Grid label shift
- */
- public void setGridLabelShift(int value) {
- _mapFrame.setGridLabelShift(value);
- }
-
- ///
- /// Get or set grid label position
- /**
- * Get grid label position
- *
- * @return Grid label position
- */
- public GridLabelPosition getGridLabelPosition() {
- return _mapFrame.getGridLabelPosition();
- }
-
- /**
- * Set grid label positiont
- *
- * @param value Grid label position
- */
- public void setGridLabelPosition(GridLabelPosition value) {
- _mapFrame.setGridLabelPosition(value);
- }
-
- /**
- * Get if draw grid line
- *
- * @return If draw grid line
- */
- public boolean isDrawGridLine() {
- return _mapFrame.isDrawGridLine();
- }
-
- /**
- * Set if draw grid line
- *
- * @param istrue If draw grid line
- */
- public void setDrawGridLine(boolean istrue) {
- _mapFrame.setDrawGridLine(istrue);
- }
-
- /**
- * Get if draw grid tick line
- *
- * @return Boolean
- */
- public boolean isDrawGridTickLine() {
- return _mapFrame.isDrawGridTickLine();
- }
-
- /**
- * Set if draw grid tick line
- *
- * @param istrue Boolean
- */
- public void setDrawGridTickLine(boolean istrue) {
- _mapFrame.setDrawGridTickLine(istrue);
- }
-
- /**
- * Get if draw degree symbol
- *
- * @return Boolean
- */
- public boolean isDrawDegreeSymbol() {
- return _drawDegreeSymbol;
- }
-
- /**
- * Set if draw degree symbol
- *
- * @param value Boolean
- */
- public void setDrawDegreeSymbol(boolean value) {
- _drawDegreeSymbol = value;
- }
-
- /**
- * Get grid label font
- *
- * @return Grid label font
- */
- public Font getGridFont() {
- return _mapFrame.getGridFont();
- }
-
- /**
- * Set grid label font
- *
- * @param font Grid label font
- */
- public void setGridFont(Font font) {
- _mapFrame.setGridFont(font);
- }
-
- /**
- * Get grid x delt
- *
- * @return Grid x delt
- */
- public double getGridXDelt() {
- return _mapFrame.getGridXDelt();
- }
-
- /**
- * Set grid x delt
- *
- * @param value The value
- */
- public void setGridXDelt(double value) {
- _mapFrame.setGridXDelt(value);
- }
-
- /**
- * Get grid y delt
- *
- * @return Grid y delt
- */
- public double getGridYDelt() {
- return _mapFrame.getGridYDelt();
- }
-
- /**
- * Set grid y delt
- *
- * @param value Grid y delt
- */
- public void setGridYDelt(double value) {
- _mapFrame.setGridYDelt(value);
- }
-
- /**
- * Get grid x origin
- *
- * @return Grid x origin
- */
- public float getGridXOrigin() {
- return _mapFrame.getGridXOrigin();
- }
-
- /**
- * Set grid x origin
- *
- * @param value Grid x origin
- */
- public void setGridXOrigin(float value) {
- _mapFrame.setGridXOrigin(value);
- }
-
- /**
- * Get grid y origin
- *
- * @return Grid y origin
- */
- public float getGridYOrigin() {
- return _mapFrame.getGridYOrigin();
- }
-
- /**
- * Set grid y origin
- *
- * @param value Grid y origin
- */
- public void setGridYOrigin(float value) {
- _mapFrame.setGridYOrigin(value);
- }
-
- //
- //
- /**
- * Zoom to exactly lon/lat extent
- *
- * @param aExtent The lon/lat extent
- */
- public void zoomToExtentLonLatEx(Extent aExtent) {
- if (!_mapFrame.getMapView().getProjection().isLonLatMap()) {
- aExtent = _mapFrame.getMapView().getProjection().getProjectedExtentFromLonLat(aExtent);
- }
-
- setSizeByExtent(aExtent);
- _mapFrame.getMapView().setViewExtent(aExtent);
- }
-
- private void setSizeByExtent(Extent aExtent) {
- double scaleFactor;
-
- double scaleX = this.getWidth() / (aExtent.maxX - aExtent.minX);
- double scaleY = this.getHeight() / (aExtent.maxY - aExtent.minY);
- if (_mapFrame.getMapView().getProjection().isLonLatMap()) {
- scaleFactor = _mapFrame.getMapView().getXYScaleFactor();
- } else {
- scaleFactor = 1;
- }
-
- if (scaleX > scaleY) {
- scaleX = scaleY / scaleFactor;
- this.setWidth((int) ((aExtent.maxX - aExtent.minX) * scaleX));
- } else {
- scaleY = scaleX * scaleFactor;
- this.setHeight((int) ((aExtent.maxY - aExtent.minY) * scaleY));
- }
- }
-
- /**
- * Paint method
- *
- * @param g Graphics2D
- */
- @Override
- public void paint(Graphics2D g) {
- if (_mapFrame != null) {
- g.setColor(_mapFrame.getMapView().getBackground());
- g.fill(_mapFrame.getLayoutBounds());
-
- _mapFrame.getMapView().paintGraphics(g, _mapFrame.getLayoutBounds(), this.tileLoadListener);
-
-// //Draw lon/lat grid labels
-// if (_mapFrame.getDrawGridLabel())
-// {
-// List extentList = new ArrayList();
-// Extent maxExtent = new Extent();
-// Extent aExtent = new Extent();
-// SizeF aSF = new SizeF();
-// SolidBrush aBrush = new SolidBrush(this.ForeColor);
-// Pen aPen = new Pen(_mapFrame.GridLineColor);
-// aPen.Width = _mapFrame.GridLineSize;
-// String drawStr;
-// PointF sP = new PointF(0, 0);
-// PointF eP = new PointF(0, 0);
-// Font font = new Font(_mapFrame.getGridFont().Name, _mapFrame.getGridFont().Size, _mapFrame.getGridFont().Style);
-// float labX, labY;
-// int len = 5;
-// int space = len + 2;
-// for (int i = 0; i < _mapFrame.getMapView().getGridLabels().Count; i++)
-// {
-// GridLabel aGL = _mapFrame.getMapView().getGridLabels()[i];
-// switch (_mapFrame.getGridLabelPosition())
-// {
-// case GridLabelPosition.LeftBottom:
-// switch (aGL.LabDirection)
-// {
-// case Direction.East:
-// case Direction.North:
-// continue;
-// }
-// break;
-// case GridLabelPosition.LeftUp:
-// switch (aGL.LabDirection)
-// {
-// case Direction.East:
-// case Direction.South:
-// continue;
-// }
-// break;
-// case GridLabelPosition.RightBottom:
-// switch (aGL.LabDirection)
-// {
-// case Direction.Weast:
-// case Direction.North:
-// continue;
-// }
-// break;
-// case GridLabelPosition.RightUp:
-// switch (aGL.LabDirection)
-// {
-// case Direction.Weast:
-// case Direction.South:
-// continue;
-// }
-// break;
-// }
-//
-// labX = (float)aGL.LabPoint.X;
-// labY = (float)aGL.LabPoint.Y;
-// labX = labX + this.Left;
-// labY = labY + this.Top;
-// sP.X = labX;
-// sP.Y = labY;
-//
-// drawStr = aGL.LabString;
-// aSF = g.MeasureString(drawStr, font);
-// switch (aGL.LabDirection)
-// {
-// case Direction.South:
-// labX = labX - aSF.Width / 2;
-// labY = labY + space;
-// eP.X = sP.X;
-// eP.Y = sP.Y + len;
-// break;
-// case Direction.Weast:
-// labX = labX - aSF.Width - space;
-// labY = labY - aSF.Height / 2;
-// eP.X = sP.X - len;
-// eP.Y = sP.Y;
-// break;
-// case Direction.North:
-// labX = labX - aSF.Width / 2;
-// labY = labY - aSF.Height - space;
-// eP.X = sP.X;
-// eP.Y = sP.Y - len;
-// break;
-// case Direction.East:
-// labX = labX + space;
-// labY = labY - aSF.Height / 2;
-// eP.X = sP.X + len;
-// eP.Y = sP.Y;
-// break;
-// }
-//
-// bool ifDraw = true;
-// float aSize = aSF.Width / 2;
-// float bSize = aSF.Height / 2;
-// aExtent.minX = labX;
-// aExtent.maxX = labX + aSF.Width;
-// aExtent.minY = labY - aSF.Height;
-// aExtent.maxY = labY;
-//
-// //Judge extent
-// if (extentList.Count == 0)
-// {
-// maxExtent = aExtent;
-// extentList.Add(aExtent);
-// }
-// else
-// {
-// if (!MIMath.IsExtentCross(aExtent, maxExtent))
-// {
-// extentList.Add(aExtent);
-// maxExtent = MIMath.GetLagerExtent(maxExtent, aExtent);
-// }
-// else
-// {
-// for (int j = 0; j < extentList.Count; j++)
-// {
-// if (MIMath.IsExtentCross(aExtent, extentList[j]))
-// {
-// ifDraw = false;
-// break;
-// }
-// }
-// if (ifDraw)
-// {
-// extentList.Add(aExtent);
-// maxExtent = MIMath.GetLagerExtent(maxExtent, aExtent);
-// }
-// }
-// }
-//
-// if (ifDraw)
-// {
-// g.DrawLine(aPen, sP, eP);
-// g.DrawString(drawStr, font, aBrush, labX, labY);
-// }
-// }
-// }
- if (_mapFrame.isDrawNeatLine()) {
- g.setColor(_mapFrame.getNeatLineColor());
- g.setStroke(new BasicStroke(_mapFrame.getNeatLineSize()));
- g.draw(_mapFrame.getLayoutBounds());
- }
- }
- }
-
- @Override
- public void paintOnLayout(Graphics2D g, PointF pageLocation, float zoom) {
- if (_mapFrame != null) {
- PointF aP = pageToScreen(this.getLeft(), this.getTop(), pageLocation, zoom);
- Rectangle rect = new Rectangle((int) aP.X, (int) aP.Y, (int) (this.getWidth() * zoom), (int) (this.getHeight() * zoom));
- //g.setColor(_mapFrame.getMapView().getBackground());
- //g.fill(rect);
-
- _mapFrame.getMapView().paintGraphics(g, rect, this.tileLoadListener);
-
- //Draw lon/lat grid labels
- if (_mapFrame.isDrawGridLabel()) {
- List extentList = new ArrayList<>();
- Extent maxExtent = new Extent();
- Extent aExtent;
- Dimension aSF;
- g.setColor(_mapFrame.getGridLineColor());
- g.setStroke(new BasicStroke(_mapFrame.getGridLineSize()));
- String drawStr;
- PointF sP = new PointF(0, 0);
- PointF eP = new PointF(0, 0);
- Font font = new Font(_mapFrame.getGridFont().getFontName(), _mapFrame.getGridFont().getStyle(), (int) (_mapFrame.getGridFont().getSize() * zoom));
- g.setFont(font);
- float labX, labY;
- int len = _mapFrame.getTickLineLength();
- int space = len + _mapFrame.getGridLabelShift();
- if (_mapFrame.isInsideTickLine()) {
- space = _mapFrame.getGridLabelShift();
- }
-
- for (int i = 0; i < _mapFrame.getMapView().getGridLabels().size(); i++) {
- GridLabel aGL = _mapFrame.getMapView().getGridLabels().get(i);
- switch (_mapFrame.getGridLabelPosition()) {
- case LEFT_BOTTOM:
- switch (aGL.getLabDirection()) {
- case East:
- case North:
- continue;
- }
- break;
- case LEFT_UP:
- switch (aGL.getLabDirection()) {
- case East:
- case South:
- continue;
- }
- break;
- case RIGHT_BOTTOM:
- switch (aGL.getLabDirection()) {
- case Weast:
- case North:
- continue;
- }
- break;
- case RIGHT_UP:
- switch (aGL.getLabDirection()) {
- case Weast:
- case South:
- continue;
- }
- break;
- }
-
- labX = (float) aGL.getLabPoint().X;
- labY = (float) aGL.getLabPoint().Y;
- labX = labX + this.getLeft() * zoom + pageLocation.X;
- labY = labY + this.getTop() * zoom + pageLocation.Y;
- sP.X = labX;
- sP.Y = labY;
-
- drawStr = aGL.getLabString();
- if (_drawDegreeSymbol) {
- if (drawStr.endsWith("E") || drawStr.endsWith("W") || drawStr.endsWith("N") || drawStr.endsWith("S")) {
- drawStr = drawStr.substring(0, drawStr.length() - 1) + String.valueOf((char) 186) + drawStr.substring(drawStr.length() - 1);
- } else {
- drawStr = drawStr + String.valueOf((char) 186);
- }
- }
- FontMetrics metrics = g.getFontMetrics(font);
- aSF = new Dimension(metrics.stringWidth(drawStr), metrics.getHeight());
- switch (aGL.getLabDirection()) {
- case South:
- labX = labX - aSF.width / 2;
- labY = labY + aSF.height * 3 / 4 + space;
- eP.X = sP.X;
- if (_mapFrame.isInsideTickLine()) {
- eP.Y = sP.Y - len;
- } else {
- eP.Y = sP.Y + len;
- }
- break;
- case Weast:
- labX = labX - aSF.width - space;
- labY = labY + aSF.height / 3;
- eP.Y = sP.Y;
- if (_mapFrame.isInsideTickLine()) {
- eP.X = sP.X + len;
- } else {
- eP.X = sP.X - len;
- }
- break;
- case North:
- labX = labX - aSF.width / 2;
- //labY = labY - aSF.height / 3 - space;
- labY = labY - space;
- eP.X = sP.X;
- if (_mapFrame.isInsideTickLine()) {
- eP.Y = sP.Y + len;
- } else {
- eP.Y = sP.Y - len;
- }
- break;
- case East:
- labX = labX + space;
- labY = labY + aSF.height / 3;
- eP.Y = sP.Y;
- if (_mapFrame.isInsideTickLine()) {
- eP.X = sP.X - len;
- } else {
- eP.X = sP.X + len;
- }
- break;
- }
-
- boolean ifDraw = true;
- float aSize = aSF.width / 2;
- float bSize = aSF.height / 2;
- aExtent = new Extent();
- aExtent.minX = labX;
- aExtent.maxX = labX + aSF.width;
- aExtent.minY = labY - aSF.height;
- aExtent.maxY = labY;
-
- //Judge extent
- if (extentList.isEmpty()) {
- maxExtent = (Extent) aExtent.clone();
- extentList.add((Extent) aExtent.clone());
- } else {
- if (!MIMath.isExtentCross(aExtent, maxExtent)) {
- extentList.add((Extent) aExtent.clone());
- maxExtent = MIMath.getLagerExtent(maxExtent, aExtent);
- } else {
- for (int j = 0; j < extentList.size(); j++) {
- if (MIMath.isExtentCross(aExtent, extentList.get(j))) {
- ifDraw = false;
- break;
- }
- }
- if (ifDraw) {
- extentList.add(aExtent);
- maxExtent = MIMath.getLagerExtent(maxExtent, aExtent);
- }
- }
- }
-
- if (ifDraw) {
- g.setColor(_mapFrame.getGridLineColor());
- g.draw(new Line2D.Float(sP.X, sP.Y, eP.X, eP.Y));
- g.setColor(this.getForeColor());
- g.drawString(drawStr, labX, labY);
- }
- }
- }
-
- //Draw neat line
- if (_mapFrame.isDrawNeatLine()) {
- g.setColor(_mapFrame.getNeatLineColor());
- g.setStroke(new BasicStroke(_mapFrame.getNeatLineSize()));
- g.draw(rect);
- }
- }
- }
-
- @Override
- public void moveUpdate() {
- }
-
- @Override
- public void resizeUpdate() {
- }
- //
- //
-
- public class LayoutMapBean {
-
- LayoutMapBean() {
- }
- //
-
- /**
- * Get left
- *
- * @return Left
- */
- public int getLeft() {
- return _mapFrame.getLayoutBounds().x;
- }
-
- /**
- * Set left
- *
- * @param left Left
- */
- public void setLeft(int left) {
- _mapFrame.setLayoutBounds(new Rectangle(left, _mapFrame.getLayoutBounds().y, _mapFrame.getLayoutBounds().width,
- _mapFrame.getLayoutBounds().height));
- }
-
- /**
- * Get top
- *
- * @return Top
- */
- public int getTop() {
- return _mapFrame.getLayoutBounds().y;
- }
-
- /**
- * Set top
- *
- * @param top Top
- */
- public void setTop(int top) {
- _mapFrame.setLayoutBounds(new Rectangle(_mapFrame.getLayoutBounds().x, top, _mapFrame.getLayoutBounds().width,
- _mapFrame.getLayoutBounds().height));
- }
-
- /**
- * Get width
- *
- * @return Width
- */
- public int getWidth() {
- return _mapFrame.getLayoutBounds().width;
- }
-
- /**
- * Set width
- *
- * @param width Width
- */
- public void setWidth(int width) {
- _mapFrame.setLayoutBounds(new Rectangle(_mapFrame.getLayoutBounds().x, _mapFrame.getLayoutBounds().y, width,
- _mapFrame.getLayoutBounds().height));
- }
-
- /**
- * Get height
- *
- * @return Height
- */
- public int getHeight() {
- return _mapFrame.getLayoutBounds().height;
- }
-
- /**
- * Set height
- *
- * @param height Height
- */
- public void setHeight(int height) {
- _mapFrame.setLayoutBounds(new Rectangle(_mapFrame.getLayoutBounds().x, _mapFrame.getLayoutBounds().y,
- _mapFrame.getLayoutBounds().width, height));
- }
-
- /**
- * Get bounds rectangle
- *
- * @return The bounds rectangle
- */
- public Rectangle getBounds() {
- return _mapFrame.getLayoutBounds();
- }
-
- /**
- * Set bounds rectangle
- *
- * @param rect Bounds rectangle
- */
- public void setBounds(Rectangle rect) {
- _mapFrame.setLayoutBounds(rect);
- }
-
- /**
- * Get is draw backcolor
- *
- * @return Boolean
- */
- public boolean isDrawBackColor() {
- return LayoutMap.this.isDrawBackColor();
- }
-
- /**
- * Set is draw backcolor
- *
- * @param value Boolean
- */
- public void setDrawBackColor(boolean value) {
- LayoutMap.this.setDrawBackColor(value);
- }
-
- /**
- * Get background color
- *
- * @return Background color
- */
- public Color getBackColor() {
- return _mapFrame.getBackColor();
- }
-
- /**
- * Set background color
- *
- * @param color Background color
- */
- public void setBackColor(Color color) {
- _mapFrame.setBackColor(color);
- }
-
- /**
- * Get foreground color
- *
- * @return Foreground color
- */
- public Color getForeColor() {
- return _mapFrame.getForeColor();
- }
-
- /**
- * Set foreground color
- *
- * @param color
- */
- public void setForeColor(Color color) {
- _mapFrame.setForeColor(color);
- }
-
- /**
- * Get if draw map view neat line
- *
- * @return Boolean
- */
- public boolean isDrawNeatLine() {
- return _mapFrame.isDrawNeatLine();
- }
-
- /**
- * Set if draw map view neat line
- *
- * @param istrue Boolean
- */
- public void setDrawNeatLine(boolean istrue) {
- _mapFrame.setDrawNeatLine(istrue);
- }
-
- /**
- * Get map view neat line color
- *
- * @return Neat line color
- */
- public Color getNeatLineColor() {
- return _mapFrame.getNeatLineColor();
- }
-
- /**
- * Set map view neat line color
- *
- * @param color Neat line color
- */
- public void setNeatLineColor(Color color) {
- _mapFrame.setNeatLineColor(color);
- }
-
- /**
- * Get map view neat line size
- *
- * @return Neat line size
- */
- public float getNeatLineSize() {
- return _mapFrame.getNeatLineSize();
- }
-
- /**
- * Set map view neat line size
- *
- * @param size Neat line size
- */
- public void setNeatLineSize(float size) {
- _mapFrame.setNeatLineSize(size);
- }
-
- /**
- * Get grid line color
- *
- * @return Grid line color
- */
- public Color getGridLineColor() {
- return _mapFrame.getGridLineColor();
- }
-
- /**
- * Set grid line color
- *
- * @param color Grid line color
- */
- public void setGridLineColor(Color color) {
- _mapFrame.setGridLineColor(color);
- }
-
- /**
- * Get grid line size
- *
- * @return Grid line size
- */
- public float getGridLineSize() {
- return _mapFrame.getGridLineSize();
- }
-
- /**
- * Set grid line size
- *
- * @param size Grid line size
- */
- public void setGridLineSize(float size) {
- _mapFrame.setGridLineSize(size);
- }
-
- /**
- * Get grid line style
- *
- * @return Grid line style
- */
- public String getGridLineStyle() {
- return _mapFrame.getGridLineStyle().toString();
- }
-
- /**
- * Set grid line style
- *
- * @param style Grid line style
- */
- public void setGridLineStyle(String style) {
- _mapFrame.setGridLineStyle(LineStyles.valueOf(style));
- }
-
- /**
- * Get if draw grid labels
- *
- * @return If draw grid labels
- */
- public boolean isDrawGridLabel() {
- return _mapFrame.isDrawGridLabel();
- }
-
- /**
- * Set if draw grid labels
- *
- * @param istrue Boolean
- */
- public void setDrawGridLabel(boolean istrue) {
- _mapFrame.setDrawGridLabel(istrue);
- }
-
- /**
- * Get if draw grid tick line inside
- *
- * @return Booelan
- */
- public boolean isInsideTickLine() {
- return _mapFrame.isInsideTickLine();
- }
-
- /**
- * Set if draw grid tick line inside
- *
- * @param istrue Boolean
- */
- public void setInsideTickLine(boolean istrue) {
- _mapFrame.setInsideTickLine(istrue);
- }
-
- /**
- * Get grid tick line length
- *
- * @return Grid tick line length
- */
- public int getTickLineLength() {
- return _mapFrame.getTickLineLength();
- }
-
- /**
- * Set grid tick line length
- *
- * @param value tick line length
- */
- public void setTickLineLength(int value) {
- _mapFrame.setTickLineLength(value);
- }
-
- /**
- * Get grid label shift
- *
- * @return Grid label shift
- */
- public int getGridLabelShift() {
- return _mapFrame.getGridLabelShift();
- }
-
- /**
- * Set grid label shift
- *
- * @param value Grid label shift
- */
- public void setGridLabelShift(int value) {
- _mapFrame.setGridLabelShift(value);
- }
-
- ///
- /// Get or set grid label position
- /**
- * Get grid label position
- *
- * @return Grid label position
- */
- public String getGridLabelPosition() {
- return _mapFrame.getGridLabelPosition().toString();
- }
-
- /**
- * Set grid label positiont
- *
- * @param value Grid label position
- */
- public void setGridLabelPosition(String value) {
- _mapFrame.setGridLabelPosition(GridLabelPosition.valueOf(value));
- }
-
- /**
- * Get if draw grid line
- *
- * @return If draw grid line
- */
- public boolean isDrawGridLine() {
- return _mapFrame.isDrawGridLine();
- }
-
- /**
- * Set if draw grid line
- *
- * @param istrue If draw grid line
- */
- public void setDrawGridLine(boolean istrue) {
- _mapFrame.setDrawGridLine(istrue);
- }
-
- /**
- * Get if draw grid tick line
- *
- * @return Boolean
- */
- public boolean isDrawGridTickLine() {
- return _mapFrame.isDrawGridTickLine();
- }
-
- /**
- * Set if draw grid tick line
- *
- * @param istrue Boolean
- */
- public void setDrawGridTickLine(boolean istrue) {
- _mapFrame.setDrawGridTickLine(istrue);
- }
-
- /**
- * Get if draw degree symbol
- *
- * @return Boolean
- */
- public boolean isDrawDegreeSymbol() {
- return _drawDegreeSymbol;
- }
-
- /**
- * Set if draw degree symbol
- *
- * @param value Boolean
- */
- public void setDrawDegreeSymbol(boolean value) {
- _drawDegreeSymbol = value;
- }
-
- /**
- * Get grid label font
- *
- * @return Grid label font
- */
- public Font getGridFont() {
- return _mapFrame.getGridFont();
- }
-
- /**
- * Set grid label font
- *
- * @param font Grid label font
- */
- public void setGridFont(Font font) {
- _mapFrame.setGridFont(font);
- }
-
- /**
- * Get grid x delt
- *
- * @return Grid x delt
- */
- public double getGridXDelt() {
- return _mapFrame.getGridXDelt();
- }
-
- /**
- * Set grid x delt
- *
- * @param value The value
- */
- public void setGridXDelt(double value) {
- _mapFrame.setGridXDelt(value);
- }
-
- /**
- * Get grid y delt
- *
- * @return Grid y delt
- */
- public double getGridYDelt() {
- return _mapFrame.getGridYDelt();
- }
-
- /**
- * Set grid y delt
- *
- * @param value Grid y delt
- */
- public void setGridYDelt(double value) {
- _mapFrame.setGridYDelt(value);
- }
-
- /**
- * Get grid x origin
- *
- * @return Grid x origin
- */
- public float getGridXOrigin() {
- return _mapFrame.getGridXOrigin();
- }
-
- /**
- * Set grid x origin
- *
- * @param value Grid x origin
- */
- public void setGridXOrigin(float value) {
- _mapFrame.setGridXOrigin(value);
- }
-
- /**
- * Get grid y origin
- *
- * @return Grid y origin
- */
- public float getGridYOrigin() {
- return _mapFrame.getGridYOrigin();
- }
-
- /**
- * Set grid y origin
- *
- * @param value Grid y origin
- */
- public void setGridYOrigin(float value) {
- _mapFrame.setGridYOrigin(value);
- }
- //
- }
-
- public static class LayoutMapBeanBeanInfo extends BaseBeanInfo {
-
- public LayoutMapBeanBeanInfo() {
- super(LayoutMapBean.class);
- addProperty("drawBackColor").setCategory("General").setDisplayName("Draw Background");
- addProperty("backColor").setCategory("General").setDisplayName("Background");
- addProperty("foreColor").setCategory("General").setDisplayName("Foreground");
- addProperty("drawNeatLine").setCategory("Neat Line").setDisplayName("Draw Neat Line");
- addProperty("neatLineColor").setCategory("Neat Line").setDisplayName("Neat Line Color");
- addProperty("neatLineSize").setCategory("Neat Line").setDisplayName("Neat Line Size");
- addProperty("drawGridLine").setCategory("Grid Line").setDisplayName("Draw Grid Line");
- addProperty("drawGridLabel").setCategory("Grid Line").setDisplayName("Draw Grid Label");
- addProperty("gridXDelt").setCategory("Grid Line").setDisplayName("Grid X Interval");
- addProperty("gridYDelt").setCategory("Grid Line").setDisplayName("Grid Y Interval");
- addProperty("gridXOrigin").setCategory("Grid Line").setDisplayName("Grid X Origin");
- addProperty("gridYOrigin").setCategory("Grid Line").setDisplayName("Grid Y Origin");
- addProperty("gridFont").setCategory("Grid Line").setDisplayName("Grid Label Font");
- addProperty("gridLabelShift").setCategory("Grid Line").setDisplayName("Grid Label Shift");
- ExtendedPropertyDescriptor e = addProperty("gridLabelPosition");
- e.setCategory("Grid Line").setDisplayName("Grid Label Position");
- e.setPropertyEditorClass(GridLabelPositionEditor.class);
- addProperty("drawDegreeSymbol").setCategory("Grid Line").setDisplayName("Draw Degree Symbol");
- addProperty("gridLineColor").setCategory("Grid Line").setDisplayName("Grid Line Color");
- addProperty("gridLineSize").setCategory("Grid Line").setDisplayName("Grid Line Size");
- e = addProperty("gridLineStyle");
- e.setCategory("Grid Line").setDisplayName("Grid Line Style");
- e.setPropertyEditorClass(LineStyleEditor.class);
- addProperty("insideTickLine").setCategory("Grid Line").setDisplayName("Inside Tick Line");
- addProperty("tickLineLength").setCategory("Grid Line").setDisplayName("Tick Line Length");
- addProperty("left").setCategory("Location").setDisplayName("Left");
- addProperty("top").setCategory("Location").setDisplayName("Top");
- addProperty("width").setCategory("Location").setDisplayName("Width");
- addProperty("height").setCategory("Location").setDisplayName("Height");
- }
- }
-
- public static class GridLabelPositionEditor extends ComboBoxPropertyEditor {
-
- public GridLabelPositionEditor() {
- super();
- GridLabelPosition[] lutypes = GridLabelPosition.values();
- String[] types = new String[lutypes.length];
- int i = 0;
- for (GridLabelPosition type : lutypes) {
- types[i] = type.toString();
- i += 1;
- }
- setAvailableValues(types);
- }
- }
-
- public static class LineStyleEditor extends ComboBoxPropertyEditor {
-
- public LineStyleEditor() {
- super();
- LineStyles[] lutypes = LineStyles.values();
- String[] types = new String[lutypes.length];
- int i = 0;
- for (LineStyles type : lutypes) {
- types[i] = type.toString();
- i += 1;
- }
- setAvailableValues(types);
- }
- }
- //
-}
+/* Copyright 2012 Yaqiang Wang,
+ * yaqiang.wang@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ */
+package org.meteoinfo.layout;
+
+import com.l2fprod.common.beans.BaseBeanInfo;
+import com.l2fprod.common.beans.ExtendedPropertyDescriptor;
+import com.l2fprod.common.beans.editor.ComboBoxPropertyEditor;
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.MIMath;
+import org.meteoinfo.common.PointF;
+import org.meteoinfo.global.event.ILayersUpdatedListener;
+import org.meteoinfo.global.event.IMapViewUpdatedListener;
+import org.meteoinfo.global.event.LayersUpdatedEvent;
+import org.meteoinfo.global.event.MapViewUpdatedEvent;
+import org.meteoinfo.legend.GridLabelPosition;
+import org.meteoinfo.legend.LineStyles;
+import org.meteoinfo.legend.MapFrame;
+import org.meteoinfo.map.GridLabel;
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.geom.Line2D;
+import java.util.ArrayList;
+import java.util.List;
+import javax.swing.event.EventListenerList;
+import org.meteoinfo.data.mapdata.webmap.TileLoadListener;
+
+/**
+ *
+ * @author yaqiang
+ */
+public class LayoutMap extends LayoutElement {
+ //
+
+ public void addMapViewUpdatedListener(IMapViewUpdatedListener listener) {
+ this._listeners.add(IMapViewUpdatedListener.class, listener);
+ }
+
+ public void removeMapViewUpdatedListener(IMapViewUpdatedListener listener) {
+ this._listeners.remove(IMapViewUpdatedListener.class, listener);
+ }
+
+ public void fireMapViewUpdatedEvent() {
+ fireMapViewUpdatedEvent(new MapViewUpdatedEvent(this));
+ }
+
+ private void fireMapViewUpdatedEvent(MapViewUpdatedEvent event) {
+ Object[] listeners = _listeners.getListenerList();
+ for (int i = 0; i < listeners.length; i = i + 2) {
+ if (listeners[i] == IMapViewUpdatedListener.class) {
+ ((IMapViewUpdatedListener) listeners[i + 1]).mapViewUpdatedEvent(event);
+ }
+ }
+ }
+ //
+ //
+ private EventListenerList _listeners = new EventListenerList();
+ private MapFrame _mapFrame = null;
+ private boolean _drawDegreeSymbol = false;
+ private final TileLoadListener tileLoadListener;
+ //
+ //
+
+ /**
+ * Constructor
+ *
+ * @param mapFrame MapFrame
+ * @param tll TileLoadListener
+ */
+ public LayoutMap(MapFrame mapFrame, TileLoadListener tll) {
+ super();
+ this.setElementType(ElementType.LayoutMap);
+ this.setResizeAbility(ResizeAbility.ResizeAll);
+ this.setMapFrame(mapFrame);
+ this.tileLoadListener = tll;
+ }
+ //
+ //
+
+ public MapFrame getMapFrame() {
+ return _mapFrame;
+ }
+
+ public void setMapFrame(MapFrame mf) {
+ _mapFrame = mf;
+ _mapFrame.addMapViewUpdatedListener(new IMapViewUpdatedListener() {
+ @Override
+ public void mapViewUpdatedEvent(MapViewUpdatedEvent event) {
+ fireMapViewUpdatedEvent();
+ }
+ });
+
+ _mapFrame.addLayersUpdatedListener(new ILayersUpdatedListener() {
+ @Override
+ public void layersUpdatedEvent(LayersUpdatedEvent event) {
+ fireMapViewUpdatedEvent();
+ }
+ });
+ }
+
+ /**
+ * Get left
+ *
+ * @return Left
+ */
+ @Override
+ public int getLeft() {
+ return _mapFrame.getLayoutBounds().x;
+ }
+
+ /**
+ * Set left
+ *
+ * @param left Left
+ */
+ @Override
+ public void setLeft(int left) {
+ _mapFrame.setLayoutBounds(new Rectangle(left, _mapFrame.getLayoutBounds().y, _mapFrame.getLayoutBounds().width,
+ _mapFrame.getLayoutBounds().height));
+ }
+
+ /**
+ * Get top
+ *
+ * @return Top
+ */
+ @Override
+ public int getTop() {
+ return _mapFrame.getLayoutBounds().y;
+ }
+
+ /**
+ * Set top
+ *
+ * @param top Top
+ */
+ @Override
+ public void setTop(int top) {
+ _mapFrame.setLayoutBounds(new Rectangle(_mapFrame.getLayoutBounds().x, top, _mapFrame.getLayoutBounds().width,
+ _mapFrame.getLayoutBounds().height));
+ }
+
+ /**
+ * Get width
+ *
+ * @return Width
+ */
+ @Override
+ public int getWidth() {
+ return _mapFrame.getLayoutBounds().width;
+ }
+
+ /**
+ * Set width
+ *
+ * @param width Width
+ */
+ @Override
+ public void setWidth(int width) {
+ _mapFrame.setLayoutBounds(new Rectangle(_mapFrame.getLayoutBounds().x, _mapFrame.getLayoutBounds().y, width,
+ _mapFrame.getLayoutBounds().height));
+ }
+
+ /**
+ * Get height
+ *
+ * @return Height
+ */
+ @Override
+ public int getHeight() {
+ return _mapFrame.getLayoutBounds().height;
+ }
+
+ /**
+ * Set height
+ *
+ * @param height Height
+ */
+ @Override
+ public void setHeight(int height) {
+ _mapFrame.setLayoutBounds(new Rectangle(_mapFrame.getLayoutBounds().x, _mapFrame.getLayoutBounds().y,
+ _mapFrame.getLayoutBounds().width, height));
+ }
+
+ /**
+ * Get bounds rectangle
+ *
+ * @return The bounds rectangle
+ */
+ @Override
+ public Rectangle getBounds() {
+ return _mapFrame.getLayoutBounds();
+ }
+
+ /**
+ * Set bounds rectangle
+ *
+ * @param rect Bounds rectangle
+ */
+ public void setBounds(Rectangle rect) {
+ _mapFrame.setLayoutBounds(rect);
+ }
+
+ /**
+ * Get background color
+ *
+ * @return Background color
+ */
+ @Override
+ public Color getBackColor() {
+ return _mapFrame.getBackColor();
+ }
+
+ /**
+ * Set background color
+ *
+ * @param color Background color
+ */
+ @Override
+ public void setBackColor(Color color) {
+ _mapFrame.setBackColor(color);
+ }
+
+ /**
+ * Get foreground color
+ *
+ * @return Foreground color
+ */
+ @Override
+ public Color getForeColor() {
+ return _mapFrame.getForeColor();
+ }
+
+ /**
+ * Set foreground color
+ *
+ * @param color
+ */
+ @Override
+ public void setForeColor(Color color) {
+ _mapFrame.setForeColor(color);
+ }
+
+ /**
+ * Get if draw map view neat line
+ *
+ * @return Boolean
+ */
+ public boolean isDrawNeatLine() {
+ return _mapFrame.isDrawNeatLine();
+ }
+
+ /**
+ * Set if draw map view neat line
+ *
+ * @param istrue Boolean
+ */
+ public void setDrawNeatLine(boolean istrue) {
+ _mapFrame.setDrawNeatLine(istrue);
+ }
+
+ /**
+ * Get map view neat line color
+ *
+ * @return Neat line color
+ */
+ public Color getNeatLineColor() {
+ return _mapFrame.getNeatLineColor();
+ }
+
+ /**
+ * Set map view neat line color
+ *
+ * @param color Neat line color
+ */
+ public void setNeatLineColor(Color color) {
+ _mapFrame.setNeatLineColor(color);
+ }
+
+ /**
+ * Get map view neat line size
+ *
+ * @return Neat line size
+ */
+ public float getNeatLineSize() {
+ return _mapFrame.getNeatLineSize();
+ }
+
+ /**
+ * Set map view neat line size
+ *
+ * @param size Neat line size
+ */
+ public void setNeatLineSize(float size) {
+ _mapFrame.setNeatLineSize(size);
+ }
+
+ /**
+ * Get grid line color
+ *
+ * @return Grid line color
+ */
+ public Color getGridLineColor() {
+ return _mapFrame.getGridLineColor();
+ }
+
+ /**
+ * Set grid line color
+ *
+ * @param color Grid line color
+ */
+ public void setGridLineColor(Color color) {
+ _mapFrame.setGridLineColor(color);
+ }
+
+ /**
+ * Get grid line size
+ *
+ * @return Grid line size
+ */
+ public float getGridLineSize() {
+ return _mapFrame.getGridLineSize();
+ }
+
+ /**
+ * Set grid line size
+ *
+ * @param size Grid line size
+ */
+ public void setGridLineSize(float size) {
+ _mapFrame.setGridLineSize(size);
+ }
+
+ /**
+ * Get grid line style
+ *
+ * @return Grid line style
+ */
+ public LineStyles getGridLineStyle() {
+ return _mapFrame.getGridLineStyle();
+ }
+
+ /**
+ * Set grid line style
+ *
+ * @param style Grid line style
+ */
+ public void setGridLineStyle(LineStyles style) {
+ _mapFrame.setGridLineStyle(style);
+ }
+
+ /**
+ * Get if draw grid labels
+ *
+ * @return If draw grid labels
+ */
+ public boolean isDrawGridLabel() {
+ return _mapFrame.isDrawGridLabel();
+ }
+
+ /**
+ * Set if draw grid labels
+ *
+ * @param istrue Boolean
+ */
+ public void setDrawGridLabel(boolean istrue) {
+ _mapFrame.setDrawGridLabel(istrue);
+ }
+
+ /**
+ * Get if draw grid tick line inside
+ *
+ * @return Booelan
+ */
+ public boolean isInsideTickLine() {
+ return _mapFrame.isInsideTickLine();
+ }
+
+ /**
+ * Set if draw grid tick line inside
+ *
+ * @param istrue Boolean
+ */
+ public void setInsideTickLine(boolean istrue) {
+ _mapFrame.setInsideTickLine(istrue);
+ }
+
+ /**
+ * Get grid tick line length
+ *
+ * @return Grid tick line length
+ */
+ public int getTickLineLength() {
+ return _mapFrame.getTickLineLength();
+ }
+
+ /**
+ * Set grid tick line length
+ *
+ * @param value Tick line length value
+ */
+ public void setTickLineLength(int value) {
+ _mapFrame.setTickLineLength(value);
+ }
+
+ /**
+ * Get grid label shift
+ *
+ * @return Grid label shift
+ */
+ public int getGridLabelShift() {
+ return _mapFrame.getGridLabelShift();
+ }
+
+ /**
+ * Set grid label shift
+ *
+ * @param value Grid label shift
+ */
+ public void setGridLabelShift(int value) {
+ _mapFrame.setGridLabelShift(value);
+ }
+
+ ///
+ /// Get or set grid label position
+ /**
+ * Get grid label position
+ *
+ * @return Grid label position
+ */
+ public GridLabelPosition getGridLabelPosition() {
+ return _mapFrame.getGridLabelPosition();
+ }
+
+ /**
+ * Set grid label positiont
+ *
+ * @param value Grid label position
+ */
+ public void setGridLabelPosition(GridLabelPosition value) {
+ _mapFrame.setGridLabelPosition(value);
+ }
+
+ /**
+ * Get if draw grid line
+ *
+ * @return If draw grid line
+ */
+ public boolean isDrawGridLine() {
+ return _mapFrame.isDrawGridLine();
+ }
+
+ /**
+ * Set if draw grid line
+ *
+ * @param istrue If draw grid line
+ */
+ public void setDrawGridLine(boolean istrue) {
+ _mapFrame.setDrawGridLine(istrue);
+ }
+
+ /**
+ * Get if draw grid tick line
+ *
+ * @return Boolean
+ */
+ public boolean isDrawGridTickLine() {
+ return _mapFrame.isDrawGridTickLine();
+ }
+
+ /**
+ * Set if draw grid tick line
+ *
+ * @param istrue Boolean
+ */
+ public void setDrawGridTickLine(boolean istrue) {
+ _mapFrame.setDrawGridTickLine(istrue);
+ }
+
+ /**
+ * Get if draw degree symbol
+ *
+ * @return Boolean
+ */
+ public boolean isDrawDegreeSymbol() {
+ return _drawDegreeSymbol;
+ }
+
+ /**
+ * Set if draw degree symbol
+ *
+ * @param value Boolean
+ */
+ public void setDrawDegreeSymbol(boolean value) {
+ _drawDegreeSymbol = value;
+ }
+
+ /**
+ * Get grid label font
+ *
+ * @return Grid label font
+ */
+ public Font getGridFont() {
+ return _mapFrame.getGridFont();
+ }
+
+ /**
+ * Set grid label font
+ *
+ * @param font Grid label font
+ */
+ public void setGridFont(Font font) {
+ _mapFrame.setGridFont(font);
+ }
+
+ /**
+ * Get grid x delt
+ *
+ * @return Grid x delt
+ */
+ public double getGridXDelt() {
+ return _mapFrame.getGridXDelt();
+ }
+
+ /**
+ * Set grid x delt
+ *
+ * @param value The value
+ */
+ public void setGridXDelt(double value) {
+ _mapFrame.setGridXDelt(value);
+ }
+
+ /**
+ * Get grid y delt
+ *
+ * @return Grid y delt
+ */
+ public double getGridYDelt() {
+ return _mapFrame.getGridYDelt();
+ }
+
+ /**
+ * Set grid y delt
+ *
+ * @param value Grid y delt
+ */
+ public void setGridYDelt(double value) {
+ _mapFrame.setGridYDelt(value);
+ }
+
+ /**
+ * Get grid x origin
+ *
+ * @return Grid x origin
+ */
+ public float getGridXOrigin() {
+ return _mapFrame.getGridXOrigin();
+ }
+
+ /**
+ * Set grid x origin
+ *
+ * @param value Grid x origin
+ */
+ public void setGridXOrigin(float value) {
+ _mapFrame.setGridXOrigin(value);
+ }
+
+ /**
+ * Get grid y origin
+ *
+ * @return Grid y origin
+ */
+ public float getGridYOrigin() {
+ return _mapFrame.getGridYOrigin();
+ }
+
+ /**
+ * Set grid y origin
+ *
+ * @param value Grid y origin
+ */
+ public void setGridYOrigin(float value) {
+ _mapFrame.setGridYOrigin(value);
+ }
+
+ //
+ //
+ /**
+ * Zoom to exactly lon/lat extent
+ *
+ * @param aExtent The lon/lat extent
+ */
+ public void zoomToExtentLonLatEx(Extent aExtent) {
+ if (!_mapFrame.getMapView().getProjection().isLonLatMap()) {
+ aExtent = _mapFrame.getMapView().getProjection().getProjectedExtentFromLonLat(aExtent);
+ }
+
+ setSizeByExtent(aExtent);
+ _mapFrame.getMapView().setViewExtent(aExtent);
+ }
+
+ private void setSizeByExtent(Extent aExtent) {
+ double scaleFactor;
+
+ double scaleX = this.getWidth() / (aExtent.maxX - aExtent.minX);
+ double scaleY = this.getHeight() / (aExtent.maxY - aExtent.minY);
+ if (_mapFrame.getMapView().getProjection().isLonLatMap()) {
+ scaleFactor = _mapFrame.getMapView().getXYScaleFactor();
+ } else {
+ scaleFactor = 1;
+ }
+
+ if (scaleX > scaleY) {
+ scaleX = scaleY / scaleFactor;
+ this.setWidth((int) ((aExtent.maxX - aExtent.minX) * scaleX));
+ } else {
+ scaleY = scaleX * scaleFactor;
+ this.setHeight((int) ((aExtent.maxY - aExtent.minY) * scaleY));
+ }
+ }
+
+ /**
+ * Paint method
+ *
+ * @param g Graphics2D
+ */
+ @Override
+ public void paint(Graphics2D g) {
+ if (_mapFrame != null) {
+ g.setColor(_mapFrame.getMapView().getBackground());
+ g.fill(_mapFrame.getLayoutBounds());
+
+ _mapFrame.getMapView().paintGraphics(g, _mapFrame.getLayoutBounds(), this.tileLoadListener);
+
+// //Draw lon/lat grid labels
+// if (_mapFrame.getDrawGridLabel())
+// {
+// List extentList = new ArrayList();
+// Extent maxExtent = new Extent();
+// Extent aExtent = new Extent();
+// SizeF aSF = new SizeF();
+// SolidBrush aBrush = new SolidBrush(this.ForeColor);
+// Pen aPen = new Pen(_mapFrame.GridLineColor);
+// aPen.Width = _mapFrame.GridLineSize;
+// String drawStr;
+// PointF sP = new PointF(0, 0);
+// PointF eP = new PointF(0, 0);
+// Font font = new Font(_mapFrame.getGridFont().Name, _mapFrame.getGridFont().Size, _mapFrame.getGridFont().Style);
+// float labX, labY;
+// int len = 5;
+// int space = len + 2;
+// for (int i = 0; i < _mapFrame.getMapView().getGridLabels().Count; i++)
+// {
+// GridLabel aGL = _mapFrame.getMapView().getGridLabels()[i];
+// switch (_mapFrame.getGridLabelPosition())
+// {
+// case GridLabelPosition.LeftBottom:
+// switch (aGL.LabDirection)
+// {
+// case Direction.East:
+// case Direction.North:
+// continue;
+// }
+// break;
+// case GridLabelPosition.LeftUp:
+// switch (aGL.LabDirection)
+// {
+// case Direction.East:
+// case Direction.South:
+// continue;
+// }
+// break;
+// case GridLabelPosition.RightBottom:
+// switch (aGL.LabDirection)
+// {
+// case Direction.Weast:
+// case Direction.North:
+// continue;
+// }
+// break;
+// case GridLabelPosition.RightUp:
+// switch (aGL.LabDirection)
+// {
+// case Direction.Weast:
+// case Direction.South:
+// continue;
+// }
+// break;
+// }
+//
+// labX = (float)aGL.LabPoint.X;
+// labY = (float)aGL.LabPoint.Y;
+// labX = labX + this.Left;
+// labY = labY + this.Top;
+// sP.X = labX;
+// sP.Y = labY;
+//
+// drawStr = aGL.LabString;
+// aSF = g.MeasureString(drawStr, font);
+// switch (aGL.LabDirection)
+// {
+// case Direction.South:
+// labX = labX - aSF.Width / 2;
+// labY = labY + space;
+// eP.X = sP.X;
+// eP.Y = sP.Y + len;
+// break;
+// case Direction.Weast:
+// labX = labX - aSF.Width - space;
+// labY = labY - aSF.Height / 2;
+// eP.X = sP.X - len;
+// eP.Y = sP.Y;
+// break;
+// case Direction.North:
+// labX = labX - aSF.Width / 2;
+// labY = labY - aSF.Height - space;
+// eP.X = sP.X;
+// eP.Y = sP.Y - len;
+// break;
+// case Direction.East:
+// labX = labX + space;
+// labY = labY - aSF.Height / 2;
+// eP.X = sP.X + len;
+// eP.Y = sP.Y;
+// break;
+// }
+//
+// bool ifDraw = true;
+// float aSize = aSF.Width / 2;
+// float bSize = aSF.Height / 2;
+// aExtent.minX = labX;
+// aExtent.maxX = labX + aSF.Width;
+// aExtent.minY = labY - aSF.Height;
+// aExtent.maxY = labY;
+//
+// //Judge extent
+// if (extentList.Count == 0)
+// {
+// maxExtent = aExtent;
+// extentList.Add(aExtent);
+// }
+// else
+// {
+// if (!MIMath.IsExtentCross(aExtent, maxExtent))
+// {
+// extentList.Add(aExtent);
+// maxExtent = MIMath.GetLagerExtent(maxExtent, aExtent);
+// }
+// else
+// {
+// for (int j = 0; j < extentList.Count; j++)
+// {
+// if (MIMath.IsExtentCross(aExtent, extentList[j]))
+// {
+// ifDraw = false;
+// break;
+// }
+// }
+// if (ifDraw)
+// {
+// extentList.Add(aExtent);
+// maxExtent = MIMath.GetLagerExtent(maxExtent, aExtent);
+// }
+// }
+// }
+//
+// if (ifDraw)
+// {
+// g.DrawLine(aPen, sP, eP);
+// g.DrawString(drawStr, font, aBrush, labX, labY);
+// }
+// }
+// }
+ if (_mapFrame.isDrawNeatLine()) {
+ g.setColor(_mapFrame.getNeatLineColor());
+ g.setStroke(new BasicStroke(_mapFrame.getNeatLineSize()));
+ g.draw(_mapFrame.getLayoutBounds());
+ }
+ }
+ }
+
+ @Override
+ public void paintOnLayout(Graphics2D g, PointF pageLocation, float zoom) {
+ if (_mapFrame != null) {
+ PointF aP = pageToScreen(this.getLeft(), this.getTop(), pageLocation, zoom);
+ Rectangle rect = new Rectangle((int) aP.X, (int) aP.Y, (int) (this.getWidth() * zoom), (int) (this.getHeight() * zoom));
+ //g.setColor(_mapFrame.getMapView().getBackground());
+ //g.fill(rect);
+
+ _mapFrame.getMapView().paintGraphics(g, rect, this.tileLoadListener);
+
+ //Draw lon/lat grid labels
+ if (_mapFrame.isDrawGridLabel()) {
+ List extentList = new ArrayList<>();
+ Extent maxExtent = new Extent();
+ Extent aExtent;
+ Dimension aSF;
+ g.setColor(_mapFrame.getGridLineColor());
+ g.setStroke(new BasicStroke(_mapFrame.getGridLineSize()));
+ String drawStr;
+ PointF sP = new PointF(0, 0);
+ PointF eP = new PointF(0, 0);
+ Font font = new Font(_mapFrame.getGridFont().getFontName(), _mapFrame.getGridFont().getStyle(), (int) (_mapFrame.getGridFont().getSize() * zoom));
+ g.setFont(font);
+ float labX, labY;
+ int len = _mapFrame.getTickLineLength();
+ int space = len + _mapFrame.getGridLabelShift();
+ if (_mapFrame.isInsideTickLine()) {
+ space = _mapFrame.getGridLabelShift();
+ }
+
+ for (int i = 0; i < _mapFrame.getMapView().getGridLabels().size(); i++) {
+ GridLabel aGL = _mapFrame.getMapView().getGridLabels().get(i);
+ switch (_mapFrame.getGridLabelPosition()) {
+ case LEFT_BOTTOM:
+ switch (aGL.getLabDirection()) {
+ case East:
+ case North:
+ continue;
+ }
+ break;
+ case LEFT_UP:
+ switch (aGL.getLabDirection()) {
+ case East:
+ case South:
+ continue;
+ }
+ break;
+ case RIGHT_BOTTOM:
+ switch (aGL.getLabDirection()) {
+ case Weast:
+ case North:
+ continue;
+ }
+ break;
+ case RIGHT_UP:
+ switch (aGL.getLabDirection()) {
+ case Weast:
+ case South:
+ continue;
+ }
+ break;
+ }
+
+ labX = (float) aGL.getLabPoint().X;
+ labY = (float) aGL.getLabPoint().Y;
+ labX = labX + this.getLeft() * zoom + pageLocation.X;
+ labY = labY + this.getTop() * zoom + pageLocation.Y;
+ sP.X = labX;
+ sP.Y = labY;
+
+ drawStr = aGL.getLabString();
+ if (_drawDegreeSymbol) {
+ if (drawStr.endsWith("E") || drawStr.endsWith("W") || drawStr.endsWith("N") || drawStr.endsWith("S")) {
+ drawStr = drawStr.substring(0, drawStr.length() - 1) + String.valueOf((char) 186) + drawStr.substring(drawStr.length() - 1);
+ } else {
+ drawStr = drawStr + String.valueOf((char) 186);
+ }
+ }
+ FontMetrics metrics = g.getFontMetrics(font);
+ aSF = new Dimension(metrics.stringWidth(drawStr), metrics.getHeight());
+ switch (aGL.getLabDirection()) {
+ case South:
+ labX = labX - aSF.width / 2;
+ labY = labY + aSF.height * 3 / 4 + space;
+ eP.X = sP.X;
+ if (_mapFrame.isInsideTickLine()) {
+ eP.Y = sP.Y - len;
+ } else {
+ eP.Y = sP.Y + len;
+ }
+ break;
+ case Weast:
+ labX = labX - aSF.width - space;
+ labY = labY + aSF.height / 3;
+ eP.Y = sP.Y;
+ if (_mapFrame.isInsideTickLine()) {
+ eP.X = sP.X + len;
+ } else {
+ eP.X = sP.X - len;
+ }
+ break;
+ case North:
+ labX = labX - aSF.width / 2;
+ //labY = labY - aSF.height / 3 - space;
+ labY = labY - space;
+ eP.X = sP.X;
+ if (_mapFrame.isInsideTickLine()) {
+ eP.Y = sP.Y + len;
+ } else {
+ eP.Y = sP.Y - len;
+ }
+ break;
+ case East:
+ labX = labX + space;
+ labY = labY + aSF.height / 3;
+ eP.Y = sP.Y;
+ if (_mapFrame.isInsideTickLine()) {
+ eP.X = sP.X - len;
+ } else {
+ eP.X = sP.X + len;
+ }
+ break;
+ }
+
+ boolean ifDraw = true;
+ float aSize = aSF.width / 2;
+ float bSize = aSF.height / 2;
+ aExtent = new Extent();
+ aExtent.minX = labX;
+ aExtent.maxX = labX + aSF.width;
+ aExtent.minY = labY - aSF.height;
+ aExtent.maxY = labY;
+
+ //Judge extent
+ if (extentList.isEmpty()) {
+ maxExtent = (Extent) aExtent.clone();
+ extentList.add((Extent) aExtent.clone());
+ } else {
+ if (!MIMath.isExtentCross(aExtent, maxExtent)) {
+ extentList.add((Extent) aExtent.clone());
+ maxExtent = MIMath.getLagerExtent(maxExtent, aExtent);
+ } else {
+ for (int j = 0; j < extentList.size(); j++) {
+ if (MIMath.isExtentCross(aExtent, extentList.get(j))) {
+ ifDraw = false;
+ break;
+ }
+ }
+ if (ifDraw) {
+ extentList.add(aExtent);
+ maxExtent = MIMath.getLagerExtent(maxExtent, aExtent);
+ }
+ }
+ }
+
+ if (ifDraw) {
+ g.setColor(_mapFrame.getGridLineColor());
+ g.draw(new Line2D.Float(sP.X, sP.Y, eP.X, eP.Y));
+ g.setColor(this.getForeColor());
+ g.drawString(drawStr, labX, labY);
+ }
+ }
+ }
+
+ //Draw neat line
+ if (_mapFrame.isDrawNeatLine()) {
+ g.setColor(_mapFrame.getNeatLineColor());
+ g.setStroke(new BasicStroke(_mapFrame.getNeatLineSize()));
+ g.draw(rect);
+ }
+ }
+ }
+
+ @Override
+ public void moveUpdate() {
+ }
+
+ @Override
+ public void resizeUpdate() {
+ }
+ //
+ //
+
+ public class LayoutMapBean {
+
+ LayoutMapBean() {
+ }
+ //
+
+ /**
+ * Get left
+ *
+ * @return Left
+ */
+ public int getLeft() {
+ return _mapFrame.getLayoutBounds().x;
+ }
+
+ /**
+ * Set left
+ *
+ * @param left Left
+ */
+ public void setLeft(int left) {
+ _mapFrame.setLayoutBounds(new Rectangle(left, _mapFrame.getLayoutBounds().y, _mapFrame.getLayoutBounds().width,
+ _mapFrame.getLayoutBounds().height));
+ }
+
+ /**
+ * Get top
+ *
+ * @return Top
+ */
+ public int getTop() {
+ return _mapFrame.getLayoutBounds().y;
+ }
+
+ /**
+ * Set top
+ *
+ * @param top Top
+ */
+ public void setTop(int top) {
+ _mapFrame.setLayoutBounds(new Rectangle(_mapFrame.getLayoutBounds().x, top, _mapFrame.getLayoutBounds().width,
+ _mapFrame.getLayoutBounds().height));
+ }
+
+ /**
+ * Get width
+ *
+ * @return Width
+ */
+ public int getWidth() {
+ return _mapFrame.getLayoutBounds().width;
+ }
+
+ /**
+ * Set width
+ *
+ * @param width Width
+ */
+ public void setWidth(int width) {
+ _mapFrame.setLayoutBounds(new Rectangle(_mapFrame.getLayoutBounds().x, _mapFrame.getLayoutBounds().y, width,
+ _mapFrame.getLayoutBounds().height));
+ }
+
+ /**
+ * Get height
+ *
+ * @return Height
+ */
+ public int getHeight() {
+ return _mapFrame.getLayoutBounds().height;
+ }
+
+ /**
+ * Set height
+ *
+ * @param height Height
+ */
+ public void setHeight(int height) {
+ _mapFrame.setLayoutBounds(new Rectangle(_mapFrame.getLayoutBounds().x, _mapFrame.getLayoutBounds().y,
+ _mapFrame.getLayoutBounds().width, height));
+ }
+
+ /**
+ * Get bounds rectangle
+ *
+ * @return The bounds rectangle
+ */
+ public Rectangle getBounds() {
+ return _mapFrame.getLayoutBounds();
+ }
+
+ /**
+ * Set bounds rectangle
+ *
+ * @param rect Bounds rectangle
+ */
+ public void setBounds(Rectangle rect) {
+ _mapFrame.setLayoutBounds(rect);
+ }
+
+ /**
+ * Get is draw backcolor
+ *
+ * @return Boolean
+ */
+ public boolean isDrawBackColor() {
+ return LayoutMap.this.isDrawBackColor();
+ }
+
+ /**
+ * Set is draw backcolor
+ *
+ * @param value Boolean
+ */
+ public void setDrawBackColor(boolean value) {
+ LayoutMap.this.setDrawBackColor(value);
+ }
+
+ /**
+ * Get background color
+ *
+ * @return Background color
+ */
+ public Color getBackColor() {
+ return _mapFrame.getBackColor();
+ }
+
+ /**
+ * Set background color
+ *
+ * @param color Background color
+ */
+ public void setBackColor(Color color) {
+ _mapFrame.setBackColor(color);
+ }
+
+ /**
+ * Get foreground color
+ *
+ * @return Foreground color
+ */
+ public Color getForeColor() {
+ return _mapFrame.getForeColor();
+ }
+
+ /**
+ * Set foreground color
+ *
+ * @param color
+ */
+ public void setForeColor(Color color) {
+ _mapFrame.setForeColor(color);
+ }
+
+ /**
+ * Get if draw map view neat line
+ *
+ * @return Boolean
+ */
+ public boolean isDrawNeatLine() {
+ return _mapFrame.isDrawNeatLine();
+ }
+
+ /**
+ * Set if draw map view neat line
+ *
+ * @param istrue Boolean
+ */
+ public void setDrawNeatLine(boolean istrue) {
+ _mapFrame.setDrawNeatLine(istrue);
+ }
+
+ /**
+ * Get map view neat line color
+ *
+ * @return Neat line color
+ */
+ public Color getNeatLineColor() {
+ return _mapFrame.getNeatLineColor();
+ }
+
+ /**
+ * Set map view neat line color
+ *
+ * @param color Neat line color
+ */
+ public void setNeatLineColor(Color color) {
+ _mapFrame.setNeatLineColor(color);
+ }
+
+ /**
+ * Get map view neat line size
+ *
+ * @return Neat line size
+ */
+ public float getNeatLineSize() {
+ return _mapFrame.getNeatLineSize();
+ }
+
+ /**
+ * Set map view neat line size
+ *
+ * @param size Neat line size
+ */
+ public void setNeatLineSize(float size) {
+ _mapFrame.setNeatLineSize(size);
+ }
+
+ /**
+ * Get grid line color
+ *
+ * @return Grid line color
+ */
+ public Color getGridLineColor() {
+ return _mapFrame.getGridLineColor();
+ }
+
+ /**
+ * Set grid line color
+ *
+ * @param color Grid line color
+ */
+ public void setGridLineColor(Color color) {
+ _mapFrame.setGridLineColor(color);
+ }
+
+ /**
+ * Get grid line size
+ *
+ * @return Grid line size
+ */
+ public float getGridLineSize() {
+ return _mapFrame.getGridLineSize();
+ }
+
+ /**
+ * Set grid line size
+ *
+ * @param size Grid line size
+ */
+ public void setGridLineSize(float size) {
+ _mapFrame.setGridLineSize(size);
+ }
+
+ /**
+ * Get grid line style
+ *
+ * @return Grid line style
+ */
+ public String getGridLineStyle() {
+ return _mapFrame.getGridLineStyle().toString();
+ }
+
+ /**
+ * Set grid line style
+ *
+ * @param style Grid line style
+ */
+ public void setGridLineStyle(String style) {
+ _mapFrame.setGridLineStyle(LineStyles.valueOf(style));
+ }
+
+ /**
+ * Get if draw grid labels
+ *
+ * @return If draw grid labels
+ */
+ public boolean isDrawGridLabel() {
+ return _mapFrame.isDrawGridLabel();
+ }
+
+ /**
+ * Set if draw grid labels
+ *
+ * @param istrue Boolean
+ */
+ public void setDrawGridLabel(boolean istrue) {
+ _mapFrame.setDrawGridLabel(istrue);
+ }
+
+ /**
+ * Get if draw grid tick line inside
+ *
+ * @return Booelan
+ */
+ public boolean isInsideTickLine() {
+ return _mapFrame.isInsideTickLine();
+ }
+
+ /**
+ * Set if draw grid tick line inside
+ *
+ * @param istrue Boolean
+ */
+ public void setInsideTickLine(boolean istrue) {
+ _mapFrame.setInsideTickLine(istrue);
+ }
+
+ /**
+ * Get grid tick line length
+ *
+ * @return Grid tick line length
+ */
+ public int getTickLineLength() {
+ return _mapFrame.getTickLineLength();
+ }
+
+ /**
+ * Set grid tick line length
+ *
+ * @param value tick line length
+ */
+ public void setTickLineLength(int value) {
+ _mapFrame.setTickLineLength(value);
+ }
+
+ /**
+ * Get grid label shift
+ *
+ * @return Grid label shift
+ */
+ public int getGridLabelShift() {
+ return _mapFrame.getGridLabelShift();
+ }
+
+ /**
+ * Set grid label shift
+ *
+ * @param value Grid label shift
+ */
+ public void setGridLabelShift(int value) {
+ _mapFrame.setGridLabelShift(value);
+ }
+
+ ///
+ /// Get or set grid label position
+ /**
+ * Get grid label position
+ *
+ * @return Grid label position
+ */
+ public String getGridLabelPosition() {
+ return _mapFrame.getGridLabelPosition().toString();
+ }
+
+ /**
+ * Set grid label positiont
+ *
+ * @param value Grid label position
+ */
+ public void setGridLabelPosition(String value) {
+ _mapFrame.setGridLabelPosition(GridLabelPosition.valueOf(value));
+ }
+
+ /**
+ * Get if draw grid line
+ *
+ * @return If draw grid line
+ */
+ public boolean isDrawGridLine() {
+ return _mapFrame.isDrawGridLine();
+ }
+
+ /**
+ * Set if draw grid line
+ *
+ * @param istrue If draw grid line
+ */
+ public void setDrawGridLine(boolean istrue) {
+ _mapFrame.setDrawGridLine(istrue);
+ }
+
+ /**
+ * Get if draw grid tick line
+ *
+ * @return Boolean
+ */
+ public boolean isDrawGridTickLine() {
+ return _mapFrame.isDrawGridTickLine();
+ }
+
+ /**
+ * Set if draw grid tick line
+ *
+ * @param istrue Boolean
+ */
+ public void setDrawGridTickLine(boolean istrue) {
+ _mapFrame.setDrawGridTickLine(istrue);
+ }
+
+ /**
+ * Get if draw degree symbol
+ *
+ * @return Boolean
+ */
+ public boolean isDrawDegreeSymbol() {
+ return _drawDegreeSymbol;
+ }
+
+ /**
+ * Set if draw degree symbol
+ *
+ * @param value Boolean
+ */
+ public void setDrawDegreeSymbol(boolean value) {
+ _drawDegreeSymbol = value;
+ }
+
+ /**
+ * Get grid label font
+ *
+ * @return Grid label font
+ */
+ public Font getGridFont() {
+ return _mapFrame.getGridFont();
+ }
+
+ /**
+ * Set grid label font
+ *
+ * @param font Grid label font
+ */
+ public void setGridFont(Font font) {
+ _mapFrame.setGridFont(font);
+ }
+
+ /**
+ * Get grid x delt
+ *
+ * @return Grid x delt
+ */
+ public double getGridXDelt() {
+ return _mapFrame.getGridXDelt();
+ }
+
+ /**
+ * Set grid x delt
+ *
+ * @param value The value
+ */
+ public void setGridXDelt(double value) {
+ _mapFrame.setGridXDelt(value);
+ }
+
+ /**
+ * Get grid y delt
+ *
+ * @return Grid y delt
+ */
+ public double getGridYDelt() {
+ return _mapFrame.getGridYDelt();
+ }
+
+ /**
+ * Set grid y delt
+ *
+ * @param value Grid y delt
+ */
+ public void setGridYDelt(double value) {
+ _mapFrame.setGridYDelt(value);
+ }
+
+ /**
+ * Get grid x origin
+ *
+ * @return Grid x origin
+ */
+ public float getGridXOrigin() {
+ return _mapFrame.getGridXOrigin();
+ }
+
+ /**
+ * Set grid x origin
+ *
+ * @param value Grid x origin
+ */
+ public void setGridXOrigin(float value) {
+ _mapFrame.setGridXOrigin(value);
+ }
+
+ /**
+ * Get grid y origin
+ *
+ * @return Grid y origin
+ */
+ public float getGridYOrigin() {
+ return _mapFrame.getGridYOrigin();
+ }
+
+ /**
+ * Set grid y origin
+ *
+ * @param value Grid y origin
+ */
+ public void setGridYOrigin(float value) {
+ _mapFrame.setGridYOrigin(value);
+ }
+ //
+ }
+
+ public static class LayoutMapBeanBeanInfo extends BaseBeanInfo {
+
+ public LayoutMapBeanBeanInfo() {
+ super(LayoutMapBean.class);
+ addProperty("drawBackColor").setCategory("General").setDisplayName("Draw Background");
+ addProperty("backColor").setCategory("General").setDisplayName("Background");
+ addProperty("foreColor").setCategory("General").setDisplayName("Foreground");
+ addProperty("drawNeatLine").setCategory("Neat Line").setDisplayName("Draw Neat Line");
+ addProperty("neatLineColor").setCategory("Neat Line").setDisplayName("Neat Line Color");
+ addProperty("neatLineSize").setCategory("Neat Line").setDisplayName("Neat Line Size");
+ addProperty("drawGridLine").setCategory("Grid Line").setDisplayName("Draw Grid Line");
+ addProperty("drawGridLabel").setCategory("Grid Line").setDisplayName("Draw Grid Label");
+ addProperty("gridXDelt").setCategory("Grid Line").setDisplayName("Grid X Interval");
+ addProperty("gridYDelt").setCategory("Grid Line").setDisplayName("Grid Y Interval");
+ addProperty("gridXOrigin").setCategory("Grid Line").setDisplayName("Grid X Origin");
+ addProperty("gridYOrigin").setCategory("Grid Line").setDisplayName("Grid Y Origin");
+ addProperty("gridFont").setCategory("Grid Line").setDisplayName("Grid Label Font");
+ addProperty("gridLabelShift").setCategory("Grid Line").setDisplayName("Grid Label Shift");
+ ExtendedPropertyDescriptor e = addProperty("gridLabelPosition");
+ e.setCategory("Grid Line").setDisplayName("Grid Label Position");
+ e.setPropertyEditorClass(GridLabelPositionEditor.class);
+ addProperty("drawDegreeSymbol").setCategory("Grid Line").setDisplayName("Draw Degree Symbol");
+ addProperty("gridLineColor").setCategory("Grid Line").setDisplayName("Grid Line Color");
+ addProperty("gridLineSize").setCategory("Grid Line").setDisplayName("Grid Line Size");
+ e = addProperty("gridLineStyle");
+ e.setCategory("Grid Line").setDisplayName("Grid Line Style");
+ e.setPropertyEditorClass(LineStyleEditor.class);
+ addProperty("insideTickLine").setCategory("Grid Line").setDisplayName("Inside Tick Line");
+ addProperty("tickLineLength").setCategory("Grid Line").setDisplayName("Tick Line Length");
+ addProperty("left").setCategory("Location").setDisplayName("Left");
+ addProperty("top").setCategory("Location").setDisplayName("Top");
+ addProperty("width").setCategory("Location").setDisplayName("Width");
+ addProperty("height").setCategory("Location").setDisplayName("Height");
+ }
+ }
+
+ public static class GridLabelPositionEditor extends ComboBoxPropertyEditor {
+
+ public GridLabelPositionEditor() {
+ super();
+ GridLabelPosition[] lutypes = GridLabelPosition.values();
+ String[] types = new String[lutypes.length];
+ int i = 0;
+ for (GridLabelPosition type : lutypes) {
+ types[i] = type.toString();
+ i += 1;
+ }
+ setAvailableValues(types);
+ }
+ }
+
+ public static class LineStyleEditor extends ComboBoxPropertyEditor {
+
+ public LineStyleEditor() {
+ super();
+ LineStyles[] lutypes = LineStyles.values();
+ String[] types = new String[lutypes.length];
+ int i = 0;
+ for (LineStyles type : lutypes) {
+ types[i] = type.toString();
+ i += 1;
+ }
+ setAvailableValues(types);
+ }
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/layout/LayoutNorthArrow.java b/MeteoInfoLib/src/main/java/org/meteoinfo/layout/LayoutNorthArrow.java
index 2a0aee9e..958ebf06 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/layout/LayoutNorthArrow.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/layout/LayoutNorthArrow.java
@@ -1,476 +1,477 @@
-/* Copyright 2012 Yaqiang Wang,
- * yaqiang.wang@gmail.com
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.layout;
-
-import com.l2fprod.common.beans.BaseBeanInfo;
-import org.meteoinfo.drawing.Draw;
-import org.meteoinfo.global.PointF;
-import java.awt.BasicStroke;
-import java.awt.Color;
-import java.awt.Graphics2D;
-import java.awt.Rectangle;
-import java.awt.RenderingHints;
-import java.awt.geom.AffineTransform;
-
-/**
- *
- * @author Yaqiang Wang
- */
-public class LayoutNorthArrow extends LayoutElement {
-//
-
- private LayoutMap _layoutMap;
- private boolean _antiAlias;
- private boolean _drawNeatLine;
- private Color _neatLineColor;
- private float _neatLineSize;
- private NorthArrowType _northArrowType;
- private float _angle;
- //
- //
-
- /**
- * Constructor
- *
- * @param layoutMap The layout map
- */
- public LayoutNorthArrow(LayoutMap layoutMap) {
- super();
- this.setElementType(ElementType.LayoutNorthArraw);
- this.setResizeAbility(ResizeAbility.ResizeAll);
-
- this.setWidth(50);
- this.setHeight(50);
-
- _layoutMap = layoutMap;
- _antiAlias = true;
- _drawNeatLine = false;
- _neatLineColor = Color.black;
- _neatLineSize = 1;
- _northArrowType = NorthArrowType.NORTHARROW_1;
- _angle = 0;
- }
- //
- //
-
- /**
- * Get layout map
- *
- * @return The layout map
- */
- public LayoutMap getLayoutMap() {
- return _layoutMap;
- }
-
- /**
- * Get if draw neat line
- *
- * @return If draw neat line
- */
- public boolean isDrawNeatLine() {
- return _drawNeatLine;
- }
-
- /**
- * Set if draw neat line
- *
- * @param istrue If draw neat line
- */
- public void setDrawNeatLine(boolean istrue) {
- _drawNeatLine = istrue;
- }
-
- /**
- * Get neat line color
- *
- * @return Neat line color
- */
- public Color getNeatLineColor() {
- return _neatLineColor;
- }
-
- /**
- * Set neat line color
- *
- * @param color Neat line color
- */
- public void setNeatLineColor(Color color) {
- _neatLineColor = color;
- }
-
- /**
- * Get neat line size
- *
- * @return Neat line size
- */
- public float getNeatLineSize() {
- return _neatLineSize;
- }
-
- /**
- * Set neat line size
- *
- * @param size Neat line size
- */
- public void setNeatLineSize(float size) {
- _neatLineSize = size;
- }
-
- /**
- * Get angle
- *
- * @return Angle
- */
- public float getAngle() {
- return _angle;
- }
-
- /**
- * Set angle
- *
- * @param angle The angle
- */
- public void setAngle(float angle) {
- _angle = angle;
- }
-
- //
- //
- @Override
- public void paint(Graphics2D g) {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- @Override
- public void paintOnLayout(Graphics2D g, PointF pageLocation, float zoom) {
- if (this.isVisible()) {
- paintGraphics(g, pageLocation, zoom);
- }
- }
-
- /**
- * Paint graphics
- *
- * @param g Graphics
- * @param pageLocation Page location
- * @param zoom Zoom
- */
- public void paintGraphics(Graphics2D g, PointF pageLocation, float zoom) {
- AffineTransform oldMatrix = g.getTransform();
- PointF aP = pageToScreen(this.getLeft(), this.getTop(), pageLocation, zoom);
- g.translate(aP.X, aP.Y);
- g.scale(zoom, zoom);
- if (_angle != 0) {
- g.rotate(_angle);
- }
- if (_antiAlias) {
- g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
- } else {
- g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
- }
-
- //Draw background color
- if (this.isDrawBackColor()){
- g.setColor(this.getBackColor());
- g.fill(new Rectangle.Float(0, 0, this.getWidth() * zoom, this.getHeight() * zoom));
- }
-
- drawNorthArrow(g, zoom);
-
- //Draw neatline
- if (_drawNeatLine) {
- Rectangle.Float mapRect = new Rectangle.Float(_neatLineSize - 1, _neatLineSize - 1,
- (this.getWidth() - _neatLineSize) * zoom, (this.getHeight() - _neatLineSize) * zoom);
- g.setColor(_neatLineColor);
- g.setStroke(new BasicStroke(_neatLineSize));
- g.draw(mapRect);
- }
-
- g.setTransform(oldMatrix);
- }
-
- private void drawNorthArrow(Graphics2D g, float zoom) {
- switch (_northArrowType) {
- case NORTHARROW_1:
- drawNorthArrow1(g, zoom);
- break;
- }
- }
-
- private void drawNorthArrow1(Graphics2D g, float zoom) {
- g.setColor(this.getForeColor());
- g.setStroke(new BasicStroke(zoom));
-
- //Draw N symbol
- PointF[] points = new PointF[4];
- int x = this.getWidth() / 2;
- int y = this.getHeight() / 6;
- int w = this.getWidth() / 6;
- int h = this.getHeight() / 4;
- points[0] = new PointF(x - w / 2, y + h / 2);
- points[1] = new PointF(x - w / 2, y - h / 2);
- points[2] = new PointF(x + w / 2, y + h / 2);
- points[3] = new PointF(x + w / 2, y - h / 2);
- Draw.drawPolyline(points, g);
-
- //Draw arrow
- w = this.getWidth() / 2;
- h = this.getHeight() * 2 / 3;
- points = new PointF[3];
- points[0] = new PointF(x - w / 2, this.getHeight());
- points[1] = new PointF(x, this.getHeight() - h / 2);
- points[2] = new PointF(x, this.getHeight() - h);
- Draw.fillPolygon(points, g, null);
-
- points = new PointF[4];
- points[0] = new PointF(x + w / 2, this.getHeight());
- points[1] = new PointF(x, this.getHeight() - h / 2);
- points[2] = new PointF(x, this.getHeight() - h);
- points[3] = points[0];
- Draw.drawPolyline(points, g);
- }
-
- @Override
- public void moveUpdate() {
- }
-
- @Override
- public void resizeUpdate() {
- }
- //
- //
-
- public class LayoutNorthArrowBean {
-
- LayoutNorthArrowBean() {
- }
- //
-
- /**
- * Get if draw neat line
- *
- * @return If draw neat line
- */
- public boolean isDrawNeatLine() {
- return _drawNeatLine;
- }
-
- /**
- * Set if draw neat line
- *
- * @param istrue If draw neat line
- */
- public void setDrawNeatLine(boolean istrue) {
- _drawNeatLine = istrue;
- }
-
- /**
- * Get neat line color
- *
- * @return Neat line color
- */
- public Color getNeatLineColor() {
- return _neatLineColor;
- }
-
- /**
- * Set neat line color
- *
- * @param color Neat line color
- */
- public void setNeatLineColor(Color color) {
- _neatLineColor = color;
- }
-
- /**
- * Get neat line size
- *
- * @return Neat line size
- */
- public float getNeatLineSize() {
- return _neatLineSize;
- }
-
- /**
- * Set neat line size
- *
- * @param size Neat line size
- */
- public void setNeatLineSize(float size) {
- _neatLineSize = size;
- }
-
- /**
- * Get angle
- *
- * @return Angle
- */
- public float getAngle() {
- return _angle;
- }
-
- /**
- * Set angle
- *
- * @param angle The angle
- */
- public void setAngle(float angle) {
- _angle = angle;
- }
-
- /**
- * Get is draw backcolor
- * @return Boolean
- */
- public boolean isDrawBackColor(){
- return LayoutNorthArrow.this.isDrawBackColor();
- }
-
- /**
- * Set is draw backcolor
- * @param value Boolean
- */
- public void setDrawBackColor(boolean value){
- LayoutNorthArrow.this.setDrawBackColor(value);
- }
-
- /**
- * Get background color
- *
- * @return Background color
- */
- public Color getBackColor() {
- return LayoutNorthArrow.this.getBackColor();
- }
-
- /**
- * Set background color
- *
- * @param c Background color
- */
- public void setBackColor(Color c) {
- LayoutNorthArrow.this.setBackColor(c);
- }
-
- /**
- * Get foreground color
- *
- * @return Foreground color
- */
- public Color getForeColor() {
- return LayoutNorthArrow.this.getForeColor();
- }
-
- /**
- * Set foreground color
- *
- * @param c Foreground color
- */
- public void setForeColor(Color c) {
- LayoutNorthArrow.this.setForeColor(c);
- }
-
- /**
- * Get left
- *
- * @return Left
- */
- public int getLeft() {
- return LayoutNorthArrow.this.getLeft();
- }
-
- /**
- * Set left
- *
- * @param left Left
- */
- public void setLeft(int left) {
- LayoutNorthArrow.this.setLeft(left);
- }
-
- /**
- * Get top
- *
- * @return Top
- */
- public int getTop() {
- return LayoutNorthArrow.this.getTop();
- }
-
- /**
- * Set top
- *
- * @param top Top
- */
- public void setTop(int top) {
- LayoutNorthArrow.this.setTop(top);
- }
-
- /**
- * Get width
- *
- * @return Width
- */
- public int getWidth() {
- return LayoutNorthArrow.this.getWidth();
- }
-
- /**
- * Set width
- *
- * @param width Width
- */
- public void setWidth(int width) {
- LayoutNorthArrow.this.setWidth(width);
- }
-
- /**
- * Get height
- *
- * @return Height
- */
- public int getHeight() {
- return LayoutNorthArrow.this.getHeight();
- }
-
- /**
- * Set height
- *
- * @param height Height
- */
- public void setHeight(int height) {
- LayoutNorthArrow.this.setHeight(height);
- }
- //
- }
-
- public static class LayoutNorthArrowBeanBeanInfo extends BaseBeanInfo {
-
- public LayoutNorthArrowBeanBeanInfo() {
- super(LayoutNorthArrowBean.class);
- addProperty("drawBackColor").setCategory("General").setDisplayName("Draw Background");
- addProperty("backColor").setCategory("General").setDisplayName("Background");
- addProperty("foreColor").setCategory("General").setDisplayName("Foreground");
- addProperty("drawNeatLine").setCategory("Neat Line").setDisplayName("Draw Neat Line");
- addProperty("neatLineColor").setCategory("Neat Line").setDisplayName("Neat Line Color");
- addProperty("neatLineSize").setCategory("Neat Line").setDisplayName("Neat Line Size");
- addProperty("angle").setCategory("Location").setDisplayName("Angle");
- addProperty("left").setCategory("Location").setDisplayName("Left");
- addProperty("top").setCategory("Location").setDisplayName("Top");
- addProperty("width").setCategory("Location").setDisplayName("Width");
- addProperty("height").setCategory("Location").setDisplayName("Height");
- }
- }
- //
-}
+/* Copyright 2012 Yaqiang Wang,
+ * yaqiang.wang@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ */
+package org.meteoinfo.layout;
+
+import com.l2fprod.common.beans.BaseBeanInfo;
+import org.meteoinfo.common.PointF;
+import org.meteoinfo.drawing.Draw;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.geom.AffineTransform;
+
+/**
+ *
+ * @author Yaqiang Wang
+ */
+public class LayoutNorthArrow extends LayoutElement {
+//
+
+ private LayoutMap _layoutMap;
+ private boolean _antiAlias;
+ private boolean _drawNeatLine;
+ private Color _neatLineColor;
+ private float _neatLineSize;
+ private NorthArrowType _northArrowType;
+ private float _angle;
+ //
+ //
+
+ /**
+ * Constructor
+ *
+ * @param layoutMap The layout map
+ */
+ public LayoutNorthArrow(LayoutMap layoutMap) {
+ super();
+ this.setElementType(ElementType.LayoutNorthArraw);
+ this.setResizeAbility(ResizeAbility.ResizeAll);
+
+ this.setWidth(50);
+ this.setHeight(50);
+
+ _layoutMap = layoutMap;
+ _antiAlias = true;
+ _drawNeatLine = false;
+ _neatLineColor = Color.black;
+ _neatLineSize = 1;
+ _northArrowType = NorthArrowType.NORTHARROW_1;
+ _angle = 0;
+ }
+ //
+ //
+
+ /**
+ * Get layout map
+ *
+ * @return The layout map
+ */
+ public LayoutMap getLayoutMap() {
+ return _layoutMap;
+ }
+
+ /**
+ * Get if draw neat line
+ *
+ * @return If draw neat line
+ */
+ public boolean isDrawNeatLine() {
+ return _drawNeatLine;
+ }
+
+ /**
+ * Set if draw neat line
+ *
+ * @param istrue If draw neat line
+ */
+ public void setDrawNeatLine(boolean istrue) {
+ _drawNeatLine = istrue;
+ }
+
+ /**
+ * Get neat line color
+ *
+ * @return Neat line color
+ */
+ public Color getNeatLineColor() {
+ return _neatLineColor;
+ }
+
+ /**
+ * Set neat line color
+ *
+ * @param color Neat line color
+ */
+ public void setNeatLineColor(Color color) {
+ _neatLineColor = color;
+ }
+
+ /**
+ * Get neat line size
+ *
+ * @return Neat line size
+ */
+ public float getNeatLineSize() {
+ return _neatLineSize;
+ }
+
+ /**
+ * Set neat line size
+ *
+ * @param size Neat line size
+ */
+ public void setNeatLineSize(float size) {
+ _neatLineSize = size;
+ }
+
+ /**
+ * Get angle
+ *
+ * @return Angle
+ */
+ public float getAngle() {
+ return _angle;
+ }
+
+ /**
+ * Set angle
+ *
+ * @param angle The angle
+ */
+ public void setAngle(float angle) {
+ _angle = angle;
+ }
+
+ //
+ //
+ @Override
+ public void paint(Graphics2D g) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void paintOnLayout(Graphics2D g, PointF pageLocation, float zoom) {
+ if (this.isVisible()) {
+ paintGraphics(g, pageLocation, zoom);
+ }
+ }
+
+ /**
+ * Paint graphics
+ *
+ * @param g Graphics
+ * @param pageLocation Page location
+ * @param zoom Zoom
+ */
+ public void paintGraphics(Graphics2D g, PointF pageLocation, float zoom) {
+ AffineTransform oldMatrix = g.getTransform();
+ PointF aP = pageToScreen(this.getLeft(), this.getTop(), pageLocation, zoom);
+ g.translate(aP.X, aP.Y);
+ g.scale(zoom, zoom);
+ if (_angle != 0) {
+ g.rotate(_angle);
+ }
+ if (_antiAlias) {
+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ } else {
+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
+ }
+
+ //Draw background color
+ if (this.isDrawBackColor()){
+ g.setColor(this.getBackColor());
+ g.fill(new Rectangle.Float(0, 0, this.getWidth() * zoom, this.getHeight() * zoom));
+ }
+
+ drawNorthArrow(g, zoom);
+
+ //Draw neatline
+ if (_drawNeatLine) {
+ Rectangle.Float mapRect = new Rectangle.Float(_neatLineSize - 1, _neatLineSize - 1,
+ (this.getWidth() - _neatLineSize) * zoom, (this.getHeight() - _neatLineSize) * zoom);
+ g.setColor(_neatLineColor);
+ g.setStroke(new BasicStroke(_neatLineSize));
+ g.draw(mapRect);
+ }
+
+ g.setTransform(oldMatrix);
+ }
+
+ private void drawNorthArrow(Graphics2D g, float zoom) {
+ switch (_northArrowType) {
+ case NORTHARROW_1:
+ drawNorthArrow1(g, zoom);
+ break;
+ }
+ }
+
+ private void drawNorthArrow1(Graphics2D g, float zoom) {
+ g.setColor(this.getForeColor());
+ g.setStroke(new BasicStroke(zoom));
+
+ //Draw N symbol
+ PointF[] points = new PointF[4];
+ int x = this.getWidth() / 2;
+ int y = this.getHeight() / 6;
+ int w = this.getWidth() / 6;
+ int h = this.getHeight() / 4;
+ points[0] = new PointF(x - w / 2, y + h / 2);
+ points[1] = new PointF(x - w / 2, y - h / 2);
+ points[2] = new PointF(x + w / 2, y + h / 2);
+ points[3] = new PointF(x + w / 2, y - h / 2);
+ Draw.drawPolyline(points, g);
+
+ //Draw arrow
+ w = this.getWidth() / 2;
+ h = this.getHeight() * 2 / 3;
+ points = new PointF[3];
+ points[0] = new PointF(x - w / 2, this.getHeight());
+ points[1] = new PointF(x, this.getHeight() - h / 2);
+ points[2] = new PointF(x, this.getHeight() - h);
+ Draw.fillPolygon(points, g, null);
+
+ points = new PointF[4];
+ points[0] = new PointF(x + w / 2, this.getHeight());
+ points[1] = new PointF(x, this.getHeight() - h / 2);
+ points[2] = new PointF(x, this.getHeight() - h);
+ points[3] = points[0];
+ Draw.drawPolyline(points, g);
+ }
+
+ @Override
+ public void moveUpdate() {
+ }
+
+ @Override
+ public void resizeUpdate() {
+ }
+ //
+ //
+
+ public class LayoutNorthArrowBean {
+
+ LayoutNorthArrowBean() {
+ }
+ //
+
+ /**
+ * Get if draw neat line
+ *
+ * @return If draw neat line
+ */
+ public boolean isDrawNeatLine() {
+ return _drawNeatLine;
+ }
+
+ /**
+ * Set if draw neat line
+ *
+ * @param istrue If draw neat line
+ */
+ public void setDrawNeatLine(boolean istrue) {
+ _drawNeatLine = istrue;
+ }
+
+ /**
+ * Get neat line color
+ *
+ * @return Neat line color
+ */
+ public Color getNeatLineColor() {
+ return _neatLineColor;
+ }
+
+ /**
+ * Set neat line color
+ *
+ * @param color Neat line color
+ */
+ public void setNeatLineColor(Color color) {
+ _neatLineColor = color;
+ }
+
+ /**
+ * Get neat line size
+ *
+ * @return Neat line size
+ */
+ public float getNeatLineSize() {
+ return _neatLineSize;
+ }
+
+ /**
+ * Set neat line size
+ *
+ * @param size Neat line size
+ */
+ public void setNeatLineSize(float size) {
+ _neatLineSize = size;
+ }
+
+ /**
+ * Get angle
+ *
+ * @return Angle
+ */
+ public float getAngle() {
+ return _angle;
+ }
+
+ /**
+ * Set angle
+ *
+ * @param angle The angle
+ */
+ public void setAngle(float angle) {
+ _angle = angle;
+ }
+
+ /**
+ * Get is draw backcolor
+ * @return Boolean
+ */
+ public boolean isDrawBackColor(){
+ return LayoutNorthArrow.this.isDrawBackColor();
+ }
+
+ /**
+ * Set is draw backcolor
+ * @param value Boolean
+ */
+ public void setDrawBackColor(boolean value){
+ LayoutNorthArrow.this.setDrawBackColor(value);
+ }
+
+ /**
+ * Get background color
+ *
+ * @return Background color
+ */
+ public Color getBackColor() {
+ return LayoutNorthArrow.this.getBackColor();
+ }
+
+ /**
+ * Set background color
+ *
+ * @param c Background color
+ */
+ public void setBackColor(Color c) {
+ LayoutNorthArrow.this.setBackColor(c);
+ }
+
+ /**
+ * Get foreground color
+ *
+ * @return Foreground color
+ */
+ public Color getForeColor() {
+ return LayoutNorthArrow.this.getForeColor();
+ }
+
+ /**
+ * Set foreground color
+ *
+ * @param c Foreground color
+ */
+ public void setForeColor(Color c) {
+ LayoutNorthArrow.this.setForeColor(c);
+ }
+
+ /**
+ * Get left
+ *
+ * @return Left
+ */
+ public int getLeft() {
+ return LayoutNorthArrow.this.getLeft();
+ }
+
+ /**
+ * Set left
+ *
+ * @param left Left
+ */
+ public void setLeft(int left) {
+ LayoutNorthArrow.this.setLeft(left);
+ }
+
+ /**
+ * Get top
+ *
+ * @return Top
+ */
+ public int getTop() {
+ return LayoutNorthArrow.this.getTop();
+ }
+
+ /**
+ * Set top
+ *
+ * @param top Top
+ */
+ public void setTop(int top) {
+ LayoutNorthArrow.this.setTop(top);
+ }
+
+ /**
+ * Get width
+ *
+ * @return Width
+ */
+ public int getWidth() {
+ return LayoutNorthArrow.this.getWidth();
+ }
+
+ /**
+ * Set width
+ *
+ * @param width Width
+ */
+ public void setWidth(int width) {
+ LayoutNorthArrow.this.setWidth(width);
+ }
+
+ /**
+ * Get height
+ *
+ * @return Height
+ */
+ public int getHeight() {
+ return LayoutNorthArrow.this.getHeight();
+ }
+
+ /**
+ * Set height
+ *
+ * @param height Height
+ */
+ public void setHeight(int height) {
+ LayoutNorthArrow.this.setHeight(height);
+ }
+ //
+ }
+
+ public static class LayoutNorthArrowBeanBeanInfo extends BaseBeanInfo {
+
+ public LayoutNorthArrowBeanBeanInfo() {
+ super(LayoutNorthArrowBean.class);
+ addProperty("drawBackColor").setCategory("General").setDisplayName("Draw Background");
+ addProperty("backColor").setCategory("General").setDisplayName("Background");
+ addProperty("foreColor").setCategory("General").setDisplayName("Foreground");
+ addProperty("drawNeatLine").setCategory("Neat Line").setDisplayName("Draw Neat Line");
+ addProperty("neatLineColor").setCategory("Neat Line").setDisplayName("Neat Line Color");
+ addProperty("neatLineSize").setCategory("Neat Line").setDisplayName("Neat Line Size");
+ addProperty("angle").setCategory("Location").setDisplayName("Angle");
+ addProperty("left").setCategory("Location").setDisplayName("Left");
+ addProperty("top").setCategory("Location").setDisplayName("Top");
+ addProperty("width").setCategory("Location").setDisplayName("Width");
+ addProperty("height").setCategory("Location").setDisplayName("Height");
+ }
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/layout/LayoutScaleBar.java b/MeteoInfoLib/src/main/java/org/meteoinfo/layout/LayoutScaleBar.java
index 2cd93cba..fc64637e 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/layout/LayoutScaleBar.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/layout/LayoutScaleBar.java
@@ -1,729 +1,730 @@
- /* Copyright 2012 Yaqiang Wang,
- * yaqiang.wang@gmail.com
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.layout;
-
-import com.l2fprod.common.beans.BaseBeanInfo;
-import com.l2fprod.common.beans.ExtendedPropertyDescriptor;
-import com.l2fprod.common.beans.editor.ComboBoxPropertyEditor;
-import org.meteoinfo.global.PointF;
-import java.awt.BasicStroke;
-import java.awt.Color;
-import java.awt.Font;
-import java.awt.FontMetrics;
-import java.awt.Graphics2D;
-import java.awt.Rectangle;
-import java.awt.RenderingHints;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Line2D;
-
-/**
- *
- * @author Yaqiang Wang
- */
-public class LayoutScaleBar extends LayoutElement {
-//
-
- private LayoutMap _layoutMap;
- private boolean _antiAlias;
- private Font _font;
- private ScaleBarType _scaleBarType;
- private ScaleBarUnits _unit;
- private String _unitText;
- private int _numBreaks;
- private boolean _drawNeatLine;
- private Color _neatLineColor;
- private float _neatLineSize;
- private boolean _drawScaleText;
- private float _yShiftScale = 2.0f;
- //
- //
-
- /**
- * Constructor
- *
- * @param layoutMap The layout map
- */
- public LayoutScaleBar(LayoutMap layoutMap) {
- super();
- this.setElementType(ElementType.LayoutScaleBar);
- this.setResizeAbility(ResizeAbility.ResizeAll);
-
- this.setWidth(200);
- this.setHeight(50);
- _layoutMap = layoutMap;
- _antiAlias = true;
- _scaleBarType = ScaleBarType.SCALELINE_1;
- _drawNeatLine = false;
- _neatLineColor = Color.black;
- _neatLineSize = 1;
- _font = new Font("Arial", Font.PLAIN, 12);
- _unit = ScaleBarUnits.KILOMETERS;
- _unitText = "km";
- _numBreaks = 4;
- _drawScaleText = false;
- }
- //
- //
-
- /**
- * Get layout map
- *
- * @return The layout map
- */
- public LayoutMap getLayoutMap() {
- return _layoutMap;
- }
-
- /**
- * Get scale bar type
- *
- * @return Scale bar type
- */
- public ScaleBarType getScaleBarType() {
- return _scaleBarType;
- }
-
- /**
- * Set scale bar type
- *
- * @param type Scale bar type
- */
- public void setScaleBarType(ScaleBarType type) {
- _scaleBarType = type;
- }
-
- /**
- * Get if draw neat line
- *
- * @return If draw neat line
- */
- public boolean isDrawNeatLine() {
- return _drawNeatLine;
- }
-
- /**
- * Set if draw neat line
- *
- * @param istrue If draw neat line
- */
- public void setDrawNeatLine(boolean istrue) {
- _drawNeatLine = istrue;
- }
-
- /**
- * Get neat line color
- *
- * @return Neat line color
- */
- public Color getNeatLineColor() {
- return _neatLineColor;
- }
-
- /**
- * Set neat line color
- *
- * @param color Neat line color
- */
- public void setNeatLineColor(Color color) {
- _neatLineColor = color;
- }
-
- /**
- * Get neat line size
- *
- * @return Neat line size
- */
- public float getNeatLineSize() {
- return _neatLineSize;
- }
-
- /**
- * Set neat line size
- *
- * @param size Neat line size
- */
- public void setNeatLineSize(float size) {
- _neatLineSize = size;
- }
-
- /**
- * Get font
- *
- * @return The font
- */
- public Font getFont() {
- return _font;
- }
-
- /**
- * Set font
- *
- * @param font The font
- */
- public void setFont(Font font) {
- _font = font;
- }
-
- /**
- * Get break number
- *
- * @return The break number
- */
- public int getBreakNumber() {
- return _numBreaks;
- }
-
- /**
- * Set break number
- *
- * @param num Break number
- */
- public void setBreakNumber(int num) {
- _numBreaks = num;
- }
-
- /**
- * Get if draw scale text
- *
- * @return If draw scale text
- */
- public boolean isDrawScaleText() {
- return _drawScaleText;
- }
-
- /**
- * Set if draw scale text
- *
- * @param istrue If draw scale text
- */
- public void setDrawScaleText(boolean istrue) {
- _drawScaleText = istrue;
- }
- //
- //
-
- @Override
- public void paint(Graphics2D g) {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- @Override
- public void paintOnLayout(Graphics2D g, PointF pageLocation, float zoom) {
- if (this.isVisible()) {
- paintGraphics(g, pageLocation, zoom);
- }
- }
-
- /**
- * Paint graphics
- *
- * @param g Graphics
- * @param pageLocation Page location
- * @param zoom Zoom
- */
- public void paintGraphics(Graphics2D g, PointF pageLocation, float zoom) {
- AffineTransform oldMatrix = g.getTransform();
- PointF aP = pageToScreen(this.getLeft(), this.getTop(), pageLocation, zoom);
- g.translate(aP.X, aP.Y);
- g.scale(zoom, zoom);
- if (_antiAlias) {
- g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
- } else {
- g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
- }
-
- //Draw background color
- if (this.isDrawBackColor()){
- g.setColor(this.getBackColor());
- g.fill(new Rectangle.Float(0, 0, this.getWidth() * zoom, this.getHeight() * zoom));
- }
-
- drawScaleBar(g, zoom);
-
- //Draw neatline
- if (_drawNeatLine) {
- Rectangle.Float mapRect = new Rectangle.Float(_neatLineSize - 1, _neatLineSize - 1,
- (this.getWidth() - _neatLineSize) * zoom, (this.getHeight() - _neatLineSize) * zoom);
- g.setColor(_neatLineColor);
- g.setStroke(new BasicStroke(_neatLineSize));
- g.draw(mapRect);
- }
-
- g.setTransform(oldMatrix);
- }
-
- private void drawScaleBar(Graphics2D g, float zoom) {
- Font aFont = new Font(_font.getFontName(), _font.getStyle(), (int) (_font.getSize() * zoom));
- //Calculates the width of one break in greographic units
- FontMetrics metrics = g.getFontMetrics(aFont);
- float unitLegnth = metrics.stringWidth(_unitText) * 2;
- float widthNoUnit = (this.getWidth() * zoom - unitLegnth);
- long geoBreakWidth = (long) (getGeoWidth(widthNoUnit / _numBreaks));
-
- //If the geobreakWidth is less than 1 we return and don't draw anything
- if (geoBreakWidth < 1) {
- return;
- }
-
- double n = Math.pow(10, String.valueOf(geoBreakWidth).length() - 1);
- geoBreakWidth = (long) (Math.floor(geoBreakWidth / n) * n);
-
- long breakWidth = (long) (getWidth(geoBreakWidth));
- FontMetrics metrics1 = g.getFontMetrics(_font);
- float fontHeight = metrics1.getHeight() * zoom;
- float leftStart = metrics1.stringWidth(String.valueOf(Math.abs(geoBreakWidth))) / 2F;
-
- //Draw scale text
- double scale = geoBreakWidth * getConversionFactor(_unit) * 100 / (breakWidth / 96 * 2.539999918) * zoom;
- if (_drawScaleText) {
- g.setFont(aFont);
- g.setColor(this.getForeColor());
- g.drawString("1 : " + String.format("{0:0,0}", scale),
- leftStart - (metrics.stringWidth(String.valueOf(Math.abs(0))) / 2), fontHeight * 2.5F);
- }
-
- //Draw scale bar
- switch (_scaleBarType) {
- case SCALELINE_1:
- drawScaleLine1(g, zoom, aFont, breakWidth, geoBreakWidth);
- break;
- case SCALELINE_2:
- drawScaleLine2(g, zoom, aFont, breakWidth, geoBreakWidth);
- break;
- case ALTERNATING_BAR:
- drawAlternatingBar(g, zoom, aFont, breakWidth, geoBreakWidth);
- break;
- }
- }
-
- private double getConversionFactor(ScaleBarUnits unit) {
- switch (unit) {
- case KILOMETERS:
- return 1000;
- default:
- return 1;
- }
- }
-
- private double getGeoWidth(double width) {
- double geoWidth = width / _layoutMap.getMapFrame().getMapView().getXScale() / getConversionFactor(_unit);
- if (_layoutMap.getMapFrame().getMapView().getProjection().isLonLatMap()) {
- geoWidth = geoWidth * getLonDistScale();
- }
-
- return geoWidth;
- }
-
- private double getWidth(double geoWidth) {
- double width = geoWidth * _layoutMap.getMapFrame().getMapView().getXScale() * getConversionFactor(_unit);
- if (_layoutMap.getMapFrame().getMapView().getProjection().isLonLatMap()) {
- width = width / getLonDistScale();
- }
-
- return width;
- }
-
- private double getLonDistScale() {
- //Get meters of one longitude degree
- double pY = (_layoutMap.getMapFrame().getMapView().getViewExtent().maxY + _layoutMap.getMapFrame().getMapView().getViewExtent().minY) / 2;
- double ProjX = 0, ProjY = pY, pProjX = 1, pProjY = pY;
- double dx = Math.abs(ProjX - pProjX);
- double dy = Math.abs(ProjY - pProjY);
- double dist;
- double y = (ProjY + pProjY) / 2;
- double factor = Math.cos(y * Math.PI / 180);
- dx *= factor;
- dist = Math.sqrt(dx * dx + dy * dy);
- dist = dist * 111319.5;
-
- return dist;
- }
-
- private void drawScaleLine1(Graphics2D g, float zoom, Font aFont, long breakWidth, long geoBreakWidth) {
- FontMetrics metrics = g.getFontMetrics(_font);
- float fontHeight = metrics.getHeight() * zoom;
- float leftStart = metrics.stringWidth(String.valueOf(Math.abs(geoBreakWidth))) / 2F;
- int yShift = 10;
-
- g.setColor(this.getForeColor());
- g.setStroke(new BasicStroke(zoom));
- g.draw(new Line2D.Float(leftStart, fontHeight * 1.6f + yShift, leftStart + (breakWidth * _numBreaks), fontHeight * 1.6f + yShift));
- FontMetrics metrics1 = g.getFontMetrics(aFont);
- g.setFont(aFont);
- for (int i = 0; i <= _numBreaks; i++) {
- g.draw(new Line2D.Float(leftStart, fontHeight * 1.1f + yShift, leftStart, fontHeight * 1.6f + yShift));
- g.drawString(String.valueOf(Math.abs(geoBreakWidth * i)),
- leftStart - (metrics1.stringWidth(String.valueOf(Math.abs(geoBreakWidth * i))) / 2), yShift * _yShiftScale);
- leftStart = leftStart + breakWidth;
- }
- g.drawString(_unitText, leftStart - breakWidth + (fontHeight / 2), fontHeight * 1.1f + yShift * _yShiftScale);
- }
-
- private void drawScaleLine2(Graphics2D g, float zoom, Font aFont, long breakWidth, long geoBreakWidth) {
- FontMetrics metrics = g.getFontMetrics(_font);
- float fontHeight = metrics.getHeight() * zoom;
- float leftStart = metrics.stringWidth(String.valueOf(Math.abs(geoBreakWidth))) / 2F;
- int yShift = 5;
-
- g.setColor(this.getForeColor());
- g.draw(new Line2D.Float(leftStart, fontHeight * 1.6f + yShift, leftStart + (breakWidth * _numBreaks), fontHeight * 1.6f + yShift));
- FontMetrics metrics1 = g.getFontMetrics(aFont);
- g.setFont(aFont);
- for (int i = 0; i <= _numBreaks; i++) {
- g.draw(new Line2D.Float(leftStart, fontHeight * 1.1f + yShift, leftStart, fontHeight + (fontHeight * 1.1f) + yShift));
- g.drawString(String.valueOf(Math.abs(geoBreakWidth * i)),
- leftStart - (metrics1.stringWidth(String.valueOf(Math.abs(geoBreakWidth * i))) / 2), yShift * _yShiftScale);
- leftStart = leftStart + breakWidth;
- }
- g.drawString(_unitText, leftStart - breakWidth + (fontHeight / 2), fontHeight * 1.1f + yShift * _yShiftScale);
- }
-
- private void drawAlternatingBar(Graphics2D g, float zoom, Font aFont, long breakWidth, long geoBreakWidth) {
- FontMetrics metrics = g.getFontMetrics(_font);
- float fontHeight = metrics.getHeight() * zoom;
- float leftStart = metrics.stringWidth(String.valueOf(Math.abs(geoBreakWidth))) / 2F;
- int yShift = 5;
- float rHeight = fontHeight / 2;
- FontMetrics metrics1 = g.getFontMetrics(aFont);
-
- boolean isFill = false;
- for (int i = 0; i <= _numBreaks; i++) {
- if (i < _numBreaks) {
- if (isFill) {
- g.setColor(this.getForeColor());
- g.fill(new Rectangle.Float(leftStart, fontHeight * 1.1f + yShift, breakWidth, rHeight));
- } else {
- g.setColor(this.getForeColor());
- g.draw(new Rectangle.Float(leftStart, fontHeight * 1.1f + yShift, breakWidth, rHeight));
- }
- }
-
- g.setColor(this.getForeColor());
- g.setFont(aFont);
- g.drawString(String.valueOf(Math.abs(geoBreakWidth * i)),
- leftStart - (metrics1.stringWidth(String.valueOf(Math.abs(geoBreakWidth * i))) / 2), yShift * _yShiftScale);
- leftStart = leftStart + breakWidth;
- isFill = !isFill;
- }
- g.setColor(this.getForeColor());
- g.setFont(aFont);
- g.drawString(_unitText, leftStart - breakWidth + (fontHeight / 2), fontHeight * 1.1f + yShift * _yShiftScale);
- }
-
- @Override
- public void moveUpdate() {
- }
-
- @Override
- public void resizeUpdate() {
- }
- //
- //
-
- public class LayoutScaleBarBean {
-
- LayoutScaleBarBean() {
- }
- //
-
- /**
- * Get scale bar type
- *
- * @return Scale bar type
- */
- public String getScaleBarType() {
- return _scaleBarType.toString();
- }
-
- /**
- * Set scale bar type
- *
- * @param type Scale bar type
- */
- public void setScaleBarType(String type) {
- _scaleBarType = ScaleBarType.valueOf(type);
- }
-
- /**
- * Get if draw neat line
- *
- * @return If draw neat line
- */
- public boolean isDrawNeatLine() {
- return _drawNeatLine;
- }
-
- /**
- * Set if draw neat line
- *
- * @param istrue If draw neat line
- */
- public void setDrawNeatLine(boolean istrue) {
- _drawNeatLine = istrue;
- }
-
- /**
- * Get neat line color
- *
- * @return Neat line color
- */
- public Color getNeatLineColor() {
- return _neatLineColor;
- }
-
- /**
- * Set neat line color
- *
- * @param color Neat line color
- */
- public void setNeatLineColor(Color color) {
- _neatLineColor = color;
- }
-
- /**
- * Get neat line size
- *
- * @return Neat line size
- */
- public float getNeatLineSize() {
- return _neatLineSize;
- }
-
- /**
- * Set neat line size
- *
- * @param size Neat line size
- */
- public void setNeatLineSize(float size) {
- _neatLineSize = size;
- }
-
- /**
- * Get font
- *
- * @return The font
- */
- public Font getFont() {
- return _font;
- }
-
- /**
- * Set font
- *
- * @param font The font
- */
- public void setFont(Font font) {
- _font = font;
- }
-
- /**
- * Get break number
- *
- * @return The break number
- */
- public int getBreakNumber() {
- return _numBreaks;
- }
-
- /**
- * Set break number
- *
- * @param num Break number
- */
- public void setBreakNumber(int num) {
- _numBreaks = num;
- }
-
- /**
- * Get if draw scale text
- *
- * @return If draw scale text
- */
- public boolean isDrawScaleText() {
- return _drawScaleText;
- }
-
- /**
- * Set if draw scale text
- *
- * @param istrue If draw scale text
- */
- public void setDrawScaleText(boolean istrue) {
- _drawScaleText = istrue;
- }
-
- /**
- * Get is draw backcolor
- * @return Boolean
- */
- public boolean isDrawBackColor(){
- return LayoutScaleBar.this.isDrawBackColor();
- }
-
- /**
- * Set is draw backcolor
- * @param value Boolean
- */
- public void setDrawBackColor(boolean value){
- LayoutScaleBar.this.setDrawBackColor(value);
- }
-
- /**
- * Get background color
- *
- * @return Background color
- */
- public Color getBackColor() {
- return LayoutScaleBar.this.getBackColor();
- }
-
- /**
- * Set background color
- *
- * @param c Background color
- */
- public void setBackColor(Color c) {
- LayoutScaleBar.this.setBackColor(c);
- }
-
- /**
- * Get foreground color
- *
- * @return Foreground color
- */
- public Color getForeColor() {
- return LayoutScaleBar.this.getForeColor();
- }
-
- /**
- * Set foreground color
- *
- * @param c Foreground color
- */
- public void setForeColor(Color c) {
- LayoutScaleBar.this.setForeColor(c);
- }
-
- /**
- * Get left
- *
- * @return Left
- */
- public int getLeft() {
- return LayoutScaleBar.this.getLeft();
- }
-
- /**
- * Set left
- *
- * @param left Left
- */
- public void setLeft(int left) {
- LayoutScaleBar.this.setLeft(left);
- }
-
- /**
- * Get top
- *
- * @return Top
- */
- public int getTop() {
- return LayoutScaleBar.this.getTop();
- }
-
- /**
- * Set top
- *
- * @param top Top
- */
- public void setTop(int top) {
- LayoutScaleBar.this.setTop(top);
- }
-
- /**
- * Get width
- *
- * @return Width
- */
- public int getWidth() {
- return LayoutScaleBar.this.getWidth();
- }
-
- /**
- * Set width
- *
- * @param width Width
- */
- public void setWidth(int width) {
- LayoutScaleBar.this.setWidth(width);
- }
-
- /**
- * Get height
- *
- * @return Height
- */
- public int getHeight() {
- return LayoutScaleBar.this.getHeight();
- }
-
- /**
- * Set height
- *
- * @param height Height
- */
- public void setHeight(int height) {
- LayoutScaleBar.this.setHeight(height);
- }
- //
- }
-
- public static class LayoutScaleBarBeanBeanInfo extends BaseBeanInfo {
-
- public LayoutScaleBarBeanBeanInfo() {
- super(LayoutScaleBarBean.class);
- ExtendedPropertyDescriptor e = addProperty("scaleBarType");
- e.setCategory("General").setDisplayName("Scale Bar Type");
- e.setPropertyEditorClass(ScaleBarTypeEditor.class);
- addProperty("drawBackColor").setCategory("General").setDisplayName("Draw Background");
- addProperty("backColor").setCategory("General").setDisplayName("Background");
- addProperty("foreColor").setCategory("General").setDisplayName("Foreground");
- addProperty("font").setCategory("General").setDisplayName("Font");
- addProperty("drawScaleText").setCategory("General").setDisplayName("Draw Scale Text");
- addProperty("drawNeatLine").setCategory("Neat Line").setDisplayName("Draw Neat Line");
- addProperty("neatLineColor").setCategory("Neat Line").setDisplayName("Neat Line Color");
- addProperty("neatLineSize").setCategory("Neat Line").setDisplayName("Neat Line Size");
- addProperty("left").setCategory("Location").setDisplayName("Left");
- addProperty("top").setCategory("Location").setDisplayName("Top");
- addProperty("width").setCategory("Location").setDisplayName("Width");
- addProperty("height").setCategory("Location").setDisplayName("Height");
- }
- }
-
- public static class ScaleBarTypeEditor extends ComboBoxPropertyEditor {
-
- public ScaleBarTypeEditor() {
- super();
- ScaleBarType[] lutypes = ScaleBarType.values();
- String[] types = new String[lutypes.length];
- int i = 0;
- for (ScaleBarType type : lutypes) {
- types[i] = type.toString();
- i += 1;
- }
- setAvailableValues(types);
- }
- }
- //
-}
+ /* Copyright 2012 Yaqiang Wang,
+ * yaqiang.wang@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ */
+package org.meteoinfo.layout;
+
+import com.l2fprod.common.beans.BaseBeanInfo;
+import com.l2fprod.common.beans.ExtendedPropertyDescriptor;
+import com.l2fprod.common.beans.editor.ComboBoxPropertyEditor;
+import org.meteoinfo.common.PointF;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Line2D;
+
+/**
+ *
+ * @author Yaqiang Wang
+ */
+public class LayoutScaleBar extends LayoutElement {
+//
+
+ private LayoutMap _layoutMap;
+ private boolean _antiAlias;
+ private Font _font;
+ private ScaleBarType _scaleBarType;
+ private ScaleBarUnits _unit;
+ private String _unitText;
+ private int _numBreaks;
+ private boolean _drawNeatLine;
+ private Color _neatLineColor;
+ private float _neatLineSize;
+ private boolean _drawScaleText;
+ private float _yShiftScale = 2.0f;
+ //
+ //
+
+ /**
+ * Constructor
+ *
+ * @param layoutMap The layout map
+ */
+ public LayoutScaleBar(LayoutMap layoutMap) {
+ super();
+ this.setElementType(ElementType.LayoutScaleBar);
+ this.setResizeAbility(ResizeAbility.ResizeAll);
+
+ this.setWidth(200);
+ this.setHeight(50);
+ _layoutMap = layoutMap;
+ _antiAlias = true;
+ _scaleBarType = ScaleBarType.SCALELINE_1;
+ _drawNeatLine = false;
+ _neatLineColor = Color.black;
+ _neatLineSize = 1;
+ _font = new Font("Arial", Font.PLAIN, 12);
+ _unit = ScaleBarUnits.KILOMETERS;
+ _unitText = "km";
+ _numBreaks = 4;
+ _drawScaleText = false;
+ }
+ //
+ //
+
+ /**
+ * Get layout map
+ *
+ * @return The layout map
+ */
+ public LayoutMap getLayoutMap() {
+ return _layoutMap;
+ }
+
+ /**
+ * Get scale bar type
+ *
+ * @return Scale bar type
+ */
+ public ScaleBarType getScaleBarType() {
+ return _scaleBarType;
+ }
+
+ /**
+ * Set scale bar type
+ *
+ * @param type Scale bar type
+ */
+ public void setScaleBarType(ScaleBarType type) {
+ _scaleBarType = type;
+ }
+
+ /**
+ * Get if draw neat line
+ *
+ * @return If draw neat line
+ */
+ public boolean isDrawNeatLine() {
+ return _drawNeatLine;
+ }
+
+ /**
+ * Set if draw neat line
+ *
+ * @param istrue If draw neat line
+ */
+ public void setDrawNeatLine(boolean istrue) {
+ _drawNeatLine = istrue;
+ }
+
+ /**
+ * Get neat line color
+ *
+ * @return Neat line color
+ */
+ public Color getNeatLineColor() {
+ return _neatLineColor;
+ }
+
+ /**
+ * Set neat line color
+ *
+ * @param color Neat line color
+ */
+ public void setNeatLineColor(Color color) {
+ _neatLineColor = color;
+ }
+
+ /**
+ * Get neat line size
+ *
+ * @return Neat line size
+ */
+ public float getNeatLineSize() {
+ return _neatLineSize;
+ }
+
+ /**
+ * Set neat line size
+ *
+ * @param size Neat line size
+ */
+ public void setNeatLineSize(float size) {
+ _neatLineSize = size;
+ }
+
+ /**
+ * Get font
+ *
+ * @return The font
+ */
+ public Font getFont() {
+ return _font;
+ }
+
+ /**
+ * Set font
+ *
+ * @param font The font
+ */
+ public void setFont(Font font) {
+ _font = font;
+ }
+
+ /**
+ * Get break number
+ *
+ * @return The break number
+ */
+ public int getBreakNumber() {
+ return _numBreaks;
+ }
+
+ /**
+ * Set break number
+ *
+ * @param num Break number
+ */
+ public void setBreakNumber(int num) {
+ _numBreaks = num;
+ }
+
+ /**
+ * Get if draw scale text
+ *
+ * @return If draw scale text
+ */
+ public boolean isDrawScaleText() {
+ return _drawScaleText;
+ }
+
+ /**
+ * Set if draw scale text
+ *
+ * @param istrue If draw scale text
+ */
+ public void setDrawScaleText(boolean istrue) {
+ _drawScaleText = istrue;
+ }
+ //
+ //
+
+ @Override
+ public void paint(Graphics2D g) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void paintOnLayout(Graphics2D g, PointF pageLocation, float zoom) {
+ if (this.isVisible()) {
+ paintGraphics(g, pageLocation, zoom);
+ }
+ }
+
+ /**
+ * Paint graphics
+ *
+ * @param g Graphics
+ * @param pageLocation Page location
+ * @param zoom Zoom
+ */
+ public void paintGraphics(Graphics2D g, PointF pageLocation, float zoom) {
+ AffineTransform oldMatrix = g.getTransform();
+ PointF aP = pageToScreen(this.getLeft(), this.getTop(), pageLocation, zoom);
+ g.translate(aP.X, aP.Y);
+ g.scale(zoom, zoom);
+ if (_antiAlias) {
+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ } else {
+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
+ }
+
+ //Draw background color
+ if (this.isDrawBackColor()){
+ g.setColor(this.getBackColor());
+ g.fill(new Rectangle.Float(0, 0, this.getWidth() * zoom, this.getHeight() * zoom));
+ }
+
+ drawScaleBar(g, zoom);
+
+ //Draw neatline
+ if (_drawNeatLine) {
+ Rectangle.Float mapRect = new Rectangle.Float(_neatLineSize - 1, _neatLineSize - 1,
+ (this.getWidth() - _neatLineSize) * zoom, (this.getHeight() - _neatLineSize) * zoom);
+ g.setColor(_neatLineColor);
+ g.setStroke(new BasicStroke(_neatLineSize));
+ g.draw(mapRect);
+ }
+
+ g.setTransform(oldMatrix);
+ }
+
+ private void drawScaleBar(Graphics2D g, float zoom) {
+ Font aFont = new Font(_font.getFontName(), _font.getStyle(), (int) (_font.getSize() * zoom));
+ //Calculates the width of one break in greographic units
+ FontMetrics metrics = g.getFontMetrics(aFont);
+ float unitLegnth = metrics.stringWidth(_unitText) * 2;
+ float widthNoUnit = (this.getWidth() * zoom - unitLegnth);
+ long geoBreakWidth = (long) (getGeoWidth(widthNoUnit / _numBreaks));
+
+ //If the geobreakWidth is less than 1 we return and don't draw anything
+ if (geoBreakWidth < 1) {
+ return;
+ }
+
+ double n = Math.pow(10, String.valueOf(geoBreakWidth).length() - 1);
+ geoBreakWidth = (long) (Math.floor(geoBreakWidth / n) * n);
+
+ long breakWidth = (long) (getWidth(geoBreakWidth));
+ FontMetrics metrics1 = g.getFontMetrics(_font);
+ float fontHeight = metrics1.getHeight() * zoom;
+ float leftStart = metrics1.stringWidth(String.valueOf(Math.abs(geoBreakWidth))) / 2F;
+
+ //Draw scale text
+ double scale = geoBreakWidth * getConversionFactor(_unit) * 100 / (breakWidth / 96 * 2.539999918) * zoom;
+ if (_drawScaleText) {
+ g.setFont(aFont);
+ g.setColor(this.getForeColor());
+ g.drawString("1 : " + String.format("{0:0,0}", scale),
+ leftStart - (metrics.stringWidth(String.valueOf(Math.abs(0))) / 2), fontHeight * 2.5F);
+ }
+
+ //Draw scale bar
+ switch (_scaleBarType) {
+ case SCALELINE_1:
+ drawScaleLine1(g, zoom, aFont, breakWidth, geoBreakWidth);
+ break;
+ case SCALELINE_2:
+ drawScaleLine2(g, zoom, aFont, breakWidth, geoBreakWidth);
+ break;
+ case ALTERNATING_BAR:
+ drawAlternatingBar(g, zoom, aFont, breakWidth, geoBreakWidth);
+ break;
+ }
+ }
+
+ private double getConversionFactor(ScaleBarUnits unit) {
+ switch (unit) {
+ case KILOMETERS:
+ return 1000;
+ default:
+ return 1;
+ }
+ }
+
+ private double getGeoWidth(double width) {
+ double geoWidth = width / _layoutMap.getMapFrame().getMapView().getXScale() / getConversionFactor(_unit);
+ if (_layoutMap.getMapFrame().getMapView().getProjection().isLonLatMap()) {
+ geoWidth = geoWidth * getLonDistScale();
+ }
+
+ return geoWidth;
+ }
+
+ private double getWidth(double geoWidth) {
+ double width = geoWidth * _layoutMap.getMapFrame().getMapView().getXScale() * getConversionFactor(_unit);
+ if (_layoutMap.getMapFrame().getMapView().getProjection().isLonLatMap()) {
+ width = width / getLonDistScale();
+ }
+
+ return width;
+ }
+
+ private double getLonDistScale() {
+ //Get meters of one longitude degree
+ double pY = (_layoutMap.getMapFrame().getMapView().getViewExtent().maxY + _layoutMap.getMapFrame().getMapView().getViewExtent().minY) / 2;
+ double ProjX = 0, ProjY = pY, pProjX = 1, pProjY = pY;
+ double dx = Math.abs(ProjX - pProjX);
+ double dy = Math.abs(ProjY - pProjY);
+ double dist;
+ double y = (ProjY + pProjY) / 2;
+ double factor = Math.cos(y * Math.PI / 180);
+ dx *= factor;
+ dist = Math.sqrt(dx * dx + dy * dy);
+ dist = dist * 111319.5;
+
+ return dist;
+ }
+
+ private void drawScaleLine1(Graphics2D g, float zoom, Font aFont, long breakWidth, long geoBreakWidth) {
+ FontMetrics metrics = g.getFontMetrics(_font);
+ float fontHeight = metrics.getHeight() * zoom;
+ float leftStart = metrics.stringWidth(String.valueOf(Math.abs(geoBreakWidth))) / 2F;
+ int yShift = 10;
+
+ g.setColor(this.getForeColor());
+ g.setStroke(new BasicStroke(zoom));
+ g.draw(new Line2D.Float(leftStart, fontHeight * 1.6f + yShift, leftStart + (breakWidth * _numBreaks), fontHeight * 1.6f + yShift));
+ FontMetrics metrics1 = g.getFontMetrics(aFont);
+ g.setFont(aFont);
+ for (int i = 0; i <= _numBreaks; i++) {
+ g.draw(new Line2D.Float(leftStart, fontHeight * 1.1f + yShift, leftStart, fontHeight * 1.6f + yShift));
+ g.drawString(String.valueOf(Math.abs(geoBreakWidth * i)),
+ leftStart - (metrics1.stringWidth(String.valueOf(Math.abs(geoBreakWidth * i))) / 2), yShift * _yShiftScale);
+ leftStart = leftStart + breakWidth;
+ }
+ g.drawString(_unitText, leftStart - breakWidth + (fontHeight / 2), fontHeight * 1.1f + yShift * _yShiftScale);
+ }
+
+ private void drawScaleLine2(Graphics2D g, float zoom, Font aFont, long breakWidth, long geoBreakWidth) {
+ FontMetrics metrics = g.getFontMetrics(_font);
+ float fontHeight = metrics.getHeight() * zoom;
+ float leftStart = metrics.stringWidth(String.valueOf(Math.abs(geoBreakWidth))) / 2F;
+ int yShift = 5;
+
+ g.setColor(this.getForeColor());
+ g.draw(new Line2D.Float(leftStart, fontHeight * 1.6f + yShift, leftStart + (breakWidth * _numBreaks), fontHeight * 1.6f + yShift));
+ FontMetrics metrics1 = g.getFontMetrics(aFont);
+ g.setFont(aFont);
+ for (int i = 0; i <= _numBreaks; i++) {
+ g.draw(new Line2D.Float(leftStart, fontHeight * 1.1f + yShift, leftStart, fontHeight + (fontHeight * 1.1f) + yShift));
+ g.drawString(String.valueOf(Math.abs(geoBreakWidth * i)),
+ leftStart - (metrics1.stringWidth(String.valueOf(Math.abs(geoBreakWidth * i))) / 2), yShift * _yShiftScale);
+ leftStart = leftStart + breakWidth;
+ }
+ g.drawString(_unitText, leftStart - breakWidth + (fontHeight / 2), fontHeight * 1.1f + yShift * _yShiftScale);
+ }
+
+ private void drawAlternatingBar(Graphics2D g, float zoom, Font aFont, long breakWidth, long geoBreakWidth) {
+ FontMetrics metrics = g.getFontMetrics(_font);
+ float fontHeight = metrics.getHeight() * zoom;
+ float leftStart = metrics.stringWidth(String.valueOf(Math.abs(geoBreakWidth))) / 2F;
+ int yShift = 5;
+ float rHeight = fontHeight / 2;
+ FontMetrics metrics1 = g.getFontMetrics(aFont);
+
+ boolean isFill = false;
+ for (int i = 0; i <= _numBreaks; i++) {
+ if (i < _numBreaks) {
+ if (isFill) {
+ g.setColor(this.getForeColor());
+ g.fill(new Rectangle.Float(leftStart, fontHeight * 1.1f + yShift, breakWidth, rHeight));
+ } else {
+ g.setColor(this.getForeColor());
+ g.draw(new Rectangle.Float(leftStart, fontHeight * 1.1f + yShift, breakWidth, rHeight));
+ }
+ }
+
+ g.setColor(this.getForeColor());
+ g.setFont(aFont);
+ g.drawString(String.valueOf(Math.abs(geoBreakWidth * i)),
+ leftStart - (metrics1.stringWidth(String.valueOf(Math.abs(geoBreakWidth * i))) / 2), yShift * _yShiftScale);
+ leftStart = leftStart + breakWidth;
+ isFill = !isFill;
+ }
+ g.setColor(this.getForeColor());
+ g.setFont(aFont);
+ g.drawString(_unitText, leftStart - breakWidth + (fontHeight / 2), fontHeight * 1.1f + yShift * _yShiftScale);
+ }
+
+ @Override
+ public void moveUpdate() {
+ }
+
+ @Override
+ public void resizeUpdate() {
+ }
+ //
+ //
+
+ public class LayoutScaleBarBean {
+
+ LayoutScaleBarBean() {
+ }
+ //
+
+ /**
+ * Get scale bar type
+ *
+ * @return Scale bar type
+ */
+ public String getScaleBarType() {
+ return _scaleBarType.toString();
+ }
+
+ /**
+ * Set scale bar type
+ *
+ * @param type Scale bar type
+ */
+ public void setScaleBarType(String type) {
+ _scaleBarType = ScaleBarType.valueOf(type);
+ }
+
+ /**
+ * Get if draw neat line
+ *
+ * @return If draw neat line
+ */
+ public boolean isDrawNeatLine() {
+ return _drawNeatLine;
+ }
+
+ /**
+ * Set if draw neat line
+ *
+ * @param istrue If draw neat line
+ */
+ public void setDrawNeatLine(boolean istrue) {
+ _drawNeatLine = istrue;
+ }
+
+ /**
+ * Get neat line color
+ *
+ * @return Neat line color
+ */
+ public Color getNeatLineColor() {
+ return _neatLineColor;
+ }
+
+ /**
+ * Set neat line color
+ *
+ * @param color Neat line color
+ */
+ public void setNeatLineColor(Color color) {
+ _neatLineColor = color;
+ }
+
+ /**
+ * Get neat line size
+ *
+ * @return Neat line size
+ */
+ public float getNeatLineSize() {
+ return _neatLineSize;
+ }
+
+ /**
+ * Set neat line size
+ *
+ * @param size Neat line size
+ */
+ public void setNeatLineSize(float size) {
+ _neatLineSize = size;
+ }
+
+ /**
+ * Get font
+ *
+ * @return The font
+ */
+ public Font getFont() {
+ return _font;
+ }
+
+ /**
+ * Set font
+ *
+ * @param font The font
+ */
+ public void setFont(Font font) {
+ _font = font;
+ }
+
+ /**
+ * Get break number
+ *
+ * @return The break number
+ */
+ public int getBreakNumber() {
+ return _numBreaks;
+ }
+
+ /**
+ * Set break number
+ *
+ * @param num Break number
+ */
+ public void setBreakNumber(int num) {
+ _numBreaks = num;
+ }
+
+ /**
+ * Get if draw scale text
+ *
+ * @return If draw scale text
+ */
+ public boolean isDrawScaleText() {
+ return _drawScaleText;
+ }
+
+ /**
+ * Set if draw scale text
+ *
+ * @param istrue If draw scale text
+ */
+ public void setDrawScaleText(boolean istrue) {
+ _drawScaleText = istrue;
+ }
+
+ /**
+ * Get is draw backcolor
+ * @return Boolean
+ */
+ public boolean isDrawBackColor(){
+ return LayoutScaleBar.this.isDrawBackColor();
+ }
+
+ /**
+ * Set is draw backcolor
+ * @param value Boolean
+ */
+ public void setDrawBackColor(boolean value){
+ LayoutScaleBar.this.setDrawBackColor(value);
+ }
+
+ /**
+ * Get background color
+ *
+ * @return Background color
+ */
+ public Color getBackColor() {
+ return LayoutScaleBar.this.getBackColor();
+ }
+
+ /**
+ * Set background color
+ *
+ * @param c Background color
+ */
+ public void setBackColor(Color c) {
+ LayoutScaleBar.this.setBackColor(c);
+ }
+
+ /**
+ * Get foreground color
+ *
+ * @return Foreground color
+ */
+ public Color getForeColor() {
+ return LayoutScaleBar.this.getForeColor();
+ }
+
+ /**
+ * Set foreground color
+ *
+ * @param c Foreground color
+ */
+ public void setForeColor(Color c) {
+ LayoutScaleBar.this.setForeColor(c);
+ }
+
+ /**
+ * Get left
+ *
+ * @return Left
+ */
+ public int getLeft() {
+ return LayoutScaleBar.this.getLeft();
+ }
+
+ /**
+ * Set left
+ *
+ * @param left Left
+ */
+ public void setLeft(int left) {
+ LayoutScaleBar.this.setLeft(left);
+ }
+
+ /**
+ * Get top
+ *
+ * @return Top
+ */
+ public int getTop() {
+ return LayoutScaleBar.this.getTop();
+ }
+
+ /**
+ * Set top
+ *
+ * @param top Top
+ */
+ public void setTop(int top) {
+ LayoutScaleBar.this.setTop(top);
+ }
+
+ /**
+ * Get width
+ *
+ * @return Width
+ */
+ public int getWidth() {
+ return LayoutScaleBar.this.getWidth();
+ }
+
+ /**
+ * Set width
+ *
+ * @param width Width
+ */
+ public void setWidth(int width) {
+ LayoutScaleBar.this.setWidth(width);
+ }
+
+ /**
+ * Get height
+ *
+ * @return Height
+ */
+ public int getHeight() {
+ return LayoutScaleBar.this.getHeight();
+ }
+
+ /**
+ * Set height
+ *
+ * @param height Height
+ */
+ public void setHeight(int height) {
+ LayoutScaleBar.this.setHeight(height);
+ }
+ //
+ }
+
+ public static class LayoutScaleBarBeanBeanInfo extends BaseBeanInfo {
+
+ public LayoutScaleBarBeanBeanInfo() {
+ super(LayoutScaleBarBean.class);
+ ExtendedPropertyDescriptor e = addProperty("scaleBarType");
+ e.setCategory("General").setDisplayName("Scale Bar Type");
+ e.setPropertyEditorClass(ScaleBarTypeEditor.class);
+ addProperty("drawBackColor").setCategory("General").setDisplayName("Draw Background");
+ addProperty("backColor").setCategory("General").setDisplayName("Background");
+ addProperty("foreColor").setCategory("General").setDisplayName("Foreground");
+ addProperty("font").setCategory("General").setDisplayName("Font");
+ addProperty("drawScaleText").setCategory("General").setDisplayName("Draw Scale Text");
+ addProperty("drawNeatLine").setCategory("Neat Line").setDisplayName("Draw Neat Line");
+ addProperty("neatLineColor").setCategory("Neat Line").setDisplayName("Neat Line Color");
+ addProperty("neatLineSize").setCategory("Neat Line").setDisplayName("Neat Line Size");
+ addProperty("left").setCategory("Location").setDisplayName("Left");
+ addProperty("top").setCategory("Location").setDisplayName("Top");
+ addProperty("width").setCategory("Location").setDisplayName("Width");
+ addProperty("height").setCategory("Location").setDisplayName("Height");
+ }
+ }
+
+ public static class ScaleBarTypeEditor extends ComboBoxPropertyEditor {
+
+ public ScaleBarTypeEditor() {
+ super();
+ ScaleBarType[] lutypes = ScaleBarType.values();
+ String[] types = new String[lutypes.length];
+ int i = 0;
+ for (ScaleBarType type : lutypes) {
+ types[i] = type.toString();
+ i += 1;
+ }
+ setAvailableValues(types);
+ }
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/layout/MapLayout.java b/MeteoInfoLib/src/main/java/org/meteoinfo/layout/MapLayout.java
index f5fb9a82..73ff4a3b 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/layout/MapLayout.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/layout/MapLayout.java
@@ -18,6 +18,10 @@ import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfTemplate;
import com.itextpdf.text.pdf.PdfWriter;
+import org.meteoinfo.common.MIMath;
+import org.meteoinfo.common.PointD;
+import org.meteoinfo.common.PointF;
+import org.meteoinfo.common.util.GlobalUtil;
import org.meteoinfo.drawing.Draw;
import org.meteoinfo.geoprocess.GeoComputation;
import org.meteoinfo.global.colors.ColorUtil;
@@ -34,9 +38,6 @@ import org.meteoinfo.global.event.ZoomChangedEvent;
import org.meteoinfo.global.FrmMeasurement;
import org.meteoinfo.global.FrmMeasurement.MeasureTypes;
import org.meteoinfo.global.FrmProperty;
-import org.meteoinfo.global.MIMath;
-import org.meteoinfo.global.PointD;
-import org.meteoinfo.global.PointF;
import org.meteoinfo.layer.LayerTypes;
import org.meteoinfo.layer.MapLayer;
import org.meteoinfo.layer.VectorLayer;
@@ -134,7 +135,6 @@ import org.meteoinfo.data.mapdata.webmap.IWebMapPanel;
import org.meteoinfo.data.mapdata.webmap.TileLoadListener;
import org.meteoinfo.global.event.IUndoEditListener;
import org.meteoinfo.global.event.UndoEditEvent;
-import org.meteoinfo.global.util.GlobalUtil;
import org.meteoinfo.image.ImageUtil;
import org.meteoinfo.layer.RasterLayer;
import org.meteoinfo.layer.WebMapLayer;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/layout/MapLayoutUndoRedo.java b/MeteoInfoLib/src/main/java/org/meteoinfo/layout/MapLayoutUndoRedo.java
index 8f3b15d5..1b10d64c 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/layout/MapLayoutUndoRedo.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/layout/MapLayoutUndoRedo.java
@@ -1,283 +1,282 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.meteoinfo.layout;
-
-import org.meteoinfo.map.*;
-import java.awt.Rectangle;
-import java.util.ArrayList;
-import java.util.List;
-import javax.swing.undo.AbstractUndoableEdit;
-import org.meteoinfo.global.PointF;
-import org.meteoinfo.shape.Graphic;
-
-/**
- *
- * @author yaqiang
- */
-public class MapLayoutUndoRedo {
-
- //
- public class AddElementEdit extends AbstractUndoableEdit {
-
- MapLayout mapLayout;
- LayoutElement element;
-
- public AddElementEdit(MapLayout mapLayout, LayoutElement element) {
- this.mapLayout = mapLayout;
- this.element = element;
- }
-
- @Override
- public String getPresentationName() {
- return "Add a Layout Element";
- }
-
- @Override
- public void undo() {
- super.undo();
- mapLayout.removeElement(element);
- mapLayout.paintGraphics();
- }
-
- @Override
- public void redo() {
- super.redo();
- mapLayout.addElement(element);
- mapLayout.paintGraphics();
- }
- }
-
- public class RemoveElementEdit extends AbstractUndoableEdit {
-
- MapLayout mapLayout;
- LayoutElement element;
-
- public RemoveElementEdit(MapLayout mapLayout, LayoutElement element) {
- this.mapLayout = mapLayout;
- this.element = element;
- }
-
- @Override
- public String getPresentationName() {
- return "Remove a Layout Element";
- }
-
- @Override
- public void undo() {
- super.undo();
- mapLayout.addElement(element);
- mapLayout.paintGraphics();
- }
-
- @Override
- public void redo() {
- super.redo();
- mapLayout.removeElement(element);
- mapLayout.paintGraphics();
- }
- }
-
- public class RemoveElementsEdit extends AbstractUndoableEdit {
-
- MapLayout mapLayout;
- List elements;
-
- public RemoveElementsEdit(MapLayout mapLayout, List elements) {
- this.mapLayout = mapLayout;
- this.elements = new ArrayList(elements);
- }
-
- @Override
- public String getPresentationName() {
- return "Remove Layout Elements";
- }
-
- @Override
- public void undo() {
- super.undo();
- for (LayoutElement element : elements) {
- mapLayout.addElement(element);
- }
- mapLayout.paintGraphics();
- }
-
- @Override
- public void redo() {
- super.redo();
- for (LayoutElement element : elements) {
- mapLayout.removeElement(element);
- }
- mapLayout.paintGraphics();
- }
- }
-
- class MoveElementEdit extends AbstractUndoableEdit {
-
- MapLayout mapLayout;
- LayoutElement element;
- int deltaX;
- int deltaY;
-
- public MoveElementEdit(MapLayout mapLayout, LayoutElement element, int deltaX, int deltaY) {
- this.mapLayout = mapLayout;
- this.element = element;
- this.deltaX = deltaX;
- this.deltaY = deltaY;
- }
-
- @Override
- public String getPresentationName() {
- return "Move a Layout Element";
- }
-
- @Override
- public void undo() {
- super.undo();
- element.setLeft(element.getLeft() - deltaX);
- element.setTop(element.getTop() - deltaY);
- element.moveUpdate();
- mapLayout.paintGraphics();
- }
-
- @Override
- public void redo() {
- super.redo();
- element.setLeft(element.getLeft() + deltaX);
- element.setTop(element.getTop() + deltaY);
- element.moveUpdate();
- mapLayout.paintGraphics();
- }
- }
-
- class MoveElementsEdit extends AbstractUndoableEdit {
-
- MapLayout mapLayout;
- List elements;
- int deltaX;
- int deltaY;
-
- public MoveElementsEdit(MapLayout mapLayout, List elements, int deltaX, int deltaY) {
- this.mapLayout = mapLayout;
- this.elements = new ArrayList(elements);
- this.deltaX = deltaX;
- this.deltaY = deltaY;
- }
-
- @Override
- public String getPresentationName() {
- return "Move a Layout Element";
- }
-
- @Override
- public void undo() {
- super.undo();
- for (LayoutElement element : elements) {
- element.setLeft(element.getLeft() - deltaX);
- element.setTop(element.getTop() - deltaY);
- element.moveUpdate();
- }
- mapLayout.paintGraphics();
- }
-
- @Override
- public void redo() {
- super.redo();
- for (LayoutElement element : elements) {
- element.setLeft(element.getLeft() + deltaX);
- element.setTop(element.getTop() + deltaY);
- element.moveUpdate();
- }
- mapLayout.paintGraphics();
- }
- }
-
- class MoveGraphicVerticeEdit extends AbstractUndoableEdit {
-
- MapLayout mapLayout;
- LayoutGraphic lg;
- int verticeIdx;
- double newX;
- double newY;
- double oldX;
- double oldY;
-
- public MoveGraphicVerticeEdit(MapLayout mapLayout, LayoutGraphic lg, int vIdx, double newX, double newY) {
- this.mapLayout = mapLayout;
- this.lg = lg;
- this.verticeIdx = vIdx;
- this.newX = newX;
- this.newY = newY;
- this.oldX = lg.getGraphic().getShape().getPoints().get(vIdx).X;
- this.oldY = lg.getGraphic().getShape().getPoints().get(vIdx).Y;
- }
-
- @Override
- public String getPresentationName() {
- return "Move Grahic vertice";
- }
-
- @Override
- public void undo() {
- super.undo();
- lg.verticeEditUpdate(verticeIdx, oldX, oldY);
- mapLayout.paintGraphics();
- }
-
- @Override
- public void redo() {
- super.redo();
- lg.verticeEditUpdate(verticeIdx, newX, newY);
- mapLayout.paintGraphics();
- }
- }
-
- class ResizeElementEdit extends AbstractUndoableEdit {
-
- MapLayout mapLayout;
- LayoutElement element;
- Rectangle oldRect;
- Rectangle newRect;
-
- public ResizeElementEdit(MapLayout mapLayout, LayoutElement element, Rectangle newRect) {
- this.mapLayout = mapLayout;
- this.element = element;
- this.newRect = (Rectangle)newRect.clone();
- this.oldRect = (Rectangle)element.getBounds().clone();
- }
-
- @Override
- public String getPresentationName() {
- return "Resize a Layout Element";
- }
-
- @Override
- public void undo() {
- super.undo();
- PointF minP = mapLayout.screenToPage((float) oldRect.x, (float) oldRect.y);
- PointF maxP = mapLayout.screenToPage((float) oldRect.x + oldRect.width, oldRect.y + oldRect.height);
- element.setLeft((int) minP.X);
- element.setTop((int) minP.Y);
- element.setWidth((int) (maxP.X - minP.X));
- element.setHeight((int) (maxP.Y - minP.Y));
- element.resizeUpdate();
- mapLayout.paintGraphics();
- }
-
- @Override
- public void redo() {
- super.redo();
- PointF minP = mapLayout.screenToPage((float) newRect.x, (float) newRect.y);
- PointF maxP = mapLayout.screenToPage((float) newRect.x + newRect.width, newRect.y + newRect.height);
- element.setLeft((int) minP.X);
- element.setTop((int) minP.Y);
- element.setWidth((int) (maxP.X - minP.X));
- element.setHeight((int) (maxP.Y - minP.Y));
- element.resizeUpdate();
- mapLayout.paintGraphics();
- }
- }
- //
-}
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.meteoinfo.layout;
+
+import org.meteoinfo.common.PointF;
+
+import java.awt.Rectangle;
+import java.util.ArrayList;
+import java.util.List;
+import javax.swing.undo.AbstractUndoableEdit;
+
+/**
+ *
+ * @author yaqiang
+ */
+public class MapLayoutUndoRedo {
+
+ //
+ public class AddElementEdit extends AbstractUndoableEdit {
+
+ MapLayout mapLayout;
+ LayoutElement element;
+
+ public AddElementEdit(MapLayout mapLayout, LayoutElement element) {
+ this.mapLayout = mapLayout;
+ this.element = element;
+ }
+
+ @Override
+ public String getPresentationName() {
+ return "Add a Layout Element";
+ }
+
+ @Override
+ public void undo() {
+ super.undo();
+ mapLayout.removeElement(element);
+ mapLayout.paintGraphics();
+ }
+
+ @Override
+ public void redo() {
+ super.redo();
+ mapLayout.addElement(element);
+ mapLayout.paintGraphics();
+ }
+ }
+
+ public class RemoveElementEdit extends AbstractUndoableEdit {
+
+ MapLayout mapLayout;
+ LayoutElement element;
+
+ public RemoveElementEdit(MapLayout mapLayout, LayoutElement element) {
+ this.mapLayout = mapLayout;
+ this.element = element;
+ }
+
+ @Override
+ public String getPresentationName() {
+ return "Remove a Layout Element";
+ }
+
+ @Override
+ public void undo() {
+ super.undo();
+ mapLayout.addElement(element);
+ mapLayout.paintGraphics();
+ }
+
+ @Override
+ public void redo() {
+ super.redo();
+ mapLayout.removeElement(element);
+ mapLayout.paintGraphics();
+ }
+ }
+
+ public class RemoveElementsEdit extends AbstractUndoableEdit {
+
+ MapLayout mapLayout;
+ List elements;
+
+ public RemoveElementsEdit(MapLayout mapLayout, List elements) {
+ this.mapLayout = mapLayout;
+ this.elements = new ArrayList(elements);
+ }
+
+ @Override
+ public String getPresentationName() {
+ return "Remove Layout Elements";
+ }
+
+ @Override
+ public void undo() {
+ super.undo();
+ for (LayoutElement element : elements) {
+ mapLayout.addElement(element);
+ }
+ mapLayout.paintGraphics();
+ }
+
+ @Override
+ public void redo() {
+ super.redo();
+ for (LayoutElement element : elements) {
+ mapLayout.removeElement(element);
+ }
+ mapLayout.paintGraphics();
+ }
+ }
+
+ class MoveElementEdit extends AbstractUndoableEdit {
+
+ MapLayout mapLayout;
+ LayoutElement element;
+ int deltaX;
+ int deltaY;
+
+ public MoveElementEdit(MapLayout mapLayout, LayoutElement element, int deltaX, int deltaY) {
+ this.mapLayout = mapLayout;
+ this.element = element;
+ this.deltaX = deltaX;
+ this.deltaY = deltaY;
+ }
+
+ @Override
+ public String getPresentationName() {
+ return "Move a Layout Element";
+ }
+
+ @Override
+ public void undo() {
+ super.undo();
+ element.setLeft(element.getLeft() - deltaX);
+ element.setTop(element.getTop() - deltaY);
+ element.moveUpdate();
+ mapLayout.paintGraphics();
+ }
+
+ @Override
+ public void redo() {
+ super.redo();
+ element.setLeft(element.getLeft() + deltaX);
+ element.setTop(element.getTop() + deltaY);
+ element.moveUpdate();
+ mapLayout.paintGraphics();
+ }
+ }
+
+ class MoveElementsEdit extends AbstractUndoableEdit {
+
+ MapLayout mapLayout;
+ List elements;
+ int deltaX;
+ int deltaY;
+
+ public MoveElementsEdit(MapLayout mapLayout, List elements, int deltaX, int deltaY) {
+ this.mapLayout = mapLayout;
+ this.elements = new ArrayList(elements);
+ this.deltaX = deltaX;
+ this.deltaY = deltaY;
+ }
+
+ @Override
+ public String getPresentationName() {
+ return "Move a Layout Element";
+ }
+
+ @Override
+ public void undo() {
+ super.undo();
+ for (LayoutElement element : elements) {
+ element.setLeft(element.getLeft() - deltaX);
+ element.setTop(element.getTop() - deltaY);
+ element.moveUpdate();
+ }
+ mapLayout.paintGraphics();
+ }
+
+ @Override
+ public void redo() {
+ super.redo();
+ for (LayoutElement element : elements) {
+ element.setLeft(element.getLeft() + deltaX);
+ element.setTop(element.getTop() + deltaY);
+ element.moveUpdate();
+ }
+ mapLayout.paintGraphics();
+ }
+ }
+
+ class MoveGraphicVerticeEdit extends AbstractUndoableEdit {
+
+ MapLayout mapLayout;
+ LayoutGraphic lg;
+ int verticeIdx;
+ double newX;
+ double newY;
+ double oldX;
+ double oldY;
+
+ public MoveGraphicVerticeEdit(MapLayout mapLayout, LayoutGraphic lg, int vIdx, double newX, double newY) {
+ this.mapLayout = mapLayout;
+ this.lg = lg;
+ this.verticeIdx = vIdx;
+ this.newX = newX;
+ this.newY = newY;
+ this.oldX = lg.getGraphic().getShape().getPoints().get(vIdx).X;
+ this.oldY = lg.getGraphic().getShape().getPoints().get(vIdx).Y;
+ }
+
+ @Override
+ public String getPresentationName() {
+ return "Move Grahic vertice";
+ }
+
+ @Override
+ public void undo() {
+ super.undo();
+ lg.verticeEditUpdate(verticeIdx, oldX, oldY);
+ mapLayout.paintGraphics();
+ }
+
+ @Override
+ public void redo() {
+ super.redo();
+ lg.verticeEditUpdate(verticeIdx, newX, newY);
+ mapLayout.paintGraphics();
+ }
+ }
+
+ class ResizeElementEdit extends AbstractUndoableEdit {
+
+ MapLayout mapLayout;
+ LayoutElement element;
+ Rectangle oldRect;
+ Rectangle newRect;
+
+ public ResizeElementEdit(MapLayout mapLayout, LayoutElement element, Rectangle newRect) {
+ this.mapLayout = mapLayout;
+ this.element = element;
+ this.newRect = (Rectangle)newRect.clone();
+ this.oldRect = (Rectangle)element.getBounds().clone();
+ }
+
+ @Override
+ public String getPresentationName() {
+ return "Resize a Layout Element";
+ }
+
+ @Override
+ public void undo() {
+ super.undo();
+ PointF minP = mapLayout.screenToPage((float) oldRect.x, (float) oldRect.y);
+ PointF maxP = mapLayout.screenToPage((float) oldRect.x + oldRect.width, oldRect.y + oldRect.height);
+ element.setLeft((int) minP.X);
+ element.setTop((int) minP.Y);
+ element.setWidth((int) (maxP.X - minP.X));
+ element.setHeight((int) (maxP.Y - minP.Y));
+ element.resizeUpdate();
+ mapLayout.paintGraphics();
+ }
+
+ @Override
+ public void redo() {
+ super.redo();
+ PointF minP = mapLayout.screenToPage((float) newRect.x, (float) newRect.y);
+ PointF maxP = mapLayout.screenToPage((float) newRect.x + newRect.width, newRect.y + newRect.height);
+ element.setLeft((int) minP.X);
+ element.setTop((int) minP.Y);
+ element.setWidth((int) (maxP.X - minP.X));
+ element.setHeight((int) (maxP.Y - minP.Y));
+ element.resizeUpdate();
+ mapLayout.paintGraphics();
+ }
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/legend/ChartBreak.java b/MeteoInfoLib/src/main/java/org/meteoinfo/legend/ChartBreak.java
index cbd3c3c8..0fc0097e 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/legend/ChartBreak.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/legend/ChartBreak.java
@@ -1,644 +1,645 @@
- /* Copyright 2012 Yaqiang Wang,
- * yaqiang.wang@gmail.com
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.legend;
-
-import java.awt.Color;
-import java.awt.Font;
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.global.PointF;
-import org.meteoinfo.shape.ShapeTypes;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Chart break class
- *
- * @author Yaqiang Wang
- */
-public class ChartBreak extends ColorBreak {
- //
-
- private ChartTypes _chartType;
- private List _chartData;
- private int _xShift;
- private int _yShift;
- private LegendScheme _legendScheme;
- private int _maxSize;
- private int _minSize;
- private float _maxValue;
- private float _minValue;
- private int _barWidth;
- private AlignType _alignType;
- private boolean _view3D;
- private int _thickness;
- private int _shpIdx;
- private boolean drawLabel;
- private Font labelFont;
- private Color labelColor;
- private int decimalDigits;
- //
- //
-
- /**
- * Constructor
- *
- * @param chartType Chart type
- */
- public ChartBreak(ChartTypes chartType) {
- super();
- this.setBreakType(BreakTypes.ChartBreak);
- _chartType = chartType;
- _chartData = new ArrayList<>();
- _xShift = 0;
- _yShift = 0;
- _legendScheme = new LegendScheme(ShapeTypes.Polygon);
- _maxSize = 50;
- _minSize = 10;
- _barWidth = 10;
- _alignType = AlignType.Center;
- _view3D = false;
- _thickness = 5;
- _shpIdx = 0;
- drawLabel = false;
- labelFont = new Font("Arial", Font.PLAIN, 12);
- labelColor = Color.black;
- this.decimalDigits = 0;
- }
- //
- //
-
- /**
- * Get chart type
- *
- * @return Chart type
- */
- public ChartTypes getChartType() {
- return _chartType;
- }
-
- /**
- * Set chart type
- *
- * @param cType Chart type
- */
- public void setChartType(ChartTypes cType) {
- _chartType = cType;
- }
-
- /**
- * Get chart data
- *
- * @return Chart data list
- */
- public List getChartData() {
- return _chartData;
- }
-
- /**
- * Set chart data
- *
- * @param cData Chart data list
- */
- public void setChartData(List cData) {
- _chartData = cData;
- }
-
- /**
- * Get chart item number
- *
- * @return Chart item number
- */
- public int getItemNum() {
- return _chartData.size();
- }
-
- /**
- * Get chart data sum
- *
- * @return Chart data sum
- */
- public float getDataSum() {
- float sum = 0;
- for (float d : _chartData) {
- sum += d;
- }
- return sum;
- }
-
- /**
- * Get x shift
- *
- * @return X shift
- */
- public int getXShift() {
- return _xShift;
- }
-
- /**
- * Set x shift
- *
- * @param xshift X shift
- */
- public void setXShift(int xshift) {
- _xShift = xshift;
- }
-
- /**
- * Get y shift
- *
- * @return Y shift
- */
- public int getYShift() {
- return _yShift;
- }
-
- /**
- * Set y shift
- *
- * @param yshift Y shift
- */
- public void setYShift(int yshift) {
- _yShift = yshift;
- }
-
- /**
- * Get legend scheme
- *
- * @return Legend Scheme
- */
- public LegendScheme getLegendScheme() {
- return _legendScheme;
- }
-
- /**
- * Set legend scheme
- *
- * @param ls Legend scheme
- */
- public void setLegendScheme(LegendScheme ls) {
- _legendScheme = ls;
- }
-
- /**
- * Get maximum size
- *
- * @return Maximum size
- */
- public int getMaxSize() {
- return _maxSize;
- }
-
- /**
- * Set maximum size
- *
- * @param maxSize Maximum size
- */
- public void setMaxSize(int maxSize) {
- _maxSize = maxSize;
- }
-
- /**
- * Get minimum size
- *
- * @return Minimum size
- */
- public int getMinSize() {
- return _minSize;
- }
-
- /**
- * Set minimum size
- *
- * @param minSize Minimum size
- */
- public void setMinSize(int minSize) {
- _minSize = minSize;
- }
-
- /**
- * Get maximum value
- *
- * @return Maximum value
- */
- public float getMaxValue() {
- return _maxValue;
- }
-
- /**
- * Set maximum value
- *
- * @param maxValue Maximum value
- */
- public void setMaxValue(float maxValue) {
- _maxValue = maxValue;
- }
-
- /**
- * Get minimum value
- *
- * @return Minimum value
- */
- public float getMinValue() {
- return _minValue;
- }
-
- /**
- * Set minimum value
- *
- * @param minValue Minimum value
- */
- public void setMinValue(float minValue) {
- _minValue = minValue;
- }
-
- /**
- * Get bar width
- *
- * @return Bar width
- */
- public int getBarWidth() {
- return _barWidth;
- }
-
- /**
- * Set bar width
- *
- * @param width Bar width
- */
- public void setBarWidth(int width) {
- _barWidth = width;
- }
-
- /**
- * Get align type
- *
- * @return Align type
- */
- public AlignType getAlignType() {
- return _alignType;
- }
-
- /**
- * Set align type
- *
- * @param atype Align type
- */
- public void setAlignType(AlignType atype) {
- _alignType = atype;
- }
-
- /**
- * Get if view 3D
- *
- * @return Boolean
- */
- public boolean isView3D() {
- return _view3D;
- }
-
- /**
- * Set if view 3D
- *
- * @param v3d
- */
- public void setView3D(boolean v3d) {
- _view3D = v3d;
- }
-
- /**
- * Get 3D thickness
- *
- * @return 3D thickness
- */
- public int getThickness() {
- return _thickness;
- }
-
- /**
- * Set 3D thickness
- *
- * @param thickness 3D thickness
- */
- public void setThickness(int thickness) {
- _thickness = thickness;
- }
-
- /**
- * Get shape index
- *
- * @return Shape index
- */
- public int getShapeIndex() {
- return _shpIdx;
- }
-
- /**
- * Set shape index
- *
- * @param sIdx Shape index
- */
- public void setShapeIndex(int sIdx) {
- _shpIdx = sIdx;
- }
-
- /**
- * Get if draw label
- * @return Boolean
- */
- public boolean isDrawLabel(){
- return this.drawLabel;
- }
-
- /**
- * Set if draw label
- * @param value Boolean
- */
- public void setDrawLabel(boolean value){
- this.drawLabel = value;
- }
-
- /**
- * Get label font
- * @return Label font
- */
- public Font getLabelFont(){
- return this.labelFont;
- }
-
- /**
- * Set label font
- * @param value Label font
- */
- public void setLabelFont(Font value){
- this.labelFont = value;
- }
-
- /**
- * Get label color
- * @return Label color
- */
- public Color getLabelColor(){
- return this.labelColor;
- }
-
- /**
- * Set label color
- * @param value Label color
- */
- public void setLabelColor(Color value){
- this.labelColor = value;
- }
-
- /**
- * Get decimal digits
- * @return Decimal digits
- */
- public int getDecimalDigits(){
- return this.decimalDigits;
- }
-
- /**
- * Set decimal digits
- * @param value Decimal digits
- */
- public void setDecimalDigits(int value){
- this.decimalDigits = value;
- }
- //
- //
-
- /**
- * Get bar heights
- *
- * @return Bar heights
- */
- public List getBarHeights() {
- List heights = new ArrayList<>();
- int i, h;
- for (i = 0; i < _chartData.size(); i++) {
- if (_minSize == 0) {
- h = (int) (_chartData.get(i) / _maxValue * _maxSize);
- } else {
- h = (int) ((_chartData.get(i) - _minValue) / (_maxValue - _minValue)
- * (_maxSize - _minSize) + _minSize);
- }
- heights.add(h);
- }
-
- return heights;
- }
-
- /**
- * Get chart width
- *
- * @return Chart width
- */
- public int getWidth() {
- int width = 0;
- switch (_chartType) {
- case BarChart:
- width = _barWidth * _chartData.size();
- if (_view3D) {
- width += _thickness;
- }
- break;
- case PieChart:
- if (_minSize == _maxSize) {
- width = _maxSize;
- } else if (_minSize == 0) {
- width = (int) (this.getDataSum() / _maxValue * _maxSize);
- } else {
- width = (int) ((this.getDataSum() - _minValue) / (_maxValue - _minValue)
- * (_maxSize - _minSize) + _minSize);
- }
- break;
- }
-
- return width;
- }
-
- /**
- * Get chart height
- *
- * @return Chart height
- */
- public int getHeight() {
- int height = 0;
- switch (_chartType) {
- case BarChart:
- height = Collections.max(getBarHeights());
- break;
- case PieChart:
- if (_minSize == _maxSize) {
- height = _maxSize;
- } else if (_minSize == 0) {
- height = (int) (this.getDataSum() / _maxValue * _maxSize);
- } else {
- height = (int) ((this.getDataSum() - _minValue) / (_maxValue - _minValue)
- * (_maxSize - _minSize) + _minSize);
- }
-
- if (_view3D) {
- height = height * 2 / 3;
- }
- break;
- }
-
- if (_view3D) {
- height += _thickness;
- }
-
- return height;
- }
-
- /**
- * Get pie angles
- *
- * @return Pie angle list
- */
- public List> getPieAngles() {
- List> angles = new ArrayList<>();
- float sum = this.getDataSum();
- float startAngle = 0;
- float sweepAngle;
- for (Float value : _chartData) {
- sweepAngle = value / sum * 360;
- List ssa = new ArrayList<>();
- ssa.add(startAngle);
- ssa.add(sweepAngle);
- angles.add(ssa);
- startAngle += sweepAngle;
- if (startAngle > 360) {
- startAngle = startAngle - 360;
- }
- }
-
- return angles;
- }
-
- /**
- * Get pie ratios
- *
- * @return Pie ratio list
- */
- public List getPieRatios() {
- List ratios = new ArrayList<>();
- float sum = this.getDataSum();
- float ratio;
- for (Float value : _chartData) {
- ratio = value / sum;
- ratios.add(ratio);
- }
-
- return ratios;
- }
-
- /**
- * Clone
- *
- * @return ChartBreak object
- */
- @Override
- public Object clone() {
- ChartBreak aCB = new ChartBreak(_chartType);
- aCB.setCaption(this.getCaption());
- aCB.setAlignType(_alignType);
- aCB.setBarWidth(_barWidth);
- aCB.setChartData(new ArrayList<>(_chartData));
- aCB.setColor(this.getColor());
- aCB.setDrawShape(this.isDrawShape());
- aCB.setLegendScheme(_legendScheme);
- aCB.setMaxSize(_maxSize);
- aCB.setMaxValue(_maxValue);
- aCB.setMinSize(_minSize);
- aCB.setMinValue(_minValue);
- aCB.setThickness(_thickness);
- aCB.setView3D(_view3D);
- aCB.setXShift(_xShift);
- aCB.setYShift(_yShift);
- aCB.setDrawLabel(this.drawLabel);
- aCB.setLabelColor(this.labelColor);
- aCB.setLabelFont(labelFont);
- aCB.setDecimalDigits(this.decimalDigits);
-
- return aCB;
- }
-
- /**
- * Get sample chart break
- *
- * @return Sample chart break
- */
- public ChartBreak getSampleChartBreak() {
- ChartBreak aCB = (ChartBreak) clone();
- int i;
- switch (aCB.getChartType()) {
- case BarChart:
- float min = aCB.getMaxValue() / aCB.getItemNum();
- float dv = (aCB.getMaxValue() - min) / aCB.getItemNum();
- for (i = 0; i < aCB.getItemNum(); i++) {
- aCB.getChartData().set(i, min + dv * i);
- }
- break;
- case PieChart:
- //float sum = (aCB.getMaxValue() - aCB.getMinValue()) * 2 / 3;
- float sum = aCB.getMaxValue();
- float data = sum / aCB.getItemNum();
- for (i = 0; i < aCB.getItemNum(); i++) {
- aCB.getChartData().set(i, data);
- }
- aCB.setMinSize(aCB._maxSize);
- //aCB.setMaxSize(20);
- break;
- }
-
- return aCB;
- }
-
- /**
- * Get draw extent
- *
- * @param aPoint start point
- * @return draw extent
- */
- public Extent getDrawExtent(PointF aPoint) {
- int width = this.getWidth();
- int height = this.getHeight();
- switch (_alignType) {
- case Center:
- aPoint.X -= width / 2;
- aPoint.Y += height / 2;
- break;
- case Left:
- aPoint.X -= width;
- aPoint.Y += height / 2;
- break;
- case Right:
- aPoint.Y += height / 2;
- break;
- }
- aPoint.X += _xShift;
- aPoint.Y -= _yShift;
-
- Extent aExtent = new Extent();
- aExtent.minX = aPoint.X;
- aExtent.maxX = aPoint.X + width;
- aExtent.minY = aPoint.Y - height;
- aExtent.maxY = aPoint.Y;
-
- return aExtent;
- }
- //
-}
+ /* Copyright 2012 Yaqiang Wang,
+ * yaqiang.wang@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ */
+package org.meteoinfo.legend;
+
+import java.awt.Color;
+import java.awt.Font;
+
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.PointF;
+import org.meteoinfo.shape.ShapeTypes;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Chart break class
+ *
+ * @author Yaqiang Wang
+ */
+public class ChartBreak extends ColorBreak {
+ //
+
+ private ChartTypes _chartType;
+ private List _chartData;
+ private int _xShift;
+ private int _yShift;
+ private LegendScheme _legendScheme;
+ private int _maxSize;
+ private int _minSize;
+ private float _maxValue;
+ private float _minValue;
+ private int _barWidth;
+ private AlignType _alignType;
+ private boolean _view3D;
+ private int _thickness;
+ private int _shpIdx;
+ private boolean drawLabel;
+ private Font labelFont;
+ private Color labelColor;
+ private int decimalDigits;
+ //
+ //
+
+ /**
+ * Constructor
+ *
+ * @param chartType Chart type
+ */
+ public ChartBreak(ChartTypes chartType) {
+ super();
+ this.setBreakType(BreakTypes.ChartBreak);
+ _chartType = chartType;
+ _chartData = new ArrayList<>();
+ _xShift = 0;
+ _yShift = 0;
+ _legendScheme = new LegendScheme(ShapeTypes.Polygon);
+ _maxSize = 50;
+ _minSize = 10;
+ _barWidth = 10;
+ _alignType = AlignType.Center;
+ _view3D = false;
+ _thickness = 5;
+ _shpIdx = 0;
+ drawLabel = false;
+ labelFont = new Font("Arial", Font.PLAIN, 12);
+ labelColor = Color.black;
+ this.decimalDigits = 0;
+ }
+ //
+ //
+
+ /**
+ * Get chart type
+ *
+ * @return Chart type
+ */
+ public ChartTypes getChartType() {
+ return _chartType;
+ }
+
+ /**
+ * Set chart type
+ *
+ * @param cType Chart type
+ */
+ public void setChartType(ChartTypes cType) {
+ _chartType = cType;
+ }
+
+ /**
+ * Get chart data
+ *
+ * @return Chart data list
+ */
+ public List getChartData() {
+ return _chartData;
+ }
+
+ /**
+ * Set chart data
+ *
+ * @param cData Chart data list
+ */
+ public void setChartData(List cData) {
+ _chartData = cData;
+ }
+
+ /**
+ * Get chart item number
+ *
+ * @return Chart item number
+ */
+ public int getItemNum() {
+ return _chartData.size();
+ }
+
+ /**
+ * Get chart data sum
+ *
+ * @return Chart data sum
+ */
+ public float getDataSum() {
+ float sum = 0;
+ for (float d : _chartData) {
+ sum += d;
+ }
+ return sum;
+ }
+
+ /**
+ * Get x shift
+ *
+ * @return X shift
+ */
+ public int getXShift() {
+ return _xShift;
+ }
+
+ /**
+ * Set x shift
+ *
+ * @param xshift X shift
+ */
+ public void setXShift(int xshift) {
+ _xShift = xshift;
+ }
+
+ /**
+ * Get y shift
+ *
+ * @return Y shift
+ */
+ public int getYShift() {
+ return _yShift;
+ }
+
+ /**
+ * Set y shift
+ *
+ * @param yshift Y shift
+ */
+ public void setYShift(int yshift) {
+ _yShift = yshift;
+ }
+
+ /**
+ * Get legend scheme
+ *
+ * @return Legend Scheme
+ */
+ public LegendScheme getLegendScheme() {
+ return _legendScheme;
+ }
+
+ /**
+ * Set legend scheme
+ *
+ * @param ls Legend scheme
+ */
+ public void setLegendScheme(LegendScheme ls) {
+ _legendScheme = ls;
+ }
+
+ /**
+ * Get maximum size
+ *
+ * @return Maximum size
+ */
+ public int getMaxSize() {
+ return _maxSize;
+ }
+
+ /**
+ * Set maximum size
+ *
+ * @param maxSize Maximum size
+ */
+ public void setMaxSize(int maxSize) {
+ _maxSize = maxSize;
+ }
+
+ /**
+ * Get minimum size
+ *
+ * @return Minimum size
+ */
+ public int getMinSize() {
+ return _minSize;
+ }
+
+ /**
+ * Set minimum size
+ *
+ * @param minSize Minimum size
+ */
+ public void setMinSize(int minSize) {
+ _minSize = minSize;
+ }
+
+ /**
+ * Get maximum value
+ *
+ * @return Maximum value
+ */
+ public float getMaxValue() {
+ return _maxValue;
+ }
+
+ /**
+ * Set maximum value
+ *
+ * @param maxValue Maximum value
+ */
+ public void setMaxValue(float maxValue) {
+ _maxValue = maxValue;
+ }
+
+ /**
+ * Get minimum value
+ *
+ * @return Minimum value
+ */
+ public float getMinValue() {
+ return _minValue;
+ }
+
+ /**
+ * Set minimum value
+ *
+ * @param minValue Minimum value
+ */
+ public void setMinValue(float minValue) {
+ _minValue = minValue;
+ }
+
+ /**
+ * Get bar width
+ *
+ * @return Bar width
+ */
+ public int getBarWidth() {
+ return _barWidth;
+ }
+
+ /**
+ * Set bar width
+ *
+ * @param width Bar width
+ */
+ public void setBarWidth(int width) {
+ _barWidth = width;
+ }
+
+ /**
+ * Get align type
+ *
+ * @return Align type
+ */
+ public AlignType getAlignType() {
+ return _alignType;
+ }
+
+ /**
+ * Set align type
+ *
+ * @param atype Align type
+ */
+ public void setAlignType(AlignType atype) {
+ _alignType = atype;
+ }
+
+ /**
+ * Get if view 3D
+ *
+ * @return Boolean
+ */
+ public boolean isView3D() {
+ return _view3D;
+ }
+
+ /**
+ * Set if view 3D
+ *
+ * @param v3d
+ */
+ public void setView3D(boolean v3d) {
+ _view3D = v3d;
+ }
+
+ /**
+ * Get 3D thickness
+ *
+ * @return 3D thickness
+ */
+ public int getThickness() {
+ return _thickness;
+ }
+
+ /**
+ * Set 3D thickness
+ *
+ * @param thickness 3D thickness
+ */
+ public void setThickness(int thickness) {
+ _thickness = thickness;
+ }
+
+ /**
+ * Get shape index
+ *
+ * @return Shape index
+ */
+ public int getShapeIndex() {
+ return _shpIdx;
+ }
+
+ /**
+ * Set shape index
+ *
+ * @param sIdx Shape index
+ */
+ public void setShapeIndex(int sIdx) {
+ _shpIdx = sIdx;
+ }
+
+ /**
+ * Get if draw label
+ * @return Boolean
+ */
+ public boolean isDrawLabel(){
+ return this.drawLabel;
+ }
+
+ /**
+ * Set if draw label
+ * @param value Boolean
+ */
+ public void setDrawLabel(boolean value){
+ this.drawLabel = value;
+ }
+
+ /**
+ * Get label font
+ * @return Label font
+ */
+ public Font getLabelFont(){
+ return this.labelFont;
+ }
+
+ /**
+ * Set label font
+ * @param value Label font
+ */
+ public void setLabelFont(Font value){
+ this.labelFont = value;
+ }
+
+ /**
+ * Get label color
+ * @return Label color
+ */
+ public Color getLabelColor(){
+ return this.labelColor;
+ }
+
+ /**
+ * Set label color
+ * @param value Label color
+ */
+ public void setLabelColor(Color value){
+ this.labelColor = value;
+ }
+
+ /**
+ * Get decimal digits
+ * @return Decimal digits
+ */
+ public int getDecimalDigits(){
+ return this.decimalDigits;
+ }
+
+ /**
+ * Set decimal digits
+ * @param value Decimal digits
+ */
+ public void setDecimalDigits(int value){
+ this.decimalDigits = value;
+ }
+ //
+ //
+
+ /**
+ * Get bar heights
+ *
+ * @return Bar heights
+ */
+ public List getBarHeights() {
+ List heights = new ArrayList<>();
+ int i, h;
+ for (i = 0; i < _chartData.size(); i++) {
+ if (_minSize == 0) {
+ h = (int) (_chartData.get(i) / _maxValue * _maxSize);
+ } else {
+ h = (int) ((_chartData.get(i) - _minValue) / (_maxValue - _minValue)
+ * (_maxSize - _minSize) + _minSize);
+ }
+ heights.add(h);
+ }
+
+ return heights;
+ }
+
+ /**
+ * Get chart width
+ *
+ * @return Chart width
+ */
+ public int getWidth() {
+ int width = 0;
+ switch (_chartType) {
+ case BarChart:
+ width = _barWidth * _chartData.size();
+ if (_view3D) {
+ width += _thickness;
+ }
+ break;
+ case PieChart:
+ if (_minSize == _maxSize) {
+ width = _maxSize;
+ } else if (_minSize == 0) {
+ width = (int) (this.getDataSum() / _maxValue * _maxSize);
+ } else {
+ width = (int) ((this.getDataSum() - _minValue) / (_maxValue - _minValue)
+ * (_maxSize - _minSize) + _minSize);
+ }
+ break;
+ }
+
+ return width;
+ }
+
+ /**
+ * Get chart height
+ *
+ * @return Chart height
+ */
+ public int getHeight() {
+ int height = 0;
+ switch (_chartType) {
+ case BarChart:
+ height = Collections.max(getBarHeights());
+ break;
+ case PieChart:
+ if (_minSize == _maxSize) {
+ height = _maxSize;
+ } else if (_minSize == 0) {
+ height = (int) (this.getDataSum() / _maxValue * _maxSize);
+ } else {
+ height = (int) ((this.getDataSum() - _minValue) / (_maxValue - _minValue)
+ * (_maxSize - _minSize) + _minSize);
+ }
+
+ if (_view3D) {
+ height = height * 2 / 3;
+ }
+ break;
+ }
+
+ if (_view3D) {
+ height += _thickness;
+ }
+
+ return height;
+ }
+
+ /**
+ * Get pie angles
+ *
+ * @return Pie angle list
+ */
+ public List> getPieAngles() {
+ List> angles = new ArrayList<>();
+ float sum = this.getDataSum();
+ float startAngle = 0;
+ float sweepAngle;
+ for (Float value : _chartData) {
+ sweepAngle = value / sum * 360;
+ List ssa = new ArrayList<>();
+ ssa.add(startAngle);
+ ssa.add(sweepAngle);
+ angles.add(ssa);
+ startAngle += sweepAngle;
+ if (startAngle > 360) {
+ startAngle = startAngle - 360;
+ }
+ }
+
+ return angles;
+ }
+
+ /**
+ * Get pie ratios
+ *
+ * @return Pie ratio list
+ */
+ public List getPieRatios() {
+ List ratios = new ArrayList<>();
+ float sum = this.getDataSum();
+ float ratio;
+ for (Float value : _chartData) {
+ ratio = value / sum;
+ ratios.add(ratio);
+ }
+
+ return ratios;
+ }
+
+ /**
+ * Clone
+ *
+ * @return ChartBreak object
+ */
+ @Override
+ public Object clone() {
+ ChartBreak aCB = new ChartBreak(_chartType);
+ aCB.setCaption(this.getCaption());
+ aCB.setAlignType(_alignType);
+ aCB.setBarWidth(_barWidth);
+ aCB.setChartData(new ArrayList<>(_chartData));
+ aCB.setColor(this.getColor());
+ aCB.setDrawShape(this.isDrawShape());
+ aCB.setLegendScheme(_legendScheme);
+ aCB.setMaxSize(_maxSize);
+ aCB.setMaxValue(_maxValue);
+ aCB.setMinSize(_minSize);
+ aCB.setMinValue(_minValue);
+ aCB.setThickness(_thickness);
+ aCB.setView3D(_view3D);
+ aCB.setXShift(_xShift);
+ aCB.setYShift(_yShift);
+ aCB.setDrawLabel(this.drawLabel);
+ aCB.setLabelColor(this.labelColor);
+ aCB.setLabelFont(labelFont);
+ aCB.setDecimalDigits(this.decimalDigits);
+
+ return aCB;
+ }
+
+ /**
+ * Get sample chart break
+ *
+ * @return Sample chart break
+ */
+ public ChartBreak getSampleChartBreak() {
+ ChartBreak aCB = (ChartBreak) clone();
+ int i;
+ switch (aCB.getChartType()) {
+ case BarChart:
+ float min = aCB.getMaxValue() / aCB.getItemNum();
+ float dv = (aCB.getMaxValue() - min) / aCB.getItemNum();
+ for (i = 0; i < aCB.getItemNum(); i++) {
+ aCB.getChartData().set(i, min + dv * i);
+ }
+ break;
+ case PieChart:
+ //float sum = (aCB.getMaxValue() - aCB.getMinValue()) * 2 / 3;
+ float sum = aCB.getMaxValue();
+ float data = sum / aCB.getItemNum();
+ for (i = 0; i < aCB.getItemNum(); i++) {
+ aCB.getChartData().set(i, data);
+ }
+ aCB.setMinSize(aCB._maxSize);
+ //aCB.setMaxSize(20);
+ break;
+ }
+
+ return aCB;
+ }
+
+ /**
+ * Get draw extent
+ *
+ * @param aPoint start point
+ * @return draw extent
+ */
+ public Extent getDrawExtent(PointF aPoint) {
+ int width = this.getWidth();
+ int height = this.getHeight();
+ switch (_alignType) {
+ case Center:
+ aPoint.X -= width / 2;
+ aPoint.Y += height / 2;
+ break;
+ case Left:
+ aPoint.X -= width;
+ aPoint.Y += height / 2;
+ break;
+ case Right:
+ aPoint.Y += height / 2;
+ break;
+ }
+ aPoint.X += _xShift;
+ aPoint.Y -= _yShift;
+
+ Extent aExtent = new Extent();
+ aExtent.minX = aPoint.X;
+ aExtent.maxX = aPoint.X + width;
+ aExtent.minY = aPoint.Y - height;
+ aExtent.maxY = aPoint.Y;
+
+ return aExtent;
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/legend/ColorScheme.java b/MeteoInfoLib/src/main/java/org/meteoinfo/legend/ColorScheme.java
index 860d494b..6b750fe3 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/legend/ColorScheme.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/legend/ColorScheme.java
@@ -1,53 +1,54 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.meteoinfo.legend;
-
-import java.awt.Color;
-import org.meteoinfo.global.MIMath;
-import org.meteoinfo.global.colors.ColorMap;
-
-/**
- *
- * @author yaqiang
- */
-public class ColorScheme {
- //
- private double[] values;
- private Color[] colors;
- //
- //
- /**
- * Constructor
- * @param min Minimum value
- * @param max Maximum value
- * @param n Level number
- * @param ct Color table
- */
- public ColorScheme(double min, double max, int n, ColorMap ct){
- this.values = MIMath.getIntervalValues(min, max, n);
- this.colors = ct.getColors(n);
- }
- //
- //
- /**
- * Get values
- * @return Values
- */
- public double[] getValues(){
- return this.values;
- }
-
- /**
- * Get colors
- * @return Colors
- */
- public Color[] getColors(){
- return this.colors;
- }
- //
- //
- //
-}
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.meteoinfo.legend;
+
+import java.awt.Color;
+
+import org.meteoinfo.common.MIMath;
+import org.meteoinfo.global.colors.ColorMap;
+
+/**
+ *
+ * @author yaqiang
+ */
+public class ColorScheme {
+ //
+ private double[] values;
+ private Color[] colors;
+ //
+ //
+ /**
+ * Constructor
+ * @param min Minimum value
+ * @param max Maximum value
+ * @param n Level number
+ * @param ct Color table
+ */
+ public ColorScheme(double min, double max, int n, ColorMap ct){
+ this.values = MIMath.getIntervalValues(min, max, n);
+ this.colors = ct.getColors(n);
+ }
+ //
+ //
+ /**
+ * Get values
+ * @return Values
+ */
+ public double[] getValues(){
+ return this.values;
+ }
+
+ /**
+ * Get colors
+ * @return Colors
+ */
+ public Color[] getColors(){
+ return this.colors;
+ }
+ //
+ //
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/legend/FrmLegendSet.java b/MeteoInfoLib/src/main/java/org/meteoinfo/legend/FrmLegendSet.java
index f10047ea..7e25a363 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/legend/FrmLegendSet.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/legend/FrmLegendSet.java
@@ -5,7 +5,7 @@
package org.meteoinfo.legend;
import com.formdev.flatlaf.extras.FlatSVGIcon;
-import org.meteoinfo.global.GenericFileFilter;
+import org.meteoinfo.common.GenericFileFilter;
import org.meteoinfo.shape.ShapeTypes;
import java.awt.Color;
import java.io.File;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/legend/FrmPointSymbolSet.java b/MeteoInfoLib/src/main/java/org/meteoinfo/legend/FrmPointSymbolSet.java
index b73df7f1..e1afbbdd 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/legend/FrmPointSymbolSet.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/legend/FrmPointSymbolSet.java
@@ -4,7 +4,7 @@
*/
package org.meteoinfo.legend;
-import org.meteoinfo.global.util.GlobalUtil;
+import org.meteoinfo.common.util.GlobalUtil;
import org.meteoinfo.global.event.ISelectedCellChangedListener;
import org.meteoinfo.global.event.SelectedCellChangedEvent;
import org.meteoinfo.layout.MapLayout;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/legend/LabelBreak.java b/MeteoInfoLib/src/main/java/org/meteoinfo/legend/LabelBreak.java
index 80e70eeb..ede7d29f 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/legend/LabelBreak.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/legend/LabelBreak.java
@@ -1,243 +1,243 @@
- /* Copyright 2012 Yaqiang Wang,
- * yaqiang.wang@gmail.com
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.legend;
-
-import org.meteoinfo.global.event.ISizeChangedListener;
-import org.meteoinfo.global.event.SizeChangedEvent;
-import java.awt.Color;
-import java.awt.Font;
-import java.util.HashMap;
-import javax.swing.event.EventListenerList;
-import org.meteoinfo.global.util.GlobalUtil;
-
-/**
- * Label break class
- *
- * @author Yaqiang Wang
- */
-public class LabelBreak extends ColorBreak {
- //
-
- private EventListenerList _listeners = new EventListenerList();
- private String _text;
- private float _angle;
- private Font _font;
- private AlignType _alignType;
- private float _xShift;
- private float _yShift;
- //
- //
-
- public LabelBreak() {
- super();
- this.setBreakType(BreakTypes.LabelBreak);
- _text = "";
- _angle = 0;
- this.setColor(Color.black);
- _font = new Font(GlobalUtil.getDefaultFontName(), Font.PLAIN, 7);
- _alignType = AlignType.Center;
- _yShift = 0;
- }
- //
- //
-
- /**
- * Get text string
- *
- * @return Text string
- */
- public String getText() {
- return _text;
- }
-
- /**
- * Set text string and fire size changed event
- *
- * @param text Text string
- */
- public void setText(String text) {
- _text = text;
- this.fireSizeChangedEvent(new SizeChangedEvent(this));
- }
-
- /**
- * Get angle
- *
- * @return Angle
- */
- public float getAngle() {
- return _angle;
- }
-
- /**
- * Set angle
- *
- * @param angle Angle
- */
- public void setAngle(float angle) {
- _angle = angle;
- }
-
- /**
- * Get font
- *
- * @return Font
- */
- public Font getFont() {
- return _font;
- }
-
- /**
- * Set font and fire size changed event
- *
- * @param f Font
- */
- public void setFont(Font f) {
- _font = f;
- this.fireSizeChangedEvent(new SizeChangedEvent(this));
- }
-
- /**
- * Get align type
- *
- * @return Align type
- */
- public AlignType getAlignType() {
- return _alignType;
- }
-
- /**
- * Set align type
- *
- * @param at Align type
- */
- public void setAlignType(AlignType at) {
- _alignType = at;
- }
-
- /**
- * Get y shift
- *
- * @return Y shift
- */
- public float getYShift() {
- return _yShift;
- }
-
- /**
- * Set y shift
- *
- * @param yshift Y shift
- */
- public void setYShift(float yshift) {
- _yShift = yshift;
- }
-
- /**
- * Get x shift
- *
- * @return X shift
- */
- public float getXShift() {
- return _xShift;
- }
-
- /**
- * Set x shift
- *
- * @param xshift X shift
- */
- public void setXShift(float xshift) {
- _xShift = xshift;
- }
-
- //
- //
- /**
- * Get property object
- *
- * @return Property object
- */
- @Override
- public Object getPropertyObject() {
- HashMap objAttr = new HashMap();
- objAttr.put("Text", "Text");
- objAttr.put("Angle", "Angle");
- objAttr.put("Color", "Color");
- objAttr.put("Font", "Font");
- //objAttr.Add("AlignType", "AlignType");
- //objAttr.Add("YShift", "YShift");
- //CustomProperty cp = new CustomProperty(this, objAttr);
- return objAttr;
- }
-
- /**
- * Clone
- *
- * @return LabelBreak object
- */
- @Override
- public Object clone() {
- LabelBreak aCB = new LabelBreak();
- aCB.setCaption(this.getCaption());
- aCB.setColor(this.getColor());
- aCB.setDrawShape(this.isDrawShape());
- aCB.setEndValue(this.getEndValue());
- aCB.setNoData(this.isNoData());
- aCB.setStartValue(this.getStartValue());
- aCB.setAngle(_angle);
- aCB.setText(_text);
- aCB.setFont(_font);
- aCB.setAlignType(_alignType);
- aCB.setYShift(_yShift);
- aCB.setXShift(_xShift);
-
- return aCB;
- }
- //
- //
-
- /**
- * Add size changed listener
- *
- * @param scl SizeChangedListener interface
- */
- public void addSizeChangedListener(ISizeChangedListener scl) {
- this._listeners.add(ISizeChangedListener.class, scl);
- }
-
- /**
- * Remove size changed listener
- *
- * @param scl SizeChangedListener interface
- */
- public void removeSizeChangedListener(ISizeChangedListener scl) {
- this._listeners.remove(ISizeChangedListener.class, scl);
- }
-
- /**
- * Fire size changed event
- *
- * @param event SizeChangedEvent
- */
- public void fireSizeChangedEvent(SizeChangedEvent event) {
- Object[] listeners = _listeners.getListenerList();
- for (int i = 0; i < listeners.length; i = i + 2) {
- if (listeners[i] == ISizeChangedListener.class) {
- ((ISizeChangedListener) listeners[i + 1]).sizeChangedEvent(event);
- }
- }
- }
- //
+ /* Copyright 2012 Yaqiang Wang,
+ * yaqiang.wang@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ */
+package org.meteoinfo.legend;
+
+import org.meteoinfo.common.util.GlobalUtil;
+import org.meteoinfo.global.event.ISizeChangedListener;
+import org.meteoinfo.global.event.SizeChangedEvent;
+import java.awt.Color;
+import java.awt.Font;
+import java.util.HashMap;
+import javax.swing.event.EventListenerList;
+
+ /**
+ * Label break class
+ *
+ * @author Yaqiang Wang
+ */
+public class LabelBreak extends ColorBreak {
+ //
+
+ private EventListenerList _listeners = new EventListenerList();
+ private String _text;
+ private float _angle;
+ private Font _font;
+ private AlignType _alignType;
+ private float _xShift;
+ private float _yShift;
+ //
+ //
+
+ public LabelBreak() {
+ super();
+ this.setBreakType(BreakTypes.LabelBreak);
+ _text = "";
+ _angle = 0;
+ this.setColor(Color.black);
+ _font = new Font(GlobalUtil.getDefaultFontName(), Font.PLAIN, 7);
+ _alignType = AlignType.Center;
+ _yShift = 0;
+ }
+ //
+ //
+
+ /**
+ * Get text string
+ *
+ * @return Text string
+ */
+ public String getText() {
+ return _text;
+ }
+
+ /**
+ * Set text string and fire size changed event
+ *
+ * @param text Text string
+ */
+ public void setText(String text) {
+ _text = text;
+ this.fireSizeChangedEvent(new SizeChangedEvent(this));
+ }
+
+ /**
+ * Get angle
+ *
+ * @return Angle
+ */
+ public float getAngle() {
+ return _angle;
+ }
+
+ /**
+ * Set angle
+ *
+ * @param angle Angle
+ */
+ public void setAngle(float angle) {
+ _angle = angle;
+ }
+
+ /**
+ * Get font
+ *
+ * @return Font
+ */
+ public Font getFont() {
+ return _font;
+ }
+
+ /**
+ * Set font and fire size changed event
+ *
+ * @param f Font
+ */
+ public void setFont(Font f) {
+ _font = f;
+ this.fireSizeChangedEvent(new SizeChangedEvent(this));
+ }
+
+ /**
+ * Get align type
+ *
+ * @return Align type
+ */
+ public AlignType getAlignType() {
+ return _alignType;
+ }
+
+ /**
+ * Set align type
+ *
+ * @param at Align type
+ */
+ public void setAlignType(AlignType at) {
+ _alignType = at;
+ }
+
+ /**
+ * Get y shift
+ *
+ * @return Y shift
+ */
+ public float getYShift() {
+ return _yShift;
+ }
+
+ /**
+ * Set y shift
+ *
+ * @param yshift Y shift
+ */
+ public void setYShift(float yshift) {
+ _yShift = yshift;
+ }
+
+ /**
+ * Get x shift
+ *
+ * @return X shift
+ */
+ public float getXShift() {
+ return _xShift;
+ }
+
+ /**
+ * Set x shift
+ *
+ * @param xshift X shift
+ */
+ public void setXShift(float xshift) {
+ _xShift = xshift;
+ }
+
+ //
+ //
+ /**
+ * Get property object
+ *
+ * @return Property object
+ */
+ @Override
+ public Object getPropertyObject() {
+ HashMap objAttr = new HashMap();
+ objAttr.put("Text", "Text");
+ objAttr.put("Angle", "Angle");
+ objAttr.put("Color", "Color");
+ objAttr.put("Font", "Font");
+ //objAttr.Add("AlignType", "AlignType");
+ //objAttr.Add("YShift", "YShift");
+ //CustomProperty cp = new CustomProperty(this, objAttr);
+ return objAttr;
+ }
+
+ /**
+ * Clone
+ *
+ * @return LabelBreak object
+ */
+ @Override
+ public Object clone() {
+ LabelBreak aCB = new LabelBreak();
+ aCB.setCaption(this.getCaption());
+ aCB.setColor(this.getColor());
+ aCB.setDrawShape(this.isDrawShape());
+ aCB.setEndValue(this.getEndValue());
+ aCB.setNoData(this.isNoData());
+ aCB.setStartValue(this.getStartValue());
+ aCB.setAngle(_angle);
+ aCB.setText(_text);
+ aCB.setFont(_font);
+ aCB.setAlignType(_alignType);
+ aCB.setYShift(_yShift);
+ aCB.setXShift(_xShift);
+
+ return aCB;
+ }
+ //
+ //
+
+ /**
+ * Add size changed listener
+ *
+ * @param scl SizeChangedListener interface
+ */
+ public void addSizeChangedListener(ISizeChangedListener scl) {
+ this._listeners.add(ISizeChangedListener.class, scl);
+ }
+
+ /**
+ * Remove size changed listener
+ *
+ * @param scl SizeChangedListener interface
+ */
+ public void removeSizeChangedListener(ISizeChangedListener scl) {
+ this._listeners.remove(ISizeChangedListener.class, scl);
+ }
+
+ /**
+ * Fire size changed event
+ *
+ * @param event SizeChangedEvent
+ */
+ public void fireSizeChangedEvent(SizeChangedEvent event) {
+ Object[] listeners = _listeners.getListenerList();
+ for (int i = 0; i < listeners.length; i = i + 2) {
+ if (listeners[i] == ISizeChangedListener.class) {
+ ((ISizeChangedListener) listeners[i + 1]).sizeChangedEvent(event);
+ }
+ }
+ }
+ //
}
\ No newline at end of file
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/legend/LayersLegend.java b/MeteoInfoLib/src/main/java/org/meteoinfo/legend/LayersLegend.java
index d7b70400..72bb903f 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/legend/LayersLegend.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/legend/LayersLegend.java
@@ -14,6 +14,9 @@
package org.meteoinfo.legend;
import com.formdev.flatlaf.extras.FlatSVGIcon;
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.GenericFileFilter;
+import org.meteoinfo.common.PointF;
import org.meteoinfo.data.mapdata.MapDataManage;
import org.meteoinfo.drawing.Draw;
import org.meteoinfo.global.event.ActiveMapFrameChangedEvent;
@@ -22,8 +25,6 @@ import org.meteoinfo.global.event.ILayersUpdatedListener;
import org.meteoinfo.global.event.IMapFramesUpdatedListener;
import org.meteoinfo.global.event.LayersUpdatedEvent;
import org.meteoinfo.global.event.MapFramesUpdatedEvent;
-import org.meteoinfo.global.GenericFileFilter;
-import org.meteoinfo.global.PointF;
import org.meteoinfo.layer.FrmLayerProperty;
import org.meteoinfo.layer.LayerTypes;
import org.meteoinfo.layer.MapLayer;
@@ -51,7 +52,6 @@ import java.awt.geom.GeneralPath;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
-import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
@@ -65,7 +65,6 @@ import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.meteoinfo.data.mapdata.FrmAttriData;
import org.meteoinfo.data.mapdata.webmap.WebMapProvider;
-import org.meteoinfo.global.Extent;
import org.meteoinfo.global.FrmProperty;
import org.meteoinfo.global.event.INodeSelectedListener;
import org.meteoinfo.global.event.NodeSelectedEvent;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/legend/LegendManage.java b/MeteoInfoLib/src/main/java/org/meteoinfo/legend/LegendManage.java
index 46335336..86b8b904 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/legend/LegendManage.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/legend/LegendManage.java
@@ -13,10 +13,10 @@
*/
package org.meteoinfo.legend;
+import org.meteoinfo.common.MIMath;
import org.meteoinfo.data.GridData;
import org.meteoinfo.data.StationData;
import org.meteoinfo.drawing.ContourDraw;
-import org.meteoinfo.global.MIMath;
import org.meteoinfo.ndarray.util.BigDecimalUtil;
import org.meteoinfo.shape.ShapeTypes;
import java.awt.Color;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/legend/LegendScheme.java b/MeteoInfoLib/src/main/java/org/meteoinfo/legend/LegendScheme.java
index 19705aa4..198ca6fc 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/legend/LegendScheme.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/legend/LegendScheme.java
@@ -17,7 +17,6 @@ import org.meteoinfo.data.meteodata.DrawType2D;
import org.meteoinfo.global.DataConvert;
import org.meteoinfo.global.colors.ColorMap;
import org.meteoinfo.global.colors.ColorUtil;
-import org.meteoinfo.global.util.GlobalUtil;
import org.meteoinfo.shape.ShapeTypes;
import java.awt.Color;
import java.io.BufferedReader;
@@ -44,15 +43,6 @@ import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
-import static org.meteoinfo.shape.ShapeTypes.Point;
-import static org.meteoinfo.shape.ShapeTypes.PointM;
-import static org.meteoinfo.shape.ShapeTypes.PointZ;
-import static org.meteoinfo.shape.ShapeTypes.Polygon;
-import static org.meteoinfo.shape.ShapeTypes.PolygonM;
-import static org.meteoinfo.shape.ShapeTypes.PolygonZ;
-import static org.meteoinfo.shape.ShapeTypes.Polyline;
-import static org.meteoinfo.shape.ShapeTypes.PolylineM;
-import static org.meteoinfo.shape.ShapeTypes.PolylineZ;
import org.w3c.dom.DOMException;
/**
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/legend/LegendView.java b/MeteoInfoLib/src/main/java/org/meteoinfo/legend/LegendView.java
index da8c9135..ef98cca7 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/legend/LegendView.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/legend/LegendView.java
@@ -13,9 +13,10 @@
*/
package org.meteoinfo.legend;
+import org.meteoinfo.common.MIMath;
+import org.meteoinfo.common.PointF;
import org.meteoinfo.drawing.Draw;
-import org.meteoinfo.global.MIMath;
-import org.meteoinfo.global.PointF;
+
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/legend/SymbolControl.java b/MeteoInfoLib/src/main/java/org/meteoinfo/legend/SymbolControl.java
index ae98043e..04a599a1 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/legend/SymbolControl.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/legend/SymbolControl.java
@@ -1,496 +1,496 @@
-/* Copyright 2012 Yaqiang Wang,
- * yaqiang.wang@gmail.com
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.legend;
-
-import org.meteoinfo.drawing.Draw;
-import org.meteoinfo.global.event.ISelectedCellChangedListener;
-import org.meteoinfo.global.event.SelectedCellChangedEvent;
-import org.meteoinfo.global.PointF;
-import org.meteoinfo.shape.ShapeTypes;
-import java.awt.BorderLayout;
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.Font;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.Image;
-import java.awt.Rectangle;
-import java.awt.RenderingHints;
-import java.awt.event.AdjustmentEvent;
-import java.awt.event.AdjustmentListener;
-import java.awt.event.ComponentAdapter;
-import java.awt.event.ComponentEvent;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
-import java.util.ArrayList;
-import java.util.List;
-import javax.swing.JPanel;
-import javax.swing.JScrollBar;
-import javax.swing.event.EventListenerList;
-
-/**
- *
- * @author Yaqiang Wang
- */
-public class SymbolControl extends JPanel {
- //
-
- private EventListenerList _listeners = new EventListenerList();
- private ShapeTypes _shapeType;
- private MarkerType _markerType;
- private Dimension _cellSize;
- private int _symbolNumber;
- private int _colNumber;
- private int _rowNumber;
- private int _selectedCell;
- private List _imageList;
- private JScrollBar _vScrollBar;
- private Color _selColor = new Color(210, 255, 255);
- //
- //
-
- public SymbolControl() {
- initComponents();
-
- this.addComponentListener(new ComponentAdapter() {
- @Override
- public void componentResized(ComponentEvent e) {
- onComponentResized(e);
- }
- });
-
- this.addMouseListener(new MouseAdapter() {
- @Override
- public void mouseClicked(MouseEvent e) {
- onMouseClicked(e);
- }
- });
-
- _shapeType = ShapeTypes.Point;
- _markerType = MarkerType.Simple;
- _cellSize = new Dimension(25, 25);
- _symbolNumber = PointStyle.values().length;
- _colNumber = 10;
- _rowNumber = 26;
- _selectedCell = -1;
- _imageList = new ArrayList<>();
- }
-
- private void initComponents() {
- this.setPreferredSize(new Dimension(200, 100));
- this.setLayout(new BorderLayout());
- this.setBackground(Color.white);
-
- _vScrollBar = new JScrollBar(JScrollBar.VERTICAL);
- _vScrollBar.addAdjustmentListener(new AdjustmentListener() {
- @Override
- public void adjustmentValueChanged(AdjustmentEvent e) {
- onScrollValueChanged(e);
- }
- });
- this.add(_vScrollBar, BorderLayout.EAST);
- //this._vScrollBar.setSize(this._vScrollBar.getWidth(), this.getHeight());
- this._vScrollBar.setSize(20, this.getHeight());
- this._vScrollBar.setLocation(this.getWidth() - this._vScrollBar.getWidth(), 0);
- }
- //
-
- //
- public void addSelectedCellChangedListener(ISelectedCellChangedListener listener) {
- this._listeners.add(ISelectedCellChangedListener.class, listener);
- }
-
- public void removeSelectedCellChangedListener(ISelectedCellChangedListener listener) {
- this._listeners.remove(ISelectedCellChangedListener.class, listener);
- }
-
- public void fireSelectedCellChangedEvent() {
- fireSelectedCellChangedEvent(new SelectedCellChangedEvent(this));
- }
-
- private void fireSelectedCellChangedEvent(SelectedCellChangedEvent event) {
- Object[] listeners = _listeners.getListenerList();
- for (int i = 0; i < listeners.length; i = i + 2) {
- if (listeners[i] == ISelectedCellChangedListener.class) {
- ((ISelectedCellChangedListener) listeners[i + 1]).selectedCellChangedEvent(event);
- }
- }
- }
-
- public void onScrollValueChanged(AdjustmentEvent e) {
- _vScrollBar.setValue(e.getValue());
- this.repaint();
- }
-
- public void onComponentResized(ComponentEvent e) {
- if (this.getWidth() > 0 && this.getHeight() > 0) {
- this.updateSize();
- this._vScrollBar.setLocation(this.getWidth() - this._vScrollBar.getWidth(), 0);
- this._vScrollBar.setSize(this._vScrollBar.getWidth(), this.getHeight());
- }
- this.repaint();
- }
-
- public void onMouseClicked(MouseEvent e) {
- int col = e.getX() / _cellSize.width;
- int row = (e.getY() + _vScrollBar.getValue()) / _cellSize.height;
- int sel = row * _colNumber + col;
- if (sel < _symbolNumber) {
- _selectedCell = row * _colNumber + col;
- //((frmPointSymbolSet)this.ParentForm).PointBreak.CharIndex = _selectedCell;
- this.repaint();
-
- this.fireSelectedCellChangedEvent();
- }
- }
- //
- //
-
- /**
- * Get shape type
- *
- * @return The shape type
- */
- public ShapeTypes getShapeType() {
- return _shapeType;
- }
-
- /**
- * Set shape type
- *
- * @param st The shape type
- */
- public void setShapeType(ShapeTypes st) {
- _shapeType = st;
- switch (_shapeType) {
- case Point:
- setCellSize(new Dimension(25, 25));
- if (_markerType == MarkerType.Simple) {
- setSymbolNumber(PointStyle.values().length);
- } else {
- setSymbolNumber(256);
- }
- break;
- case Polyline:
- setCellSize(new Dimension(50, 40));
- setSymbolNumber(LineStyles.values().length);
- break;
- case Polygon:
- setCellSize(new Dimension(30, 30));
- setSymbolNumber(HatchStyle.values().length);
- break;
- }
- }
-
- /**
- * Get marker type
- *
- * @return Marker type
- */
- public MarkerType getMarkerType() {
- return _markerType;
- }
-
- /**
- * Set marker type
- *
- * @param mt
- */
- public void setMarkerType(MarkerType mt) {
- _markerType = mt;
- if (_selectedCell < 0 || _selectedCell >= _symbolNumber) {
- _selectedCell = 0;
- }
- this.repaint();
- }
-
- /**
- * Get cell size
- *
- * @return Cell size
- */
- public Dimension getCellSize() {
- return _cellSize;
- }
-
- /**
- * Set cell size
- *
- * @param size Cell size
- */
- public void setCellSize(Dimension size) {
- _cellSize = size;
- this.updateSize();
- }
-
- /**
- * Get selected cell index
- *
- * @return Selected cell index
- */
- public int getSelectedCell() {
- return _selectedCell;
- }
-
- /**
- * Set selected cell index
- *
- * @param idx Selected cell index
- */
- public void setSelectedCell(int idx) {
- _selectedCell = idx;
- }
-
- /**
- * Get symbol number
- *
- * @return The symbol number
- */
- public int getSymbolNumber() {
- return _symbolNumber;
- }
-
- /**
- * Set symbol number
- *
- * @param sn The symbol number
- */
- public void setSymbolNumber(int sn) {
- _symbolNumber = sn;
- _rowNumber = (int) Math.ceil((float) _symbolNumber / _colNumber);
- }
-
- /**
- * Get column number
- *
- * @return The column number
- */
- public int getColumnNumber() {
- return _colNumber;
- }
-
- /**
- * Set column number
- *
- * @param n The column number
- */
- public void setColumnNumber(int n) {
- _colNumber = n;
- }
- //
- //
-
- /**
- * Set image list
- *
- * @param imageList The image list
- */
- public void setIamgeList(List imageList) {
- _imageList = imageList;
- setSymbolNumber(imageList.size());
- }
-
- private void updateSize() {
- if (this._vScrollBar.isVisible()) {
- this._colNumber = (this.getWidth() - this._vScrollBar.getWidth()) / this._cellSize.width;
- } else {
- this._colNumber = this.getWidth() / this._cellSize.width;
- }
- if (_colNumber == 0) {
- _colNumber = 1;
- }
- this._rowNumber = (int) Math.ceil((float) _symbolNumber / _colNumber);
- }
-
- @Override
- public void paintComponent(Graphics g) {
- super.paintComponent(g);
-
- Graphics2D g2 = (Graphics2D) g;
-
- g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
- paintGraphics(g2);
- //g2.dispose();
- }
-
- private void paintGraphics(Graphics2D g) {
- int TotalHeight = calcTotalDrawHeight();
- Rectangle rect;
- if (TotalHeight > this.getHeight()) {
- _vScrollBar.setMinimum(0);
- _vScrollBar.setUnitIncrement(_cellSize.height);
- _vScrollBar.setBlockIncrement(this.getHeight());
- _vScrollBar.setMaximum(TotalHeight);
-
- if (_vScrollBar.isVisible() == false) {
- _vScrollBar.setValue(0);
- _vScrollBar.setVisible(true);
- }
- rect = new Rectangle(0, -_vScrollBar.getValue(), this.getWidth() - _vScrollBar.getWidth(), TotalHeight);
- } else {
- _vScrollBar.setVisible(false);
- rect = new Rectangle(0, 0, this.getWidth(), this.getHeight());
- }
-
- this.updateSize();
- drawCells(g, rect.y);
- }
-
- private void drawCells(Graphics2D g, int sHeight) {
- int hideRows = 0;
- switch (_shapeType) {
- case Point:
- switch (_markerType) {
- case Character:
- Font smallFont = new Font(this.getFont().getFamily(), Font.PLAIN, (int) (_cellSize.width * 0.8F));
- for (int i = 0; i < _symbolNumber; i++) {
- int row = i / _colNumber;
- if (row > hideRows) {
- sHeight += _cellSize.height;
- hideRows = row;
- }
- if (sHeight + _cellSize.height < 0) {
- continue;
- }
-
- int col = i % _colNumber;
- if (i == _selectedCell) {
- g.setColor(_selColor);
- g.fill(new Rectangle(col * _cellSize.width, sHeight, _cellSize.width, _cellSize.height));
- }
-
- String text = String.valueOf((char) i);
- g.setColor(Color.black);
- g.setFont(smallFont);
- g.drawString(text, col * _cellSize.width, sHeight + _cellSize.height);
- }
- break;
- case Simple:
- PointBreak aPB = new PointBreak();
- aPB.setColor(Color.red);
- aPB.setDrawOutline(true);
- aPB.setSize(_cellSize.width * 0.8f);
- for (int i = 0; i < _symbolNumber; i++) {
-// if (i == PointStyle.values().length) {
-// break;
-// }
-
- int row = i / _colNumber;
- if (row > hideRows) {
- sHeight += _cellSize.height;
- hideRows = row;
- }
- if (sHeight + _cellSize.height < 0) {
- continue;
- }
-
- int col = i % _colNumber;
- if (i == _selectedCell) {
- g.setColor(_selColor);
- g.fill(new Rectangle(col * _cellSize.width, sHeight, _cellSize.width, _cellSize.height));
- }
-
- PointF sP = new PointF(col * _cellSize.width + _cellSize.width / 2,
- sHeight + _cellSize.height / 2);
- aPB.setStyle(PointStyle.values()[i]);
- Draw.drawPoint(sP, aPB, g);
- }
- break;
- case Image:
- float size = _cellSize.width * 0.8f;
- for (int i = 0; i < _symbolNumber; i++) {
- int row = i / _colNumber;
- if (row > hideRows) {
- sHeight += _cellSize.height;
- hideRows = row;
- }
- if (sHeight + _cellSize.height < 0) {
- continue;
- }
-
- int col = i % _colNumber;
- if (i == _selectedCell) {
- g.setColor(_selColor);
- g.fill(new Rectangle(col * _cellSize.width, sHeight, _cellSize.width, _cellSize.height));
- }
-
- //((Bitmap)_imageList[i]).MakeTransparent(Color.White);
- if (_imageList.size() > i) {
- g.drawImage(_imageList.get(i), col * _cellSize.width, sHeight, (int) size, (int) size, null);
- }
- }
- break;
- }
- break;
- case Polyline:
- PolylineBreak aPLB = new PolylineBreak();
- aPLB.setWidth(2);
- aPLB.setColor(Color.black);
- for (int i = 0; i < _symbolNumber; i++) {
- int row = i / _colNumber;
- if (row > hideRows) {
- sHeight += _cellSize.height;
- hideRows = row;
- }
- if (sHeight + _cellSize.height < 0) {
- continue;
- }
-
- int col = i % _colNumber;
- Rectangle rect = new Rectangle(col * _cellSize.width, sHeight + _cellSize.height / 4,
- _cellSize.width, _cellSize.height / 2);
- if (i == _selectedCell) {
- g.setColor(_selColor);
- g.fill(rect);
- }
-
- aPLB.setStyle(LineStyles.values()[i]);
- Draw.drawPolylineSymbol(new PointF(rect.x + rect.width / 2, rect.y + rect.height / 2),
- rect.width * 0.8f, rect.height * 0.8f, aPLB, g);
- }
- break;
- case Polygon:
- PolygonBreak aPGB = new PolygonBreak();
- aPGB.setColor(Color.red);
- aPGB.setOutlineColor(Color.black);
- for (int i = 0; i < _symbolNumber; i++) {
- int row = i / _colNumber;
- if (row > hideRows) {
- sHeight += _cellSize.height;
- hideRows = row;
- }
- if (sHeight + _cellSize.height < 0) {
- continue;
- }
-
- int col = i % _colNumber;
- Rectangle rect = new Rectangle(col * _cellSize.width, sHeight, _cellSize.width, _cellSize.height);
- if (i == _selectedCell) {
- g.setColor(_selColor);
- g.fill(rect);
- }
-
- aPGB.setStyle(HatchStyle.values()[i]);
- Draw.drawPolygonSymbol(new PointF(rect.x + rect.width / 2, rect.y + rect.height / 2),
- rect.width * 0.8f, rect.height * 0.8f, aPGB, g);
- }
- break;
- }
- }
-
- private int calcTotalDrawHeight() {
- return _cellSize.height * _rowNumber;
- }
- //
-}
+/* Copyright 2012 Yaqiang Wang,
+ * yaqiang.wang@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ */
+package org.meteoinfo.legend;
+
+import org.meteoinfo.common.PointF;
+import org.meteoinfo.drawing.Draw;
+import org.meteoinfo.global.event.ISelectedCellChangedListener;
+import org.meteoinfo.global.event.SelectedCellChangedEvent;
+import org.meteoinfo.shape.ShapeTypes;
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.event.AdjustmentEvent;
+import java.awt.event.AdjustmentListener;
+import java.awt.event.ComponentAdapter;
+import java.awt.event.ComponentEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.util.ArrayList;
+import java.util.List;
+import javax.swing.JPanel;
+import javax.swing.JScrollBar;
+import javax.swing.event.EventListenerList;
+
+/**
+ *
+ * @author Yaqiang Wang
+ */
+public class SymbolControl extends JPanel {
+ //
+
+ private EventListenerList _listeners = new EventListenerList();
+ private ShapeTypes _shapeType;
+ private MarkerType _markerType;
+ private Dimension _cellSize;
+ private int _symbolNumber;
+ private int _colNumber;
+ private int _rowNumber;
+ private int _selectedCell;
+ private List _imageList;
+ private JScrollBar _vScrollBar;
+ private Color _selColor = new Color(210, 255, 255);
+ //
+ //
+
+ public SymbolControl() {
+ initComponents();
+
+ this.addComponentListener(new ComponentAdapter() {
+ @Override
+ public void componentResized(ComponentEvent e) {
+ onComponentResized(e);
+ }
+ });
+
+ this.addMouseListener(new MouseAdapter() {
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ onMouseClicked(e);
+ }
+ });
+
+ _shapeType = ShapeTypes.Point;
+ _markerType = MarkerType.Simple;
+ _cellSize = new Dimension(25, 25);
+ _symbolNumber = PointStyle.values().length;
+ _colNumber = 10;
+ _rowNumber = 26;
+ _selectedCell = -1;
+ _imageList = new ArrayList<>();
+ }
+
+ private void initComponents() {
+ this.setPreferredSize(new Dimension(200, 100));
+ this.setLayout(new BorderLayout());
+ this.setBackground(Color.white);
+
+ _vScrollBar = new JScrollBar(JScrollBar.VERTICAL);
+ _vScrollBar.addAdjustmentListener(new AdjustmentListener() {
+ @Override
+ public void adjustmentValueChanged(AdjustmentEvent e) {
+ onScrollValueChanged(e);
+ }
+ });
+ this.add(_vScrollBar, BorderLayout.EAST);
+ //this._vScrollBar.setSize(this._vScrollBar.getWidth(), this.getHeight());
+ this._vScrollBar.setSize(20, this.getHeight());
+ this._vScrollBar.setLocation(this.getWidth() - this._vScrollBar.getWidth(), 0);
+ }
+ //
+
+ //
+ public void addSelectedCellChangedListener(ISelectedCellChangedListener listener) {
+ this._listeners.add(ISelectedCellChangedListener.class, listener);
+ }
+
+ public void removeSelectedCellChangedListener(ISelectedCellChangedListener listener) {
+ this._listeners.remove(ISelectedCellChangedListener.class, listener);
+ }
+
+ public void fireSelectedCellChangedEvent() {
+ fireSelectedCellChangedEvent(new SelectedCellChangedEvent(this));
+ }
+
+ private void fireSelectedCellChangedEvent(SelectedCellChangedEvent event) {
+ Object[] listeners = _listeners.getListenerList();
+ for (int i = 0; i < listeners.length; i = i + 2) {
+ if (listeners[i] == ISelectedCellChangedListener.class) {
+ ((ISelectedCellChangedListener) listeners[i + 1]).selectedCellChangedEvent(event);
+ }
+ }
+ }
+
+ public void onScrollValueChanged(AdjustmentEvent e) {
+ _vScrollBar.setValue(e.getValue());
+ this.repaint();
+ }
+
+ public void onComponentResized(ComponentEvent e) {
+ if (this.getWidth() > 0 && this.getHeight() > 0) {
+ this.updateSize();
+ this._vScrollBar.setLocation(this.getWidth() - this._vScrollBar.getWidth(), 0);
+ this._vScrollBar.setSize(this._vScrollBar.getWidth(), this.getHeight());
+ }
+ this.repaint();
+ }
+
+ public void onMouseClicked(MouseEvent e) {
+ int col = e.getX() / _cellSize.width;
+ int row = (e.getY() + _vScrollBar.getValue()) / _cellSize.height;
+ int sel = row * _colNumber + col;
+ if (sel < _symbolNumber) {
+ _selectedCell = row * _colNumber + col;
+ //((frmPointSymbolSet)this.ParentForm).PointBreak.CharIndex = _selectedCell;
+ this.repaint();
+
+ this.fireSelectedCellChangedEvent();
+ }
+ }
+ //
+ //
+
+ /**
+ * Get shape type
+ *
+ * @return The shape type
+ */
+ public ShapeTypes getShapeType() {
+ return _shapeType;
+ }
+
+ /**
+ * Set shape type
+ *
+ * @param st The shape type
+ */
+ public void setShapeType(ShapeTypes st) {
+ _shapeType = st;
+ switch (_shapeType) {
+ case Point:
+ setCellSize(new Dimension(25, 25));
+ if (_markerType == MarkerType.Simple) {
+ setSymbolNumber(PointStyle.values().length);
+ } else {
+ setSymbolNumber(256);
+ }
+ break;
+ case Polyline:
+ setCellSize(new Dimension(50, 40));
+ setSymbolNumber(LineStyles.values().length);
+ break;
+ case Polygon:
+ setCellSize(new Dimension(30, 30));
+ setSymbolNumber(HatchStyle.values().length);
+ break;
+ }
+ }
+
+ /**
+ * Get marker type
+ *
+ * @return Marker type
+ */
+ public MarkerType getMarkerType() {
+ return _markerType;
+ }
+
+ /**
+ * Set marker type
+ *
+ * @param mt
+ */
+ public void setMarkerType(MarkerType mt) {
+ _markerType = mt;
+ if (_selectedCell < 0 || _selectedCell >= _symbolNumber) {
+ _selectedCell = 0;
+ }
+ this.repaint();
+ }
+
+ /**
+ * Get cell size
+ *
+ * @return Cell size
+ */
+ public Dimension getCellSize() {
+ return _cellSize;
+ }
+
+ /**
+ * Set cell size
+ *
+ * @param size Cell size
+ */
+ public void setCellSize(Dimension size) {
+ _cellSize = size;
+ this.updateSize();
+ }
+
+ /**
+ * Get selected cell index
+ *
+ * @return Selected cell index
+ */
+ public int getSelectedCell() {
+ return _selectedCell;
+ }
+
+ /**
+ * Set selected cell index
+ *
+ * @param idx Selected cell index
+ */
+ public void setSelectedCell(int idx) {
+ _selectedCell = idx;
+ }
+
+ /**
+ * Get symbol number
+ *
+ * @return The symbol number
+ */
+ public int getSymbolNumber() {
+ return _symbolNumber;
+ }
+
+ /**
+ * Set symbol number
+ *
+ * @param sn The symbol number
+ */
+ public void setSymbolNumber(int sn) {
+ _symbolNumber = sn;
+ _rowNumber = (int) Math.ceil((float) _symbolNumber / _colNumber);
+ }
+
+ /**
+ * Get column number
+ *
+ * @return The column number
+ */
+ public int getColumnNumber() {
+ return _colNumber;
+ }
+
+ /**
+ * Set column number
+ *
+ * @param n The column number
+ */
+ public void setColumnNumber(int n) {
+ _colNumber = n;
+ }
+ //
+ //
+
+ /**
+ * Set image list
+ *
+ * @param imageList The image list
+ */
+ public void setIamgeList(List imageList) {
+ _imageList = imageList;
+ setSymbolNumber(imageList.size());
+ }
+
+ private void updateSize() {
+ if (this._vScrollBar.isVisible()) {
+ this._colNumber = (this.getWidth() - this._vScrollBar.getWidth()) / this._cellSize.width;
+ } else {
+ this._colNumber = this.getWidth() / this._cellSize.width;
+ }
+ if (_colNumber == 0) {
+ _colNumber = 1;
+ }
+ this._rowNumber = (int) Math.ceil((float) _symbolNumber / _colNumber);
+ }
+
+ @Override
+ public void paintComponent(Graphics g) {
+ super.paintComponent(g);
+
+ Graphics2D g2 = (Graphics2D) g;
+
+ g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ paintGraphics(g2);
+ //g2.dispose();
+ }
+
+ private void paintGraphics(Graphics2D g) {
+ int TotalHeight = calcTotalDrawHeight();
+ Rectangle rect;
+ if (TotalHeight > this.getHeight()) {
+ _vScrollBar.setMinimum(0);
+ _vScrollBar.setUnitIncrement(_cellSize.height);
+ _vScrollBar.setBlockIncrement(this.getHeight());
+ _vScrollBar.setMaximum(TotalHeight);
+
+ if (_vScrollBar.isVisible() == false) {
+ _vScrollBar.setValue(0);
+ _vScrollBar.setVisible(true);
+ }
+ rect = new Rectangle(0, -_vScrollBar.getValue(), this.getWidth() - _vScrollBar.getWidth(), TotalHeight);
+ } else {
+ _vScrollBar.setVisible(false);
+ rect = new Rectangle(0, 0, this.getWidth(), this.getHeight());
+ }
+
+ this.updateSize();
+ drawCells(g, rect.y);
+ }
+
+ private void drawCells(Graphics2D g, int sHeight) {
+ int hideRows = 0;
+ switch (_shapeType) {
+ case Point:
+ switch (_markerType) {
+ case Character:
+ Font smallFont = new Font(this.getFont().getFamily(), Font.PLAIN, (int) (_cellSize.width * 0.8F));
+ for (int i = 0; i < _symbolNumber; i++) {
+ int row = i / _colNumber;
+ if (row > hideRows) {
+ sHeight += _cellSize.height;
+ hideRows = row;
+ }
+ if (sHeight + _cellSize.height < 0) {
+ continue;
+ }
+
+ int col = i % _colNumber;
+ if (i == _selectedCell) {
+ g.setColor(_selColor);
+ g.fill(new Rectangle(col * _cellSize.width, sHeight, _cellSize.width, _cellSize.height));
+ }
+
+ String text = String.valueOf((char) i);
+ g.setColor(Color.black);
+ g.setFont(smallFont);
+ g.drawString(text, col * _cellSize.width, sHeight + _cellSize.height);
+ }
+ break;
+ case Simple:
+ PointBreak aPB = new PointBreak();
+ aPB.setColor(Color.red);
+ aPB.setDrawOutline(true);
+ aPB.setSize(_cellSize.width * 0.8f);
+ for (int i = 0; i < _symbolNumber; i++) {
+// if (i == PointStyle.values().length) {
+// break;
+// }
+
+ int row = i / _colNumber;
+ if (row > hideRows) {
+ sHeight += _cellSize.height;
+ hideRows = row;
+ }
+ if (sHeight + _cellSize.height < 0) {
+ continue;
+ }
+
+ int col = i % _colNumber;
+ if (i == _selectedCell) {
+ g.setColor(_selColor);
+ g.fill(new Rectangle(col * _cellSize.width, sHeight, _cellSize.width, _cellSize.height));
+ }
+
+ PointF sP = new PointF(col * _cellSize.width + _cellSize.width / 2,
+ sHeight + _cellSize.height / 2);
+ aPB.setStyle(PointStyle.values()[i]);
+ Draw.drawPoint(sP, aPB, g);
+ }
+ break;
+ case Image:
+ float size = _cellSize.width * 0.8f;
+ for (int i = 0; i < _symbolNumber; i++) {
+ int row = i / _colNumber;
+ if (row > hideRows) {
+ sHeight += _cellSize.height;
+ hideRows = row;
+ }
+ if (sHeight + _cellSize.height < 0) {
+ continue;
+ }
+
+ int col = i % _colNumber;
+ if (i == _selectedCell) {
+ g.setColor(_selColor);
+ g.fill(new Rectangle(col * _cellSize.width, sHeight, _cellSize.width, _cellSize.height));
+ }
+
+ //((Bitmap)_imageList[i]).MakeTransparent(Color.White);
+ if (_imageList.size() > i) {
+ g.drawImage(_imageList.get(i), col * _cellSize.width, sHeight, (int) size, (int) size, null);
+ }
+ }
+ break;
+ }
+ break;
+ case Polyline:
+ PolylineBreak aPLB = new PolylineBreak();
+ aPLB.setWidth(2);
+ aPLB.setColor(Color.black);
+ for (int i = 0; i < _symbolNumber; i++) {
+ int row = i / _colNumber;
+ if (row > hideRows) {
+ sHeight += _cellSize.height;
+ hideRows = row;
+ }
+ if (sHeight + _cellSize.height < 0) {
+ continue;
+ }
+
+ int col = i % _colNumber;
+ Rectangle rect = new Rectangle(col * _cellSize.width, sHeight + _cellSize.height / 4,
+ _cellSize.width, _cellSize.height / 2);
+ if (i == _selectedCell) {
+ g.setColor(_selColor);
+ g.fill(rect);
+ }
+
+ aPLB.setStyle(LineStyles.values()[i]);
+ Draw.drawPolylineSymbol(new PointF(rect.x + rect.width / 2, rect.y + rect.height / 2),
+ rect.width * 0.8f, rect.height * 0.8f, aPLB, g);
+ }
+ break;
+ case Polygon:
+ PolygonBreak aPGB = new PolygonBreak();
+ aPGB.setColor(Color.red);
+ aPGB.setOutlineColor(Color.black);
+ for (int i = 0; i < _symbolNumber; i++) {
+ int row = i / _colNumber;
+ if (row > hideRows) {
+ sHeight += _cellSize.height;
+ hideRows = row;
+ }
+ if (sHeight + _cellSize.height < 0) {
+ continue;
+ }
+
+ int col = i % _colNumber;
+ Rectangle rect = new Rectangle(col * _cellSize.width, sHeight, _cellSize.width, _cellSize.height);
+ if (i == _selectedCell) {
+ g.setColor(_selColor);
+ g.fill(rect);
+ }
+
+ aPGB.setStyle(HatchStyle.values()[i]);
+ Draw.drawPolygonSymbol(new PointF(rect.x + rect.width / 2, rect.y + rect.height / 2),
+ rect.width * 0.8f, rect.height * 0.8f, aPGB, g);
+ }
+ break;
+ }
+ }
+
+ private int calcTotalDrawHeight() {
+ return _cellSize.height * _rowNumber;
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/map/FrmVerticeEdit.java b/MeteoInfoLib/src/main/java/org/meteoinfo/map/FrmVerticeEdit.java
index 240ee29d..8b856670 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/map/FrmVerticeEdit.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/map/FrmVerticeEdit.java
@@ -5,7 +5,7 @@
*/
package org.meteoinfo.map;
-import org.meteoinfo.global.PointD;
+import org.meteoinfo.common.PointD;
/**
*
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/map/GridLabel.java b/MeteoInfoLib/src/main/java/org/meteoinfo/map/GridLabel.java
index 30aa3612..3c3e78b9 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/map/GridLabel.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/map/GridLabel.java
@@ -1,190 +1,190 @@
- /* Copyright 2012 Yaqiang Wang,
- * yaqiang.wang@gmail.com
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.map;
-
-import org.meteoinfo.global.Direction;
-import org.meteoinfo.global.PointD;
-
-/**
- *
- * @author Yaqiang Wang
- */
-public class GridLabel {
- //
-
- private Direction _labDirection;
- private String _labString;
- private PointD _labPoint;
- private PointD coord;
- private boolean _isLon;
- private boolean _isBorder;
- private float _value;
- private float angle;
- //
- //
- /**
- * Constructor
- */
- public GridLabel() {
- _labDirection = Direction.East;
- _isLon = true;
- _isBorder = true;
- this.angle = Float.NaN;
- }
- //
- //
-
- /**
- * Get label direction
- *
- * @return Label direction
- */
- public Direction getLabDirection() {
- return _labDirection;
- }
-
- /**
- * Set label direction
- *
- * @param dir Label direction
- */
- public void setLabDirection(Direction dir) {
- _labDirection = dir;
- }
-
- /**
- * Get label string
- *
- * @return label string
- */
- public String getLabString() {
- return _labString;
- }
-
- /**
- * Set label string
- *
- * @param str Label string
- */
- public void setLabString(String str) {
- _labString = str;
- }
-
- /**
- * Get label point
- *
- * @return Label Point
- */
- public PointD getLabPoint() {
- return _labPoint;
- }
-
- /**
- * Set label point
- *
- * @param p Label Point
- */
- public void setLabPoint(PointD p) {
- _labPoint = p;
- }
-
- /**
- * Get coordinate
- * @return Coordinate
- */
- public PointD getCoord() {
- return this.coord;
- }
-
- /**
- * Set coordinate
- * @param value Coordinate
- */
- public void setCoord(PointD value) {
- this.coord = value;
- }
-
- /**
- * Get if is longitude
- *
- * @return Boolean
- */
- public boolean isLongitude() {
- return _isLon;
- }
-
- /**
- * Set if is longitude
- *
- * @param istrue Boolean
- */
- public void setLongitude(boolean istrue) {
- _isLon = istrue;
- }
-
- /**
- * Get if is border
- *
- * @return Boolean
- */
- public boolean isBorder() {
- return _isBorder;
- }
-
- /**
- * Set if is border
- *
- * @param istrue Boolean
- */
- public void setBorder(boolean istrue) {
- _isBorder = istrue;
- }
-
- /**
- * Get value
- *
- * @return Value
- */
- public float getValue() {
- return _value;
- }
-
- /**
- * Set value
- *
- * @param value Value
- */
- public void setValue(float value) {
- _value = value;
- }
-
- /**
- * Get angle
- * @return Angle
- */
- public float getAngle() {
- return this.angle;
- }
-
- /**
- * Set angle
- * @param value Angle
- */
- public void setAnge(float value){
- this.angle = value;
- }
- //
- //
- //
-}
+ /* Copyright 2012 Yaqiang Wang,
+ * yaqiang.wang@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ */
+package org.meteoinfo.map;
+
+ import org.meteoinfo.common.Direction;
+ import org.meteoinfo.common.PointD;
+
+ /**
+ *
+ * @author Yaqiang Wang
+ */
+public class GridLabel {
+ //
+
+ private Direction _labDirection;
+ private String _labString;
+ private PointD _labPoint;
+ private PointD coord;
+ private boolean _isLon;
+ private boolean _isBorder;
+ private float _value;
+ private float angle;
+ //
+ //
+ /**
+ * Constructor
+ */
+ public GridLabel() {
+ _labDirection = Direction.East;
+ _isLon = true;
+ _isBorder = true;
+ this.angle = Float.NaN;
+ }
+ //
+ //
+
+ /**
+ * Get label direction
+ *
+ * @return Label direction
+ */
+ public Direction getLabDirection() {
+ return _labDirection;
+ }
+
+ /**
+ * Set label direction
+ *
+ * @param dir Label direction
+ */
+ public void setLabDirection(Direction dir) {
+ _labDirection = dir;
+ }
+
+ /**
+ * Get label string
+ *
+ * @return label string
+ */
+ public String getLabString() {
+ return _labString;
+ }
+
+ /**
+ * Set label string
+ *
+ * @param str Label string
+ */
+ public void setLabString(String str) {
+ _labString = str;
+ }
+
+ /**
+ * Get label point
+ *
+ * @return Label Point
+ */
+ public PointD getLabPoint() {
+ return _labPoint;
+ }
+
+ /**
+ * Set label point
+ *
+ * @param p Label Point
+ */
+ public void setLabPoint(PointD p) {
+ _labPoint = p;
+ }
+
+ /**
+ * Get coordinate
+ * @return Coordinate
+ */
+ public PointD getCoord() {
+ return this.coord;
+ }
+
+ /**
+ * Set coordinate
+ * @param value Coordinate
+ */
+ public void setCoord(PointD value) {
+ this.coord = value;
+ }
+
+ /**
+ * Get if is longitude
+ *
+ * @return Boolean
+ */
+ public boolean isLongitude() {
+ return _isLon;
+ }
+
+ /**
+ * Set if is longitude
+ *
+ * @param istrue Boolean
+ */
+ public void setLongitude(boolean istrue) {
+ _isLon = istrue;
+ }
+
+ /**
+ * Get if is border
+ *
+ * @return Boolean
+ */
+ public boolean isBorder() {
+ return _isBorder;
+ }
+
+ /**
+ * Set if is border
+ *
+ * @param istrue Boolean
+ */
+ public void setBorder(boolean istrue) {
+ _isBorder = istrue;
+ }
+
+ /**
+ * Get value
+ *
+ * @return Value
+ */
+ public float getValue() {
+ return _value;
+ }
+
+ /**
+ * Set value
+ *
+ * @param value Value
+ */
+ public void setValue(float value) {
+ _value = value;
+ }
+
+ /**
+ * Get angle
+ * @return Angle
+ */
+ public float getAngle() {
+ return this.angle;
+ }
+
+ /**
+ * Set angle
+ * @param value Angle
+ */
+ public void setAnge(float value){
+ this.angle = value;
+ }
+ //
+ //
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/map/MapView.java b/MeteoInfoLib/src/main/java/org/meteoinfo/map/MapView.java
index 44281733..1d03dcd5 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/map/MapView.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/map/MapView.java
@@ -18,13 +18,15 @@ import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfTemplate;
import com.itextpdf.text.pdf.PdfWriter;
+import org.meteoinfo.common.*;
+import org.meteoinfo.common.util.GlobalUtil;
import org.meteoinfo.data.mapdata.Field;
import org.meteoinfo.data.mapdata.MapDataManage;
import org.meteoinfo.drawing.Draw;
+import org.meteoinfo.geoprocess.GeometryUtil;
import org.meteoinfo.legend.PointStyle;
import org.meteoinfo.geoprocess.GeoComputation;
import org.meteoinfo.global.colors.ColorUtil;
-import org.meteoinfo.global.Direction;
import org.meteoinfo.global.event.GraphicSelectedEvent;
import org.meteoinfo.global.event.IGraphicSelectedListener;
import org.meteoinfo.global.event.ILayersUpdatedListener;
@@ -33,13 +35,8 @@ import org.meteoinfo.global.event.IViewExtentChangedListener;
import org.meteoinfo.global.event.LayersUpdatedEvent;
import org.meteoinfo.global.event.ProjectionChangedEvent;
import org.meteoinfo.global.event.ViewExtentChangedEvent;
-import org.meteoinfo.global.Extent;
import org.meteoinfo.global.FrmMeasurement;
import org.meteoinfo.global.FrmMeasurement.MeasureTypes;
-import org.meteoinfo.global.util.GlobalUtil;
-import org.meteoinfo.global.MIMath;
-import org.meteoinfo.global.PointD;
-import org.meteoinfo.global.PointF;
import org.meteoinfo.ndarray.DataType;
import org.meteoinfo.ndarray.util.BigDecimalUtil;
import org.meteoinfo.layer.ChartSet;
@@ -8860,7 +8857,7 @@ public class MapView extends JPanel implements IWebMapPanel {
aY = (float) sXY[1];
points.add(new PointD(aX, aY));
}
- Extent aExtent = MIMath.getPointsExtent(points);
+ Extent aExtent = GeometryUtil.getPointsExtent(points);
rect.x = (int) aExtent.minX;
rect.y = (int) aExtent.minY;
rect.width = (int) (aExtent.maxX - aExtent.minX);
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/map/MapViewUndoRedo.java b/MeteoInfoLib/src/main/java/org/meteoinfo/map/MapViewUndoRedo.java
index 8e986269..a71d4849 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/map/MapViewUndoRedo.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/map/MapViewUndoRedo.java
@@ -1,943 +1,944 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.meteoinfo.map;
-
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import javax.swing.undo.AbstractUndoableEdit;
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.global.PointD;
-import org.meteoinfo.layer.VectorLayer;
-import org.meteoinfo.shape.Graphic;
-import org.meteoinfo.shape.PolygonShape;
-import org.meteoinfo.shape.Shape;
-import org.meteoinfo.table.DataRow;
-
-/**
- *
- * @author yaqiang
- */
-public class MapViewUndoRedo {
- //
- public class ZoomEdit extends AbstractUndoableEdit {
- MapView mapView;
- Extent newExtent;
- Extent oldExtent;
-
- public ZoomEdit(MapView mapView, Extent oldExtent, Extent newExtent){
- this.mapView = mapView;
- this.newExtent = newExtent;
- this.oldExtent = oldExtent;
- }
-
- @Override
- public String getPresentationName() {
- return "Zoom";
- }
-
- @Override
- public void undo() {
- super.undo();
- mapView.zoomToExtent(oldExtent);
- }
-
- @Override
- public void redo(){
- super.redo();
- mapView.zoomToExtent(newExtent);
- }
- }
-
- public class AddFeatureEdit extends FeatureUndoableEdit {
- MapView mapView;
- Shape shape;
- VectorLayer layer;
-
- public AddFeatureEdit(MapView mapView, VectorLayer layer, Shape shape){
- this.mapView = mapView;
- this.layer = layer;
- this.shape = shape;
- }
-
- @Override
- public String getPresentationName() {
- return "Add a Feature";
- }
-
- @Override
- public void undo() {
- super.undo();
- layer.editRemoveShape(shape);
- mapView.paintLayers();
- System.out.println("Undo add a feature");
- }
-
- @Override
- public void redo(){
- super.redo();
- try {
- layer.editAddShape(shape);
- mapView.paintLayers();
- System.out.println("Redo add a feature");
- } catch (Exception ex) {
- Logger.getLogger(MapView.class.getName()).log(Level.SEVERE, null, ex);
- }
- }
- }
-
- public class AddFeaturesEdit extends FeatureUndoableEdit {
- MapView mapView;
- List shapes;
- VectorLayer layer;
-
- public AddFeaturesEdit(MapView mapView, VectorLayer layer, List shapes){
- this.mapView = mapView;
- this.layer = layer;
- this.shapes = shapes;
- }
-
- @Override
- public String getPresentationName() {
- return "Add Features";
- }
-
- @Override
- public void undo() {
- super.undo();
- for (Shape shape : shapes)
- layer.editRemoveShape(shape);
- mapView.paintLayers();
- System.out.println("Undo add features");
- }
-
- @Override
- public void redo(){
- super.redo();
- try {
- for (Shape shape : shapes)
- layer.editAddShape(shape);
- mapView.paintLayers();
- System.out.println("Redo add features");
- } catch (Exception ex) {
- Logger.getLogger(MapView.class.getName()).log(Level.SEVERE, null, ex);
- }
- }
- }
-
- public class ReplaceFeatureEdit extends FeatureUndoableEdit {
- MapView mapView;
- Shape s0;
- Shape s1;
- Shape s00;
- VectorLayer layer;
-
- public ReplaceFeatureEdit(MapView mapView, VectorLayer layer, Shape s0, Shape s1){
- this.mapView = mapView;
- this.layer = layer;
- this.s0 = s0;
- this.s1 = s1;
- this.s00 = (Shape)s0.clone();
- }
-
- @Override
- public String getPresentationName() {
- return "Replace Feature";
- }
-
- @Override
- public void undo() {
- super.undo();
- s0.cloneValue(s00);
- mapView.paintLayers();
- System.out.println("Undo replace feature");
- }
-
- @Override
- public void redo(){
- super.redo();
- s0.cloneValue(s1);
- mapView.paintLayers();
- System.out.println("Redo replace feature");
- }
- }
-
- public class SplitFeatureEdit extends FeatureUndoableEdit {
- MapView mapView;
- Shape shape;
- List shapes;
- VectorLayer layer;
-
- public SplitFeatureEdit(MapView mapView, VectorLayer layer, Shape shape, List shapes){
- this.mapView = mapView;
- this.layer = layer;
- this.shape = shape;
- this.shapes = shapes;
- }
-
- @Override
- public String getPresentationName() {
- return "Split Feature";
- }
-
- @Override
- public void undo() {
- super.undo();
- for (Shape s : shapes)
- layer.editRemoveShape(s);
- try {
- layer.editAddShape(shape);
- } catch (Exception ex) {
- Logger.getLogger(MapViewUndoRedo.class.getName()).log(Level.SEVERE, null, ex);
- }
- mapView.paintLayers();
- System.out.println("Undo split feature");
- }
-
- @Override
- public void redo(){
- super.redo();
- try {
- for (Shape s : shapes)
- layer.editAddShape(s);
- layer.editRemoveShape(shape);
- mapView.paintLayers();
- System.out.println("Redo split feature");
- } catch (Exception ex) {
- Logger.getLogger(MapView.class.getName()).log(Level.SEVERE, null, ex);
- }
- }
- }
-
- public class UnionFeaturesEdit extends FeatureUndoableEdit {
- MapView mapView;
- Shape shape;
- List shapes;
- VectorLayer layer;
-
- public UnionFeaturesEdit(MapView mapView, VectorLayer layer, Shape shape, List shapes){
- this.mapView = mapView;
- this.layer = layer;
- this.shape = shape;
- this.shapes = shapes;
- }
-
- @Override
- public String getPresentationName() {
- return "Union Features";
- }
-
- @Override
- public void undo() {
- super.undo();
- try {
- layer.editRemoveShape(shape);
- for (Shape s : shapes)
- layer.editAddShape(s);
- mapView.paintLayers();
- System.out.println("Undo split feature");
- } catch (Exception ex){
- Logger.getLogger(MapView.class.getName()).log(Level.SEVERE, null, ex);
- }
- }
-
- @Override
- public void redo(){
- super.redo();
- try {
- for (Shape s : shapes)
- layer.editRemoveShape(s);
- layer.editAddShape(shape);
- mapView.paintLayers();
- System.out.println("Redo split feature");
- } catch (Exception ex) {
- Logger.getLogger(MapView.class.getName()).log(Level.SEVERE, null, ex);
- }
- }
- }
-
- public class AddRingEdit extends FeatureUndoableEdit {
- MapView mapView;
- PolygonShape shape;
- List points;
- int polyIdx;
- int holeIdx;
-
- public AddRingEdit(MapView mapView, PolygonShape shape, List points,
- int polygonIdx, int holeIdx){
- this.mapView = mapView;
- this.shape = shape;
- this.points = points;
- this.polyIdx = polygonIdx;
- this.holeIdx = holeIdx;
- }
-
- @Override
- public String getPresentationName() {
- return "Add a hole";
- }
-
- @Override
- public void undo() {
- super.undo();
- shape.removeHole(polyIdx, holeIdx);
- mapView.paintLayers();
- System.out.println("Undo add a hole");
- }
-
- @Override
- public void redo(){
- super.redo();
- try {
- shape.addHole(points, polyIdx);
- mapView.paintLayers();
- System.out.println("Redo add a hole");
- } catch (Exception ex) {
- Logger.getLogger(MapView.class.getName()).log(Level.SEVERE, null, ex);
- }
- }
- }
-
- public class FillRingEdit extends FeatureUndoableEdit {
- MapView mapView;
- VectorLayer layer;
- PolygonShape shape;
- PolygonShape hole;
- int polyIdx;
- int holeIdx;
-
- public FillRingEdit(MapView mapView, VectorLayer layer, PolygonShape shape, PolygonShape hole,
- int polygonIdx, int holeIdx){
- this.mapView = mapView;
- this.layer = layer;
- this.shape = shape;
- this.hole = hole;
- this.polyIdx = polygonIdx;
- this.holeIdx = holeIdx;
- }
-
- @Override
- public String getPresentationName() {
- return "Fill a hole";
- }
-
- @Override
- public void undo() {
- super.undo();
- shape.removeHole(polyIdx, holeIdx);
- layer.editRemoveShape(hole);
- mapView.paintLayers();
- System.out.println("Undo Fill a hole");
- }
-
- @Override
- public void redo(){
- super.redo();
- try {
- shape.addHole((List)hole.getPoints(), polyIdx);
- layer.editAddShape(hole);
- mapView.paintLayers();
- System.out.println("Redo Fill a hole");
- } catch (Exception ex) {
- Logger.getLogger(MapView.class.getName()).log(Level.SEVERE, null, ex);
- }
- }
- }
-
- public class RemoveRingEdit extends FeatureUndoableEdit {
- MapView mapView;
- PolygonShape shape;
- List points;
- int polyIdx;
- int holeIdx;
-
- public RemoveRingEdit(MapView mapView, PolygonShape shape, List hole, int polygonIdx, int holeIdx){
- this.mapView = mapView;
- this.shape = shape;
- this.points = hole;
- this.polyIdx = polygonIdx;
- this.holeIdx = holeIdx;
- }
-
- @Override
- public String getPresentationName() {
- return "Remove a hole";
- }
-
- @Override
- public void undo() {
- super.undo();
- try {
- shape.addHole(points, polyIdx);
- mapView.paintLayers();
- System.out.println("Redo remove a hole");
- } catch (Exception ex) {
- Logger.getLogger(MapView.class.getName()).log(Level.SEVERE, null, ex);
- }
- }
-
- @Override
- public void redo(){
- super.redo();
- shape.removeHole(polyIdx, holeIdx);
- mapView.paintLayers();
- System.out.println("Undo remove a hole");
- }
- }
-
- public class RemoveFeaturesEdit extends FeatureUndoableEdit {
- MapView mapView;
- List shapes;
- VectorLayer layer;
- List indices;
- List records;
-
- public RemoveFeaturesEdit(MapView mapView, VectorLayer layer, List shapes){
- this.mapView = mapView;
- this.layer = layer;
- this.shapes = shapes;
- indices = new ArrayList<>();
- records = new ArrayList<>();
- int idx;
- DataRow row;
- for (Shape shape : shapes){
- idx = layer.getShapes().indexOf(shape);
- row = layer.getAttributeTable().getTable().getRows().get(idx);
- indices.add(idx);
- records.add(row);
- }
- }
-
- @Override
- public String getPresentationName() {
- return "Remove Features";
- }
-
- @Override
- public void undo() {
- super.undo();
- try {
- for (int i = 0; i < shapes.size(); i++){
- layer.editInsertShape(shapes.get(i), indices.get(i), records.get(i));
- }
- mapView.paintLayers();
- System.out.println("Undo remove features");
- } catch (Exception ex) {
- Logger.getLogger(MapView.class.getName()).log(Level.SEVERE, null, ex);
- }
- }
-
- @Override
- public void redo(){
- super.redo();
- for (Shape shape : shapes)
- layer.editRemoveShape(shape);
- mapView.paintLayers();
- System.out.println("Undo remove features");
- }
- }
-
- class MoveFeatureEdit extends FeatureUndoableEdit {
- MapView mapView;
- Shape shape;
- Point fromPoint;
- Point toPoint;
-
- public MoveFeatureEdit(MapView mapView, Shape shape, Point fromPoint, Point toPoint){
- this.mapView = mapView;
- this.shape = shape;
- this.fromPoint = new Point(fromPoint.x, fromPoint.y);
- this.toPoint = new Point(toPoint.x, toPoint.y);
- }
-
- @Override
- public String getPresentationName() {
- return "Move a Feature";
- }
-
- @Override
- public void undo() {
- super.undo();
- mapView.moveShapeOnScreen(shape, toPoint, fromPoint);
- mapView.paintLayers();
- }
-
- @Override
- public void redo(){
- super.redo();
- mapView.moveShapeOnScreen(shape, fromPoint, toPoint);
- mapView.paintLayers();
- }
- }
-
- class MoveFeaturesEdit extends FeatureUndoableEdit {
- MapView mapView;
- List shapes;
- Point fromPoint;
- Point toPoint;
-
- public MoveFeaturesEdit(MapView mapView, List shapes, Point fromPoint, Point toPoint){
- this.mapView = mapView;
- this.shapes = shapes;
- this.fromPoint = new Point(fromPoint.x, fromPoint.y);
- this.toPoint = new Point(toPoint.x, toPoint.y);
- }
-
- @Override
- public String getPresentationName() {
- return "Move a Feature";
- }
-
- @Override
- public void undo() {
- super.undo();
- for (Shape shape : shapes)
- mapView.moveShapeOnScreen(shape, toPoint, fromPoint);
- mapView.paintLayers();
- }
-
- @Override
- public void redo(){
- super.redo();
- for (Shape shape : shapes)
- mapView.moveShapeOnScreen(shape, fromPoint, toPoint);
- mapView.paintLayers();
- }
- }
-
- class MoveFeatureVerticeEdit extends FeatureUndoableEdit {
- MapView mapView;
- Shape shape;
- int verticeIdx;
- double newX;
- double newY;
- double oldX;
- double oldY;
-
- public MoveFeatureVerticeEdit(MapView mapView, Shape shape, int vIdx, double newX, double newY){
- this.mapView = mapView;
- this.shape = shape;
- this.verticeIdx = vIdx;
- this.newX = newX;
- this.newY = newY;
- this.oldX = shape.getPoints().get(vIdx).X;
- this.oldY = shape.getPoints().get(vIdx).Y;
- }
-
- @Override
- public String getPresentationName() {
- return "Move a Feature";
- }
-
- @Override
- public void undo() {
- super.undo();
- shape.moveVertice(verticeIdx, oldX, oldY);
- mapView.paintLayers();
- }
-
- @Override
- public void redo(){
- super.redo();
- shape.moveVertice(verticeIdx, newX, newY);
- mapView.paintLayers();
- }
- }
-
- class AddFeatureVerticeEdit extends AbstractUndoableEdit {
- MapView mapView;
- Shape shape;
- int verticeIdx;
- PointD vertice;
-
- public AddFeatureVerticeEdit(MapView mapView, Shape shape, int vIdx, PointD vertice){
- this.mapView = mapView;
- this.shape = shape;
- this.verticeIdx = vIdx;
- this.vertice = vertice;
- }
-
- @Override
- public String getPresentationName() {
- return "Add feature vertice";
- }
-
- @Override
- public void undo() {
- super.undo();
- shape.removeVerice(verticeIdx);
- mapView.paintLayers();
- }
-
- @Override
- public void redo(){
- super.redo();
- shape.addVertice(verticeIdx, vertice);
- mapView.paintLayers();
- }
- }
-
- class RemoveFeatureVerticeEdit extends AbstractUndoableEdit {
- MapView mapView;
- Shape shape;
- int verticeIdx;
- PointD vertice;
-
- public RemoveFeatureVerticeEdit(MapView mapView, Shape shape, int vIdx){
- this.mapView = mapView;
- this.shape = shape;
- this.verticeIdx = vIdx;
- this.vertice = shape.getPoints().get(vIdx);
- }
-
- @Override
- public String getPresentationName() {
- return "Remove feature vertice";
- }
-
- @Override
- public void undo() {
- super.undo();
- shape.addVertice(verticeIdx, vertice);
- mapView.paintLayers();
- }
-
- @Override
- public void redo(){
- super.redo();
- shape.removeVerice(verticeIdx);
- mapView.paintLayers();
- }
- }
-
- class AddGraphicEdit extends AbstractUndoableEdit {
- MapView mapView;
- Graphic graphic;
-
- public AddGraphicEdit(MapView mapView, Graphic graphic){
- this.mapView = mapView;
- this.graphic = graphic;
- }
-
- @Override
- public String getPresentationName() {
- return "Add a Graphic";
- }
-
- @Override
- public void undo() {
- super.undo();
- mapView.removeGraphic(graphic);
- mapView.paintLayers();
- }
-
- @Override
- public void redo(){
- super.redo();
- mapView.getGraphicCollection().add(graphic);
- mapView.paintLayers();
- }
- }
-
- class RemoveGraphicEdit extends AbstractUndoableEdit {
- MapView mapView;
- Graphic graphic;
-
- public RemoveGraphicEdit(MapView mapView, Graphic graphic){
- this.mapView = mapView;
- this.graphic = graphic;
- }
-
- @Override
- public String getPresentationName() {
- return "Remove a Graphic";
- }
-
- @Override
- public void undo() {
- super.undo();
- mapView.getGraphicCollection().add(graphic);
- mapView.paintLayers();
- }
-
- @Override
- public void redo(){
- super.redo();
- mapView.removeGraphic(graphic);
- mapView.paintLayers();
- }
- }
-
- class RemoveGraphicsEdit extends AbstractUndoableEdit {
- MapView mapView;
- List graphics;
-
- public RemoveGraphicsEdit(MapView mapView, List graphics){
- this.mapView = mapView;
- this.graphics = new ArrayList<>(graphics);
- }
-
- @Override
- public String getPresentationName() {
- return "Remove Graphics";
- }
-
- @Override
- public void undo() {
- super.undo();
- mapView.getGraphicCollection().addAll(graphics);
- mapView.paintLayers();
- }
-
- @Override
- public void redo(){
- super.redo();
- mapView.getGraphicCollection().removeAll(graphics);
- mapView.paintLayers();
- }
- }
-
- class MoveGraphicEdit extends AbstractUndoableEdit {
- MapView mapView;
- Graphic graphic;
- Point fromPoint;
- Point toPoint;
-
- public MoveGraphicEdit(MapView mapView, Graphic graphic, Point fromPoint, Point toPoint){
- this.mapView = mapView;
- this.graphic = graphic;
- this.fromPoint = new Point(fromPoint.x, fromPoint.y);
- this.toPoint = new Point(toPoint.x, toPoint.y);
- }
-
- @Override
- public String getPresentationName() {
- return "Move a Graphic";
- }
-
- @Override
- public void undo() {
- super.undo();
- mapView.moveShapeOnScreen(graphic.getShape(), toPoint, fromPoint);
- mapView.paintLayers();
- }
-
- @Override
- public void redo(){
- super.redo();
- mapView.moveShapeOnScreen(graphic.getShape(), fromPoint, toPoint);
- mapView.paintLayers();
- }
- }
-
- class MoveGraphicVerticeEdit extends AbstractUndoableEdit {
- MapView mapView;
- Graphic graphic;
- int verticeIdx;
- double newX;
- double newY;
- double oldX;
- double oldY;
-
- public MoveGraphicVerticeEdit(MapView mapView, Graphic graphic, int vIdx, double newX, double newY){
- this.mapView = mapView;
- this.graphic = graphic;
- this.verticeIdx = vIdx;
- this.newX = newX;
- this.newY = newY;
- this.oldX = graphic.getShape().getPoints().get(vIdx).X;
- this.oldY = graphic.getShape().getPoints().get(vIdx).Y;
- }
-
- @Override
- public String getPresentationName() {
- return "Move Grahic vertice";
- }
-
- @Override
- public void undo() {
- super.undo();
- graphic.verticeMoveUpdate(verticeIdx, oldX, oldY);
- mapView.paintLayers();
- }
-
- @Override
- public void redo(){
- super.redo();
- graphic.verticeMoveUpdate(verticeIdx, newX, newY);
- mapView.paintLayers();
- }
- }
-
- class AddGraphicVerticeEdit extends AbstractUndoableEdit {
- MapView mapView;
- Graphic graphic;
- int verticeIdx;
- PointD vertice;
-
- public AddGraphicVerticeEdit(MapView mapView, Graphic graphic, int vIdx, PointD vertice){
- this.mapView = mapView;
- this.graphic = graphic;
- this.verticeIdx = vIdx;
- this.vertice = vertice;
- }
-
- @Override
- public String getPresentationName() {
- return "Add Grahic vertice";
- }
-
- @Override
- public void undo() {
- super.undo();
- graphic.verticeRemoveUpdate(verticeIdx);
- mapView.paintLayers();
- }
-
- @Override
- public void redo(){
- super.redo();
- graphic.verticeAddUpdate(verticeIdx, vertice);
- mapView.paintLayers();
- }
- }
-
- class RemoveGraphicVerticeEdit extends AbstractUndoableEdit {
- MapView mapView;
- Graphic graphic;
- int verticeIdx;
- PointD vertice;
-
- public RemoveGraphicVerticeEdit(MapView mapView, Graphic graphic, int vIdx){
- this.mapView = mapView;
- this.graphic = graphic;
- this.verticeIdx = vIdx;
- this.vertice = graphic.getShape().getPoints().get(vIdx);
- }
-
- @Override
- public String getPresentationName() {
- return "Remove Grahic vertice";
- }
-
- @Override
- public void undo() {
- super.undo();
- graphic.verticeAddUpdate(verticeIdx, vertice);
- mapView.paintLayers();
- }
-
- @Override
- public void redo(){
- super.redo();
- graphic.verticeRemoveUpdate(verticeIdx);
- mapView.paintLayers();
- }
- }
-
- class ResizeGraphicEdit extends AbstractUndoableEdit {
- MapView mapView;
- Graphic graphic;
- Rectangle oldRect;
- Rectangle newRect;
-
- public ResizeGraphicEdit(MapView mapView, Graphic graphic, Rectangle newRect){
- this.mapView = mapView;
- this.graphic = graphic;
- this.newRect = newRect;
- this.oldRect = mapView.getGraphicRectangle(graphic);
- }
-
- @Override
- public String getPresentationName() {
- return "Resize a Graphic";
- }
-
- @Override
- public void undo() {
- super.undo();
- mapView.resizeShapeOnScreen(graphic, oldRect);
- mapView.paintLayers();
- }
-
- @Override
- public void redo(){
- super.redo();
- mapView.resizeShapeOnScreen(graphic, newRect);
- mapView.paintLayers();
- }
- }
-
- class SmoothGraphicEdit extends AbstractUndoableEdit {
- MapView mapView;
- Graphic graphic;
- List oldPoints;
- List newPoints;
-
- public SmoothGraphicEdit(MapView mapView, Graphic graphic, List points){
- this.mapView = mapView;
- this.graphic = graphic;
- this.newPoints = points;
- this.oldPoints = (List)graphic.getShape().getPoints();
- }
-
- @Override
- public String getPresentationName() {
- return "Resize a Graphic";
- }
-
- @Override
- public void undo() {
- super.undo();
- graphic.getShape().setPoints(oldPoints);
- mapView.paintLayers();
- }
-
- @Override
- public void redo(){
- super.redo();
- graphic.getShape().setPoints(newPoints);
- mapView.paintLayers();
- }
- }
-
- class SmoothFeatureEdit extends AbstractUndoableEdit {
- MapView mapView;
- Shape shape;
- List oldPoints;
- List newPoints;
-
- public SmoothFeatureEdit(MapView mapView, Shape shape, List points){
- this.mapView = mapView;
- this.shape = shape;
- this.newPoints = points;
- this.oldPoints = (List)shape.getPoints();
- }
-
- @Override
- public String getPresentationName() {
- return "Resize a Graphic";
- }
-
- @Override
- public void undo() {
- super.undo();
- shape.setPoints(oldPoints);
- mapView.paintLayers();
- }
-
- @Override
- public void redo(){
- super.redo();
- shape.setPoints(newPoints);
- mapView.paintLayers();
- }
- }
- //
-}
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.meteoinfo.map;
+
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.undo.AbstractUndoableEdit;
+
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.PointD;
+import org.meteoinfo.layer.VectorLayer;
+import org.meteoinfo.shape.Graphic;
+import org.meteoinfo.shape.PolygonShape;
+import org.meteoinfo.shape.Shape;
+import org.meteoinfo.table.DataRow;
+
+/**
+ *
+ * @author yaqiang
+ */
+public class MapViewUndoRedo {
+ //
+ public class ZoomEdit extends AbstractUndoableEdit {
+ MapView mapView;
+ Extent newExtent;
+ Extent oldExtent;
+
+ public ZoomEdit(MapView mapView, Extent oldExtent, Extent newExtent){
+ this.mapView = mapView;
+ this.newExtent = newExtent;
+ this.oldExtent = oldExtent;
+ }
+
+ @Override
+ public String getPresentationName() {
+ return "Zoom";
+ }
+
+ @Override
+ public void undo() {
+ super.undo();
+ mapView.zoomToExtent(oldExtent);
+ }
+
+ @Override
+ public void redo(){
+ super.redo();
+ mapView.zoomToExtent(newExtent);
+ }
+ }
+
+ public class AddFeatureEdit extends FeatureUndoableEdit {
+ MapView mapView;
+ Shape shape;
+ VectorLayer layer;
+
+ public AddFeatureEdit(MapView mapView, VectorLayer layer, Shape shape){
+ this.mapView = mapView;
+ this.layer = layer;
+ this.shape = shape;
+ }
+
+ @Override
+ public String getPresentationName() {
+ return "Add a Feature";
+ }
+
+ @Override
+ public void undo() {
+ super.undo();
+ layer.editRemoveShape(shape);
+ mapView.paintLayers();
+ System.out.println("Undo add a feature");
+ }
+
+ @Override
+ public void redo(){
+ super.redo();
+ try {
+ layer.editAddShape(shape);
+ mapView.paintLayers();
+ System.out.println("Redo add a feature");
+ } catch (Exception ex) {
+ Logger.getLogger(MapView.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+ }
+
+ public class AddFeaturesEdit extends FeatureUndoableEdit {
+ MapView mapView;
+ List shapes;
+ VectorLayer layer;
+
+ public AddFeaturesEdit(MapView mapView, VectorLayer layer, List shapes){
+ this.mapView = mapView;
+ this.layer = layer;
+ this.shapes = shapes;
+ }
+
+ @Override
+ public String getPresentationName() {
+ return "Add Features";
+ }
+
+ @Override
+ public void undo() {
+ super.undo();
+ for (Shape shape : shapes)
+ layer.editRemoveShape(shape);
+ mapView.paintLayers();
+ System.out.println("Undo add features");
+ }
+
+ @Override
+ public void redo(){
+ super.redo();
+ try {
+ for (Shape shape : shapes)
+ layer.editAddShape(shape);
+ mapView.paintLayers();
+ System.out.println("Redo add features");
+ } catch (Exception ex) {
+ Logger.getLogger(MapView.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+ }
+
+ public class ReplaceFeatureEdit extends FeatureUndoableEdit {
+ MapView mapView;
+ Shape s0;
+ Shape s1;
+ Shape s00;
+ VectorLayer layer;
+
+ public ReplaceFeatureEdit(MapView mapView, VectorLayer layer, Shape s0, Shape s1){
+ this.mapView = mapView;
+ this.layer = layer;
+ this.s0 = s0;
+ this.s1 = s1;
+ this.s00 = (Shape)s0.clone();
+ }
+
+ @Override
+ public String getPresentationName() {
+ return "Replace Feature";
+ }
+
+ @Override
+ public void undo() {
+ super.undo();
+ s0.cloneValue(s00);
+ mapView.paintLayers();
+ System.out.println("Undo replace feature");
+ }
+
+ @Override
+ public void redo(){
+ super.redo();
+ s0.cloneValue(s1);
+ mapView.paintLayers();
+ System.out.println("Redo replace feature");
+ }
+ }
+
+ public class SplitFeatureEdit extends FeatureUndoableEdit {
+ MapView mapView;
+ Shape shape;
+ List shapes;
+ VectorLayer layer;
+
+ public SplitFeatureEdit(MapView mapView, VectorLayer layer, Shape shape, List shapes){
+ this.mapView = mapView;
+ this.layer = layer;
+ this.shape = shape;
+ this.shapes = shapes;
+ }
+
+ @Override
+ public String getPresentationName() {
+ return "Split Feature";
+ }
+
+ @Override
+ public void undo() {
+ super.undo();
+ for (Shape s : shapes)
+ layer.editRemoveShape(s);
+ try {
+ layer.editAddShape(shape);
+ } catch (Exception ex) {
+ Logger.getLogger(MapViewUndoRedo.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ mapView.paintLayers();
+ System.out.println("Undo split feature");
+ }
+
+ @Override
+ public void redo(){
+ super.redo();
+ try {
+ for (Shape s : shapes)
+ layer.editAddShape(s);
+ layer.editRemoveShape(shape);
+ mapView.paintLayers();
+ System.out.println("Redo split feature");
+ } catch (Exception ex) {
+ Logger.getLogger(MapView.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+ }
+
+ public class UnionFeaturesEdit extends FeatureUndoableEdit {
+ MapView mapView;
+ Shape shape;
+ List shapes;
+ VectorLayer layer;
+
+ public UnionFeaturesEdit(MapView mapView, VectorLayer layer, Shape shape, List shapes){
+ this.mapView = mapView;
+ this.layer = layer;
+ this.shape = shape;
+ this.shapes = shapes;
+ }
+
+ @Override
+ public String getPresentationName() {
+ return "Union Features";
+ }
+
+ @Override
+ public void undo() {
+ super.undo();
+ try {
+ layer.editRemoveShape(shape);
+ for (Shape s : shapes)
+ layer.editAddShape(s);
+ mapView.paintLayers();
+ System.out.println("Undo split feature");
+ } catch (Exception ex){
+ Logger.getLogger(MapView.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+
+ @Override
+ public void redo(){
+ super.redo();
+ try {
+ for (Shape s : shapes)
+ layer.editRemoveShape(s);
+ layer.editAddShape(shape);
+ mapView.paintLayers();
+ System.out.println("Redo split feature");
+ } catch (Exception ex) {
+ Logger.getLogger(MapView.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+ }
+
+ public class AddRingEdit extends FeatureUndoableEdit {
+ MapView mapView;
+ PolygonShape shape;
+ List points;
+ int polyIdx;
+ int holeIdx;
+
+ public AddRingEdit(MapView mapView, PolygonShape shape, List points,
+ int polygonIdx, int holeIdx){
+ this.mapView = mapView;
+ this.shape = shape;
+ this.points = points;
+ this.polyIdx = polygonIdx;
+ this.holeIdx = holeIdx;
+ }
+
+ @Override
+ public String getPresentationName() {
+ return "Add a hole";
+ }
+
+ @Override
+ public void undo() {
+ super.undo();
+ shape.removeHole(polyIdx, holeIdx);
+ mapView.paintLayers();
+ System.out.println("Undo add a hole");
+ }
+
+ @Override
+ public void redo(){
+ super.redo();
+ try {
+ shape.addHole(points, polyIdx);
+ mapView.paintLayers();
+ System.out.println("Redo add a hole");
+ } catch (Exception ex) {
+ Logger.getLogger(MapView.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+ }
+
+ public class FillRingEdit extends FeatureUndoableEdit {
+ MapView mapView;
+ VectorLayer layer;
+ PolygonShape shape;
+ PolygonShape hole;
+ int polyIdx;
+ int holeIdx;
+
+ public FillRingEdit(MapView mapView, VectorLayer layer, PolygonShape shape, PolygonShape hole,
+ int polygonIdx, int holeIdx){
+ this.mapView = mapView;
+ this.layer = layer;
+ this.shape = shape;
+ this.hole = hole;
+ this.polyIdx = polygonIdx;
+ this.holeIdx = holeIdx;
+ }
+
+ @Override
+ public String getPresentationName() {
+ return "Fill a hole";
+ }
+
+ @Override
+ public void undo() {
+ super.undo();
+ shape.removeHole(polyIdx, holeIdx);
+ layer.editRemoveShape(hole);
+ mapView.paintLayers();
+ System.out.println("Undo Fill a hole");
+ }
+
+ @Override
+ public void redo(){
+ super.redo();
+ try {
+ shape.addHole((List)hole.getPoints(), polyIdx);
+ layer.editAddShape(hole);
+ mapView.paintLayers();
+ System.out.println("Redo Fill a hole");
+ } catch (Exception ex) {
+ Logger.getLogger(MapView.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+ }
+
+ public class RemoveRingEdit extends FeatureUndoableEdit {
+ MapView mapView;
+ PolygonShape shape;
+ List points;
+ int polyIdx;
+ int holeIdx;
+
+ public RemoveRingEdit(MapView mapView, PolygonShape shape, List hole, int polygonIdx, int holeIdx){
+ this.mapView = mapView;
+ this.shape = shape;
+ this.points = hole;
+ this.polyIdx = polygonIdx;
+ this.holeIdx = holeIdx;
+ }
+
+ @Override
+ public String getPresentationName() {
+ return "Remove a hole";
+ }
+
+ @Override
+ public void undo() {
+ super.undo();
+ try {
+ shape.addHole(points, polyIdx);
+ mapView.paintLayers();
+ System.out.println("Redo remove a hole");
+ } catch (Exception ex) {
+ Logger.getLogger(MapView.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+
+ @Override
+ public void redo(){
+ super.redo();
+ shape.removeHole(polyIdx, holeIdx);
+ mapView.paintLayers();
+ System.out.println("Undo remove a hole");
+ }
+ }
+
+ public class RemoveFeaturesEdit extends FeatureUndoableEdit {
+ MapView mapView;
+ List shapes;
+ VectorLayer layer;
+ List indices;
+ List records;
+
+ public RemoveFeaturesEdit(MapView mapView, VectorLayer layer, List shapes){
+ this.mapView = mapView;
+ this.layer = layer;
+ this.shapes = shapes;
+ indices = new ArrayList<>();
+ records = new ArrayList<>();
+ int idx;
+ DataRow row;
+ for (Shape shape : shapes){
+ idx = layer.getShapes().indexOf(shape);
+ row = layer.getAttributeTable().getTable().getRows().get(idx);
+ indices.add(idx);
+ records.add(row);
+ }
+ }
+
+ @Override
+ public String getPresentationName() {
+ return "Remove Features";
+ }
+
+ @Override
+ public void undo() {
+ super.undo();
+ try {
+ for (int i = 0; i < shapes.size(); i++){
+ layer.editInsertShape(shapes.get(i), indices.get(i), records.get(i));
+ }
+ mapView.paintLayers();
+ System.out.println("Undo remove features");
+ } catch (Exception ex) {
+ Logger.getLogger(MapView.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+
+ @Override
+ public void redo(){
+ super.redo();
+ for (Shape shape : shapes)
+ layer.editRemoveShape(shape);
+ mapView.paintLayers();
+ System.out.println("Undo remove features");
+ }
+ }
+
+ class MoveFeatureEdit extends FeatureUndoableEdit {
+ MapView mapView;
+ Shape shape;
+ Point fromPoint;
+ Point toPoint;
+
+ public MoveFeatureEdit(MapView mapView, Shape shape, Point fromPoint, Point toPoint){
+ this.mapView = mapView;
+ this.shape = shape;
+ this.fromPoint = new Point(fromPoint.x, fromPoint.y);
+ this.toPoint = new Point(toPoint.x, toPoint.y);
+ }
+
+ @Override
+ public String getPresentationName() {
+ return "Move a Feature";
+ }
+
+ @Override
+ public void undo() {
+ super.undo();
+ mapView.moveShapeOnScreen(shape, toPoint, fromPoint);
+ mapView.paintLayers();
+ }
+
+ @Override
+ public void redo(){
+ super.redo();
+ mapView.moveShapeOnScreen(shape, fromPoint, toPoint);
+ mapView.paintLayers();
+ }
+ }
+
+ class MoveFeaturesEdit extends FeatureUndoableEdit {
+ MapView mapView;
+ List shapes;
+ Point fromPoint;
+ Point toPoint;
+
+ public MoveFeaturesEdit(MapView mapView, List shapes, Point fromPoint, Point toPoint){
+ this.mapView = mapView;
+ this.shapes = shapes;
+ this.fromPoint = new Point(fromPoint.x, fromPoint.y);
+ this.toPoint = new Point(toPoint.x, toPoint.y);
+ }
+
+ @Override
+ public String getPresentationName() {
+ return "Move a Feature";
+ }
+
+ @Override
+ public void undo() {
+ super.undo();
+ for (Shape shape : shapes)
+ mapView.moveShapeOnScreen(shape, toPoint, fromPoint);
+ mapView.paintLayers();
+ }
+
+ @Override
+ public void redo(){
+ super.redo();
+ for (Shape shape : shapes)
+ mapView.moveShapeOnScreen(shape, fromPoint, toPoint);
+ mapView.paintLayers();
+ }
+ }
+
+ class MoveFeatureVerticeEdit extends FeatureUndoableEdit {
+ MapView mapView;
+ Shape shape;
+ int verticeIdx;
+ double newX;
+ double newY;
+ double oldX;
+ double oldY;
+
+ public MoveFeatureVerticeEdit(MapView mapView, Shape shape, int vIdx, double newX, double newY){
+ this.mapView = mapView;
+ this.shape = shape;
+ this.verticeIdx = vIdx;
+ this.newX = newX;
+ this.newY = newY;
+ this.oldX = shape.getPoints().get(vIdx).X;
+ this.oldY = shape.getPoints().get(vIdx).Y;
+ }
+
+ @Override
+ public String getPresentationName() {
+ return "Move a Feature";
+ }
+
+ @Override
+ public void undo() {
+ super.undo();
+ shape.moveVertice(verticeIdx, oldX, oldY);
+ mapView.paintLayers();
+ }
+
+ @Override
+ public void redo(){
+ super.redo();
+ shape.moveVertice(verticeIdx, newX, newY);
+ mapView.paintLayers();
+ }
+ }
+
+ class AddFeatureVerticeEdit extends AbstractUndoableEdit {
+ MapView mapView;
+ Shape shape;
+ int verticeIdx;
+ PointD vertice;
+
+ public AddFeatureVerticeEdit(MapView mapView, Shape shape, int vIdx, PointD vertice){
+ this.mapView = mapView;
+ this.shape = shape;
+ this.verticeIdx = vIdx;
+ this.vertice = vertice;
+ }
+
+ @Override
+ public String getPresentationName() {
+ return "Add feature vertice";
+ }
+
+ @Override
+ public void undo() {
+ super.undo();
+ shape.removeVerice(verticeIdx);
+ mapView.paintLayers();
+ }
+
+ @Override
+ public void redo(){
+ super.redo();
+ shape.addVertice(verticeIdx, vertice);
+ mapView.paintLayers();
+ }
+ }
+
+ class RemoveFeatureVerticeEdit extends AbstractUndoableEdit {
+ MapView mapView;
+ Shape shape;
+ int verticeIdx;
+ PointD vertice;
+
+ public RemoveFeatureVerticeEdit(MapView mapView, Shape shape, int vIdx){
+ this.mapView = mapView;
+ this.shape = shape;
+ this.verticeIdx = vIdx;
+ this.vertice = shape.getPoints().get(vIdx);
+ }
+
+ @Override
+ public String getPresentationName() {
+ return "Remove feature vertice";
+ }
+
+ @Override
+ public void undo() {
+ super.undo();
+ shape.addVertice(verticeIdx, vertice);
+ mapView.paintLayers();
+ }
+
+ @Override
+ public void redo(){
+ super.redo();
+ shape.removeVerice(verticeIdx);
+ mapView.paintLayers();
+ }
+ }
+
+ class AddGraphicEdit extends AbstractUndoableEdit {
+ MapView mapView;
+ Graphic graphic;
+
+ public AddGraphicEdit(MapView mapView, Graphic graphic){
+ this.mapView = mapView;
+ this.graphic = graphic;
+ }
+
+ @Override
+ public String getPresentationName() {
+ return "Add a Graphic";
+ }
+
+ @Override
+ public void undo() {
+ super.undo();
+ mapView.removeGraphic(graphic);
+ mapView.paintLayers();
+ }
+
+ @Override
+ public void redo(){
+ super.redo();
+ mapView.getGraphicCollection().add(graphic);
+ mapView.paintLayers();
+ }
+ }
+
+ class RemoveGraphicEdit extends AbstractUndoableEdit {
+ MapView mapView;
+ Graphic graphic;
+
+ public RemoveGraphicEdit(MapView mapView, Graphic graphic){
+ this.mapView = mapView;
+ this.graphic = graphic;
+ }
+
+ @Override
+ public String getPresentationName() {
+ return "Remove a Graphic";
+ }
+
+ @Override
+ public void undo() {
+ super.undo();
+ mapView.getGraphicCollection().add(graphic);
+ mapView.paintLayers();
+ }
+
+ @Override
+ public void redo(){
+ super.redo();
+ mapView.removeGraphic(graphic);
+ mapView.paintLayers();
+ }
+ }
+
+ class RemoveGraphicsEdit extends AbstractUndoableEdit {
+ MapView mapView;
+ List graphics;
+
+ public RemoveGraphicsEdit(MapView mapView, List graphics){
+ this.mapView = mapView;
+ this.graphics = new ArrayList<>(graphics);
+ }
+
+ @Override
+ public String getPresentationName() {
+ return "Remove Graphics";
+ }
+
+ @Override
+ public void undo() {
+ super.undo();
+ mapView.getGraphicCollection().addAll(graphics);
+ mapView.paintLayers();
+ }
+
+ @Override
+ public void redo(){
+ super.redo();
+ mapView.getGraphicCollection().removeAll(graphics);
+ mapView.paintLayers();
+ }
+ }
+
+ class MoveGraphicEdit extends AbstractUndoableEdit {
+ MapView mapView;
+ Graphic graphic;
+ Point fromPoint;
+ Point toPoint;
+
+ public MoveGraphicEdit(MapView mapView, Graphic graphic, Point fromPoint, Point toPoint){
+ this.mapView = mapView;
+ this.graphic = graphic;
+ this.fromPoint = new Point(fromPoint.x, fromPoint.y);
+ this.toPoint = new Point(toPoint.x, toPoint.y);
+ }
+
+ @Override
+ public String getPresentationName() {
+ return "Move a Graphic";
+ }
+
+ @Override
+ public void undo() {
+ super.undo();
+ mapView.moveShapeOnScreen(graphic.getShape(), toPoint, fromPoint);
+ mapView.paintLayers();
+ }
+
+ @Override
+ public void redo(){
+ super.redo();
+ mapView.moveShapeOnScreen(graphic.getShape(), fromPoint, toPoint);
+ mapView.paintLayers();
+ }
+ }
+
+ class MoveGraphicVerticeEdit extends AbstractUndoableEdit {
+ MapView mapView;
+ Graphic graphic;
+ int verticeIdx;
+ double newX;
+ double newY;
+ double oldX;
+ double oldY;
+
+ public MoveGraphicVerticeEdit(MapView mapView, Graphic graphic, int vIdx, double newX, double newY){
+ this.mapView = mapView;
+ this.graphic = graphic;
+ this.verticeIdx = vIdx;
+ this.newX = newX;
+ this.newY = newY;
+ this.oldX = graphic.getShape().getPoints().get(vIdx).X;
+ this.oldY = graphic.getShape().getPoints().get(vIdx).Y;
+ }
+
+ @Override
+ public String getPresentationName() {
+ return "Move Grahic vertice";
+ }
+
+ @Override
+ public void undo() {
+ super.undo();
+ graphic.verticeMoveUpdate(verticeIdx, oldX, oldY);
+ mapView.paintLayers();
+ }
+
+ @Override
+ public void redo(){
+ super.redo();
+ graphic.verticeMoveUpdate(verticeIdx, newX, newY);
+ mapView.paintLayers();
+ }
+ }
+
+ class AddGraphicVerticeEdit extends AbstractUndoableEdit {
+ MapView mapView;
+ Graphic graphic;
+ int verticeIdx;
+ PointD vertice;
+
+ public AddGraphicVerticeEdit(MapView mapView, Graphic graphic, int vIdx, PointD vertice){
+ this.mapView = mapView;
+ this.graphic = graphic;
+ this.verticeIdx = vIdx;
+ this.vertice = vertice;
+ }
+
+ @Override
+ public String getPresentationName() {
+ return "Add Grahic vertice";
+ }
+
+ @Override
+ public void undo() {
+ super.undo();
+ graphic.verticeRemoveUpdate(verticeIdx);
+ mapView.paintLayers();
+ }
+
+ @Override
+ public void redo(){
+ super.redo();
+ graphic.verticeAddUpdate(verticeIdx, vertice);
+ mapView.paintLayers();
+ }
+ }
+
+ class RemoveGraphicVerticeEdit extends AbstractUndoableEdit {
+ MapView mapView;
+ Graphic graphic;
+ int verticeIdx;
+ PointD vertice;
+
+ public RemoveGraphicVerticeEdit(MapView mapView, Graphic graphic, int vIdx){
+ this.mapView = mapView;
+ this.graphic = graphic;
+ this.verticeIdx = vIdx;
+ this.vertice = graphic.getShape().getPoints().get(vIdx);
+ }
+
+ @Override
+ public String getPresentationName() {
+ return "Remove Grahic vertice";
+ }
+
+ @Override
+ public void undo() {
+ super.undo();
+ graphic.verticeAddUpdate(verticeIdx, vertice);
+ mapView.paintLayers();
+ }
+
+ @Override
+ public void redo(){
+ super.redo();
+ graphic.verticeRemoveUpdate(verticeIdx);
+ mapView.paintLayers();
+ }
+ }
+
+ class ResizeGraphicEdit extends AbstractUndoableEdit {
+ MapView mapView;
+ Graphic graphic;
+ Rectangle oldRect;
+ Rectangle newRect;
+
+ public ResizeGraphicEdit(MapView mapView, Graphic graphic, Rectangle newRect){
+ this.mapView = mapView;
+ this.graphic = graphic;
+ this.newRect = newRect;
+ this.oldRect = mapView.getGraphicRectangle(graphic);
+ }
+
+ @Override
+ public String getPresentationName() {
+ return "Resize a Graphic";
+ }
+
+ @Override
+ public void undo() {
+ super.undo();
+ mapView.resizeShapeOnScreen(graphic, oldRect);
+ mapView.paintLayers();
+ }
+
+ @Override
+ public void redo(){
+ super.redo();
+ mapView.resizeShapeOnScreen(graphic, newRect);
+ mapView.paintLayers();
+ }
+ }
+
+ class SmoothGraphicEdit extends AbstractUndoableEdit {
+ MapView mapView;
+ Graphic graphic;
+ List oldPoints;
+ List newPoints;
+
+ public SmoothGraphicEdit(MapView mapView, Graphic graphic, List points){
+ this.mapView = mapView;
+ this.graphic = graphic;
+ this.newPoints = points;
+ this.oldPoints = (List)graphic.getShape().getPoints();
+ }
+
+ @Override
+ public String getPresentationName() {
+ return "Resize a Graphic";
+ }
+
+ @Override
+ public void undo() {
+ super.undo();
+ graphic.getShape().setPoints(oldPoints);
+ mapView.paintLayers();
+ }
+
+ @Override
+ public void redo(){
+ super.redo();
+ graphic.getShape().setPoints(newPoints);
+ mapView.paintLayers();
+ }
+ }
+
+ class SmoothFeatureEdit extends AbstractUndoableEdit {
+ MapView mapView;
+ Shape shape;
+ List oldPoints;
+ List newPoints;
+
+ public SmoothFeatureEdit(MapView mapView, Shape shape, List points){
+ this.mapView = mapView;
+ this.shape = shape;
+ this.newPoints = points;
+ this.oldPoints = (List)shape.getPoints();
+ }
+
+ @Override
+ public String getPresentationName() {
+ return "Resize a Graphic";
+ }
+
+ @Override
+ public void undo() {
+ super.undo();
+ shape.setPoints(oldPoints);
+ mapView.paintLayers();
+ }
+
+ @Override
+ public void redo(){
+ super.redo();
+ shape.setPoints(newPoints);
+ mapView.paintLayers();
+ }
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/map/ProjectionSet.java b/MeteoInfoLib/src/main/java/org/meteoinfo/map/ProjectionSet.java
index 785d5d5f..b5ab4c73 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/map/ProjectionSet.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/map/ProjectionSet.java
@@ -1,1248 +1,1248 @@
-/* Copyright 2012 Yaqiang Wang,
- * yaqiang.wang@gmail.com
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.map;
-
-import org.meteoinfo.global.event.IProjectionChangedListener;
-import org.meteoinfo.global.event.ProjectionChangedEvent;
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.global.MIMath;
-import org.meteoinfo.global.PointD;
-import org.meteoinfo.layer.RasterLayer;
-import org.meteoinfo.layer.VectorLayer;
-import org.meteoinfo.projection.KnownCoordinateSystems;
-import org.meteoinfo.projection.info.ProjectionInfo;
-import org.meteoinfo.projection.Reproject;
-import org.meteoinfo.shape.CircleShape;
-import org.meteoinfo.shape.CurveLineShape;
-import org.meteoinfo.shape.CurvePolygonShape;
-import org.meteoinfo.shape.EllipseShape;
-import org.meteoinfo.shape.Graphic;
-import org.meteoinfo.shape.GraphicCollection;
-import org.meteoinfo.shape.PointShape;
-import org.meteoinfo.shape.Polygon;
-import org.meteoinfo.shape.PolygonShape;
-import org.meteoinfo.shape.Polyline;
-import org.meteoinfo.shape.PolylineShape;
-import org.meteoinfo.shape.Shape;
-import org.meteoinfo.shape.StationModelShape;
-import org.meteoinfo.shape.WindArrow;
-import org.meteoinfo.shape.WindBarb;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import javax.swing.event.EventListenerList;
-import org.meteoinfo.projection.ProjectionUtil;
-import org.locationtech.proj4j.CRSFactory;
-
-/**
- *
- * @author Yaqiang Wang
- */
-public class ProjectionSet {
- //
-
- private final EventListenerList _listeners = new EventListenerList();
- CRSFactory _crsFactory = new CRSFactory();
- private ProjectionInfo _projInfo;
- //private String _projStr;
- //private double _refLon;
- //private double _refCutLon;
- //
- //
-
- /**
- * Constructor
- */
- public ProjectionSet() {
- _projInfo = KnownCoordinateSystems.geographic.world.WGS1984;
- //_projStr = _projInfo.getParameterString();
- //_refLon = 0;
- }
- //
-
- //
- public void addProjectionChangedListener(IProjectionChangedListener listener) {
- this._listeners.add(IProjectionChangedListener.class, listener);
- }
-
- public void removeViewExtentChangedListener(IProjectionChangedListener listener) {
- this._listeners.remove(IProjectionChangedListener.class, listener);
- }
-
- public void fireProjectionChangedEvent() {
- fireProjectionChangedEvent(new ProjectionChangedEvent(this));
- }
-
- private void fireProjectionChangedEvent(ProjectionChangedEvent event) {
- Object[] listeners = _listeners.getListenerList();
- for (int i = 0; i < listeners.length; i = i + 2) {
- if (listeners[i] == IProjectionChangedListener.class) {
- ((IProjectionChangedListener) listeners[i + 1]).projectionChangedEvent(event);
- }
- }
- }
- //
- //
-
- /**
- * Get if is Lon/Lat projection
- *
- * @return Boolean
- */
- public boolean isLonLatMap() {
- return "longlat".equals(_projInfo.getCoordinateReferenceSystem().getProjection().toString().toLowerCase());
- }
-
- /**
- * Get projection info
- *
- * @return Projection Info
- */
- public ProjectionInfo getProjInfo() {
- return _projInfo;
- }
-
- /**
- * Set projection info
- *
- * @param projInfo The Projection info
- */
- public void setProjInfo(ProjectionInfo projInfo) {
- _projInfo = projInfo;
- }
-
- /**
- * Get Porj4 string
- *
- * @return Proj4 string
- */
- public String getProjStr() {
- return _projInfo.toProj4String();
- }
-
- /**
- * Set proj4 string
- *
- * @param projStr Porj4 string
- */
- public void setProjStr(String projStr) {
- _projInfo = ProjectionInfo.factory(projStr);
- }
-
-// /**
-// * Get reference longitude
-// *
-// * @return Reference longitue
-// */
-// public double getRefLon() {
-// return _refLon;
-// }
-//
-// /**
-// * Set reference longitude
-// *
-// * @param lon Reference longitude
-// */
-// public void setRefLon(double lon) {
-// _refLon = lon;
-// }
-
-// /**
-// * Get reference cut longitude
-// *
-// * @return Reference cut longitude
-// */
-// public double getRefCutLon() {
-// return _refCutLon;
-// }
-//
-// /**
-// * Set reference cut longitude
-// *
-// * @param lon
-// */
-// public void setRefCutLon(double lon) {
-// _refCutLon = lon;
-// }
- //
- //
-
- /**
- * Get projected extent from lon/lat
- *
- * @param sExtent Lon/lat extent
- * @return Projected extent
- */
- public Extent getProjectedExtentFromLonLat(Extent sExtent) {
- Extent aExtent = new Extent();
- ProjectionInfo fromProj = KnownCoordinateSystems.geographic.world.WGS1984;
- ProjectionInfo toProj = _projInfo;
-
- //Get the border of longitude and latitude
- double[][] points = new double[4][];
- points[0] = new double[]{sExtent.minX, sExtent.minY};
- points[1] = new double[]{sExtent.minX, sExtent.maxY};
- points[2] = new double[]{sExtent.maxX, sExtent.maxY};
- points[3] = new double[]{sExtent.maxX, sExtent.minY};
- Reproject.reprojectPoints(points, fromProj, toProj, 0, points.length);
-
- //Get lon lat extent
- aExtent.minX = Math.min(points[0][0], points[1][0]);
- aExtent.minY = Math.min(points[0][1], points[3][1]);
- aExtent.maxX = Math.max(points[2][0], points[3][0]);
- aExtent.maxY = Math.max(points[1][1], points[2][1]);
-
- return aExtent;
- }
-
- /**
- * Project layers
- *
- * @param aMapView The Map view
- * @param toProj To projection info
- */
- public void projectLayers(MapView aMapView, ProjectionInfo toProj) {
- projectLayers(aMapView, toProj, true);
- }
-
- /**
- * Project layers
- *
- * @param aMapView The map view
- * @param toProj To projection
- * @param isUpdateView If repaint mapview
- */
- public void projectLayers(MapView aMapView, ProjectionInfo toProj, boolean isUpdateView) {
- if (aMapView.getProjection().getProjInfo().toProj4String().equals(toProj.toProj4String())) {
- return;
- }
-
- aMapView.setLockViewUpdate(true);
-
- ProjectionInfo fromProj = aMapView.getProjection().getProjInfo();
-
- aMapView.getProjection().setProjInfo(toProj);
- double refLon = toProj.getRefCutLon();
- //aMapView.getProjection().setRefCutLon(refLon);
-
- for (int i = 0; i < aMapView.getLayers().size(); i++) {
- switch (aMapView.getLayers().get(i).getLayerType()) {
- case VectorLayer:
- VectorLayer oLayer = (VectorLayer) aMapView.getLayers().get(i);
- //projectLayer(oLayer, toProj);
- ProjectionUtil.projectLayer(oLayer, toProj);
- break;
- case RasterLayer:
- RasterLayer oRLayer = (RasterLayer) aMapView.getLayers().get(i);
- ProjectionUtil.projectLayer(oRLayer, toProj);
- break;
- }
- }
-
- //Project graphics
- if (aMapView.getGraphicCollection().size() > 0) {
- GraphicCollection newGCollection = projectGraphics(aMapView.getGraphicCollection(), fromProj, toProj);
- aMapView.setGraphicCollection(newGCollection);
- }
-
- aMapView.setExtent(aMapView.getLayersWholeExtent());
- Extent aExten = aMapView.getExtent();
- aMapView.setLonLatLayer(aMapView.generateLonLatLayer());
- ProjectionUtil.projectLayer(aMapView.getLonLatLayer(), toProj);
- //aMapView.setLonLatProjLayer(aMapView.getLonLatLayer());
- for (int i = 0; i < aMapView.getLonLatLayer().getShapeNum(); i++) {
- PolylineShape aPLS = (PolylineShape) aMapView.getLonLatLayer().getShapes().get(i);
- if (aPLS.getPolylines().size() == 2) {
- PointD aP = aPLS.getPolylines().get(0).getPointList().get(aPLS.getPolylines().get(0).getPointList().size() - 1);
- PointD bP = aPLS.getPolylines().get(1).getPointList().get(aPLS.getPolylines().get(1).getPointList().size() - 1);
- boolean isJoin = false;
- if (refLon == 0) {
- if (Math.abs(aP.X) < 0.1 && Math.abs(bP.X) < 0.1 && MIMath.doubleEquals(aP.Y, bP.Y)) {
- isJoin = true;
- }
- } else if (MIMath.doubleEquals(aP.X, bP.X) && MIMath.doubleEquals(aP.Y, bP.Y)) {
- isJoin = true;
- }
-
- if (isJoin) {
- List polyLines = new ArrayList<>();
- Polyline aPL = new Polyline();
- List pList = (List) new ArrayList<>(aPLS.getPolylines().get(1).getPointList());
- List bPList = (List) new ArrayList<>(aPLS.getPolylines().get(0).getPointList());
- Collections.reverse(bPList);
- pList.addAll(bPList);
- aPL.setPointList(pList);
- polyLines.add(aPL);
- aPLS.setPolylines(polyLines);
- //aMapView.getLonLatProjLayer().getShapes().get(i) = aPLS;
- }
- }
- }
-
- if (isUpdateView) {
- aMapView.setLockViewUpdate(false);
- }
- aMapView.zoomToExtent(aExten);
-
- this.fireProjectionChangedEvent();
- }
-
-// /**
-// * Project raster layer
-// *
-// * @param oLayer The layer
-// * @param toProj To projection
-// */
-// public void projectLayer(RasterLayer oLayer, ProjectionInfo toProj) {
-// try {
-// // if (toProj.getProjectionName() == ProjectionNames.Robinson) {
-//// return;
-//// }
-//
-// if (oLayer.getProjInfo().toProj4String().equals(toProj.toProj4String())) {
-// if (oLayer.isProjected()) {
-// oLayer.getOriginData();
-// oLayer.updateGridData();
-// if (oLayer.getLegendScheme().getBreakNum() < 50) {
-// oLayer.updateImage();
-// } else {
-// oLayer.setPaletteByLegend();
-// }
-// }
-// return;
-// }
-//
-// if (!oLayer.isProjected()) {
-// oLayer.updateOriginData();
-// } else {
-// oLayer.getOriginData();
-// }
-//
-// oLayer.setGridData(oLayer.getGridData().project(oLayer.getProjInfo(), toProj));
-// oLayer.updateImage(oLayer.getLegendScheme());
-//// if (oLayer.getLegendScheme().getBreakNum() < 50) {
-//// oLayer.updateImage(oLayer.getLegendScheme());
-//// } else {
-//// oLayer.setPaletteByLegend();
-//// }
-// } catch (InvalidRangeException ex) {
-// Logger.getLogger(ProjectionSet.class.getName()).log(Level.SEVERE, null, ex);
-// }
-// }
-//
-// /**
-// * Project vector layer
-// *
-// * @param oLayer The layer
-// * @param toProj To projection info
-// */
-// public void projectLayer(VectorLayer oLayer, ProjectionInfo toProj) {
-// projectLayer(oLayer, toProj, true);
-// }
-//
-// /**
-// * Project vector layer
-// *
-// * @param oLayer The layer
-// * @param toProj To projection info
-// * @param projectLabels If project labels
-// */
-// public void projectLayer(VectorLayer oLayer, ProjectionInfo toProj, boolean projectLabels) {
-// ProjectionInfo fromProj = oLayer.getProjInfo();
-// if (fromProj.equals(toProj)) {
-// if (oLayer.isProjected()) {
-// oLayer.getOriginData();
-// }
-//
-// return;
-// }
-//
-// if (oLayer.isProjected()) {
-// oLayer.getOriginData();
-// } else {
-// oLayer.updateOriginData();
-// }
-//
-// double refLon = toProj.getRefCutLon();
-// if (oLayer.getExtent().maxX > 180 && oLayer.getExtent().minX > refLon) {
-// refLon += 360;
-// }
-//
-// //coordinate transform process
-// int i, s;
-// ArrayList newPoints = new ArrayList();
-// Extent lExtent = new Extent();
-//
-// DataTable aTable = new DataTable();
-// for (DataColumn aDC : oLayer.getAttributeTable().getTable().getColumns()) {
-// Field bDC = new Field(aDC.getColumnName(), aDC.getDataType());
-// aTable.getColumns().add(bDC);
-// }
-//
-// //aLayer.AttributeTable.Table.Rows.Clear();
-// switch (oLayer.getShapeType()) {
-// case Point:
-// case PointM:
-// case PointZ:
-// case WeatherSymbol:
-// case WindArraw:
-// case WindBarb:
-// case StationModel:
-// List shapePoints = new ArrayList<>();
-// newPoints.clear();
-// for (s = 0; s < oLayer.getShapeNum(); s++) {
-// PointShape aPS = (PointShape) oLayer.getShapes().get(s);
-// if (fromProj.getProjectionName() == ProjectionNames.LongLat) {
-// switch (toProj.getProjectionName()) {
-// case Lambert_Conformal_Conic:
-// if (aPS.getPoint().Y < -80) {
-// continue;
-// }
-// break;
-// case North_Polar_Stereographic_Azimuthal:
-// if (aPS.getPoint().Y < 0) {
-// continue;
-// }
-// break;
-// case South_Polar_Stereographic_Azimuthal:
-// if (aPS.getPoint().Y > 0) {
-// continue;
-// }
-// break;
-// case Mercator:
-// if (aPS.getPoint().Y > 85.0511 || aPS.getPoint().Y < -85.0511) {
-// continue;
-// }
-// break;
-// }
-// }
-// aPS = projectPointShape(aPS, fromProj, toProj);
-// if (aPS != null) {
-// shapePoints.add(aPS);
-// newPoints.add(aPS.getPoint());
-//
-// DataRow aDR = oLayer.getAttributeTable().getTable().getRows().get(s);
-// try {
-// aTable.addRow(aDR);
-// } catch (Exception ex) {
-// Logger.getLogger(ProjectionSet.class.getName()).log(Level.SEVERE, null, ex);
-// }
-// }
-// }
-// oLayer.setShapes(new ArrayList<>(shapePoints));
-// oLayer.setExtent(MIMath.getPointsExtent(newPoints));
-//
-// break;
-// case Polyline:
-// case PolylineM:
-// case PolylineZ:
-// List newPolylines = new ArrayList<>();
-// for (s = 0; s < oLayer.getShapeNum(); s++) {
-// PolylineShape aPLS = (PolylineShape) oLayer.getShapes().get(s);
-// List plsList = new ArrayList<>();
-// if (fromProj.getProjectionName() == ProjectionNames.LongLat) {
-// switch (toProj.getProjectionName()) {
-// case Lambert_Conformal_Conic:
-// if (aPLS.getExtent().minY < -80) {
-// aPLS = GeoComputation.clipPolylineShape_Lat(aPLS, -80, true);
-// }
-// break;
-// case North_Polar_Stereographic_Azimuthal:
-// if (aPLS.getExtent().minY < 0) {
-// //continue;
-// aPLS = GeoComputation.clipPolylineShape_Lat(aPLS, 0, true);
-// }
-// break;
-// case South_Polar_Stereographic_Azimuthal:
-// if (aPLS.getExtent().maxY > 0) {
-// //continue;
-// aPLS = GeoComputation.clipPolylineShape_Lat(aPLS, 0, false);
-// }
-// break;
-// case Mercator:
-// if (aPLS.getExtent().maxY > 85.0511) {
-// aPLS = GeoComputation.clipPolylineShape_Lat(aPLS, 85.0511, false);
-// }
-// if (aPLS.getExtent().minY < -85.0511) {
-// aPLS = GeoComputation.clipPolylineShape_Lat(aPLS, -85.0511, true);
-// }
-// break;
-// }
-// if (aPLS == null) {
-// continue;
-// }
-//
-//// aPLS = GeoComputation.clipPolylineShape_Lon(aPLS, refLon);
-//// if (aPLS == null) {
-//// continue;
-//// }
-// if (aPLS.getExtent().minX < refLon && aPLS.getExtent().maxX > refLon) {
-// plsList.add(GeoComputation.clipPolylineShape_Lon(aPLS, refLon));
-// } else {
-// plsList.add(aPLS);
-// }
-// } else {
-// plsList.add(aPLS);
-// }
-// for (i = 0; i < plsList.size(); i++) {
-// aPLS = plsList.get(i);
-// aPLS = projectPolylineShape(aPLS, fromProj, toProj);
-// if (aPLS != null) {
-// newPolylines.add(aPLS);
-//
-// DataRow aDR = oLayer.getAttributeTable().getTable().getRows().get(s);
-// try {
-// aTable.addRow(aDR);
-// } catch (Exception ex) {
-// Logger.getLogger(ProjectionSet.class.getName()).log(Level.SEVERE, null, ex);
-// }
-//
-// if (s == 0 && i == 0) {
-// lExtent = (Extent) aPLS.getExtent().clone();
-// } else {
-// lExtent = MIMath.getLagerExtent(lExtent, aPLS.getExtent());
-// }
-// }
-// }
-// }
-// oLayer.setShapes(new ArrayList<>(newPolylines));
-// newPolylines.clear();
-// oLayer.setExtent(lExtent);
-// break;
-// case Polygon:
-// case PolygonM:
-// List newPolygons = new ArrayList<>();
-// for (s = 0; s < oLayer.getShapeNum(); s++) {
-// DataRow aDR = oLayer.getAttributeTable().getTable().getRows().get(s);
-// PolygonShape aPGS = (PolygonShape) oLayer.getShapes().get(s);
-// List pgsList = new ArrayList<>();
-// if (fromProj.getProjectionName() == ProjectionNames.LongLat) {
-// switch (toProj.getProjectionName()) {
-// case Lambert_Conformal_Conic:
-// if (aPGS.getExtent().minY < -80) {
-// aPGS = GeoComputation.clipPolygonShape_Lat(aPGS, -80, true);
-// }
-// break;
-// case North_Polar_Stereographic_Azimuthal:
-// if (aPGS.getExtent().minY < 0) {
-// //continue;
-// aPGS = GeoComputation.clipPolygonShape_Lat(aPGS, 0, true);
-// }
-// break;
-// case South_Polar_Stereographic_Azimuthal:
-// if (aPGS.getExtent().maxY > 0) {
-// //continue;
-// aPGS = GeoComputation.clipPolygonShape_Lat(aPGS, 0, false);
-// }
-// break;
-// case Mercator:
-// if (aPGS.getExtent().maxY > 85.0511) {
-// aPGS = GeoComputation.clipPolygonShape_Lat(aPGS, 85.0511, false);
-// }
-// if (aPGS.getExtent().minY < -85.0511) {
-// aPGS = GeoComputation.clipPolygonShape_Lat(aPGS, -85.0511, true);
-// }
-// break;
-// }
-// if (aPGS == null) {
-// continue;
-// }
-//
-// if (aPGS.getExtent().minX <= refLon && aPGS.getExtent().maxX >= refLon) {
-// pgsList.add(GeoComputation.clipPolygonShape_Lon(aPGS, refLon));
-// } else {
-// pgsList.add(aPGS);
-// }
-// } else {
-// pgsList.add(aPGS);
-// }
-// for (i = 0; i < pgsList.size(); i++) {
-// aPGS = pgsList.get(i);
-// aPGS = projectPolygonShape(aPGS, fromProj, toProj);
-// if (aPGS != null) {
-// newPolygons.add(aPGS);
-//
-// aTable.getRows().add(aDR);
-//
-// if (s == 0) {
-// lExtent = (Extent) aPGS.getExtent().clone();
-// } else {
-// lExtent = MIMath.getLagerExtent(lExtent, aPGS.getExtent());
-// }
-// }
-// }
-// }
-// oLayer.setShapes(new ArrayList<>(newPolygons));
-// newPolygons.clear();
-// oLayer.setExtent(lExtent);
-// break;
-// }
-// oLayer.getAttributeTable().setTable(aTable);
-//
-// if (oLayer.getLabelPoints().size() > 0) {
-// if (projectLabels) {
-// oLayer.setLabelPoints(projectGraphics(oLayer.getLabelPoints(), fromProj, toProj));
-// } else {
-// oLayer.setLabelPoints(new ArrayList<>(oLayer.getLabelPoints()));
-// }
-// }
-// }
-//
-// /**
-// * Project layer angle
-// *
-// * @param oLayer The layer
-// * @param fromProj From projection
-// * @param toProj To projection
-// * @return VectorLayer
-// */
-// public VectorLayer projectLayerAngle(VectorLayer oLayer, ProjectionInfo fromProj, ProjectionInfo toProj) {
-// //coordinate transform process
-// ArrayList newPoints = new ArrayList();
-//
-// VectorLayer aLayer = (VectorLayer) oLayer.clone();
-//
-// //aLayer.AttributeTable.Table = oLayer.AttributeTable.Table.Clone();
-// DataTable aTable = new DataTable();
-// for (DataColumn aDC : oLayer.getAttributeTable().getTable().getColumns()) {
-// Field bDC = new Field(aDC.getColumnName(), aDC.getDataType());
-// aTable.getColumns().add(bDC);
-// }
-//
-// int s;
-// List vectors = new ArrayList<>();
-// newPoints.clear();
-// for (s = 0; s < aLayer.getShapeNum(); s++) {
-// PointShape aPS = (PointShape) aLayer.getShapes().get(s);
-// if (fromProj.getProjectionName() == ProjectionNames.LongLat) {
-// switch (toProj.getProjectionName()) {
-// case Lambert_Conformal_Conic:
-// case North_Polar_Stereographic_Azimuthal:
-// if (aPS.getPoint().X < -89) {
-// continue;
-// }
-// break;
-// case South_Polar_Stereographic_Azimuthal:
-// if (aPS.getPoint().Y > 89) {
-// continue;
-// }
-// break;
-// }
-// }
-// double[] fromP = new double[]{aPS.getPoint().X, aPS.getPoint().Y};
-// double[] toP;
-// double[][] points = new double[1][];
-// points[0] = (double[]) fromP.clone();
-// try {
-// //Reproject point back to fromProj
-// Reproject.reprojectPoints(points, toProj, fromProj, 0, points.length);
-// toP = points[0];
-// switch (aLayer.getLayerDrawType()) {
-// case Vector:
-// ((WindArrow) aPS).angle = projectAngle(((WindArrow) aPS).angle, toP, fromP, fromProj, toProj);
-// break;
-// case Barb:
-// ((WindBarb) aPS).angle = projectAngle(((WindBarb) aPS).angle, toP, fromP, fromProj, toProj);
-// break;
-// case StationModel:
-// ((StationModelShape) aPS).windBarb.angle = projectAngle(((StationModelShape) aPS).windBarb.angle, toP, fromP, fromProj, toProj);
-// break;
-// }
-// newPoints.add(aPS.getPoint());
-// vectors.add(aPS);
-//
-// DataRow aDR = oLayer.getAttributeTable().getTable().getRows().get(s);
-// aTable.getRows().add(aDR);
-// } catch (Exception e) {
-// }
-// }
-// aLayer.setShapes(new ArrayList<>(vectors));
-// aLayer.setExtent(MIMath.getPointsExtent(newPoints));
-// aLayer.getAttributeTable().setTable(aTable);
-//
-// //if (aLayer.LabelSetV.DrawLabels)
-// //{
-// // aLayer.AddLabels();
-// //}
-// return aLayer;
-// }
-
-// /**
-// * Project wind layer
-// *
-// * @param oLayer Origin layer
-// * @param toProj To projection
-// * @param IfReprojectAngle If reproject wind angle
-// */
-// public void projectWindLayer(VectorLayer oLayer, ProjectionInfo toProj, boolean IfReprojectAngle) {
-// ProjectionInfo fromProj = oLayer.getProjInfo();
-// if (fromProj.toProj4String().equals(toProj.toProj4String())) {
-// if (oLayer.isProjected()) {
-// oLayer.getOriginData();
-// }
-//
-// return;
-// }
-//
-// if (oLayer.isProjected()) {
-// oLayer.getOriginData();
-// } else {
-// oLayer.updateOriginData();
-// }
-//
-// //Set reference longitude
-// double refLon = toProj.getRefCutLon();
-// if (oLayer.getExtent().maxX > 180 && oLayer.getExtent().minX > refLon) {
-// refLon += 360;
-// }
-//
-// //coordinate transform process
-// int s;
-// //PointD wPoint = new PointD();
-// PointD aPoint;
-// List newPoints = new ArrayList<>();
-// //Extent lExtent = new Extent();
-//
-// DataTable aTable = new DataTable();
-// for (DataColumn aDC : oLayer.getAttributeTable().getTable().getColumns()) {
-// Field bDC = new Field(aDC.getColumnName(), aDC.getDataType());
-// aTable.getColumns().add(bDC);
-// }
-//
-// List shapes = new ArrayList<>();
-// newPoints.clear();
-// for (s = 0; s < oLayer.getShapeNum(); s++) {
-// PointShape aPS = (PointShape) oLayer.getShapes().get(s);
-// if (fromProj.getProjectionName() == ProjectionNames.LongLat) {
-// switch (toProj.getProjectionName()) {
-// case Lambert_Conformal_Conic:
-// case North_Polar_Stereographic_Azimuthal:
-// if (aPS.getPoint().Y < -89) {
-// continue;
-// }
-// break;
-// case South_Polar_Stereographic_Azimuthal:
-// if (aPS.getPoint().Y > 89) {
-// continue;
-// }
-// break;
-// }
-// }
-// double[] fromP = new double[]{aPS.getPoint().X, aPS.getPoint().Y};
-// double[] toP;
-// double[][] points = new double[1][];
-// points[0] = (double[]) fromP.clone();
-// try {
-// Reproject.reprojectPoints(points, fromProj, toProj, 0, points.length);
-// toP = points[0];
-// aPoint = new PointD();
-// aPoint.X = (float) toP[0];
-// aPoint.Y = (float) toP[1];
-// aPS.setPoint(aPoint);
-// if (IfReprojectAngle) {
-// switch (oLayer.getLayerDrawType()) {
-// case Vector:
-// ((WindArrow) aPS).angle = projectAngle(((WindArrow) aPS).angle, fromP, toP, fromProj, toProj);
-// break;
-// case Barb:
-// ((WindBarb) aPS).angle = projectAngle(((WindBarb) aPS).angle, fromP, toP, fromProj, toProj);
-// break;
-// case StationModel:
-// ((StationModelShape) aPS).windBarb.angle = projectAngle(((StationModelShape) aPS).windBarb.angle, fromP, toP, fromProj, toProj);
-// break;
-// }
-// }
-// newPoints.add(aPoint);
-// shapes.add(aPS);
-//
-// DataRow aDR = oLayer.getAttributeTable().getTable().getRows().get(s);
-// aTable.getRows().add(aDR);
-// } catch (Exception e) {
-// }
-// }
-// oLayer.setShapes(new ArrayList<>(shapes));
-// oLayer.setExtent(MIMath.getPointsExtent(newPoints));
-// oLayer.getAttributeTable().setTable(aTable);
-//
-// if (oLayer.getLabelPoints().size() > 0) {
-// oLayer.setLabelPoints(projectGraphics(oLayer.getLabelPoints(), fromProj, toProj));
-// }
-// }
-
- private PointShape projectPointShape(PointShape aPS, ProjectionInfo fromProj, ProjectionInfo toProj) {
- PointShape newPS = (PointShape) aPS.clone();
- double[][] points = new double[1][];
- points[0] = new double[]{newPS.getPoint().X, newPS.getPoint().Y};
- double[] fromP = new double[]{newPS.getPoint().X, newPS.getPoint().Y};
- try {
- Reproject.reprojectPoints(points, fromProj, toProj, 0, points.length);
- if (!Double.isNaN(points[0][0]) && !Double.isNaN(points[0][1])) {
- double[] toP = points[0];
- newPS.setPoint(new PointD(points[0][0], points[0][1]));
- switch (aPS.getShapeType()) {
- case WindBarb:
- ((WindBarb) newPS).angle = projectAngle(((WindBarb) newPS).angle, fromP, toP, fromProj, toProj);
- break;
- case WindArraw:
- ((WindArrow) newPS).angle = projectAngle(((WindArrow) newPS).angle, fromP, toP, fromProj, toProj);
- break;
- case StationModel:
- ((StationModelShape) newPS).windBarb.angle = projectAngle(((StationModelShape) newPS).windBarb.angle, fromP, toP, fromProj, toProj);
- break;
- }
- return newPS;
- } else {
- return null;
- }
- } catch (Exception e) {
- return null;
- }
- }
-
- private PolylineShape projectPolylineShape(PolylineShape aPLS, ProjectionInfo fromProj, ProjectionInfo toProj) {
- List polyLines = new ArrayList<>();
- for (int i = 0; i < aPLS.getPolylines().size(); i++) {
- List newPoints = new ArrayList<>();
- Polyline aPL = aPLS.getPolylines().get(i);
- Polyline bPL;
- double x;
- for (int j = 0; j < aPL.getPointList().size(); j++) {
- double[][] points = new double[1][];
- PointD wPoint = aPL.getPointList().get(j);
- x = wPoint.X;
- if (fromProj.isLonLat()) {
- if (x > 180) {
- x -= 360;
- } else if (x < -180) {
- x += 360;
- }
- }
- points[0] = new double[]{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 (newPoints.size() > 1) {
- bPL = new Polyline();
- bPL.setPointList(newPoints);
- polyLines.add(bPL);
- }
- }
-
- if (polyLines.size() > 0) {
- aPLS.setPolylines(polyLines);
-
- return aPLS;
- } else {
- return null;
- }
- }
-
- private CurveLineShape projectCurvelineShape(CurveLineShape aPLS, ProjectionInfo fromProj, ProjectionInfo toProj) {
- List polyLines = new ArrayList<>();
- for (int i = 0; i < aPLS.getPolylines().size(); i++) {
- List newPoints = new ArrayList<>();
- Polyline aPL = aPLS.getPolylines().get(i);
- Polyline bPL;
- for (int j = 0; j < aPL.getPointList().size(); j++) {
- double[][] points = new double[1][];
- PointD wPoint = aPL.getPointList().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 (newPoints.size() > 1) {
- bPL = new Polyline();
- bPL.setPointList(newPoints);
- polyLines.add(bPL);
- }
- }
-
- if (polyLines.size() > 0) {
- aPLS.setPolylines(polyLines);
-
- return aPLS;
- } else {
- return null;
- }
- }
-
- /**
- * Project polygon shape
- *
- * @param aPGS A polygon shape
- * @param fromProj From projection
- * @param toProj To porjection
- * @return Projected polygon shape
- */
- public 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);
- }
- } catch (Exception e) {
- break;
- }
- }
-
- if (r == 0) {
- if (newPoints.size() > 2) {
- bPG = new Polygon();
- bPG.setOutLine(newPoints);
- } else {
- break;
- }
- } else if (newPoints.size() > 2) {
- if (bPG != null)
- bPG.addHole(newPoints);
- }
- }
-
- if (bPG != null) {
- polygons.add(bPG);
- }
- }
-
- if (polygons.size() > 0) {
- aPGS.setPolygons(polygons);
-
- return aPGS;
- } else {
- return null;
- }
- }
-
- private CurvePolygonShape projectCurvePolygonShape(CurvePolygonShape 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);
- }
- } catch (Exception e) {
- break;
- }
- }
-
- if (r == 0) {
- if (newPoints.size() > 2) {
- bPG = new Polygon();
- bPG.setOutLine(newPoints);
- } else {
- break;
- }
- } else if (newPoints.size() > 2) {
- if (bPG != null)
- bPG.addHole(newPoints);
- }
- }
-
- if (bPG != null) {
- polygons.add(bPG);
- }
- }
-
- if (polygons.size() > 0) {
- aPGS.setPolygons(polygons);
-
- return aPGS;
- } else {
- return null;
- }
- }
-
- private CircleShape projectCircleShape(CircleShape aCS, ProjectionInfo fromProj, ProjectionInfo toProj) {
- double radius = Math.abs(aCS.getPoints().get(1).X - aCS.getPoints().get(0).X);
- double[][] points = new double[1][];
- PointD centerPoint = new PointD(aCS.getPoints().get(0).X + radius, aCS.getPoints().get(0).Y);
- points[0] = new double[]{centerPoint.X, centerPoint.Y};
- try {
- Reproject.reprojectPoints(points, fromProj, toProj, 0, points.length);
- if (!Double.isNaN(points[0][0]) && !Double.isNaN(points[0][1])) {
- centerPoint.X = points[0][0];
- centerPoint.Y = points[0][1];
- } else {
- return null;
- }
- } catch (Exception e) {
- return null;
- }
-
- points = new double[1][];
- PointD leftPoint = aCS.getPoints().get(0);
- points[0] = new double[]{leftPoint.X, leftPoint.Y};
- try {
- Reproject.reprojectPoints(points, fromProj, toProj, 0, points.length);
- if (!Double.isNaN(points[0][0]) && !Double.isNaN(points[0][1])) {
- leftPoint.X = points[0][0];
- leftPoint.Y = points[0][1];
- } else {
- return null;
- }
- } catch (Exception e) {
- return null;
- }
-
- radius = Math.abs(centerPoint.X - leftPoint.X);
- List newPoints = new ArrayList<>();
- newPoints.add(new PointD(centerPoint.X - radius, centerPoint.Y));
- newPoints.add(new PointD(centerPoint.X, centerPoint.Y - radius));
- newPoints.add(new PointD(centerPoint.X + radius, centerPoint.Y));
- newPoints.add(new PointD(centerPoint.X, centerPoint.Y + radius));
- CircleShape newCS = new CircleShape();
- newCS.setPoints(newPoints);
-
- return newCS;
- }
-
- private EllipseShape projectEllipseShape(EllipseShape aES, ProjectionInfo fromProj, ProjectionInfo toProj) {
- double xRadius = Math.abs(aES.getPoints().get(2).X - aES.getPoints().get(0).X) / 2;
- double yRadius = Math.abs(aES.getPoints().get(2).Y - aES.getPoints().get(0).Y) / 2;
- double[][] points = new double[1][];
- PointD centerPoint = new PointD(aES.getExtent().minX + xRadius, aES.getExtent().minY + yRadius);
- points[0] = new double[]{centerPoint.X, centerPoint.Y};
- try {
- Reproject.reprojectPoints(points, fromProj, toProj, 0, points.length);
- if (!Double.isNaN(points[0][0]) && !Double.isNaN(points[0][1])) {
- centerPoint.X = points[0][0];
- centerPoint.Y = points[0][1];
- } else {
- return null;
- }
- } catch (Exception e) {
- return null;
- }
-
- points = new double[1][];
- PointD lbPoint = new PointD(aES.getExtent().minX, aES.getExtent().minY);
- points[0] = new double[]{lbPoint.X, lbPoint.Y};
- try {
- Reproject.reprojectPoints(points, fromProj, toProj, 0, points.length);
- if (!Double.isNaN(points[0][0]) && !Double.isNaN(points[0][1])) {
- lbPoint.X = points[0][0];
- lbPoint.Y = points[0][1];
- } else {
- return null;
- }
- } catch (Exception e) {
- return null;
- }
-
- xRadius = Math.abs(centerPoint.X - lbPoint.X);
- yRadius = Math.abs(centerPoint.Y - lbPoint.Y);
- List newPoints = new ArrayList<>();
- newPoints.add(new PointD(centerPoint.X - xRadius, centerPoint.Y - yRadius));
- newPoints.add(new PointD(centerPoint.X - xRadius, centerPoint.Y + yRadius));
- newPoints.add(new PointD(centerPoint.X + xRadius, centerPoint.Y + yRadius));
- newPoints.add(new PointD(centerPoint.X + xRadius, centerPoint.Y - yRadius));
- EllipseShape newES = new EllipseShape();
- newES.setPoints(newPoints);
-
- return newES;
- }
-
- /**
- * Project angle
- *
- * @param oAngle The angle
- * @param fromP1 From point
- * @param toP1 To point
- * @param fromProj From projection
- * @param toProj To projection
- * @return Projected angle
- */
- public double projectAngle(double oAngle, double[] fromP1, double[] toP1, ProjectionInfo fromProj, ProjectionInfo toProj) {
- double pAngle = oAngle;
- double[] fromP2;
- double[] toP2;
- double[][] points = new double[1][];
-
- if (fromP1[1] == 90) {
- fromP2 = new double[]{fromP1[0], fromP1[1] - 10};
- points[0] = (double[]) fromP2.clone();
- try {
- Reproject.reprojectPoints(points, fromProj, toProj, 0, points.length);
- toP2 = points[0];
- double x, y;
- x = toP2[0] - toP1[0];
- y = toP2[1] - toP1[1];
- double aLen = Math.sqrt(x * x + y * y);
- double angle = Math.asin(x / aLen) * 180 / Math.PI;
- if (x < 0 && y < 0) {
- angle = 180.0 - angle;
- } else if (x > 0 && y < 0) {
- angle = 180.0 - angle;
- } else if (x < 0 && y > 0) {
- angle = 360.0 + angle;
- }
- if (aLen == 0) {
- System.out.print("Error");
- }
- pAngle = oAngle + (angle - 180);
- if (pAngle > 360) {
- pAngle = pAngle - 360;
- } else if (pAngle < 0) {
- pAngle = pAngle + 360;
- }
- } catch (Exception e) {
- }
- } else {
- fromP2 = new double[]{fromP1[0] + 10, fromP1[1]};
- points[0] = (double[]) fromP2.clone();
- try {
- Reproject.reprojectPoints(points, fromProj, toProj, 0, points.length);
- toP2 = points[0];
-
- double x, y;
- x = toP2[0] - toP1[0];
- y = toP2[1] - toP1[1];
- double aLen = Math.sqrt(x * x + y * y);
- if (aLen == 0) {
- return pAngle;
- }
-
- double angle = Math.asin(x / aLen) * 180 / Math.PI;
- if (Double.isNaN(angle)) {
- return pAngle;
- }
-
- if (x < 0 && y < 0) {
- angle = 180.0 - angle;
- } else if (x > 0 && y < 0) {
- angle = 180.0 - angle;
- } else if (x < 0 && y > 0) {
- angle = 360.0 + angle;
- }
-
- pAngle = oAngle + (angle - 90);
- if (pAngle > 360) {
- pAngle = pAngle - 360;
- } else if (pAngle < 0) {
- pAngle = pAngle + 360;
- }
- } catch (Exception e) {
- }
- }
-
- return pAngle;
- }
-
- private GraphicCollection projectGraphics(GraphicCollection aGCollection, ProjectionInfo fromProj, ProjectionInfo toProj) {
- GraphicCollection newGCollection = new GraphicCollection();
- for (Graphic aGraphic : aGCollection.getGraphics()) {
- aGraphic.setShape(projectShape(aGraphic.getShape(), fromProj, toProj));
- if (aGraphic.getShape() != null) {
- newGCollection.add(aGraphic);
- }
- }
-
- return newGCollection;
- }
-
- private List projectGraphics(List graphics, ProjectionInfo fromProj, ProjectionInfo toProj) {
- List newGraphics = new ArrayList<>();
- for (Graphic aGraphic : graphics) {
- Shape aShape = projectShape(aGraphic.getShape(), fromProj, toProj);
- if (aShape != null) {
- newGraphics.add(new Graphic(aShape, aGraphic.getLegend()));
- }
- }
-
- return newGraphics;
- }
-
- private Shape projectShape(Shape aShape, ProjectionInfo fromProj, ProjectionInfo toProj) {
- Shape newShape;
- switch (aShape.getShapeType()) {
- case Point:
- case PointM:
- newShape = projectPointShape((PointShape) aShape, fromProj, toProj);
- break;
- case Polyline:
- case PolylineM:
- newShape = projectPolylineShape((PolylineShape) aShape, fromProj, toProj);
- break;
- case CurveLine:
- newShape = projectCurvelineShape((CurveLineShape) aShape, fromProj, toProj);
- break;
- case Polygon:
- case PolygonM:
- case Rectangle:
- newShape = projectPolygonShape((PolygonShape) aShape, fromProj, toProj);
- break;
- case CurvePolygon:
- newShape = projectCurvePolygonShape((CurvePolygonShape) aShape, fromProj, toProj);
- break;
- case Circle:
- newShape = projectCircleShape((CircleShape) aShape, fromProj, toProj);
- break;
- case Ellipse:
- newShape = projectEllipseShape((EllipseShape) aShape, fromProj, toProj);
- break;
- default:
- newShape = null;
- break;
- }
-
- return newShape;
- }
- //
-}
+/* Copyright 2012 Yaqiang Wang,
+ * yaqiang.wang@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ */
+package org.meteoinfo.map;
+
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.MIMath;
+import org.meteoinfo.common.PointD;
+import org.meteoinfo.global.event.IProjectionChangedListener;
+import org.meteoinfo.global.event.ProjectionChangedEvent;
+import org.meteoinfo.layer.RasterLayer;
+import org.meteoinfo.layer.VectorLayer;
+import org.meteoinfo.projection.KnownCoordinateSystems;
+import org.meteoinfo.projection.info.ProjectionInfo;
+import org.meteoinfo.projection.Reproject;
+import org.meteoinfo.shape.CircleShape;
+import org.meteoinfo.shape.CurveLineShape;
+import org.meteoinfo.shape.CurvePolygonShape;
+import org.meteoinfo.shape.EllipseShape;
+import org.meteoinfo.shape.Graphic;
+import org.meteoinfo.shape.GraphicCollection;
+import org.meteoinfo.shape.PointShape;
+import org.meteoinfo.shape.Polygon;
+import org.meteoinfo.shape.PolygonShape;
+import org.meteoinfo.shape.Polyline;
+import org.meteoinfo.shape.PolylineShape;
+import org.meteoinfo.shape.Shape;
+import org.meteoinfo.shape.StationModelShape;
+import org.meteoinfo.shape.WindArrow;
+import org.meteoinfo.shape.WindBarb;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import javax.swing.event.EventListenerList;
+import org.meteoinfo.projection.ProjectionUtil;
+import org.locationtech.proj4j.CRSFactory;
+
+/**
+ *
+ * @author Yaqiang Wang
+ */
+public class ProjectionSet {
+ //
+
+ private final EventListenerList _listeners = new EventListenerList();
+ CRSFactory _crsFactory = new CRSFactory();
+ private ProjectionInfo _projInfo;
+ //private String _projStr;
+ //private double _refLon;
+ //private double _refCutLon;
+ //
+ //
+
+ /**
+ * Constructor
+ */
+ public ProjectionSet() {
+ _projInfo = KnownCoordinateSystems.geographic.world.WGS1984;
+ //_projStr = _projInfo.getParameterString();
+ //_refLon = 0;
+ }
+ //
+
+ //
+ public void addProjectionChangedListener(IProjectionChangedListener listener) {
+ this._listeners.add(IProjectionChangedListener.class, listener);
+ }
+
+ public void removeViewExtentChangedListener(IProjectionChangedListener listener) {
+ this._listeners.remove(IProjectionChangedListener.class, listener);
+ }
+
+ public void fireProjectionChangedEvent() {
+ fireProjectionChangedEvent(new ProjectionChangedEvent(this));
+ }
+
+ private void fireProjectionChangedEvent(ProjectionChangedEvent event) {
+ Object[] listeners = _listeners.getListenerList();
+ for (int i = 0; i < listeners.length; i = i + 2) {
+ if (listeners[i] == IProjectionChangedListener.class) {
+ ((IProjectionChangedListener) listeners[i + 1]).projectionChangedEvent(event);
+ }
+ }
+ }
+ //
+ //
+
+ /**
+ * Get if is Lon/Lat projection
+ *
+ * @return Boolean
+ */
+ public boolean isLonLatMap() {
+ return "longlat".equals(_projInfo.getCoordinateReferenceSystem().getProjection().toString().toLowerCase());
+ }
+
+ /**
+ * Get projection info
+ *
+ * @return Projection Info
+ */
+ public ProjectionInfo getProjInfo() {
+ return _projInfo;
+ }
+
+ /**
+ * Set projection info
+ *
+ * @param projInfo The Projection info
+ */
+ public void setProjInfo(ProjectionInfo projInfo) {
+ _projInfo = projInfo;
+ }
+
+ /**
+ * Get Porj4 string
+ *
+ * @return Proj4 string
+ */
+ public String getProjStr() {
+ return _projInfo.toProj4String();
+ }
+
+ /**
+ * Set proj4 string
+ *
+ * @param projStr Porj4 string
+ */
+ public void setProjStr(String projStr) {
+ _projInfo = ProjectionInfo.factory(projStr);
+ }
+
+// /**
+// * Get reference longitude
+// *
+// * @return Reference longitue
+// */
+// public double getRefLon() {
+// return _refLon;
+// }
+//
+// /**
+// * Set reference longitude
+// *
+// * @param lon Reference longitude
+// */
+// public void setRefLon(double lon) {
+// _refLon = lon;
+// }
+
+// /**
+// * Get reference cut longitude
+// *
+// * @return Reference cut longitude
+// */
+// public double getRefCutLon() {
+// return _refCutLon;
+// }
+//
+// /**
+// * Set reference cut longitude
+// *
+// * @param lon
+// */
+// public void setRefCutLon(double lon) {
+// _refCutLon = lon;
+// }
+ //
+ //
+
+ /**
+ * Get projected extent from lon/lat
+ *
+ * @param sExtent Lon/lat extent
+ * @return Projected extent
+ */
+ public Extent getProjectedExtentFromLonLat(Extent sExtent) {
+ Extent aExtent = new Extent();
+ ProjectionInfo fromProj = KnownCoordinateSystems.geographic.world.WGS1984;
+ ProjectionInfo toProj = _projInfo;
+
+ //Get the border of longitude and latitude
+ double[][] points = new double[4][];
+ points[0] = new double[]{sExtent.minX, sExtent.minY};
+ points[1] = new double[]{sExtent.minX, sExtent.maxY};
+ points[2] = new double[]{sExtent.maxX, sExtent.maxY};
+ points[3] = new double[]{sExtent.maxX, sExtent.minY};
+ Reproject.reprojectPoints(points, fromProj, toProj, 0, points.length);
+
+ //Get lon lat extent
+ aExtent.minX = Math.min(points[0][0], points[1][0]);
+ aExtent.minY = Math.min(points[0][1], points[3][1]);
+ aExtent.maxX = Math.max(points[2][0], points[3][0]);
+ aExtent.maxY = Math.max(points[1][1], points[2][1]);
+
+ return aExtent;
+ }
+
+ /**
+ * Project layers
+ *
+ * @param aMapView The Map view
+ * @param toProj To projection info
+ */
+ public void projectLayers(MapView aMapView, ProjectionInfo toProj) {
+ projectLayers(aMapView, toProj, true);
+ }
+
+ /**
+ * Project layers
+ *
+ * @param aMapView The map view
+ * @param toProj To projection
+ * @param isUpdateView If repaint mapview
+ */
+ public void projectLayers(MapView aMapView, ProjectionInfo toProj, boolean isUpdateView) {
+ if (aMapView.getProjection().getProjInfo().toProj4String().equals(toProj.toProj4String())) {
+ return;
+ }
+
+ aMapView.setLockViewUpdate(true);
+
+ ProjectionInfo fromProj = aMapView.getProjection().getProjInfo();
+
+ aMapView.getProjection().setProjInfo(toProj);
+ double refLon = toProj.getRefCutLon();
+ //aMapView.getProjection().setRefCutLon(refLon);
+
+ for (int i = 0; i < aMapView.getLayers().size(); i++) {
+ switch (aMapView.getLayers().get(i).getLayerType()) {
+ case VectorLayer:
+ VectorLayer oLayer = (VectorLayer) aMapView.getLayers().get(i);
+ //projectLayer(oLayer, toProj);
+ ProjectionUtil.projectLayer(oLayer, toProj);
+ break;
+ case RasterLayer:
+ RasterLayer oRLayer = (RasterLayer) aMapView.getLayers().get(i);
+ ProjectionUtil.projectLayer(oRLayer, toProj);
+ break;
+ }
+ }
+
+ //Project graphics
+ if (aMapView.getGraphicCollection().size() > 0) {
+ GraphicCollection newGCollection = projectGraphics(aMapView.getGraphicCollection(), fromProj, toProj);
+ aMapView.setGraphicCollection(newGCollection);
+ }
+
+ aMapView.setExtent(aMapView.getLayersWholeExtent());
+ Extent aExten = aMapView.getExtent();
+ aMapView.setLonLatLayer(aMapView.generateLonLatLayer());
+ ProjectionUtil.projectLayer(aMapView.getLonLatLayer(), toProj);
+ //aMapView.setLonLatProjLayer(aMapView.getLonLatLayer());
+ for (int i = 0; i < aMapView.getLonLatLayer().getShapeNum(); i++) {
+ PolylineShape aPLS = (PolylineShape) aMapView.getLonLatLayer().getShapes().get(i);
+ if (aPLS.getPolylines().size() == 2) {
+ PointD aP = aPLS.getPolylines().get(0).getPointList().get(aPLS.getPolylines().get(0).getPointList().size() - 1);
+ PointD bP = aPLS.getPolylines().get(1).getPointList().get(aPLS.getPolylines().get(1).getPointList().size() - 1);
+ boolean isJoin = false;
+ if (refLon == 0) {
+ if (Math.abs(aP.X) < 0.1 && Math.abs(bP.X) < 0.1 && MIMath.doubleEquals(aP.Y, bP.Y)) {
+ isJoin = true;
+ }
+ } else if (MIMath.doubleEquals(aP.X, bP.X) && MIMath.doubleEquals(aP.Y, bP.Y)) {
+ isJoin = true;
+ }
+
+ if (isJoin) {
+ List polyLines = new ArrayList<>();
+ Polyline aPL = new Polyline();
+ List pList = (List) new ArrayList<>(aPLS.getPolylines().get(1).getPointList());
+ List bPList = (List) new ArrayList<>(aPLS.getPolylines().get(0).getPointList());
+ Collections.reverse(bPList);
+ pList.addAll(bPList);
+ aPL.setPointList(pList);
+ polyLines.add(aPL);
+ aPLS.setPolylines(polyLines);
+ //aMapView.getLonLatProjLayer().getShapes().get(i) = aPLS;
+ }
+ }
+ }
+
+ if (isUpdateView) {
+ aMapView.setLockViewUpdate(false);
+ }
+ aMapView.zoomToExtent(aExten);
+
+ this.fireProjectionChangedEvent();
+ }
+
+// /**
+// * Project raster layer
+// *
+// * @param oLayer The layer
+// * @param toProj To projection
+// */
+// public void projectLayer(RasterLayer oLayer, ProjectionInfo toProj) {
+// try {
+// // if (toProj.getProjectionName() == ProjectionNames.Robinson) {
+//// return;
+//// }
+//
+// if (oLayer.getProjInfo().toProj4String().equals(toProj.toProj4String())) {
+// if (oLayer.isProjected()) {
+// oLayer.getOriginData();
+// oLayer.updateGridData();
+// if (oLayer.getLegendScheme().getBreakNum() < 50) {
+// oLayer.updateImage();
+// } else {
+// oLayer.setPaletteByLegend();
+// }
+// }
+// return;
+// }
+//
+// if (!oLayer.isProjected()) {
+// oLayer.updateOriginData();
+// } else {
+// oLayer.getOriginData();
+// }
+//
+// oLayer.setGridData(oLayer.getGridData().project(oLayer.getProjInfo(), toProj));
+// oLayer.updateImage(oLayer.getLegendScheme());
+//// if (oLayer.getLegendScheme().getBreakNum() < 50) {
+//// oLayer.updateImage(oLayer.getLegendScheme());
+//// } else {
+//// oLayer.setPaletteByLegend();
+//// }
+// } catch (InvalidRangeException ex) {
+// Logger.getLogger(ProjectionSet.class.getName()).log(Level.SEVERE, null, ex);
+// }
+// }
+//
+// /**
+// * Project vector layer
+// *
+// * @param oLayer The layer
+// * @param toProj To projection info
+// */
+// public void projectLayer(VectorLayer oLayer, ProjectionInfo toProj) {
+// projectLayer(oLayer, toProj, true);
+// }
+//
+// /**
+// * Project vector layer
+// *
+// * @param oLayer The layer
+// * @param toProj To projection info
+// * @param projectLabels If project labels
+// */
+// public void projectLayer(VectorLayer oLayer, ProjectionInfo toProj, boolean projectLabels) {
+// ProjectionInfo fromProj = oLayer.getProjInfo();
+// if (fromProj.equals(toProj)) {
+// if (oLayer.isProjected()) {
+// oLayer.getOriginData();
+// }
+//
+// return;
+// }
+//
+// if (oLayer.isProjected()) {
+// oLayer.getOriginData();
+// } else {
+// oLayer.updateOriginData();
+// }
+//
+// double refLon = toProj.getRefCutLon();
+// if (oLayer.getExtent().maxX > 180 && oLayer.getExtent().minX > refLon) {
+// refLon += 360;
+// }
+//
+// //coordinate transform process
+// int i, s;
+// ArrayList newPoints = new ArrayList();
+// Extent lExtent = new Extent();
+//
+// DataTable aTable = new DataTable();
+// for (DataColumn aDC : oLayer.getAttributeTable().getTable().getColumns()) {
+// Field bDC = new Field(aDC.getColumnName(), aDC.getDataType());
+// aTable.getColumns().add(bDC);
+// }
+//
+// //aLayer.AttributeTable.Table.Rows.Clear();
+// switch (oLayer.getShapeType()) {
+// case Point:
+// case PointM:
+// case PointZ:
+// case WeatherSymbol:
+// case WindArraw:
+// case WindBarb:
+// case StationModel:
+// List shapePoints = new ArrayList<>();
+// newPoints.clear();
+// for (s = 0; s < oLayer.getShapeNum(); s++) {
+// PointShape aPS = (PointShape) oLayer.getShapes().get(s);
+// if (fromProj.getProjectionName() == ProjectionNames.LongLat) {
+// switch (toProj.getProjectionName()) {
+// case Lambert_Conformal_Conic:
+// if (aPS.getPoint().Y < -80) {
+// continue;
+// }
+// break;
+// case North_Polar_Stereographic_Azimuthal:
+// if (aPS.getPoint().Y < 0) {
+// continue;
+// }
+// break;
+// case South_Polar_Stereographic_Azimuthal:
+// if (aPS.getPoint().Y > 0) {
+// continue;
+// }
+// break;
+// case Mercator:
+// if (aPS.getPoint().Y > 85.0511 || aPS.getPoint().Y < -85.0511) {
+// continue;
+// }
+// break;
+// }
+// }
+// aPS = projectPointShape(aPS, fromProj, toProj);
+// if (aPS != null) {
+// shapePoints.add(aPS);
+// newPoints.add(aPS.getPoint());
+//
+// DataRow aDR = oLayer.getAttributeTable().getTable().getRows().get(s);
+// try {
+// aTable.addRow(aDR);
+// } catch (Exception ex) {
+// Logger.getLogger(ProjectionSet.class.getName()).log(Level.SEVERE, null, ex);
+// }
+// }
+// }
+// oLayer.setShapes(new ArrayList<>(shapePoints));
+// oLayer.setExtent(MIMath.getPointsExtent(newPoints));
+//
+// break;
+// case Polyline:
+// case PolylineM:
+// case PolylineZ:
+// List newPolylines = new ArrayList<>();
+// for (s = 0; s < oLayer.getShapeNum(); s++) {
+// PolylineShape aPLS = (PolylineShape) oLayer.getShapes().get(s);
+// List plsList = new ArrayList<>();
+// if (fromProj.getProjectionName() == ProjectionNames.LongLat) {
+// switch (toProj.getProjectionName()) {
+// case Lambert_Conformal_Conic:
+// if (aPLS.getExtent().minY < -80) {
+// aPLS = GeoComputation.clipPolylineShape_Lat(aPLS, -80, true);
+// }
+// break;
+// case North_Polar_Stereographic_Azimuthal:
+// if (aPLS.getExtent().minY < 0) {
+// //continue;
+// aPLS = GeoComputation.clipPolylineShape_Lat(aPLS, 0, true);
+// }
+// break;
+// case South_Polar_Stereographic_Azimuthal:
+// if (aPLS.getExtent().maxY > 0) {
+// //continue;
+// aPLS = GeoComputation.clipPolylineShape_Lat(aPLS, 0, false);
+// }
+// break;
+// case Mercator:
+// if (aPLS.getExtent().maxY > 85.0511) {
+// aPLS = GeoComputation.clipPolylineShape_Lat(aPLS, 85.0511, false);
+// }
+// if (aPLS.getExtent().minY < -85.0511) {
+// aPLS = GeoComputation.clipPolylineShape_Lat(aPLS, -85.0511, true);
+// }
+// break;
+// }
+// if (aPLS == null) {
+// continue;
+// }
+//
+//// aPLS = GeoComputation.clipPolylineShape_Lon(aPLS, refLon);
+//// if (aPLS == null) {
+//// continue;
+//// }
+// if (aPLS.getExtent().minX < refLon && aPLS.getExtent().maxX > refLon) {
+// plsList.add(GeoComputation.clipPolylineShape_Lon(aPLS, refLon));
+// } else {
+// plsList.add(aPLS);
+// }
+// } else {
+// plsList.add(aPLS);
+// }
+// for (i = 0; i < plsList.size(); i++) {
+// aPLS = plsList.get(i);
+// aPLS = projectPolylineShape(aPLS, fromProj, toProj);
+// if (aPLS != null) {
+// newPolylines.add(aPLS);
+//
+// DataRow aDR = oLayer.getAttributeTable().getTable().getRows().get(s);
+// try {
+// aTable.addRow(aDR);
+// } catch (Exception ex) {
+// Logger.getLogger(ProjectionSet.class.getName()).log(Level.SEVERE, null, ex);
+// }
+//
+// if (s == 0 && i == 0) {
+// lExtent = (Extent) aPLS.getExtent().clone();
+// } else {
+// lExtent = MIMath.getLagerExtent(lExtent, aPLS.getExtent());
+// }
+// }
+// }
+// }
+// oLayer.setShapes(new ArrayList<>(newPolylines));
+// newPolylines.clear();
+// oLayer.setExtent(lExtent);
+// break;
+// case Polygon:
+// case PolygonM:
+// List newPolygons = new ArrayList<>();
+// for (s = 0; s < oLayer.getShapeNum(); s++) {
+// DataRow aDR = oLayer.getAttributeTable().getTable().getRows().get(s);
+// PolygonShape aPGS = (PolygonShape) oLayer.getShapes().get(s);
+// List pgsList = new ArrayList<>();
+// if (fromProj.getProjectionName() == ProjectionNames.LongLat) {
+// switch (toProj.getProjectionName()) {
+// case Lambert_Conformal_Conic:
+// if (aPGS.getExtent().minY < -80) {
+// aPGS = GeoComputation.clipPolygonShape_Lat(aPGS, -80, true);
+// }
+// break;
+// case North_Polar_Stereographic_Azimuthal:
+// if (aPGS.getExtent().minY < 0) {
+// //continue;
+// aPGS = GeoComputation.clipPolygonShape_Lat(aPGS, 0, true);
+// }
+// break;
+// case South_Polar_Stereographic_Azimuthal:
+// if (aPGS.getExtent().maxY > 0) {
+// //continue;
+// aPGS = GeoComputation.clipPolygonShape_Lat(aPGS, 0, false);
+// }
+// break;
+// case Mercator:
+// if (aPGS.getExtent().maxY > 85.0511) {
+// aPGS = GeoComputation.clipPolygonShape_Lat(aPGS, 85.0511, false);
+// }
+// if (aPGS.getExtent().minY < -85.0511) {
+// aPGS = GeoComputation.clipPolygonShape_Lat(aPGS, -85.0511, true);
+// }
+// break;
+// }
+// if (aPGS == null) {
+// continue;
+// }
+//
+// if (aPGS.getExtent().minX <= refLon && aPGS.getExtent().maxX >= refLon) {
+// pgsList.add(GeoComputation.clipPolygonShape_Lon(aPGS, refLon));
+// } else {
+// pgsList.add(aPGS);
+// }
+// } else {
+// pgsList.add(aPGS);
+// }
+// for (i = 0; i < pgsList.size(); i++) {
+// aPGS = pgsList.get(i);
+// aPGS = projectPolygonShape(aPGS, fromProj, toProj);
+// if (aPGS != null) {
+// newPolygons.add(aPGS);
+//
+// aTable.getRows().add(aDR);
+//
+// if (s == 0) {
+// lExtent = (Extent) aPGS.getExtent().clone();
+// } else {
+// lExtent = MIMath.getLagerExtent(lExtent, aPGS.getExtent());
+// }
+// }
+// }
+// }
+// oLayer.setShapes(new ArrayList<>(newPolygons));
+// newPolygons.clear();
+// oLayer.setExtent(lExtent);
+// break;
+// }
+// oLayer.getAttributeTable().setTable(aTable);
+//
+// if (oLayer.getLabelPoints().size() > 0) {
+// if (projectLabels) {
+// oLayer.setLabelPoints(projectGraphics(oLayer.getLabelPoints(), fromProj, toProj));
+// } else {
+// oLayer.setLabelPoints(new ArrayList<>(oLayer.getLabelPoints()));
+// }
+// }
+// }
+//
+// /**
+// * Project layer angle
+// *
+// * @param oLayer The layer
+// * @param fromProj From projection
+// * @param toProj To projection
+// * @return VectorLayer
+// */
+// public VectorLayer projectLayerAngle(VectorLayer oLayer, ProjectionInfo fromProj, ProjectionInfo toProj) {
+// //coordinate transform process
+// ArrayList newPoints = new ArrayList();
+//
+// VectorLayer aLayer = (VectorLayer) oLayer.clone();
+//
+// //aLayer.AttributeTable.Table = oLayer.AttributeTable.Table.Clone();
+// DataTable aTable = new DataTable();
+// for (DataColumn aDC : oLayer.getAttributeTable().getTable().getColumns()) {
+// Field bDC = new Field(aDC.getColumnName(), aDC.getDataType());
+// aTable.getColumns().add(bDC);
+// }
+//
+// int s;
+// List vectors = new ArrayList<>();
+// newPoints.clear();
+// for (s = 0; s < aLayer.getShapeNum(); s++) {
+// PointShape aPS = (PointShape) aLayer.getShapes().get(s);
+// if (fromProj.getProjectionName() == ProjectionNames.LongLat) {
+// switch (toProj.getProjectionName()) {
+// case Lambert_Conformal_Conic:
+// case North_Polar_Stereographic_Azimuthal:
+// if (aPS.getPoint().X < -89) {
+// continue;
+// }
+// break;
+// case South_Polar_Stereographic_Azimuthal:
+// if (aPS.getPoint().Y > 89) {
+// continue;
+// }
+// break;
+// }
+// }
+// double[] fromP = new double[]{aPS.getPoint().X, aPS.getPoint().Y};
+// double[] toP;
+// double[][] points = new double[1][];
+// points[0] = (double[]) fromP.clone();
+// try {
+// //Reproject point back to fromProj
+// Reproject.reprojectPoints(points, toProj, fromProj, 0, points.length);
+// toP = points[0];
+// switch (aLayer.getLayerDrawType()) {
+// case Vector:
+// ((WindArrow) aPS).angle = projectAngle(((WindArrow) aPS).angle, toP, fromP, fromProj, toProj);
+// break;
+// case Barb:
+// ((WindBarb) aPS).angle = projectAngle(((WindBarb) aPS).angle, toP, fromP, fromProj, toProj);
+// break;
+// case StationModel:
+// ((StationModelShape) aPS).windBarb.angle = projectAngle(((StationModelShape) aPS).windBarb.angle, toP, fromP, fromProj, toProj);
+// break;
+// }
+// newPoints.add(aPS.getPoint());
+// vectors.add(aPS);
+//
+// DataRow aDR = oLayer.getAttributeTable().getTable().getRows().get(s);
+// aTable.getRows().add(aDR);
+// } catch (Exception e) {
+// }
+// }
+// aLayer.setShapes(new ArrayList<>(vectors));
+// aLayer.setExtent(MIMath.getPointsExtent(newPoints));
+// aLayer.getAttributeTable().setTable(aTable);
+//
+// //if (aLayer.LabelSetV.DrawLabels)
+// //{
+// // aLayer.AddLabels();
+// //}
+// return aLayer;
+// }
+
+// /**
+// * Project wind layer
+// *
+// * @param oLayer Origin layer
+// * @param toProj To projection
+// * @param IfReprojectAngle If reproject wind angle
+// */
+// public void projectWindLayer(VectorLayer oLayer, ProjectionInfo toProj, boolean IfReprojectAngle) {
+// ProjectionInfo fromProj = oLayer.getProjInfo();
+// if (fromProj.toProj4String().equals(toProj.toProj4String())) {
+// if (oLayer.isProjected()) {
+// oLayer.getOriginData();
+// }
+//
+// return;
+// }
+//
+// if (oLayer.isProjected()) {
+// oLayer.getOriginData();
+// } else {
+// oLayer.updateOriginData();
+// }
+//
+// //Set reference longitude
+// double refLon = toProj.getRefCutLon();
+// if (oLayer.getExtent().maxX > 180 && oLayer.getExtent().minX > refLon) {
+// refLon += 360;
+// }
+//
+// //coordinate transform process
+// int s;
+// //PointD wPoint = new PointD();
+// PointD aPoint;
+// List newPoints = new ArrayList<>();
+// //Extent lExtent = new Extent();
+//
+// DataTable aTable = new DataTable();
+// for (DataColumn aDC : oLayer.getAttributeTable().getTable().getColumns()) {
+// Field bDC = new Field(aDC.getColumnName(), aDC.getDataType());
+// aTable.getColumns().add(bDC);
+// }
+//
+// List shapes = new ArrayList<>();
+// newPoints.clear();
+// for (s = 0; s < oLayer.getShapeNum(); s++) {
+// PointShape aPS = (PointShape) oLayer.getShapes().get(s);
+// if (fromProj.getProjectionName() == ProjectionNames.LongLat) {
+// switch (toProj.getProjectionName()) {
+// case Lambert_Conformal_Conic:
+// case North_Polar_Stereographic_Azimuthal:
+// if (aPS.getPoint().Y < -89) {
+// continue;
+// }
+// break;
+// case South_Polar_Stereographic_Azimuthal:
+// if (aPS.getPoint().Y > 89) {
+// continue;
+// }
+// break;
+// }
+// }
+// double[] fromP = new double[]{aPS.getPoint().X, aPS.getPoint().Y};
+// double[] toP;
+// double[][] points = new double[1][];
+// points[0] = (double[]) fromP.clone();
+// try {
+// Reproject.reprojectPoints(points, fromProj, toProj, 0, points.length);
+// toP = points[0];
+// aPoint = new PointD();
+// aPoint.X = (float) toP[0];
+// aPoint.Y = (float) toP[1];
+// aPS.setPoint(aPoint);
+// if (IfReprojectAngle) {
+// switch (oLayer.getLayerDrawType()) {
+// case Vector:
+// ((WindArrow) aPS).angle = projectAngle(((WindArrow) aPS).angle, fromP, toP, fromProj, toProj);
+// break;
+// case Barb:
+// ((WindBarb) aPS).angle = projectAngle(((WindBarb) aPS).angle, fromP, toP, fromProj, toProj);
+// break;
+// case StationModel:
+// ((StationModelShape) aPS).windBarb.angle = projectAngle(((StationModelShape) aPS).windBarb.angle, fromP, toP, fromProj, toProj);
+// break;
+// }
+// }
+// newPoints.add(aPoint);
+// shapes.add(aPS);
+//
+// DataRow aDR = oLayer.getAttributeTable().getTable().getRows().get(s);
+// aTable.getRows().add(aDR);
+// } catch (Exception e) {
+// }
+// }
+// oLayer.setShapes(new ArrayList<>(shapes));
+// oLayer.setExtent(MIMath.getPointsExtent(newPoints));
+// oLayer.getAttributeTable().setTable(aTable);
+//
+// if (oLayer.getLabelPoints().size() > 0) {
+// oLayer.setLabelPoints(projectGraphics(oLayer.getLabelPoints(), fromProj, toProj));
+// }
+// }
+
+ private PointShape projectPointShape(PointShape aPS, ProjectionInfo fromProj, ProjectionInfo toProj) {
+ PointShape newPS = (PointShape) aPS.clone();
+ double[][] points = new double[1][];
+ points[0] = new double[]{newPS.getPoint().X, newPS.getPoint().Y};
+ double[] fromP = new double[]{newPS.getPoint().X, newPS.getPoint().Y};
+ try {
+ Reproject.reprojectPoints(points, fromProj, toProj, 0, points.length);
+ if (!Double.isNaN(points[0][0]) && !Double.isNaN(points[0][1])) {
+ double[] toP = points[0];
+ newPS.setPoint(new PointD(points[0][0], points[0][1]));
+ switch (aPS.getShapeType()) {
+ case WindBarb:
+ ((WindBarb) newPS).angle = projectAngle(((WindBarb) newPS).angle, fromP, toP, fromProj, toProj);
+ break;
+ case WindArraw:
+ ((WindArrow) newPS).angle = projectAngle(((WindArrow) newPS).angle, fromP, toP, fromProj, toProj);
+ break;
+ case StationModel:
+ ((StationModelShape) newPS).windBarb.angle = projectAngle(((StationModelShape) newPS).windBarb.angle, fromP, toP, fromProj, toProj);
+ break;
+ }
+ return newPS;
+ } else {
+ return null;
+ }
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ private PolylineShape projectPolylineShape(PolylineShape aPLS, ProjectionInfo fromProj, ProjectionInfo toProj) {
+ List polyLines = new ArrayList<>();
+ for (int i = 0; i < aPLS.getPolylines().size(); i++) {
+ List newPoints = new ArrayList<>();
+ Polyline aPL = aPLS.getPolylines().get(i);
+ Polyline bPL;
+ double x;
+ for (int j = 0; j < aPL.getPointList().size(); j++) {
+ double[][] points = new double[1][];
+ PointD wPoint = aPL.getPointList().get(j);
+ x = wPoint.X;
+ if (fromProj.isLonLat()) {
+ if (x > 180) {
+ x -= 360;
+ } else if (x < -180) {
+ x += 360;
+ }
+ }
+ points[0] = new double[]{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 (newPoints.size() > 1) {
+ bPL = new Polyline();
+ bPL.setPointList(newPoints);
+ polyLines.add(bPL);
+ }
+ }
+
+ if (polyLines.size() > 0) {
+ aPLS.setPolylines(polyLines);
+
+ return aPLS;
+ } else {
+ return null;
+ }
+ }
+
+ private CurveLineShape projectCurvelineShape(CurveLineShape aPLS, ProjectionInfo fromProj, ProjectionInfo toProj) {
+ List polyLines = new ArrayList<>();
+ for (int i = 0; i < aPLS.getPolylines().size(); i++) {
+ List newPoints = new ArrayList<>();
+ Polyline aPL = aPLS.getPolylines().get(i);
+ Polyline bPL;
+ for (int j = 0; j < aPL.getPointList().size(); j++) {
+ double[][] points = new double[1][];
+ PointD wPoint = aPL.getPointList().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 (newPoints.size() > 1) {
+ bPL = new Polyline();
+ bPL.setPointList(newPoints);
+ polyLines.add(bPL);
+ }
+ }
+
+ if (polyLines.size() > 0) {
+ aPLS.setPolylines(polyLines);
+
+ return aPLS;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Project polygon shape
+ *
+ * @param aPGS A polygon shape
+ * @param fromProj From projection
+ * @param toProj To porjection
+ * @return Projected polygon shape
+ */
+ public 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);
+ }
+ } catch (Exception e) {
+ break;
+ }
+ }
+
+ if (r == 0) {
+ if (newPoints.size() > 2) {
+ bPG = new Polygon();
+ bPG.setOutLine(newPoints);
+ } else {
+ break;
+ }
+ } else if (newPoints.size() > 2) {
+ if (bPG != null)
+ bPG.addHole(newPoints);
+ }
+ }
+
+ if (bPG != null) {
+ polygons.add(bPG);
+ }
+ }
+
+ if (polygons.size() > 0) {
+ aPGS.setPolygons(polygons);
+
+ return aPGS;
+ } else {
+ return null;
+ }
+ }
+
+ private CurvePolygonShape projectCurvePolygonShape(CurvePolygonShape 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);
+ }
+ } catch (Exception e) {
+ break;
+ }
+ }
+
+ if (r == 0) {
+ if (newPoints.size() > 2) {
+ bPG = new Polygon();
+ bPG.setOutLine(newPoints);
+ } else {
+ break;
+ }
+ } else if (newPoints.size() > 2) {
+ if (bPG != null)
+ bPG.addHole(newPoints);
+ }
+ }
+
+ if (bPG != null) {
+ polygons.add(bPG);
+ }
+ }
+
+ if (polygons.size() > 0) {
+ aPGS.setPolygons(polygons);
+
+ return aPGS;
+ } else {
+ return null;
+ }
+ }
+
+ private CircleShape projectCircleShape(CircleShape aCS, ProjectionInfo fromProj, ProjectionInfo toProj) {
+ double radius = Math.abs(aCS.getPoints().get(1).X - aCS.getPoints().get(0).X);
+ double[][] points = new double[1][];
+ PointD centerPoint = new PointD(aCS.getPoints().get(0).X + radius, aCS.getPoints().get(0).Y);
+ points[0] = new double[]{centerPoint.X, centerPoint.Y};
+ try {
+ Reproject.reprojectPoints(points, fromProj, toProj, 0, points.length);
+ if (!Double.isNaN(points[0][0]) && !Double.isNaN(points[0][1])) {
+ centerPoint.X = points[0][0];
+ centerPoint.Y = points[0][1];
+ } else {
+ return null;
+ }
+ } catch (Exception e) {
+ return null;
+ }
+
+ points = new double[1][];
+ PointD leftPoint = aCS.getPoints().get(0);
+ points[0] = new double[]{leftPoint.X, leftPoint.Y};
+ try {
+ Reproject.reprojectPoints(points, fromProj, toProj, 0, points.length);
+ if (!Double.isNaN(points[0][0]) && !Double.isNaN(points[0][1])) {
+ leftPoint.X = points[0][0];
+ leftPoint.Y = points[0][1];
+ } else {
+ return null;
+ }
+ } catch (Exception e) {
+ return null;
+ }
+
+ radius = Math.abs(centerPoint.X - leftPoint.X);
+ List newPoints = new ArrayList<>();
+ newPoints.add(new PointD(centerPoint.X - radius, centerPoint.Y));
+ newPoints.add(new PointD(centerPoint.X, centerPoint.Y - radius));
+ newPoints.add(new PointD(centerPoint.X + radius, centerPoint.Y));
+ newPoints.add(new PointD(centerPoint.X, centerPoint.Y + radius));
+ CircleShape newCS = new CircleShape();
+ newCS.setPoints(newPoints);
+
+ return newCS;
+ }
+
+ private EllipseShape projectEllipseShape(EllipseShape aES, ProjectionInfo fromProj, ProjectionInfo toProj) {
+ double xRadius = Math.abs(aES.getPoints().get(2).X - aES.getPoints().get(0).X) / 2;
+ double yRadius = Math.abs(aES.getPoints().get(2).Y - aES.getPoints().get(0).Y) / 2;
+ double[][] points = new double[1][];
+ PointD centerPoint = new PointD(aES.getExtent().minX + xRadius, aES.getExtent().minY + yRadius);
+ points[0] = new double[]{centerPoint.X, centerPoint.Y};
+ try {
+ Reproject.reprojectPoints(points, fromProj, toProj, 0, points.length);
+ if (!Double.isNaN(points[0][0]) && !Double.isNaN(points[0][1])) {
+ centerPoint.X = points[0][0];
+ centerPoint.Y = points[0][1];
+ } else {
+ return null;
+ }
+ } catch (Exception e) {
+ return null;
+ }
+
+ points = new double[1][];
+ PointD lbPoint = new PointD(aES.getExtent().minX, aES.getExtent().minY);
+ points[0] = new double[]{lbPoint.X, lbPoint.Y};
+ try {
+ Reproject.reprojectPoints(points, fromProj, toProj, 0, points.length);
+ if (!Double.isNaN(points[0][0]) && !Double.isNaN(points[0][1])) {
+ lbPoint.X = points[0][0];
+ lbPoint.Y = points[0][1];
+ } else {
+ return null;
+ }
+ } catch (Exception e) {
+ return null;
+ }
+
+ xRadius = Math.abs(centerPoint.X - lbPoint.X);
+ yRadius = Math.abs(centerPoint.Y - lbPoint.Y);
+ List newPoints = new ArrayList<>();
+ newPoints.add(new PointD(centerPoint.X - xRadius, centerPoint.Y - yRadius));
+ newPoints.add(new PointD(centerPoint.X - xRadius, centerPoint.Y + yRadius));
+ newPoints.add(new PointD(centerPoint.X + xRadius, centerPoint.Y + yRadius));
+ newPoints.add(new PointD(centerPoint.X + xRadius, centerPoint.Y - yRadius));
+ EllipseShape newES = new EllipseShape();
+ newES.setPoints(newPoints);
+
+ return newES;
+ }
+
+ /**
+ * Project angle
+ *
+ * @param oAngle The angle
+ * @param fromP1 From point
+ * @param toP1 To point
+ * @param fromProj From projection
+ * @param toProj To projection
+ * @return Projected angle
+ */
+ public double projectAngle(double oAngle, double[] fromP1, double[] toP1, ProjectionInfo fromProj, ProjectionInfo toProj) {
+ double pAngle = oAngle;
+ double[] fromP2;
+ double[] toP2;
+ double[][] points = new double[1][];
+
+ if (fromP1[1] == 90) {
+ fromP2 = new double[]{fromP1[0], fromP1[1] - 10};
+ points[0] = (double[]) fromP2.clone();
+ try {
+ Reproject.reprojectPoints(points, fromProj, toProj, 0, points.length);
+ toP2 = points[0];
+ double x, y;
+ x = toP2[0] - toP1[0];
+ y = toP2[1] - toP1[1];
+ double aLen = Math.sqrt(x * x + y * y);
+ double angle = Math.asin(x / aLen) * 180 / Math.PI;
+ if (x < 0 && y < 0) {
+ angle = 180.0 - angle;
+ } else if (x > 0 && y < 0) {
+ angle = 180.0 - angle;
+ } else if (x < 0 && y > 0) {
+ angle = 360.0 + angle;
+ }
+ if (aLen == 0) {
+ System.out.print("Error");
+ }
+ pAngle = oAngle + (angle - 180);
+ if (pAngle > 360) {
+ pAngle = pAngle - 360;
+ } else if (pAngle < 0) {
+ pAngle = pAngle + 360;
+ }
+ } catch (Exception e) {
+ }
+ } else {
+ fromP2 = new double[]{fromP1[0] + 10, fromP1[1]};
+ points[0] = (double[]) fromP2.clone();
+ try {
+ Reproject.reprojectPoints(points, fromProj, toProj, 0, points.length);
+ toP2 = points[0];
+
+ double x, y;
+ x = toP2[0] - toP1[0];
+ y = toP2[1] - toP1[1];
+ double aLen = Math.sqrt(x * x + y * y);
+ if (aLen == 0) {
+ return pAngle;
+ }
+
+ double angle = Math.asin(x / aLen) * 180 / Math.PI;
+ if (Double.isNaN(angle)) {
+ return pAngle;
+ }
+
+ if (x < 0 && y < 0) {
+ angle = 180.0 - angle;
+ } else if (x > 0 && y < 0) {
+ angle = 180.0 - angle;
+ } else if (x < 0 && y > 0) {
+ angle = 360.0 + angle;
+ }
+
+ pAngle = oAngle + (angle - 90);
+ if (pAngle > 360) {
+ pAngle = pAngle - 360;
+ } else if (pAngle < 0) {
+ pAngle = pAngle + 360;
+ }
+ } catch (Exception e) {
+ }
+ }
+
+ return pAngle;
+ }
+
+ private GraphicCollection projectGraphics(GraphicCollection aGCollection, ProjectionInfo fromProj, ProjectionInfo toProj) {
+ GraphicCollection newGCollection = new GraphicCollection();
+ for (Graphic aGraphic : aGCollection.getGraphics()) {
+ aGraphic.setShape(projectShape(aGraphic.getShape(), fromProj, toProj));
+ if (aGraphic.getShape() != null) {
+ newGCollection.add(aGraphic);
+ }
+ }
+
+ return newGCollection;
+ }
+
+ private List projectGraphics(List graphics, ProjectionInfo fromProj, ProjectionInfo toProj) {
+ List newGraphics = new ArrayList<>();
+ for (Graphic aGraphic : graphics) {
+ Shape aShape = projectShape(aGraphic.getShape(), fromProj, toProj);
+ if (aShape != null) {
+ newGraphics.add(new Graphic(aShape, aGraphic.getLegend()));
+ }
+ }
+
+ return newGraphics;
+ }
+
+ private Shape projectShape(Shape aShape, ProjectionInfo fromProj, ProjectionInfo toProj) {
+ Shape newShape;
+ switch (aShape.getShapeType()) {
+ case Point:
+ case PointM:
+ newShape = projectPointShape((PointShape) aShape, fromProj, toProj);
+ break;
+ case Polyline:
+ case PolylineM:
+ newShape = projectPolylineShape((PolylineShape) aShape, fromProj, toProj);
+ break;
+ case CurveLine:
+ newShape = projectCurvelineShape((CurveLineShape) aShape, fromProj, toProj);
+ break;
+ case Polygon:
+ case PolygonM:
+ case Rectangle:
+ newShape = projectPolygonShape((PolygonShape) aShape, fromProj, toProj);
+ break;
+ case CurvePolygon:
+ newShape = projectCurvePolygonShape((CurvePolygonShape) aShape, fromProj, toProj);
+ break;
+ case Circle:
+ newShape = projectCircleShape((CircleShape) aShape, fromProj, toProj);
+ break;
+ case Ellipse:
+ newShape = projectEllipseShape((EllipseShape) aShape, fromProj, toProj);
+ break;
+ default:
+ newShape = null;
+ break;
+ }
+
+ return newShape;
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/math/fitting/FittingUtil.java b/MeteoInfoLib/src/main/java/org/meteoinfo/math/fitting/FittingUtil.java
index aa24f905..7b81325d 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/math/fitting/FittingUtil.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/math/fitting/FittingUtil.java
@@ -7,6 +7,7 @@ package org.meteoinfo.math.fitting;
import java.util.ArrayList;
import java.util.List;
+
import org.meteoinfo.math.ArrayMath;
import org.meteoinfo.ndarray.Array;
import org.meteoinfo.ndarray.DataType;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/math/interpolate/InterpUtil.java b/MeteoInfoLib/src/main/java/org/meteoinfo/math/interpolate/InterpUtil.java
index 52e38ddd..801b7254 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/math/interpolate/InterpUtil.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/math/interpolate/InterpUtil.java
@@ -11,8 +11,8 @@ import org.apache.commons.math3.analysis.BivariateFunction;
import org.apache.commons.math3.analysis.UnivariateFunction;
import org.apache.commons.math3.analysis.interpolation.*;
import org.apache.commons.math3.analysis.polynomials.PolynomialSplineFunction;
+import org.meteoinfo.common.PointD;
import org.meteoinfo.geoprocess.GeoComputation;
-import org.meteoinfo.global.PointD;
import org.meteoinfo.math.ArrayUtil;
import org.meteoinfo.math.spatial.KDTree;
import org.meteoinfo.ndarray.Array;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/math/linalg/LinalgUtil.java b/MeteoInfoLib/src/main/java/org/meteoinfo/math/linalg/LinalgUtil.java
index 29b4e477..91731734 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/math/linalg/LinalgUtil.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/math/linalg/LinalgUtil.java
@@ -1,541 +1,541 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.meteoinfo.math.linalg;
-
-import java.util.List;
-import org.apache.commons.math3.fitting.leastsquares.LeastSquaresBuilder;
-import org.apache.commons.math3.fitting.leastsquares.LeastSquaresOptimizer;
-import org.apache.commons.math3.fitting.leastsquares.LeastSquaresProblem;
-import org.apache.commons.math3.fitting.leastsquares.LevenbergMarquardtOptimizer;
-import org.apache.commons.math3.fitting.leastsquares.MultivariateJacobianFunction;
-import org.apache.commons.math3.linear.Array2DRowRealMatrix;
-import org.apache.commons.math3.linear.ArrayRealVector;
-import org.apache.commons.math3.linear.CholeskyDecomposition;
-import org.apache.commons.math3.linear.DecompositionSolver;
-import org.apache.commons.math3.linear.EigenDecomposition;
-import org.apache.commons.math3.linear.LUDecomposition;
-import org.apache.commons.math3.linear.MatrixUtils;
-import org.apache.commons.math3.linear.QRDecomposition;
-import org.apache.commons.math3.linear.RealMatrix;
-import org.apache.commons.math3.linear.RealVector;
-import org.apache.commons.math3.linear.SingularValueDecomposition;
-import org.apache.commons.math3.util.Pair;
-import org.ejml.data.Complex_F64;
-import org.ejml.simple.SimpleBase;
-import org.ejml.simple.SimpleEVD;
-import org.ejml.simple.SimpleMatrix;
-import org.ejml.simple.SimpleSVD;
-import org.meteoinfo.bak.ArrayUtil;
-import org.meteoinfo.ndarray.Complex;
-import org.meteoinfo.ndarray.Array;
-import org.meteoinfo.ndarray.DataType;
-
-/**
- *
- * @author Yaqiang Wang
- */
-public class LinalgUtil {
-
- /**
- * Solve a linear matrix equation, or system of linear scalar equations.
- *
- * @param a Coefficient matrix.
- * @param b Ordinate or “dependent variable” values.
- * @return Solution to the system a x = b. Returned shape is identical to b.
- */
- public static Array solve(Array a, Array b) {
- Array r = Array.factory(DataType.DOUBLE, b.getShape());
- double[][] aa = (double[][]) ArrayUtil.copyToNDJavaArray_Double(a);
- RealMatrix coefficients = new Array2DRowRealMatrix(aa, false);
- DecompositionSolver solver = new LUDecomposition(coefficients).getSolver();
- double[] bb = (double[]) ArrayUtil.copyToNDJavaArray_Double(b);
- RealVector constants = new ArrayRealVector(bb, false);
- RealVector solution = solver.solve(constants);
- for (int i = 0; i < r.getSize(); i++) {
- r.setDouble(i, solution.getEntry(i));
- }
-
- return r;
- }
-
- /**
- * Calculates the Cholesky decomposition of a matrix. The Cholesky
- * decomposition of a real symmetric positive-definite matrix A consists of
- * a lower triangular matrix L with same size such that: A = LLT. In a
- * sense, this is the square root of A.
- *
- * @param a The given matrix.
- * @return Result array.
- */
- public static Array cholesky(Array a) {
- Array r = Array.factory(DataType.DOUBLE, a.getShape());
- double[][] aa = (double[][]) ArrayUtil.copyToNDJavaArray_Double(a);
- RealMatrix matrix = new Array2DRowRealMatrix(aa, false);
- CholeskyDecomposition decomposition = new CholeskyDecomposition(matrix);
- RealMatrix L = decomposition.getL();
- int n = L.getColumnDimension();
- int m = L.getRowDimension();
- for (int i = 0; i < m; i++) {
- for (int j = 0; j < n; j++) {
- r.setDouble(i * n + j, L.getEntry(i, j));
- }
- }
-
- return r;
- }
-
- /**
- * Calculates the LUP-decomposition of a square matrix. The
- * LUP-decomposition of a matrix A consists of three matrices L, U and P
- * that satisfy: P×A = L×U. L is lower triangular (with unit diagonal
- * terms), U is upper triangular and P is a permutation matrix. All matrices
- * are m×m.
- *
- * @param a Given matrix.
- * @return Result P/L/U arrays.
- */
- public static Array[] lu(Array a) {
- Array Pa = Array.factory(DataType.DOUBLE, a.getShape());
- Array La = Array.factory(DataType.DOUBLE, a.getShape());
- Array Ua = Array.factory(DataType.DOUBLE, a.getShape());
- double[][] aa = (double[][]) ArrayUtil.copyToNDJavaArray_Double(a);
- RealMatrix matrix = new Array2DRowRealMatrix(aa, false);
- LUDecomposition decomposition = new LUDecomposition(matrix);
- RealMatrix P = decomposition.getP();
- RealMatrix L = decomposition.getL();
- RealMatrix U = decomposition.getU();
- int n = L.getColumnDimension();
- int m = L.getRowDimension();
- for (int i = 0; i < m; i++) {
- for (int j = 0; j < n; j++) {
- Pa.setDouble(i * n + j, P.getEntry(i, j));
- La.setDouble(i * n + j, L.getEntry(i, j));
- Ua.setDouble(i * n + j, U.getEntry(i, j));
- }
- }
-
- return new Array[]{Pa, La, Ua};
- }
-
- /**
- * Calculates the QR-decomposition of a matrix. The QR-decomposition of a
- * matrix A consists of two matrices Q and R that satisfy: A = QR, Q is
- * orthogonal (QTQ = I), and R is upper triangular. If A is m×n, Q is m×m
- * and R m×n.
- *
- * @param a Given matrix.
- * @return Result Q/R arrays.
- */
- public static Array[] qr(Array a) {
- int m = a.getShape()[0];
- int n = a.getShape()[1];
- Array Qa = Array.factory(DataType.DOUBLE, new int[]{m, m});
- Array Ra = Array.factory(DataType.DOUBLE, a.getShape());
- double[][] aa = (double[][]) ArrayUtil.copyToNDJavaArray_Double(a);
- RealMatrix matrix = new Array2DRowRealMatrix(aa, false);
- QRDecomposition decomposition = new QRDecomposition(matrix);
- RealMatrix Q = decomposition.getQ();
- RealMatrix R = decomposition.getR();
- for (int i = 0; i < m; i++) {
- for (int j = 0; j < m; j++) {
- Qa.setDouble(i * m + j, Q.getEntry(i, j));
- }
- }
- for (int i = 0; i < m; i++) {
- for (int j = 0; j < n; j++) {
- Ra.setDouble(i * n + j, R.getEntry(i, j));
- }
- }
-
- return new Array[]{Qa, Ra};
- }
-
- /**
- * Calculates the compact Singular Value Decomposition of a matrix. The
- * Singular Value Decomposition of matrix A is a set of three matrices: U, Σ
- * and V such that A = U × Σ × VT. Let A be a m × n matrix, then U is a m ×
- * p orthogonal matrix, Σ is a p × p diagonal matrix with positive or null
- * elements, V is a p × n orthogonal matrix (hence VT is also orthogonal)
- * where p=min(m,n).
- *
- * @param a Given matrix.
- * @return Result U/S/V arrays.
- */
- public static Array[] svd(Array a) {
- int m = a.getShape()[0];
- int n = a.getShape()[1];
- int k = Math.min(m, n);
- Array Ua = Array.factory(DataType.DOUBLE, new int[]{m, k});
- Array Va = Array.factory(DataType.DOUBLE, new int[]{k, n});
- Array Sa = Array.factory(DataType.DOUBLE, new int[]{k});
- double[][] aa = (double[][]) ArrayUtil.copyToNDJavaArray_Double(a);
- RealMatrix matrix = new Array2DRowRealMatrix(aa, false);
- SingularValueDecomposition decomposition = new SingularValueDecomposition(matrix);
- RealMatrix U = decomposition.getU();
- RealMatrix V = decomposition.getVT();
- double[] sv = decomposition.getSingularValues();
- for (int i = 0; i < m; i++) {
- for (int j = 0; j < k; j++) {
- Ua.setDouble(i * k + j, U.getEntry(i, j));
- }
- }
- for (int i = 0; i < k; i++) {
- for (int j = 0; j < n; j++) {
- Va.setDouble(i * n + j, V.getEntry(i, j));
- }
- }
- for (int i = 0; i < k; i++) {
- Sa.setDouble(i, sv[i]);
- }
-
- return new Array[]{Ua, Sa, Va};
- }
-
-// /**
-// * Calculates the compact Singular Value Decomposition of a matrix.
-// * The Singular Value Decomposition of matrix A is a set of three matrices: U, Σ and V
-// * such that A = U × Σ × VT. Let A be a m × n matrix, then U is a m × p orthogonal
-// * matrix, Σ is a p × p diagonal matrix with positive or null elements, V is a p × n
-// * orthogonal matrix (hence VT is also orthogonal) where p=min(m,n).
-// * @param a Given matrix.
-// * @return Result U/S/V arrays.
-// */
-// public static Array[] svd_JAMA(Array a){
-// int m = a.getShape()[0];
-// int n = a.getShape()[1];
-// int k = Math.min(m, n);
-// double[][] aa = (double[][])ArrayUtil.copyToNDJavaArray_Double(a);
-// Matrix M = new Matrix(aa);
-// Jama.SingularValueDecomposition svd = M.svd();
-// Array Ua = Array.factory(DataType.DOUBLE, new int[]{m, k});
-// Array Va = Array.factory(DataType.DOUBLE, new int[]{n, n});
-// Array Sa = Array.factory(DataType.DOUBLE, new int[]{k});
-// Matrix U = svd.getU();
-// Matrix V = svd.getV();
-// double[] sv = svd.getSingularValues();
-// for (int i = 0; i < m; i++){
-// for (int j = 0; j < k; j++){
-// Ua.setDouble(i * k + j, U.get(i, j));
-// }
-// }
-// for (int i = 0; i < n; i++){
-// for (int j = 0; j < n; j++){
-// Va.setDouble(i * n + j, V.get(i, j));
-// }
-// }
-// for (int i = 0; i < k; i++){
-// Sa.setDouble(i, sv[i]);
-// }
-//
-// return new Array[]{Ua, Sa, Va};
-// }
- /**
- * Calculates the compact Singular Value Decomposition of a matrix. The
- * Singular Value Decomposition of matrix A is a set of three matrices: U, Σ
- * and V such that A = U × Σ × VT. Let A be a m × n matrix, then U is a m ×
- * p orthogonal matrix, Σ is a p × p diagonal matrix with positive or null
- * elements, V is a p × n orthogonal matrix (hence VT is also orthogonal)
- * where p=min(m,n).
- *
- * @param a Given matrix.
- * @return Result U/S/V arrays.
- */
- public static Array[] svd_EJML(Array a) {
- int m = a.getShape()[0];
- int n = a.getShape()[1];
- int k = Math.min(m, n);
- double[][] aa = (double[][]) ArrayUtil.copyToNDJavaArray_Double(a);
- SimpleMatrix M = new SimpleMatrix(aa);
- SimpleSVD svd = M.svd(false);
- Array Ua = Array.factory(DataType.DOUBLE, new int[]{m, m});
- Array Va = Array.factory(DataType.DOUBLE, new int[]{n, n});
- Array Sa = Array.factory(DataType.DOUBLE, new int[]{k});
- SimpleBase U = svd.getU();
- SimpleBase V = svd.getV();
- for (int i = 0; i < m; i++) {
- for (int j = 0; j < m; j++) {
- Ua.setDouble(i * m + j, U.get(i, j));
- }
- }
- for (int i = 0; i < n; i++) {
- for (int j = 0; j < n; j++) {
- Va.setDouble(j * n + i, V.get(i, j));
- }
- }
- for (int i = 0; i < k; i++) {
- //Sa.setDouble(i, sv[i]);
- Sa.setDouble(i, svd.getSingleValue(i));
- }
-
- return new Array[]{Ua, Sa, Va};
- }
-
- /**
- * Calculates the eigen decomposition of a real matrix. The eigen
- * decomposition of matrix A is a set of two matrices: V and D such that A =
- * V × D × VT. A, V and D are all m × m matrices.
- *
- * @param a Given matrix.
- * @return Result W/V arrays.
- */
- public static Array[] eigen_bak(Array a) {
- int m = a.getShape()[0];
- Array Wa;
- Array Va = Array.factory(DataType.DOUBLE, new int[]{m, m});
- double[][] aa = (double[][]) ArrayUtil.copyToNDJavaArray_Double(a);
- RealMatrix matrix = new Array2DRowRealMatrix(aa, false);
- EigenDecomposition decomposition = new EigenDecomposition(matrix);
- if (decomposition.hasComplexEigenvalues()) {
- Wa = Array.factory(DataType.OBJECT, new int[]{m});
- double[] rev = decomposition.getRealEigenvalues();
- double[] iev = decomposition.getImagEigenvalues();
- for (int i = 0; i < m; i++) {
- Wa.setObject(i, new Complex(rev[i], iev[i]));
- RealVector v = decomposition.getEigenvector(i);
- for (int j = 0; j < v.getDimension(); j++) {
- Va.setDouble(j * m + i, v.getEntry(j));
- }
- }
- } else {
- RealMatrix V = decomposition.getV();
- RealMatrix D = decomposition.getD();
- Wa = Array.factory(DataType.DOUBLE, new int[]{m});
- for (int i = 0; i < m; i++) {
- for (int j = 0; j < m; j++) {
- Va.setDouble(i * m + (m - j - 1), V.getEntry(i, j));
- if (i == j) {
- Wa.setDouble(m - i - 1, D.getEntry(i, j));
- }
- }
- }
- }
-
- return new Array[]{Wa, Va};
- }
-
- /**
- * Calculates the eigen decomposition of a real matrix. The eigen
- * decomposition of matrix A is a set of two matrices: V and D such that A =
- * V × D × VT. A, V and D are all m × m matrices.
- *
- * @param a Given matrix.
- * @return Result W/V arrays.
- */
- public static Array[] eigen(Array a) {
- int m = a.getShape()[0];
- Array Wa;
- Array Va = Array.factory(DataType.DOUBLE, new int[]{m, m});
- double[][] aa = (double[][]) ArrayUtil.copyToNDJavaArray_Double(a);
- RealMatrix matrix = new Array2DRowRealMatrix(aa, false);
- EigenDecomposition decomposition = new EigenDecomposition(matrix);
- double[] rev = decomposition.getRealEigenvalues();
- double[] iev = decomposition.getImagEigenvalues();
- if (decomposition.hasComplexEigenvalues()) {
- Wa = Array.factory(DataType.OBJECT, new int[]{m});
- for (int i = 0; i < m; i++) {
- Wa.setObject(i, new Complex(rev[i], iev[i]));
- RealVector v = decomposition.getEigenvector(i);
- for (int j = 0; j < v.getDimension(); j++) {
- Va.setDouble(j * m + i, v.getEntry(j));
- }
- }
- } else {
- Wa = Array.factory(DataType.DOUBLE, new int[]{m});
- for (int i = 0; i < m; i++) {
- Wa.setDouble(i, rev[m - i - 1]);
- RealVector v = decomposition.getEigenvector(m - i - 1);
- for (int j = 0; j < v.getDimension(); j++) {
- Va.setDouble(j * m + i, v.getEntry(j));
- }
- }
- }
-
- return new Array[]{Wa, Va};
- }
-
- /**
- * Calculates the eigen decomposition of a real matrix. The eigen
- * decomposition of matrix A is a set of two matrices: V and D such that A =
- * V × D × VT. A, V and D are all m × m matrices.
- *
- * @param a Given matrix.
- * @return Result W/V arrays.
- */
- public static Array[] eigen_EJML(Array a) {
- int m = a.getShape()[0];
- Array Wa;
- Array Va = Array.factory(DataType.DOUBLE, new int[]{m, m});
- double[][] aa = (double[][]) ArrayUtil.copyToNDJavaArray_Double(a);
- SimpleMatrix M = new SimpleMatrix(aa);
- SimpleEVD evd = M.eig();
- List evs = evd.getEigenvalues();
- boolean isComplex = evd.getEigenVector(0) == null;
- if (isComplex) {
- Wa = Array.factory(DataType.OBJECT, new int[]{m});
- } else {
- Wa = Array.factory(DataType.DOUBLE, new int[]{m});
- }
- for (int i = 0; i < m; i++) {
- if (isComplex) {
- Wa.setObject(i, new Complex(evs.get(i).real, evs.get(i).imaginary));
- } else {
- Wa.setDouble(i, evs.get(m - i - 1).real);
- SimpleBase v = evd.getEigenVector(m - i - 1);
- for (int j = 0; j < v.getNumElements(); j++) {
- Va.setDouble(j * m + i, v.get(j));
- }
- }
- }
-
- return new Array[]{Wa, Va};
- }
-
- /**
- * Calculate inverse matrix
- *
- * @param a The matrix
- * @return Inverse matrix array
- */
- public static Array inv(Array a) {
- double[][] aa = (double[][]) ArrayUtil.copyToNDJavaArray_Double(a);
- RealMatrix matrix = new Array2DRowRealMatrix(aa, false);
- RealMatrix invm = MatrixUtils.inverse(matrix);
- if (invm == null) {
- return null;
- }
-
- int m = invm.getRowDimension();
- int n = invm.getColumnDimension();
- Array r = Array.factory(DataType.DOUBLE, new int[]{m, n});
- for (int i = 0; i < m; i++) {
- for (int j = 0; j < n; j++) {
- r.setDouble(i * n + j, invm.getEntry(i, j));
- }
- }
-
- return r;
- }
-
- /**
- * Not correct at present !!!
- *
- * @param a
- * @param b
- * @return
- */
- public static Array lstsq(Array a, Array b) {
- final double[][] aa = (double[][]) ArrayUtil.copyToNDJavaArray_Double(a);
- final double[] bb = (double[]) ArrayUtil.copyToNDJavaArray_Double(b);
-
- // the model function
- MultivariateJacobianFunction function = new MultivariateJacobianFunction() {
- @Override
- public Pair value(final RealVector point) {
- RealVector value = new ArrayRealVector(bb.length);
- RealMatrix jacobian = new Array2DRowRealMatrix(aa, false);
- for (int i = 0; i < bb.length; ++i) {
-
- }
- return new Pair<>(value, jacobian);
-
- }
- };
-
- // least squares problem to solve
- LeastSquaresProblem problem = new LeastSquaresBuilder().
- //start(new double[]{100.0, 50.0}).
- model(function).
- target(bb).
- lazyEvaluation(false).
- maxEvaluations(1000).
- maxIterations(1000).
- build();
- LeastSquaresOptimizer.Optimum optimum = new LevenbergMarquardtOptimizer().optimize(problem);
-
- RealVector r = optimum.getPoint();
- int n = r.getDimension();
- Array x = Array.factory(DataType.DOUBLE, new int[]{n});
- for (int i = 0; i < n; i++) {
- x.setDouble(i, r.getEntry(i));
- }
-
- return x;
- }
-
- // Function to get cofactor of
- // mat[p][q] in temp[][]. n is
- // current dimension of mat[][]
- public static void getCofactor(double mat[][],
- double temp[][], int p, int q, int n) {
- int i = 0, j = 0;
-
- // Looping for each element of
- // the matrix
- for (int row = 0; row < n; row++) {
- for (int col = 0; col < n; col++) {
-
- // Copying into temporary matrix
- // only those element which are
- // not in given row and column
- if (row != p && col != q) {
- temp[i][j++] = mat[row][col];
-
- // Row is filled, so increase
- // row index and reset col
- //index
- if (j == n - 1) {
- j = 0;
- i++;
- }
- }
- }
- }
- }
-
- /* Recursive function for finding determinant
- of matrix. n is current dimension of mat[][]. */
- public static double determinantOfMatrix(double mat[][], int n, int N) {
- int D = 0; // Initialize result
-
- // Base case : if matrix contains single
- // element
- if (n == 1) {
- return mat[0][0];
- }
-
- // To store cofactors
- double temp[][] = new double[N][N];
-
- // To store sign multiplier
- int sign = 1;
-
- // Iterate for each element of first row
- for (int f = 0; f < n; f++) {
- // Getting Cofactor of mat[0][f]
- getCofactor(mat, temp, 0, f, n);
- D += sign * mat[0][f]
- * determinantOfMatrix(temp, n - 1, N);
-
- // terms are to be added with
- // alternate sign
- sign = -sign;
- }
-
- return D;
- }
-
- /**
- * Calculate determinant of a matrix array
- *
- * @param mat Input array
- * @return Determinant
- */
- public static double determinantOfMatrix(Array mat) {
- int n = mat.getShape()[0];
- double[][] a = (double[][]) ArrayUtil.copyToNDJavaArray_Double(mat);
- return determinantOfMatrix(a, n, n);
- }
-}
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.meteoinfo.math.linalg;
+
+import java.util.List;
+import org.apache.commons.math3.fitting.leastsquares.LeastSquaresBuilder;
+import org.apache.commons.math3.fitting.leastsquares.LeastSquaresOptimizer;
+import org.apache.commons.math3.fitting.leastsquares.LeastSquaresProblem;
+import org.apache.commons.math3.fitting.leastsquares.LevenbergMarquardtOptimizer;
+import org.apache.commons.math3.fitting.leastsquares.MultivariateJacobianFunction;
+import org.apache.commons.math3.linear.Array2DRowRealMatrix;
+import org.apache.commons.math3.linear.ArrayRealVector;
+import org.apache.commons.math3.linear.CholeskyDecomposition;
+import org.apache.commons.math3.linear.DecompositionSolver;
+import org.apache.commons.math3.linear.EigenDecomposition;
+import org.apache.commons.math3.linear.LUDecomposition;
+import org.apache.commons.math3.linear.MatrixUtils;
+import org.apache.commons.math3.linear.QRDecomposition;
+import org.apache.commons.math3.linear.RealMatrix;
+import org.apache.commons.math3.linear.RealVector;
+import org.apache.commons.math3.linear.SingularValueDecomposition;
+import org.apache.commons.math3.util.Pair;
+import org.ejml.data.Complex_F64;
+import org.ejml.simple.SimpleBase;
+import org.ejml.simple.SimpleEVD;
+import org.ejml.simple.SimpleMatrix;
+import org.ejml.simple.SimpleSVD;
+import org.meteoinfo.math.ArrayUtil;
+import org.meteoinfo.ndarray.Complex;
+import org.meteoinfo.ndarray.Array;
+import org.meteoinfo.ndarray.DataType;
+
+/**
+ *
+ * @author Yaqiang Wang
+ */
+public class LinalgUtil {
+
+ /**
+ * Solve a linear matrix equation, or system of linear scalar equations.
+ *
+ * @param a Coefficient matrix.
+ * @param b Ordinate or “dependent variable” values.
+ * @return Solution to the system a x = b. Returned shape is identical to b.
+ */
+ public static Array solve(Array a, Array b) {
+ Array r = Array.factory(DataType.DOUBLE, b.getShape());
+ double[][] aa = (double[][]) ArrayUtil.copyToNDJavaArray_Double(a);
+ RealMatrix coefficients = new Array2DRowRealMatrix(aa, false);
+ DecompositionSolver solver = new LUDecomposition(coefficients).getSolver();
+ double[] bb = (double[]) ArrayUtil.copyToNDJavaArray_Double(b);
+ RealVector constants = new ArrayRealVector(bb, false);
+ RealVector solution = solver.solve(constants);
+ for (int i = 0; i < r.getSize(); i++) {
+ r.setDouble(i, solution.getEntry(i));
+ }
+
+ return r;
+ }
+
+ /**
+ * Calculates the Cholesky decomposition of a matrix. The Cholesky
+ * decomposition of a real symmetric positive-definite matrix A consists of
+ * a lower triangular matrix L with same size such that: A = LLT. In a
+ * sense, this is the square root of A.
+ *
+ * @param a The given matrix.
+ * @return Result array.
+ */
+ public static Array cholesky(Array a) {
+ Array r = Array.factory(DataType.DOUBLE, a.getShape());
+ double[][] aa = (double[][]) ArrayUtil.copyToNDJavaArray_Double(a);
+ RealMatrix matrix = new Array2DRowRealMatrix(aa, false);
+ CholeskyDecomposition decomposition = new CholeskyDecomposition(matrix);
+ RealMatrix L = decomposition.getL();
+ int n = L.getColumnDimension();
+ int m = L.getRowDimension();
+ for (int i = 0; i < m; i++) {
+ for (int j = 0; j < n; j++) {
+ r.setDouble(i * n + j, L.getEntry(i, j));
+ }
+ }
+
+ return r;
+ }
+
+ /**
+ * Calculates the LUP-decomposition of a square matrix. The
+ * LUP-decomposition of a matrix A consists of three matrices L, U and P
+ * that satisfy: P×A = L×U. L is lower triangular (with unit diagonal
+ * terms), U is upper triangular and P is a permutation matrix. All matrices
+ * are m×m.
+ *
+ * @param a Given matrix.
+ * @return Result P/L/U arrays.
+ */
+ public static Array[] lu(Array a) {
+ Array Pa = Array.factory(DataType.DOUBLE, a.getShape());
+ Array La = Array.factory(DataType.DOUBLE, a.getShape());
+ Array Ua = Array.factory(DataType.DOUBLE, a.getShape());
+ double[][] aa = (double[][]) ArrayUtil.copyToNDJavaArray_Double(a);
+ RealMatrix matrix = new Array2DRowRealMatrix(aa, false);
+ LUDecomposition decomposition = new LUDecomposition(matrix);
+ RealMatrix P = decomposition.getP();
+ RealMatrix L = decomposition.getL();
+ RealMatrix U = decomposition.getU();
+ int n = L.getColumnDimension();
+ int m = L.getRowDimension();
+ for (int i = 0; i < m; i++) {
+ for (int j = 0; j < n; j++) {
+ Pa.setDouble(i * n + j, P.getEntry(i, j));
+ La.setDouble(i * n + j, L.getEntry(i, j));
+ Ua.setDouble(i * n + j, U.getEntry(i, j));
+ }
+ }
+
+ return new Array[]{Pa, La, Ua};
+ }
+
+ /**
+ * Calculates the QR-decomposition of a matrix. The QR-decomposition of a
+ * matrix A consists of two matrices Q and R that satisfy: A = QR, Q is
+ * orthogonal (QTQ = I), and R is upper triangular. If A is m×n, Q is m×m
+ * and R m×n.
+ *
+ * @param a Given matrix.
+ * @return Result Q/R arrays.
+ */
+ public static Array[] qr(Array a) {
+ int m = a.getShape()[0];
+ int n = a.getShape()[1];
+ Array Qa = Array.factory(DataType.DOUBLE, new int[]{m, m});
+ Array Ra = Array.factory(DataType.DOUBLE, a.getShape());
+ double[][] aa = (double[][]) ArrayUtil.copyToNDJavaArray_Double(a);
+ RealMatrix matrix = new Array2DRowRealMatrix(aa, false);
+ QRDecomposition decomposition = new QRDecomposition(matrix);
+ RealMatrix Q = decomposition.getQ();
+ RealMatrix R = decomposition.getR();
+ for (int i = 0; i < m; i++) {
+ for (int j = 0; j < m; j++) {
+ Qa.setDouble(i * m + j, Q.getEntry(i, j));
+ }
+ }
+ for (int i = 0; i < m; i++) {
+ for (int j = 0; j < n; j++) {
+ Ra.setDouble(i * n + j, R.getEntry(i, j));
+ }
+ }
+
+ return new Array[]{Qa, Ra};
+ }
+
+ /**
+ * Calculates the compact Singular Value Decomposition of a matrix. The
+ * Singular Value Decomposition of matrix A is a set of three matrices: U, Σ
+ * and V such that A = U × Σ × VT. Let A be a m × n matrix, then U is a m ×
+ * p orthogonal matrix, Σ is a p × p diagonal matrix with positive or null
+ * elements, V is a p × n orthogonal matrix (hence VT is also orthogonal)
+ * where p=min(m,n).
+ *
+ * @param a Given matrix.
+ * @return Result U/S/V arrays.
+ */
+ public static Array[] svd(Array a) {
+ int m = a.getShape()[0];
+ int n = a.getShape()[1];
+ int k = Math.min(m, n);
+ Array Ua = Array.factory(DataType.DOUBLE, new int[]{m, k});
+ Array Va = Array.factory(DataType.DOUBLE, new int[]{k, n});
+ Array Sa = Array.factory(DataType.DOUBLE, new int[]{k});
+ double[][] aa = (double[][]) ArrayUtil.copyToNDJavaArray_Double(a);
+ RealMatrix matrix = new Array2DRowRealMatrix(aa, false);
+ SingularValueDecomposition decomposition = new SingularValueDecomposition(matrix);
+ RealMatrix U = decomposition.getU();
+ RealMatrix V = decomposition.getVT();
+ double[] sv = decomposition.getSingularValues();
+ for (int i = 0; i < m; i++) {
+ for (int j = 0; j < k; j++) {
+ Ua.setDouble(i * k + j, U.getEntry(i, j));
+ }
+ }
+ for (int i = 0; i < k; i++) {
+ for (int j = 0; j < n; j++) {
+ Va.setDouble(i * n + j, V.getEntry(i, j));
+ }
+ }
+ for (int i = 0; i < k; i++) {
+ Sa.setDouble(i, sv[i]);
+ }
+
+ return new Array[]{Ua, Sa, Va};
+ }
+
+// /**
+// * Calculates the compact Singular Value Decomposition of a matrix.
+// * The Singular Value Decomposition of matrix A is a set of three matrices: U, Σ and V
+// * such that A = U × Σ × VT. Let A be a m × n matrix, then U is a m × p orthogonal
+// * matrix, Σ is a p × p diagonal matrix with positive or null elements, V is a p × n
+// * orthogonal matrix (hence VT is also orthogonal) where p=min(m,n).
+// * @param a Given matrix.
+// * @return Result U/S/V arrays.
+// */
+// public static Array[] svd_JAMA(Array a){
+// int m = a.getShape()[0];
+// int n = a.getShape()[1];
+// int k = Math.min(m, n);
+// double[][] aa = (double[][])ArrayUtil.copyToNDJavaArray_Double(a);
+// Matrix M = new Matrix(aa);
+// Jama.SingularValueDecomposition svd = M.svd();
+// Array Ua = Array.factory(DataType.DOUBLE, new int[]{m, k});
+// Array Va = Array.factory(DataType.DOUBLE, new int[]{n, n});
+// Array Sa = Array.factory(DataType.DOUBLE, new int[]{k});
+// Matrix U = svd.getU();
+// Matrix V = svd.getV();
+// double[] sv = svd.getSingularValues();
+// for (int i = 0; i < m; i++){
+// for (int j = 0; j < k; j++){
+// Ua.setDouble(i * k + j, U.get(i, j));
+// }
+// }
+// for (int i = 0; i < n; i++){
+// for (int j = 0; j < n; j++){
+// Va.setDouble(i * n + j, V.get(i, j));
+// }
+// }
+// for (int i = 0; i < k; i++){
+// Sa.setDouble(i, sv[i]);
+// }
+//
+// return new Array[]{Ua, Sa, Va};
+// }
+ /**
+ * Calculates the compact Singular Value Decomposition of a matrix. The
+ * Singular Value Decomposition of matrix A is a set of three matrices: U, Σ
+ * and V such that A = U × Σ × VT. Let A be a m × n matrix, then U is a m ×
+ * p orthogonal matrix, Σ is a p × p diagonal matrix with positive or null
+ * elements, V is a p × n orthogonal matrix (hence VT is also orthogonal)
+ * where p=min(m,n).
+ *
+ * @param a Given matrix.
+ * @return Result U/S/V arrays.
+ */
+ public static Array[] svd_EJML(Array a) {
+ int m = a.getShape()[0];
+ int n = a.getShape()[1];
+ int k = Math.min(m, n);
+ double[][] aa = (double[][]) ArrayUtil.copyToNDJavaArray_Double(a);
+ SimpleMatrix M = new SimpleMatrix(aa);
+ SimpleSVD svd = M.svd(false);
+ Array Ua = Array.factory(DataType.DOUBLE, new int[]{m, m});
+ Array Va = Array.factory(DataType.DOUBLE, new int[]{n, n});
+ Array Sa = Array.factory(DataType.DOUBLE, new int[]{k});
+ SimpleBase U = svd.getU();
+ SimpleBase V = svd.getV();
+ for (int i = 0; i < m; i++) {
+ for (int j = 0; j < m; j++) {
+ Ua.setDouble(i * m + j, U.get(i, j));
+ }
+ }
+ for (int i = 0; i < n; i++) {
+ for (int j = 0; j < n; j++) {
+ Va.setDouble(j * n + i, V.get(i, j));
+ }
+ }
+ for (int i = 0; i < k; i++) {
+ //Sa.setDouble(i, sv[i]);
+ Sa.setDouble(i, svd.getSingleValue(i));
+ }
+
+ return new Array[]{Ua, Sa, Va};
+ }
+
+ /**
+ * Calculates the eigen decomposition of a real matrix. The eigen
+ * decomposition of matrix A is a set of two matrices: V and D such that A =
+ * V × D × VT. A, V and D are all m × m matrices.
+ *
+ * @param a Given matrix.
+ * @return Result W/V arrays.
+ */
+ public static Array[] eigen_bak(Array a) {
+ int m = a.getShape()[0];
+ Array Wa;
+ Array Va = Array.factory(DataType.DOUBLE, new int[]{m, m});
+ double[][] aa = (double[][]) ArrayUtil.copyToNDJavaArray_Double(a);
+ RealMatrix matrix = new Array2DRowRealMatrix(aa, false);
+ EigenDecomposition decomposition = new EigenDecomposition(matrix);
+ if (decomposition.hasComplexEigenvalues()) {
+ Wa = Array.factory(DataType.OBJECT, new int[]{m});
+ double[] rev = decomposition.getRealEigenvalues();
+ double[] iev = decomposition.getImagEigenvalues();
+ for (int i = 0; i < m; i++) {
+ Wa.setObject(i, new Complex(rev[i], iev[i]));
+ RealVector v = decomposition.getEigenvector(i);
+ for (int j = 0; j < v.getDimension(); j++) {
+ Va.setDouble(j * m + i, v.getEntry(j));
+ }
+ }
+ } else {
+ RealMatrix V = decomposition.getV();
+ RealMatrix D = decomposition.getD();
+ Wa = Array.factory(DataType.DOUBLE, new int[]{m});
+ for (int i = 0; i < m; i++) {
+ for (int j = 0; j < m; j++) {
+ Va.setDouble(i * m + (m - j - 1), V.getEntry(i, j));
+ if (i == j) {
+ Wa.setDouble(m - i - 1, D.getEntry(i, j));
+ }
+ }
+ }
+ }
+
+ return new Array[]{Wa, Va};
+ }
+
+ /**
+ * Calculates the eigen decomposition of a real matrix. The eigen
+ * decomposition of matrix A is a set of two matrices: V and D such that A =
+ * V × D × VT. A, V and D are all m × m matrices.
+ *
+ * @param a Given matrix.
+ * @return Result W/V arrays.
+ */
+ public static Array[] eigen(Array a) {
+ int m = a.getShape()[0];
+ Array Wa;
+ Array Va = Array.factory(DataType.DOUBLE, new int[]{m, m});
+ double[][] aa = (double[][]) ArrayUtil.copyToNDJavaArray_Double(a);
+ RealMatrix matrix = new Array2DRowRealMatrix(aa, false);
+ EigenDecomposition decomposition = new EigenDecomposition(matrix);
+ double[] rev = decomposition.getRealEigenvalues();
+ double[] iev = decomposition.getImagEigenvalues();
+ if (decomposition.hasComplexEigenvalues()) {
+ Wa = Array.factory(DataType.OBJECT, new int[]{m});
+ for (int i = 0; i < m; i++) {
+ Wa.setObject(i, new Complex(rev[i], iev[i]));
+ RealVector v = decomposition.getEigenvector(i);
+ for (int j = 0; j < v.getDimension(); j++) {
+ Va.setDouble(j * m + i, v.getEntry(j));
+ }
+ }
+ } else {
+ Wa = Array.factory(DataType.DOUBLE, new int[]{m});
+ for (int i = 0; i < m; i++) {
+ Wa.setDouble(i, rev[m - i - 1]);
+ RealVector v = decomposition.getEigenvector(m - i - 1);
+ for (int j = 0; j < v.getDimension(); j++) {
+ Va.setDouble(j * m + i, v.getEntry(j));
+ }
+ }
+ }
+
+ return new Array[]{Wa, Va};
+ }
+
+ /**
+ * Calculates the eigen decomposition of a real matrix. The eigen
+ * decomposition of matrix A is a set of two matrices: V and D such that A =
+ * V × D × VT. A, V and D are all m × m matrices.
+ *
+ * @param a Given matrix.
+ * @return Result W/V arrays.
+ */
+ public static Array[] eigen_EJML(Array a) {
+ int m = a.getShape()[0];
+ Array Wa;
+ Array Va = Array.factory(DataType.DOUBLE, new int[]{m, m});
+ double[][] aa = (double[][]) ArrayUtil.copyToNDJavaArray_Double(a);
+ SimpleMatrix M = new SimpleMatrix(aa);
+ SimpleEVD evd = M.eig();
+ List evs = evd.getEigenvalues();
+ boolean isComplex = evd.getEigenVector(0) == null;
+ if (isComplex) {
+ Wa = Array.factory(DataType.OBJECT, new int[]{m});
+ } else {
+ Wa = Array.factory(DataType.DOUBLE, new int[]{m});
+ }
+ for (int i = 0; i < m; i++) {
+ if (isComplex) {
+ Wa.setObject(i, new Complex(evs.get(i).real, evs.get(i).imaginary));
+ } else {
+ Wa.setDouble(i, evs.get(m - i - 1).real);
+ SimpleBase v = evd.getEigenVector(m - i - 1);
+ for (int j = 0; j < v.getNumElements(); j++) {
+ Va.setDouble(j * m + i, v.get(j));
+ }
+ }
+ }
+
+ return new Array[]{Wa, Va};
+ }
+
+ /**
+ * Calculate inverse matrix
+ *
+ * @param a The matrix
+ * @return Inverse matrix array
+ */
+ public static Array inv(Array a) {
+ double[][] aa = (double[][]) ArrayUtil.copyToNDJavaArray_Double(a);
+ RealMatrix matrix = new Array2DRowRealMatrix(aa, false);
+ RealMatrix invm = MatrixUtils.inverse(matrix);
+ if (invm == null) {
+ return null;
+ }
+
+ int m = invm.getRowDimension();
+ int n = invm.getColumnDimension();
+ Array r = Array.factory(DataType.DOUBLE, new int[]{m, n});
+ for (int i = 0; i < m; i++) {
+ for (int j = 0; j < n; j++) {
+ r.setDouble(i * n + j, invm.getEntry(i, j));
+ }
+ }
+
+ return r;
+ }
+
+ /**
+ * Not correct at present !!!
+ *
+ * @param a
+ * @param b
+ * @return
+ */
+ public static Array lstsq(Array a, Array b) {
+ final double[][] aa = (double[][]) ArrayUtil.copyToNDJavaArray_Double(a);
+ final double[] bb = (double[]) ArrayUtil.copyToNDJavaArray_Double(b);
+
+ // the model function
+ MultivariateJacobianFunction function = new MultivariateJacobianFunction() {
+ @Override
+ public Pair value(final RealVector point) {
+ RealVector value = new ArrayRealVector(bb.length);
+ RealMatrix jacobian = new Array2DRowRealMatrix(aa, false);
+ for (int i = 0; i < bb.length; ++i) {
+
+ }
+ return new Pair<>(value, jacobian);
+
+ }
+ };
+
+ // least squares problem to solve
+ LeastSquaresProblem problem = new LeastSquaresBuilder().
+ //start(new double[]{100.0, 50.0}).
+ model(function).
+ target(bb).
+ lazyEvaluation(false).
+ maxEvaluations(1000).
+ maxIterations(1000).
+ build();
+ LeastSquaresOptimizer.Optimum optimum = new LevenbergMarquardtOptimizer().optimize(problem);
+
+ RealVector r = optimum.getPoint();
+ int n = r.getDimension();
+ Array x = Array.factory(DataType.DOUBLE, new int[]{n});
+ for (int i = 0; i < n; i++) {
+ x.setDouble(i, r.getEntry(i));
+ }
+
+ return x;
+ }
+
+ // Function to get cofactor of
+ // mat[p][q] in temp[][]. n is
+ // current dimension of mat[][]
+ public static void getCofactor(double mat[][],
+ double temp[][], int p, int q, int n) {
+ int i = 0, j = 0;
+
+ // Looping for each element of
+ // the matrix
+ for (int row = 0; row < n; row++) {
+ for (int col = 0; col < n; col++) {
+
+ // Copying into temporary matrix
+ // only those element which are
+ // not in given row and column
+ if (row != p && col != q) {
+ temp[i][j++] = mat[row][col];
+
+ // Row is filled, so increase
+ // row index and reset col
+ //index
+ if (j == n - 1) {
+ j = 0;
+ i++;
+ }
+ }
+ }
+ }
+ }
+
+ /* Recursive function for finding determinant
+ of matrix. n is current dimension of mat[][]. */
+ public static double determinantOfMatrix(double mat[][], int n, int N) {
+ int D = 0; // Initialize result
+
+ // Base case : if matrix contains single
+ // element
+ if (n == 1) {
+ return mat[0][0];
+ }
+
+ // To store cofactors
+ double temp[][] = new double[N][N];
+
+ // To store sign multiplier
+ int sign = 1;
+
+ // Iterate for each element of first row
+ for (int f = 0; f < n; f++) {
+ // Getting Cofactor of mat[0][f]
+ getCofactor(mat, temp, 0, f, n);
+ D += sign * mat[0][f]
+ * determinantOfMatrix(temp, n - 1, N);
+
+ // terms are to be added with
+ // alternate sign
+ sign = -sign;
+ }
+
+ return D;
+ }
+
+ /**
+ * Calculate determinant of a matrix array
+ *
+ * @param mat Input array
+ * @return Determinant
+ */
+ public static double determinantOfMatrix(Array mat) {
+ int n = mat.getShape()[0];
+ double[][] a = (double[][]) ArrayUtil.copyToNDJavaArray_Double(mat);
+ return determinantOfMatrix(a, n, n);
+ }
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/math/meteo/MeteoMath.java b/MeteoInfoLib/src/main/java/org/meteoinfo/math/meteo/MeteoMath.java
index 63fad5a8..7bad3919 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/math/meteo/MeteoMath.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/math/meteo/MeteoMath.java
@@ -6,14 +6,12 @@
package org.meteoinfo.math.meteo;
import org.meteoinfo.math.ArrayMath;
-import org.meteoinfo.math.ArrayUtil;
import org.meteoinfo.ndarray.Array;
import org.meteoinfo.ndarray.Index;
import org.meteoinfo.ndarray.DataType;
import org.meteoinfo.ndarray.IndexIterator;
import java.util.Arrays;
-import java.util.List;
/**
*
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/plot/PlotUtil.java b/MeteoInfoLib/src/main/java/org/meteoinfo/plot/PlotUtil.java
index 13685304..93000efe 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/plot/PlotUtil.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/plot/PlotUtil.java
@@ -1,99 +1,96 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.meteoinfo.plot;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import javax.print.PrintException;
-import org.meteoinfo.chart.Chart;
-import org.meteoinfo.chart.ChartPanel;
-import org.meteoinfo.chart.plot.ChartPlotMethod;
-import org.meteoinfo.chart.plot.XY1DPlot;
-import org.meteoinfo.data.StationData;
-import org.meteoinfo.data.XYArrayDataset;
-import org.meteoinfo.data.XYDataset;
-import org.meteoinfo.global.MIMath;
-import org.meteoinfo.legend.PointBreak;
-
-/**
- *
- * @author yaqiang
- */
-public class PlotUtil {
-
- /**
- * Get XYDataset from two StationData
- *
- * @param xdata X station data
- * @param ydata Y station data
- * @param seriesKey Series key
- * @return XYDataset XYDataset
- */
- public static XYDataset getXYDataset(StationData xdata, StationData ydata, String seriesKey) {
- List xvs = new ArrayList<>();
- List yvs = new ArrayList<>();
- double x, y;
- int n = xdata.getStNum();
- for (int i = 0; i < n; i++) {
- x = xdata.data[i][2];
- if (MIMath.doubleEquals(x, xdata.missingValue)) {
- continue;
- }
- y = ydata.data[i][2];
- if (MIMath.doubleEquals(y, ydata.missingValue)) {
- continue;
- }
- xvs.add(x);
- yvs.add(y);
- }
-
- return new XYArrayDataset(xvs, yvs, seriesKey);
- }
-
- /**
- * Create scatter plot
- *
- * @param title Title
- * @param xAxisLabel X axis label
- * @param yAxisLabel Y axis label
- * @param dataset XYDataset
- * @return JFreeChart
- */
- public static Chart createScatterPlot(String title, String xAxisLabel, String yAxisLabel, XYDataset dataset) {
- XY1DPlot plot = new XY1DPlot(dataset);
- plot.setTitle(title);
- plot.setChartPlotMethod(ChartPlotMethod.POINT);
- PointBreak pb = new PointBreak();
- plot.setLegendBreak(0, pb);
- plot.getXAxis().setLabel(xAxisLabel);
- plot.getYAxis().setLabel(yAxisLabel);
- Chart chart = new Chart(plot, null);
-
- return chart;
- }
-
- /**
- * Save chart as PNG image file
- *
- * @param fileName The file name
- * @param chart The chart
- * @param width Width
- * @param height Heigth
- * @throws java.io.FileNotFoundException
- * @throws java.lang.InterruptedException
- */
- public static void exportToPicture(String fileName, Chart chart, int width, int height)
- throws FileNotFoundException, InterruptedException {
- ChartPanel cp = new ChartPanel(chart);
- cp.setSize(width, height);
- cp.paintGraphics();
- cp.saveImage(fileName);
- }
-}
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.meteoinfo.plot;
+
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.meteoinfo.chart.Chart;
+import org.meteoinfo.chart.ChartPanel;
+import org.meteoinfo.chart.plot.ChartPlotMethod;
+import org.meteoinfo.chart.plot.XY1DPlot;
+import org.meteoinfo.common.MIMath;
+import org.meteoinfo.data.StationData;
+import org.meteoinfo.data.XYArrayDataset;
+import org.meteoinfo.data.XYDataset;
+import org.meteoinfo.legend.PointBreak;
+
+/**
+ *
+ * @author yaqiang
+ */
+public class PlotUtil {
+
+ /**
+ * Get XYDataset from two StationData
+ *
+ * @param xdata X station data
+ * @param ydata Y station data
+ * @param seriesKey Series key
+ * @return XYDataset XYDataset
+ */
+ public static XYDataset getXYDataset(StationData xdata, StationData ydata, String seriesKey) {
+ List xvs = new ArrayList<>();
+ List yvs = new ArrayList<>();
+ double x, y;
+ int n = xdata.getStNum();
+ for (int i = 0; i < n; i++) {
+ x = xdata.data[i][2];
+ if (MIMath.doubleEquals(x, xdata.missingValue)) {
+ continue;
+ }
+ y = ydata.data[i][2];
+ if (MIMath.doubleEquals(y, ydata.missingValue)) {
+ continue;
+ }
+ xvs.add(x);
+ yvs.add(y);
+ }
+
+ return new XYArrayDataset(xvs, yvs, seriesKey);
+ }
+
+ /**
+ * Create scatter plot
+ *
+ * @param title Title
+ * @param xAxisLabel X axis label
+ * @param yAxisLabel Y axis label
+ * @param dataset XYDataset
+ * @return JFreeChart
+ */
+ public static Chart createScatterPlot(String title, String xAxisLabel, String yAxisLabel, XYDataset dataset) {
+ XY1DPlot plot = new XY1DPlot(dataset);
+ plot.setTitle(title);
+ plot.setChartPlotMethod(ChartPlotMethod.POINT);
+ PointBreak pb = new PointBreak();
+ plot.setLegendBreak(0, pb);
+ plot.getXAxis().setLabel(xAxisLabel);
+ plot.getYAxis().setLabel(yAxisLabel);
+ Chart chart = new Chart(plot, null);
+
+ return chart;
+ }
+
+ /**
+ * Save chart as PNG image file
+ *
+ * @param fileName The file name
+ * @param chart The chart
+ * @param width Width
+ * @param height Heigth
+ * @throws java.io.FileNotFoundException
+ * @throws java.lang.InterruptedException
+ */
+ public static void exportToPicture(String fileName, Chart chart, int width, int height)
+ throws FileNotFoundException, InterruptedException {
+ ChartPanel cp = new ChartPanel(chart);
+ cp.setSize(width, height);
+ cp.paintGraphics();
+ cp.saveImage(fileName);
+ }
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/projection/ProjectionUtil.java b/MeteoInfoLib/src/main/java/org/meteoinfo/projection/ProjectionUtil.java
index 49dc3091..7cfc5d3c 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/projection/ProjectionUtil.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/projection/ProjectionUtil.java
@@ -13,6 +13,10 @@
*/
package org.meteoinfo.projection;
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.MIMath;
+import org.meteoinfo.common.PointD;
+import org.meteoinfo.geoprocess.GeometryUtil;
import org.meteoinfo.math.ArrayUtil;
import org.meteoinfo.ndarray.Array;
import org.meteoinfo.projection.info.ProjectionInfo;
@@ -22,9 +26,6 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import org.meteoinfo.data.mapdata.Field;
import org.meteoinfo.geoprocess.GeoComputation;
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.global.MIMath;
-import org.meteoinfo.global.PointD;
import org.meteoinfo.layer.RasterLayer;
import org.meteoinfo.layer.VectorLayer;
import org.meteoinfo.map.ProjectionSet;
@@ -678,7 +679,7 @@ public class ProjectionUtil {
}
}
oLayer.setShapes(new ArrayList<>(shapePoints));
- oLayer.setExtent(MIMath.getPointsExtent(newPoints));
+ oLayer.setExtent(GeometryUtil.getPointsExtent(newPoints));
break;
case Polyline:
@@ -957,7 +958,7 @@ public class ProjectionUtil {
}
}
aLayer.setShapes(new ArrayList<>(vectors));
- aLayer.setExtent(MIMath.getPointsExtent(newPoints));
+ aLayer.setExtent(GeometryUtil.getPointsExtent(newPoints));
aLayer.getAttributeTable().setTable(aTable);
return aLayer;
@@ -1057,7 +1058,7 @@ public class ProjectionUtil {
}
}
oLayer.setShapes(new ArrayList<>(shapes));
- oLayer.setExtent(MIMath.getPointsExtent(newPoints));
+ oLayer.setExtent(GeometryUtil.getPointsExtent(newPoints));
oLayer.getAttributeTable().setTable(aTable);
if (oLayer.getLabelPoints().size() > 0) {
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/projection/Reproject.java b/MeteoInfoLib/src/main/java/org/meteoinfo/projection/Reproject.java
index ac1ecf81..dea26646 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/projection/Reproject.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/projection/Reproject.java
@@ -17,12 +17,12 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.PointD;
import org.meteoinfo.geoprocess.GeometryUtil;
import org.meteoinfo.geoprocess.analysis.ResampleMethods;
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.projection.info.ProjectionInfo;
-import org.meteoinfo.global.PointD;
import org.meteoinfo.math.ArrayUtil;
+import org.meteoinfo.projection.info.ProjectionInfo;
import org.meteoinfo.ndarray.Array;
import org.meteoinfo.ndarray.DataType;
import org.meteoinfo.ndarray.Index;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/Albers.java b/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/Albers.java
index 272900e6..49650240 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/Albers.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/Albers.java
@@ -1,94 +1,94 @@
-/* Copyright 2012 - Yaqiang Wang,
- * yaqiang.wang@gmail.com
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.projection.info;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.locationtech.proj4j.CoordinateReferenceSystem;
-import org.meteoinfo.global.PointD;
-import org.meteoinfo.projection.KnownCoordinateSystems;
-import org.meteoinfo.projection.ProjectionNames;
-import org.meteoinfo.projection.ProjectionUtil;
-import org.meteoinfo.shape.PolygonShape;
-
-/**
- *
- * @author Yaqiang Wang
- */
-public class Albers extends ProjectionInfo {
-
- //
- //
- //
- /**
- * Construction
- *
- * @param crs Coorinate reference system
- */
- public Albers(CoordinateReferenceSystem crs) {
- this.crs = crs;
- }
-
- //
- //
- /**
- * Get projection name
- *
- * @return Projection name
- */
- @Override
- public ProjectionNames getProjectionName() {
- return ProjectionNames.Albers_Equal_Area;
- }
-
- //
- //
- @Override
- void updateBoundary() {
- double epsilon = 1e-10;
- double cenLon = this.getCenterLon();
- double minLon = cenLon - 180 + epsilon;
- double maxLon = cenLon + 180 - epsilon;
- double minLat = -90;
- double maxLat = 90;
- List points = new ArrayList<>();
- double lon = minLon;
- double lat = minLat;
- while (lon < maxLon) {
- points.add(new PointD(lon, lat));
- lon += 1;
- }
- lon = maxLon;
- while (lat < maxLat) {
- points.add(new PointD(lon, lat));
- lat += 1;
- }
- lat = maxLat;
- while (lon > minLon) {
- points.add(new PointD(lon, lat));
- lon -= 1;
- }
- lon = minLon;
- while (lat > minLat) {
- points.add(new PointD(lon, lat));
- lat -= 1;
- }
- lat = minLat;
- points.add(new PointD(lon, lat));
- PolygonShape ps = new PolygonShape();
- ps.setPoints(points);
- this.boundary = ProjectionUtil.projectPolygonShape(ps, KnownCoordinateSystems.geographic.world.WGS1984, this);
- }
- //
-}
+/* Copyright 2012 - Yaqiang Wang,
+ * yaqiang.wang@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ */
+package org.meteoinfo.projection.info;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.locationtech.proj4j.CoordinateReferenceSystem;
+import org.meteoinfo.common.PointD;
+import org.meteoinfo.projection.KnownCoordinateSystems;
+import org.meteoinfo.projection.ProjectionNames;
+import org.meteoinfo.projection.ProjectionUtil;
+import org.meteoinfo.shape.PolygonShape;
+
+/**
+ *
+ * @author Yaqiang Wang
+ */
+public class Albers extends ProjectionInfo {
+
+ //
+ //
+ //
+ /**
+ * Construction
+ *
+ * @param crs Coorinate reference system
+ */
+ public Albers(CoordinateReferenceSystem crs) {
+ this.crs = crs;
+ }
+
+ //
+ //
+ /**
+ * Get projection name
+ *
+ * @return Projection name
+ */
+ @Override
+ public ProjectionNames getProjectionName() {
+ return ProjectionNames.Albers_Equal_Area;
+ }
+
+ //
+ //
+ @Override
+ void updateBoundary() {
+ double epsilon = 1e-10;
+ double cenLon = this.getCenterLon();
+ double minLon = cenLon - 180 + epsilon;
+ double maxLon = cenLon + 180 - epsilon;
+ double minLat = -90;
+ double maxLat = 90;
+ List points = new ArrayList<>();
+ double lon = minLon;
+ double lat = minLat;
+ while (lon < maxLon) {
+ points.add(new PointD(lon, lat));
+ lon += 1;
+ }
+ lon = maxLon;
+ while (lat < maxLat) {
+ points.add(new PointD(lon, lat));
+ lat += 1;
+ }
+ lat = maxLat;
+ while (lon > minLon) {
+ points.add(new PointD(lon, lat));
+ lon -= 1;
+ }
+ lon = minLon;
+ while (lat > minLat) {
+ points.add(new PointD(lon, lat));
+ lat -= 1;
+ }
+ lat = minLat;
+ points.add(new PointD(lon, lat));
+ PolygonShape ps = new PolygonShape();
+ ps.setPoints(points);
+ this.boundary = ProjectionUtil.projectPolygonShape(ps, KnownCoordinateSystems.geographic.world.WGS1984, this);
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/GeostationarySatellite.java b/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/GeostationarySatellite.java
index 3a783af3..45571f89 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/GeostationarySatellite.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/GeostationarySatellite.java
@@ -17,8 +17,8 @@ import java.util.List;
import org.meteoinfo.chart.plot.XAlign;
import org.meteoinfo.chart.plot.YAlign;
-import org.meteoinfo.global.Direction;
-import org.meteoinfo.global.PointD;
+import org.meteoinfo.common.Direction;
+import org.meteoinfo.common.PointD;
import org.meteoinfo.map.GridLabel;
import org.meteoinfo.projection.ProjectionNames;
import org.locationtech.proj4j.CoordinateReferenceSystem;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/Hammer.java b/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/Hammer.java
index 040d3871..bd610b1b 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/Hammer.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/Hammer.java
@@ -1,86 +1,87 @@
-/* Copyright 2012 - Yaqiang Wang,
- * yaqiang.wang@gmail.com
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.projection.info;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.meteoinfo.global.PointD;
-import org.meteoinfo.projection.KnownCoordinateSystems;
-import org.meteoinfo.projection.ProjectionNames;
-import org.meteoinfo.projection.ProjectionUtil;
-import org.locationtech.proj4j.CoordinateReferenceSystem;
-import org.meteoinfo.shape.PolygonShape;
-
-/**
- *
- * @author Yaqiang Wang
- */
-public class Hammer extends ProjectionInfo {
-
- //
- //
- //
- /**
- * Construction
- *
- * @param crs Coorinate reference system
- */
- public Hammer(CoordinateReferenceSystem crs) {
- this.crs = crs;
- }
-
- //
- //
- /**
- * Get projection name
- *
- * @return Projection name
- */
- @Override
- public ProjectionNames getProjectionName() {
- return ProjectionNames.Hammer_Eckert;
- }
-
- //
- //
- @Override
- void updateBoundary() {
- double epsilon = 1e-10;
- double cenLon = this.getCenterLon();
- double minLon = cenLon - 180 + epsilon;
- double maxLon = cenLon + 180 - epsilon;
- double minLat = -90;
- double maxLat = 90;
- List points = new ArrayList<>();
- double lon = minLon;
- double lat = minLat;
- lon = maxLon;
- while (lat < maxLat) {
- points.add(new PointD(lon, lat));
- lat += 1;
- }
- lat = maxLat;
- lon = minLon;
- while (lat > minLat) {
- points.add(new PointD(lon, lat));
- lat -= 1;
- }
- lat = minLat;
- points.add(new PointD(lon, lat));
- PolygonShape ps = new PolygonShape();
- ps.setPoints(points);
- this.boundary = ProjectionUtil.projectPolygonShape(ps, KnownCoordinateSystems.geographic.world.WGS1984, this);
- }
- //
-}
+/* Copyright 2012 - Yaqiang Wang,
+ * yaqiang.wang@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ */
+package org.meteoinfo.projection.info;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.meteoinfo.common.PointD;
+import org.meteoinfo.projection.KnownCoordinateSystems;
+import org.meteoinfo.projection.ProjectionNames;
+import org.meteoinfo.projection.ProjectionUtil;
+import org.locationtech.proj4j.CoordinateReferenceSystem;
+import org.meteoinfo.shape.PolygonShape;
+
+/**
+ *
+ * @author Yaqiang Wang
+ */
+public class Hammer extends ProjectionInfo {
+
+ //
+ //
+ //
+ /**
+ * Construction
+ *
+ * @param crs Coorinate reference system
+ */
+ public Hammer(CoordinateReferenceSystem crs) {
+ this.crs = crs;
+ }
+
+ //
+ //
+ /**
+ * Get projection name
+ *
+ * @return Projection name
+ */
+ @Override
+ public ProjectionNames getProjectionName() {
+ return ProjectionNames.Hammer_Eckert;
+ }
+
+ //
+ //
+ @Override
+ void updateBoundary() {
+ double epsilon = 1e-10;
+ double cenLon = this.getCenterLon();
+ double minLon = cenLon - 180 + epsilon;
+ double maxLon = cenLon + 180 - epsilon;
+ double minLat = -90;
+ double maxLat = 90;
+ List points = new ArrayList<>();
+ double lon = minLon;
+ double lat = minLat;
+ lon = maxLon;
+ while (lat < maxLat) {
+ points.add(new PointD(lon, lat));
+ lat += 1;
+ }
+ lat = maxLat;
+ lon = minLon;
+ while (lat > minLat) {
+ points.add(new PointD(lon, lat));
+ lat -= 1;
+ }
+ lat = minLat;
+ points.add(new PointD(lon, lat));
+ PolygonShape ps = new PolygonShape();
+ ps.setPoints(points);
+ this.boundary = ProjectionUtil.projectPolygonShape(ps, KnownCoordinateSystems.geographic.world.WGS1984, this);
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/LambertAzimuthalEqualArea.java b/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/LambertAzimuthalEqualArea.java
index cf4f2591..fe1dda40 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/LambertAzimuthalEqualArea.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/LambertAzimuthalEqualArea.java
@@ -1,78 +1,79 @@
-/* Copyright 2012 - Yaqiang Wang,
- * yaqiang.wang@gmail.com
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.projection.info;
-
-import java.util.List;
-import org.meteoinfo.global.PointD;
-import org.meteoinfo.projection.KnownCoordinateSystems;
-import org.meteoinfo.projection.ProjectionNames;
-import org.meteoinfo.projection.Reproject;
-import org.locationtech.proj4j.CoordinateReferenceSystem;
-import org.meteoinfo.shape.PolygonShape;
-
-/**
- *
- * @author Yaqiang Wang
- */
-public class LambertAzimuthalEqualArea extends ProjectionInfo {
-
- //
- //
- //
- /**
- * Construction
- *
- * @param crs Coorinate reference system
- */
- public LambertAzimuthalEqualArea(CoordinateReferenceSystem crs) {
- this.crs = crs;
- }
-
- //
- //
- /**
- * Get projection name
- *
- * @return Projection name
- */
- @Override
- public ProjectionNames getProjectionName() {
- return ProjectionNames.Lambert_Azimuthal_Equal_Area;
- }
-
- //
- //
- @Override
- void updateBoundary() {
- double epsilon = 1e-10;
- double a = this.crs.getDatum().getEllipsoid().getA();
- double cenLat = this.getCenterLat();
- double cenLon = this.getCenterLon();
- double lon = cenLon + 180 - epsilon;
- double sign = Math.signum(cenLat);
- if (sign == 0)
- sign = 1;
- double lat = -cenLat + sign * 0.01;
- PointD p = Reproject.reprojectPoint(lon, lat, KnownCoordinateSystems.geographic.world.WGS1984, this);
- double x = p.X;
- double max_y = p.Y;
- double easting = this.crs.getProjection().getFalseEasting();
- double northing = this.crs.getProjection().getFalseNorthing();
- List points = this.ellipse_boundary(a * 1.9999, max_y - northing, easting, northing, 61);
- PolygonShape ps = new PolygonShape();
- ps.setPoints(points);
- this.boundary = ps;
- }
- //
-}
+/* Copyright 2012 - Yaqiang Wang,
+ * yaqiang.wang@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ */
+package org.meteoinfo.projection.info;
+
+import java.util.List;
+
+import org.meteoinfo.common.PointD;
+import org.meteoinfo.projection.KnownCoordinateSystems;
+import org.meteoinfo.projection.ProjectionNames;
+import org.meteoinfo.projection.Reproject;
+import org.locationtech.proj4j.CoordinateReferenceSystem;
+import org.meteoinfo.shape.PolygonShape;
+
+/**
+ *
+ * @author Yaqiang Wang
+ */
+public class LambertAzimuthalEqualArea extends ProjectionInfo {
+
+ //
+ //
+ //
+ /**
+ * Construction
+ *
+ * @param crs Coorinate reference system
+ */
+ public LambertAzimuthalEqualArea(CoordinateReferenceSystem crs) {
+ this.crs = crs;
+ }
+
+ //
+ //
+ /**
+ * Get projection name
+ *
+ * @return Projection name
+ */
+ @Override
+ public ProjectionNames getProjectionName() {
+ return ProjectionNames.Lambert_Azimuthal_Equal_Area;
+ }
+
+ //
+ //
+ @Override
+ void updateBoundary() {
+ double epsilon = 1e-10;
+ double a = this.crs.getDatum().getEllipsoid().getA();
+ double cenLat = this.getCenterLat();
+ double cenLon = this.getCenterLon();
+ double lon = cenLon + 180 - epsilon;
+ double sign = Math.signum(cenLat);
+ if (sign == 0)
+ sign = 1;
+ double lat = -cenLat + sign * 0.01;
+ PointD p = Reproject.reprojectPoint(lon, lat, KnownCoordinateSystems.geographic.world.WGS1984, this);
+ double x = p.X;
+ double max_y = p.Y;
+ double easting = this.crs.getProjection().getFalseEasting();
+ double northing = this.crs.getProjection().getFalseNorthing();
+ List points = this.ellipse_boundary(a * 1.9999, max_y - northing, easting, northing, 61);
+ PolygonShape ps = new PolygonShape();
+ ps.setPoints(points);
+ this.boundary = ps;
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/LambertConformalConic.java b/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/LambertConformalConic.java
index 3d594f81..b610ca10 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/LambertConformalConic.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/LambertConformalConic.java
@@ -1,98 +1,99 @@
-/* Copyright 2012 - Yaqiang Wang,
- * yaqiang.wang@gmail.com
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.projection.info;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.meteoinfo.global.PointD;
-import org.meteoinfo.projection.KnownCoordinateSystems;
-import org.meteoinfo.projection.ProjectionNames;
-import org.meteoinfo.projection.ProjectionUtil;
-import org.locationtech.proj4j.CoordinateReferenceSystem;
-import org.meteoinfo.shape.PolygonShape;
-
-/**
- *
- * @author Yaqiang Wang
- */
-public class LambertConformalConic extends ProjectionInfo {
-
- //
- //
- //
- /**
- * Construction
- *
- * @param crs Coorinate reference system
- */
- public LambertConformalConic(CoordinateReferenceSystem crs) {
- this.crs = crs;
- this.cutoff = -80.f;
- }
-
- //
- //
- /**
- * Get projection name
- *
- * @return Projection name
- */
- @Override
- public ProjectionNames getProjectionName() {
- return ProjectionNames.Lambert_Conformal_Conic;
- }
-
- //
- //
- /**
- * Set latitude cutoff
- * @param value Latitude cutoff
- */
- @Override
- public void setCutoff(float value) {
- this.cutoff = value;
- this.updateBoundary();
- }
-
- @Override
- void updateBoundary() {
- double epsilon = 1e-10;
- double cenLon = this.getCenterLon();
- List points = new ArrayList<>();
- double lon = cenLon - 180 + epsilon;
- double lat = this.cutoff;
- while (lon < cenLon + 180 - epsilon) {
- points.add(new PointD(lon, lat));
- lon += 1;
- }
- lon = cenLon + 180 - epsilon;
- points.add(new PointD(lon, lat));
- lat += 1;
- while (lat < 90) {
- points.add(new PointD(lon, lat));
- lat += 1;
- }
- points.add(new PointD(lon, 90));
- lon = cenLon - 180 + epsilon;
- while (lat > this.cutoff) {
- points.add(new PointD(lon, lat));
- lat -= 1;
- }
-
- PolygonShape ps = new PolygonShape();
- ps.setPoints(points);
- this.boundary = ProjectionUtil.projectPolygonShape(ps, KnownCoordinateSystems.geographic.world.WGS1984, this);
- }
- //
-}
+/* Copyright 2012 - Yaqiang Wang,
+ * yaqiang.wang@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ */
+package org.meteoinfo.projection.info;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.meteoinfo.common.PointD;
+import org.meteoinfo.projection.KnownCoordinateSystems;
+import org.meteoinfo.projection.ProjectionNames;
+import org.meteoinfo.projection.ProjectionUtil;
+import org.locationtech.proj4j.CoordinateReferenceSystem;
+import org.meteoinfo.shape.PolygonShape;
+
+/**
+ *
+ * @author Yaqiang Wang
+ */
+public class LambertConformalConic extends ProjectionInfo {
+
+ //
+ //
+ //
+ /**
+ * Construction
+ *
+ * @param crs Coorinate reference system
+ */
+ public LambertConformalConic(CoordinateReferenceSystem crs) {
+ this.crs = crs;
+ this.cutoff = -80.f;
+ }
+
+ //
+ //
+ /**
+ * Get projection name
+ *
+ * @return Projection name
+ */
+ @Override
+ public ProjectionNames getProjectionName() {
+ return ProjectionNames.Lambert_Conformal_Conic;
+ }
+
+ //
+ //
+ /**
+ * Set latitude cutoff
+ * @param value Latitude cutoff
+ */
+ @Override
+ public void setCutoff(float value) {
+ this.cutoff = value;
+ this.updateBoundary();
+ }
+
+ @Override
+ void updateBoundary() {
+ double epsilon = 1e-10;
+ double cenLon = this.getCenterLon();
+ List points = new ArrayList<>();
+ double lon = cenLon - 180 + epsilon;
+ double lat = this.cutoff;
+ while (lon < cenLon + 180 - epsilon) {
+ points.add(new PointD(lon, lat));
+ lon += 1;
+ }
+ lon = cenLon + 180 - epsilon;
+ points.add(new PointD(lon, lat));
+ lat += 1;
+ while (lat < 90) {
+ points.add(new PointD(lon, lat));
+ lat += 1;
+ }
+ points.add(new PointD(lon, 90));
+ lon = cenLon - 180 + epsilon;
+ while (lat > this.cutoff) {
+ points.add(new PointD(lon, lat));
+ lat -= 1;
+ }
+
+ PolygonShape ps = new PolygonShape();
+ ps.setPoints(points);
+ this.boundary = ProjectionUtil.projectPolygonShape(ps, KnownCoordinateSystems.geographic.world.WGS1984, this);
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/LambertEqualAreaConic.java b/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/LambertEqualAreaConic.java
index 93bc1f63..dff74922 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/LambertEqualAreaConic.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/LambertEqualAreaConic.java
@@ -1,94 +1,95 @@
-/* Copyright 2012 - Yaqiang Wang,
- * yaqiang.wang@gmail.com
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.projection.info;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.meteoinfo.global.PointD;
-import org.meteoinfo.projection.KnownCoordinateSystems;
-import org.meteoinfo.projection.ProjectionNames;
-import org.meteoinfo.projection.ProjectionUtil;
-import org.locationtech.proj4j.CoordinateReferenceSystem;
-import org.meteoinfo.shape.PolygonShape;
-
-/**
- *
- * @author Yaqiang Wang
- */
-public class LambertEqualAreaConic extends ProjectionInfo {
-
- //
- //
- //
- /**
- * Construction
- *
- * @param crs Coorinate reference system
- */
- public LambertEqualAreaConic(CoordinateReferenceSystem crs) {
- this.crs = crs;
- }
-
- //
- //
- /**
- * Get projection name
- *
- * @return Projection name
- */
- @Override
- public ProjectionNames getProjectionName() {
- return ProjectionNames.Lambert_Equal_Area_Conic;
- }
-
- //
- //
- @Override
- void updateBoundary() {
- double epsilon = 1e-10;
- double cenLon = this.getCenterLon();
- double minLon = cenLon - 180 + epsilon;
- double maxLon = cenLon + 180 - epsilon;
- double minLat = -90;
- double maxLat = 90;
- List points = new ArrayList<>();
- double lon = minLon;
- double lat = minLat;
- while (lon < maxLon) {
- points.add(new PointD(lon, lat));
- lon += 1;
- }
- lon = maxLon;
- while (lat < maxLat) {
- points.add(new PointD(lon, lat));
- lat += 1;
- }
- lat = maxLat;
- while (lon > minLon) {
- points.add(new PointD(lon, lat));
- lon -= 1;
- }
- lon = minLon;
- while (lat > minLat) {
- points.add(new PointD(lon, lat));
- lat -= 1;
- }
- lat = minLat;
- points.add(new PointD(lon, lat));
- PolygonShape ps = new PolygonShape();
- ps.setPoints(points);
- this.boundary = ProjectionUtil.projectPolygonShape(ps, KnownCoordinateSystems.geographic.world.WGS1984, this);
- }
- //
-}
+/* Copyright 2012 - Yaqiang Wang,
+ * yaqiang.wang@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ */
+package org.meteoinfo.projection.info;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.meteoinfo.common.PointD;
+import org.meteoinfo.projection.KnownCoordinateSystems;
+import org.meteoinfo.projection.ProjectionNames;
+import org.meteoinfo.projection.ProjectionUtil;
+import org.locationtech.proj4j.CoordinateReferenceSystem;
+import org.meteoinfo.shape.PolygonShape;
+
+/**
+ *
+ * @author Yaqiang Wang
+ */
+public class LambertEqualAreaConic extends ProjectionInfo {
+
+ //
+ //
+ //
+ /**
+ * Construction
+ *
+ * @param crs Coorinate reference system
+ */
+ public LambertEqualAreaConic(CoordinateReferenceSystem crs) {
+ this.crs = crs;
+ }
+
+ //
+ //
+ /**
+ * Get projection name
+ *
+ * @return Projection name
+ */
+ @Override
+ public ProjectionNames getProjectionName() {
+ return ProjectionNames.Lambert_Equal_Area_Conic;
+ }
+
+ //
+ //
+ @Override
+ void updateBoundary() {
+ double epsilon = 1e-10;
+ double cenLon = this.getCenterLon();
+ double minLon = cenLon - 180 + epsilon;
+ double maxLon = cenLon + 180 - epsilon;
+ double minLat = -90;
+ double maxLat = 90;
+ List points = new ArrayList<>();
+ double lon = minLon;
+ double lat = minLat;
+ while (lon < maxLon) {
+ points.add(new PointD(lon, lat));
+ lon += 1;
+ }
+ lon = maxLon;
+ while (lat < maxLat) {
+ points.add(new PointD(lon, lat));
+ lat += 1;
+ }
+ lat = maxLat;
+ while (lon > minLon) {
+ points.add(new PointD(lon, lat));
+ lon -= 1;
+ }
+ lon = minLon;
+ while (lat > minLat) {
+ points.add(new PointD(lon, lat));
+ lat -= 1;
+ }
+ lat = minLat;
+ points.add(new PointD(lon, lat));
+ PolygonShape ps = new PolygonShape();
+ ps.setPoints(points);
+ this.boundary = ProjectionUtil.projectPolygonShape(ps, KnownCoordinateSystems.geographic.world.WGS1984, this);
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/Mercator.java b/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/Mercator.java
index 1d55c6aa..0ca85d44 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/Mercator.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/Mercator.java
@@ -1,88 +1,89 @@
-/* Copyright 2012 - Yaqiang Wang,
- * yaqiang.wang@gmail.com
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.projection.info;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.meteoinfo.global.PointD;
-import org.meteoinfo.projection.KnownCoordinateSystems;
-import org.meteoinfo.projection.ProjectionNames;
-import org.meteoinfo.projection.ProjectionUtil;
-import org.locationtech.proj4j.CoordinateReferenceSystem;
-import org.meteoinfo.shape.PolygonShape;
-
-/**
- *
- * @author Yaqiang Wang
- */
-public class Mercator extends ProjectionInfo {
-
- //
- //
- //
- /**
- * Construction
- *
- * @param crs Coorinate reference system
- */
- public Mercator(CoordinateReferenceSystem crs) {
- this.crs = crs;
- this.cutoff = 85.0511f;
- }
-
- //
- //
- /**
- * Get projection name
- *
- * @return Projection name
- */
- @Override
- public ProjectionNames getProjectionName() {
- return ProjectionNames.Mercator;
- }
-
- //
- //
- /**
- * Set latitude cutoff
- *
- * @param value Latitude cutoff
- */
- @Override
- public void setCutoff(float value) {
- this.cutoff = value;
- this.updateBoundary();
- }
-
- @Override
- void updateBoundary() {
- double epsilon = 1e-10;
- double cenLon = this.getCenterLon();
- double minLon = cenLon - 180 + epsilon;
- double maxLon = cenLon + 180 - epsilon;
- double minLat = -this.cutoff;
- double maxLat = this.cutoff;
- List points = new ArrayList<>();
- points.add(new PointD(minLon, minLat));
- points.add(new PointD(maxLon, minLat));
- points.add(new PointD(maxLon, maxLat));
- points.add(new PointD(minLon, maxLat));
- points.add(new PointD(minLon, minLat));
- PolygonShape ps = new PolygonShape();
- ps.setPoints(points);
- this.boundary = ProjectionUtil.projectPolygonShape(ps, KnownCoordinateSystems.geographic.world.WGS1984, this);
- }
- //
-}
+/* Copyright 2012 - Yaqiang Wang,
+ * yaqiang.wang@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ */
+package org.meteoinfo.projection.info;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.meteoinfo.common.PointD;
+import org.meteoinfo.projection.KnownCoordinateSystems;
+import org.meteoinfo.projection.ProjectionNames;
+import org.meteoinfo.projection.ProjectionUtil;
+import org.locationtech.proj4j.CoordinateReferenceSystem;
+import org.meteoinfo.shape.PolygonShape;
+
+/**
+ *
+ * @author Yaqiang Wang
+ */
+public class Mercator extends ProjectionInfo {
+
+ //
+ //
+ //
+ /**
+ * Construction
+ *
+ * @param crs Coorinate reference system
+ */
+ public Mercator(CoordinateReferenceSystem crs) {
+ this.crs = crs;
+ this.cutoff = 85.0511f;
+ }
+
+ //
+ //
+ /**
+ * Get projection name
+ *
+ * @return Projection name
+ */
+ @Override
+ public ProjectionNames getProjectionName() {
+ return ProjectionNames.Mercator;
+ }
+
+ //
+ //
+ /**
+ * Set latitude cutoff
+ *
+ * @param value Latitude cutoff
+ */
+ @Override
+ public void setCutoff(float value) {
+ this.cutoff = value;
+ this.updateBoundary();
+ }
+
+ @Override
+ void updateBoundary() {
+ double epsilon = 1e-10;
+ double cenLon = this.getCenterLon();
+ double minLon = cenLon - 180 + epsilon;
+ double maxLon = cenLon + 180 - epsilon;
+ double minLat = -this.cutoff;
+ double maxLat = this.cutoff;
+ List points = new ArrayList<>();
+ points.add(new PointD(minLon, minLat));
+ points.add(new PointD(maxLon, minLat));
+ points.add(new PointD(maxLon, maxLat));
+ points.add(new PointD(minLon, maxLat));
+ points.add(new PointD(minLon, minLat));
+ PolygonShape ps = new PolygonShape();
+ ps.setPoints(points);
+ this.boundary = ProjectionUtil.projectPolygonShape(ps, KnownCoordinateSystems.geographic.world.WGS1984, this);
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/Molleweide.java b/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/Molleweide.java
index 1dc2f1df..8c92bc2b 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/Molleweide.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/Molleweide.java
@@ -18,8 +18,8 @@ import java.util.List;
import org.meteoinfo.chart.plot.XAlign;
import org.meteoinfo.chart.plot.YAlign;
-import org.meteoinfo.global.Direction;
-import org.meteoinfo.global.PointD;
+import org.meteoinfo.common.Direction;
+import org.meteoinfo.common.PointD;
import org.meteoinfo.map.GridLabel;
import org.meteoinfo.projection.KnownCoordinateSystems;
import org.meteoinfo.projection.ProjectionNames;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/OrthographicAzimuthal.java b/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/OrthographicAzimuthal.java
index 3e913628..5a370f29 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/OrthographicAzimuthal.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/OrthographicAzimuthal.java
@@ -17,9 +17,8 @@ import java.util.List;
import org.meteoinfo.chart.plot.XAlign;
import org.meteoinfo.chart.plot.YAlign;
-import org.meteoinfo.drawing.Draw;
-import org.meteoinfo.global.Direction;
-import org.meteoinfo.global.PointD;
+import org.meteoinfo.common.Direction;
+import org.meteoinfo.common.PointD;
import org.meteoinfo.map.GridLabel;
import org.meteoinfo.projection.ProjectionNames;
import org.locationtech.proj4j.CoordinateReferenceSystem;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/ProjectionInfo.java b/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/ProjectionInfo.java
index e7366999..8a1cebd1 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/ProjectionInfo.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/ProjectionInfo.java
@@ -21,9 +21,9 @@ import java.util.Set;
import org.meteoinfo.chart.plot.XAlign;
import org.meteoinfo.chart.plot.YAlign;
+import org.meteoinfo.common.PointD;
import org.meteoinfo.map.GridLabel;
import org.meteoinfo.math.ArrayUtil;
-import org.meteoinfo.global.PointD;
import org.meteoinfo.projection.ProjectionNames;
import org.locationtech.proj4j.CRSFactory;
import org.locationtech.proj4j.CoordinateReferenceSystem;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/Robinson.java b/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/Robinson.java
index d04a6c09..b0a0ee68 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/Robinson.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/Robinson.java
@@ -18,8 +18,8 @@ import java.util.List;
import org.meteoinfo.chart.plot.XAlign;
import org.meteoinfo.chart.plot.YAlign;
-import org.meteoinfo.global.Direction;
-import org.meteoinfo.global.PointD;
+import org.meteoinfo.common.Direction;
+import org.meteoinfo.common.PointD;
import org.meteoinfo.map.GridLabel;
import org.meteoinfo.projection.KnownCoordinateSystems;
import org.meteoinfo.projection.ProjectionNames;
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/Sinusoidal.java b/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/Sinusoidal.java
index 25e23571..d5ab33ec 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/Sinusoidal.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/Sinusoidal.java
@@ -1,96 +1,97 @@
-/* Copyright 2012 - Yaqiang Wang,
- * yaqiang.wang@gmail.com
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.projection.info;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.meteoinfo.global.PointD;
-import org.meteoinfo.projection.KnownCoordinateSystems;
-import org.meteoinfo.projection.ProjectionNames;
-import org.meteoinfo.projection.ProjectionUtil;
-import org.locationtech.proj4j.CoordinateReferenceSystem;
-import org.meteoinfo.shape.PolygonShape;
-
-/**
- *
- * @author Yaqiang Wang
- */
-public class Sinusoidal extends ProjectionInfo {
-
- //
- //
- //
- /**
- * Construction
- *
- * @param crs Coorinate reference system
- */
- public Sinusoidal(CoordinateReferenceSystem crs) {
- this.crs = crs;
- }
-
- //
- //
- /**
- * Get projection name
- *
- * @return Projection name
- */
- @Override
- public ProjectionNames getProjectionName() {
- return ProjectionNames.Sinusoidal;
- }
-
- //
- //
- /**
- * Get valid parameters
- * @return Valid parameters
- */
- @Override
- public List getValidParas() {
- List paras = new ArrayList<>();
- paras.add("lon_0");
- return paras;
- }
-
- @Override
- void updateBoundary() {
- double epsilon = 1e-10;
- double cenLon = this.getCenterLon();
- double minLon = cenLon - 180 + epsilon;
- double maxLon = cenLon + 180 - epsilon;
- double minLat = -90;
- double maxLat = 90;
- List points = new ArrayList<>();
- double lon = maxLon;
- double lat = minLat;
- while (lat < maxLat) {
- points.add(new PointD(lon, lat));
- lat += 1;
- }
- lat = maxLat;
- lon = minLon;
- while (lat > minLat) {
- points.add(new PointD(lon, lat));
- lat -= 1;
- }
- lat = minLat;
- points.add(new PointD(lon, lat));
- PolygonShape ps = new PolygonShape();
- ps.setPoints(points);
- this.boundary = ProjectionUtil.projectPolygonShape(ps, KnownCoordinateSystems.geographic.world.WGS1984, this);
- }
- //
-}
+/* Copyright 2012 - Yaqiang Wang,
+ * yaqiang.wang@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ */
+package org.meteoinfo.projection.info;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.meteoinfo.common.PointD;
+import org.meteoinfo.projection.KnownCoordinateSystems;
+import org.meteoinfo.projection.ProjectionNames;
+import org.meteoinfo.projection.ProjectionUtil;
+import org.locationtech.proj4j.CoordinateReferenceSystem;
+import org.meteoinfo.shape.PolygonShape;
+
+/**
+ *
+ * @author Yaqiang Wang
+ */
+public class Sinusoidal extends ProjectionInfo {
+
+ //
+ //
+ //
+ /**
+ * Construction
+ *
+ * @param crs Coorinate reference system
+ */
+ public Sinusoidal(CoordinateReferenceSystem crs) {
+ this.crs = crs;
+ }
+
+ //
+ //
+ /**
+ * Get projection name
+ *
+ * @return Projection name
+ */
+ @Override
+ public ProjectionNames getProjectionName() {
+ return ProjectionNames.Sinusoidal;
+ }
+
+ //
+ //
+ /**
+ * Get valid parameters
+ * @return Valid parameters
+ */
+ @Override
+ public List getValidParas() {
+ List paras = new ArrayList<>();
+ paras.add("lon_0");
+ return paras;
+ }
+
+ @Override
+ void updateBoundary() {
+ double epsilon = 1e-10;
+ double cenLon = this.getCenterLon();
+ double minLon = cenLon - 180 + epsilon;
+ double maxLon = cenLon + 180 - epsilon;
+ double minLat = -90;
+ double maxLat = 90;
+ List points = new ArrayList<>();
+ double lon = maxLon;
+ double lat = minLat;
+ while (lat < maxLat) {
+ points.add(new PointD(lon, lat));
+ lat += 1;
+ }
+ lat = maxLat;
+ lon = minLon;
+ while (lat > minLat) {
+ points.add(new PointD(lon, lat));
+ lat -= 1;
+ }
+ lat = minLat;
+ points.add(new PointD(lon, lat));
+ PolygonShape ps = new PolygonShape();
+ ps.setPoints(points);
+ this.boundary = ProjectionUtil.projectPolygonShape(ps, KnownCoordinateSystems.geographic.world.WGS1984, this);
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/StereographicAzimuthal.java b/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/StereographicAzimuthal.java
index f597e2ac..51a10612 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/StereographicAzimuthal.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/StereographicAzimuthal.java
@@ -1,107 +1,108 @@
-/* Copyright 2012 - Yaqiang Wang,
- * yaqiang.wang@gmail.com
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.projection.info;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.meteoinfo.global.PointD;
-import org.meteoinfo.projection.KnownCoordinateSystems;
-import org.meteoinfo.projection.ProjectionNames;
-import org.meteoinfo.projection.ProjectionUtil;
-import org.locationtech.proj4j.CoordinateReferenceSystem;
-import org.meteoinfo.shape.PolygonShape;
-
-/**
- *
- * @author Yaqiang Wang
- */
-public class StereographicAzimuthal extends ProjectionInfo {
-
- //
- //
- //
- /**
- * Construction
- *
- * @param crs Coorinate reference system
- */
- public StereographicAzimuthal(CoordinateReferenceSystem crs) {
- this.crs = crs;
- this.cutoff = 0.f;
- }
-
- //
- //
- /**
- * Get projection name
- *
- * @return Projection name
- */
- @Override
- public ProjectionNames getProjectionName() {
- if (this.isNorthPolar()) {
- return ProjectionNames.North_Polar_Stereographic_Azimuthal;
- } else if (this.isSouthPolar()) {
- return ProjectionNames.South_Polar_Stereographic_Azimuthal;
- } else {
- return ProjectionNames.Stereographic_Azimuthal;
- }
- }
-
- //
- //
- /**
- * Check is north polar or not
- *
- * @return Boolean
- */
- public boolean isNorthPolar() {
- return this.crs.getProjection().getProjectionLatitudeDegrees() == 90;
- }
-
- /**
- * Check is south polar or not
- *
- * @return Boolean
- */
- public boolean isSouthPolar() {
- return this.crs.getProjection().getProjectionLatitudeDegrees() == -90;
- }
-
- /**
- * Set latitude cutoff
- *
- * @param value Latitude cutoff
- */
- @Override
- public void setCutoff(float value) {
- this.cutoff = value;
- this.updateBoundary();
- }
-
- @Override
- void updateBoundary() {
- List points = new ArrayList<>();
- double lon = -180;
- double lat = this.cutoff;
- while (lon <= 180) {
- points.add(new PointD(lon, lat));
- lon += 1;
- }
- PolygonShape ps = new PolygonShape();
- ps.setPoints(points);
- this.boundary = ProjectionUtil.projectPolygonShape(ps, KnownCoordinateSystems.geographic.world.WGS1984, this);
- }
- //
-}
+/* Copyright 2012 - Yaqiang Wang,
+ * yaqiang.wang@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ */
+package org.meteoinfo.projection.info;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.meteoinfo.common.PointD;
+import org.meteoinfo.projection.KnownCoordinateSystems;
+import org.meteoinfo.projection.ProjectionNames;
+import org.meteoinfo.projection.ProjectionUtil;
+import org.locationtech.proj4j.CoordinateReferenceSystem;
+import org.meteoinfo.shape.PolygonShape;
+
+/**
+ *
+ * @author Yaqiang Wang
+ */
+public class StereographicAzimuthal extends ProjectionInfo {
+
+ //
+ //
+ //
+ /**
+ * Construction
+ *
+ * @param crs Coorinate reference system
+ */
+ public StereographicAzimuthal(CoordinateReferenceSystem crs) {
+ this.crs = crs;
+ this.cutoff = 0.f;
+ }
+
+ //
+ //
+ /**
+ * Get projection name
+ *
+ * @return Projection name
+ */
+ @Override
+ public ProjectionNames getProjectionName() {
+ if (this.isNorthPolar()) {
+ return ProjectionNames.North_Polar_Stereographic_Azimuthal;
+ } else if (this.isSouthPolar()) {
+ return ProjectionNames.South_Polar_Stereographic_Azimuthal;
+ } else {
+ return ProjectionNames.Stereographic_Azimuthal;
+ }
+ }
+
+ //
+ //
+ /**
+ * Check is north polar or not
+ *
+ * @return Boolean
+ */
+ public boolean isNorthPolar() {
+ return this.crs.getProjection().getProjectionLatitudeDegrees() == 90;
+ }
+
+ /**
+ * Check is south polar or not
+ *
+ * @return Boolean
+ */
+ public boolean isSouthPolar() {
+ return this.crs.getProjection().getProjectionLatitudeDegrees() == -90;
+ }
+
+ /**
+ * Set latitude cutoff
+ *
+ * @param value Latitude cutoff
+ */
+ @Override
+ public void setCutoff(float value) {
+ this.cutoff = value;
+ this.updateBoundary();
+ }
+
+ @Override
+ void updateBoundary() {
+ List points = new ArrayList<>();
+ double lon = -180;
+ double lat = this.cutoff;
+ while (lon <= 180) {
+ points.add(new PointD(lon, lat));
+ lon += 1;
+ }
+ PolygonShape ps = new PolygonShape();
+ ps.setPoints(points);
+ this.boundary = ProjectionUtil.projectPolygonShape(ps, KnownCoordinateSystems.geographic.world.WGS1984, this);
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/TransverseMercator.java b/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/TransverseMercator.java
index af5ffc9c..8dacc2b2 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/TransverseMercator.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/TransverseMercator.java
@@ -1,84 +1,85 @@
-/* Copyright 2012 - Yaqiang Wang,
- * yaqiang.wang@gmail.com
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.projection.info;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.meteoinfo.global.PointD;
-import org.meteoinfo.projection.ProjectionNames;
-import org.locationtech.proj4j.CoordinateReferenceSystem;
-import org.meteoinfo.shape.PolygonShape;
-
-/**
- *
- * @author Yaqiang Wang
- */
-public class TransverseMercator extends ProjectionInfo {
-
- //
- //
- //
- /**
- * Construction
- *
- * @param crs Coorinate reference system
- */
- public TransverseMercator(CoordinateReferenceSystem crs) {
- this.crs = crs;
- this.cutoff = 85.0511f;
- }
-
- //
- //
- /**
- * Get projection name
- *
- * @return Projection name
- */
- @Override
- public ProjectionNames getProjectionName() {
- return ProjectionNames.Transverse_Mercator;
- }
-
- //
- //
- /**
- * Set latitude cutoff
- *
- * @param value Latitude cutoff
- */
- @Override
- public void setCutoff(float value) {
- this.cutoff = value;
- this.updateBoundary();
- }
-
- @Override
- void updateBoundary() {
- double x0 = -2e7;
- double x1 = 2e7;
- double y0 = -1e7;
- double y1 = 1e7;
- List points = new ArrayList<>();
- points.add(new PointD(x0, y0));
- points.add(new PointD(x1, y0));
- points.add(new PointD(x1, y1));
- points.add(new PointD(x0, y1));
- points.add(new PointD(x0, y0));
- PolygonShape ps = new PolygonShape();
- ps.setPoints(points);
- this.boundary = ps;
- }
- //
-}
+/* Copyright 2012 - Yaqiang Wang,
+ * yaqiang.wang@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ */
+package org.meteoinfo.projection.info;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.meteoinfo.common.PointD;
+import org.meteoinfo.projection.ProjectionNames;
+import org.locationtech.proj4j.CoordinateReferenceSystem;
+import org.meteoinfo.shape.PolygonShape;
+
+/**
+ *
+ * @author Yaqiang Wang
+ */
+public class TransverseMercator extends ProjectionInfo {
+
+ //
+ //
+ //
+ /**
+ * Construction
+ *
+ * @param crs Coorinate reference system
+ */
+ public TransverseMercator(CoordinateReferenceSystem crs) {
+ this.crs = crs;
+ this.cutoff = 85.0511f;
+ }
+
+ //
+ //
+ /**
+ * Get projection name
+ *
+ * @return Projection name
+ */
+ @Override
+ public ProjectionNames getProjectionName() {
+ return ProjectionNames.Transverse_Mercator;
+ }
+
+ //
+ //
+ /**
+ * Set latitude cutoff
+ *
+ * @param value Latitude cutoff
+ */
+ @Override
+ public void setCutoff(float value) {
+ this.cutoff = value;
+ this.updateBoundary();
+ }
+
+ @Override
+ void updateBoundary() {
+ double x0 = -2e7;
+ double x1 = 2e7;
+ double y0 = -1e7;
+ double y1 = 1e7;
+ List points = new ArrayList<>();
+ points.add(new PointD(x0, y0));
+ points.add(new PointD(x1, y0));
+ points.add(new PointD(x1, y1));
+ points.add(new PointD(x0, y1));
+ points.add(new PointD(x0, y0));
+ PolygonShape ps = new PolygonShape();
+ ps.setPoints(points);
+ this.boundary = ps;
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/Wagner3.java b/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/Wagner3.java
index 593c2655..f5caa7e9 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/Wagner3.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/projection/info/Wagner3.java
@@ -1,94 +1,95 @@
-/* Copyright 2012 - Yaqiang Wang,
- * yaqiang.wang@gmail.com
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.projection.info;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.meteoinfo.global.PointD;
-import org.meteoinfo.projection.KnownCoordinateSystems;
-import org.meteoinfo.projection.ProjectionNames;
-import org.meteoinfo.projection.ProjectionUtil;
-import org.locationtech.proj4j.CoordinateReferenceSystem;
-import org.meteoinfo.shape.PolygonShape;
-
-/**
- *
- * @author Yaqiang Wang
- */
-public class Wagner3 extends ProjectionInfo {
-
- //
- //
- //
- /**
- * Construction
- *
- * @param crs Coorinate reference system
- */
- public Wagner3(CoordinateReferenceSystem crs) {
- this.crs = crs;
- }
-
- //
- //
- /**
- * Get projection name
- *
- * @return Projection name
- */
- @Override
- public ProjectionNames getProjectionName() {
- return ProjectionNames.Wagner3;
- }
-
- //
- //
- @Override
- void updateBoundary() {
- double epsilon = 1e-10;
- double cenLon = this.getCenterLon();
- double minLon = cenLon - 180 + epsilon;
- double maxLon = cenLon + 180 - epsilon;
- double minLat = -90;
- double maxLat = 90;
- List points = new ArrayList<>();
- double lon = minLon;
- double lat = minLat;
- while (lon < maxLon) {
- points.add(new PointD(lon, lat));
- lon += 1;
- }
- lon = maxLon;
- while (lat < maxLat) {
- points.add(new PointD(lon, lat));
- lat += 1;
- }
- lat = maxLat;
- while (lon > minLon) {
- points.add(new PointD(lon, lat));
- lon -= 1;
- }
- lon = minLon;
- while (lat > minLat) {
- points.add(new PointD(lon, lat));
- lat -= 1;
- }
- lat = minLat;
- points.add(new PointD(lon, lat));
- PolygonShape ps = new PolygonShape();
- ps.setPoints(points);
- this.boundary = ProjectionUtil.projectPolygonShape(ps, KnownCoordinateSystems.geographic.world.WGS1984, this);
- }
- //
-}
+/* Copyright 2012 - Yaqiang Wang,
+ * yaqiang.wang@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ */
+package org.meteoinfo.projection.info;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.meteoinfo.common.PointD;
+import org.meteoinfo.projection.KnownCoordinateSystems;
+import org.meteoinfo.projection.ProjectionNames;
+import org.meteoinfo.projection.ProjectionUtil;
+import org.locationtech.proj4j.CoordinateReferenceSystem;
+import org.meteoinfo.shape.PolygonShape;
+
+/**
+ *
+ * @author Yaqiang Wang
+ */
+public class Wagner3 extends ProjectionInfo {
+
+ //
+ //
+ //
+ /**
+ * Construction
+ *
+ * @param crs Coorinate reference system
+ */
+ public Wagner3(CoordinateReferenceSystem crs) {
+ this.crs = crs;
+ }
+
+ //
+ //
+ /**
+ * Get projection name
+ *
+ * @return Projection name
+ */
+ @Override
+ public ProjectionNames getProjectionName() {
+ return ProjectionNames.Wagner3;
+ }
+
+ //
+ //
+ @Override
+ void updateBoundary() {
+ double epsilon = 1e-10;
+ double cenLon = this.getCenterLon();
+ double minLon = cenLon - 180 + epsilon;
+ double maxLon = cenLon + 180 - epsilon;
+ double minLat = -90;
+ double maxLat = 90;
+ List points = new ArrayList<>();
+ double lon = minLon;
+ double lat = minLat;
+ while (lon < maxLon) {
+ points.add(new PointD(lon, lat));
+ lon += 1;
+ }
+ lon = maxLon;
+ while (lat < maxLat) {
+ points.add(new PointD(lon, lat));
+ lat += 1;
+ }
+ lat = maxLat;
+ while (lon > minLon) {
+ points.add(new PointD(lon, lat));
+ lon -= 1;
+ }
+ lon = minLon;
+ while (lat > minLat) {
+ points.add(new PointD(lon, lat));
+ lat -= 1;
+ }
+ lat = minLat;
+ points.add(new PointD(lon, lat));
+ PolygonShape ps = new PolygonShape();
+ ps.setPoints(points);
+ this.boundary = ProjectionUtil.projectPolygonShape(ps, KnownCoordinateSystems.geographic.world.WGS1984, this);
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/script/MeteoInfoData.java b/MeteoInfoLib/src/main/java/org/meteoinfo/script/MeteoInfoData.java
index 916262b6..e02dca47 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/script/MeteoInfoData.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/script/MeteoInfoData.java
@@ -1,295 +1,273 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.meteoinfo.script;
-
-import java.awt.Color;
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import javax.swing.WindowConstants;
-import org.meteoinfo.chart.Chart;
-import org.meteoinfo.chart.ChartPanel;
-import org.meteoinfo.chart.plot.ChartPlotMethod;
-import org.meteoinfo.chart.plot.XY1DPlot;
-import org.meteoinfo.data.GridData;
-import org.meteoinfo.data.XYArrayDataset;
-import org.meteoinfo.data.mapdata.MapDataManage;
-import org.meteoinfo.data.meteodata.DrawMeteoData;
-import org.meteoinfo.data.meteodata.DrawType2D;
-import org.meteoinfo.data.meteodata.MeteoDataInfo;
-import org.meteoinfo.legend.PointStyle;
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.layer.MapLayer;
-import org.meteoinfo.layout.MapLayout;
-import org.meteoinfo.legend.LineStyles;
-import org.meteoinfo.legend.MapFrame;
-import org.meteoinfo.legend.PointBreak;
-import org.meteoinfo.legend.PolygonBreak;
-import org.meteoinfo.legend.PolylineBreak;
-import org.meteoinfo.map.MapView;
-
-/**
- *
- * @author yaqiang
- */
-public class MeteoInfoData {
- //
- private List dataInfoList;
- private MeteoDataInfo currentDataInfo;
-
- //
- //
- /**
- * Constructor
- */
- public MeteoInfoData() {
- dataInfoList = new ArrayList();
- }
-
- //
- //
- //
- //
- //
- /**
- * Add a meteo data info
- *
- * @param aDataInfo The meteo data info
- */
- public void addMeteoData(MeteoDataInfo aDataInfo) {
- dataInfoList.add(aDataInfo);
- currentDataInfo = aDataInfo;
- }
-
- /**
- * Open GrADS data file
- *
- * @param fileName GrADS data file name
- * @return MeteoDataInfo
- */
- public MeteoDataInfo openGrADSData(String fileName) {
- MeteoDataInfo aDataInfo = new MeteoDataInfo();
- aDataInfo.openGrADSData(fileName);
- addMeteoData(aDataInfo);
-
- return aDataInfo;
- }
-
- /**
- * Open ARL data file
- *
- * @param fileName ARL data file name
- * @return MeteoDataInfo
- */
- public MeteoDataInfo openARLData(String fileName) {
- MeteoDataInfo aDataInfo = new MeteoDataInfo();
- aDataInfo.openARLData(fileName);
- addMeteoData(aDataInfo);
-
- return aDataInfo;
- }
-
- /**
- * Open ASCII grid data file
- *
- * @param fileName ASCII grid data file name
- * @return MeteoDataInfo
- */
- public MeteoDataInfo openASCIIGridData(String fileName) {
- MeteoDataInfo aDataInfo = new MeteoDataInfo();
- aDataInfo.openASCIIGridData(fileName);
- addMeteoData(aDataInfo);
-
- return aDataInfo;
- }
-
- /**
- * Open Surfer grid data file
- *
- * @param fileName Surfer grid data file name
- * @return MeteoDataInfo
- */
- public MeteoDataInfo openSurferGridData(String fileName) {
- MeteoDataInfo aDataInfo = new MeteoDataInfo();
- aDataInfo.openSurferGridData(fileName);
- addMeteoData(aDataInfo);
-
- return aDataInfo;
- }
-
- /**
- * Open HYSPLIT concentration data file
- *
- * @param fileName HYSPLIT concentration data file name
- * @return MeteoDataInfo
- */
- public MeteoDataInfo openHYSPLITConcData(String fileName) {
- MeteoDataInfo aDataInfo = new MeteoDataInfo();
- aDataInfo.openHYSPLITConcData(fileName);
- addMeteoData(aDataInfo);
-
- return aDataInfo;
- }
-
- /**
- * Open HYSPLIT particle data file
- *
- * @param fileName HYSPLIT particle data file name
- * @return MeteoDataInfo
- */
- public MeteoDataInfo openHYSPITPartData(String fileName) {
- MeteoDataInfo aDataInfo = new MeteoDataInfo();
- aDataInfo.openHYSPLITPartData(fileName);
- addMeteoData(aDataInfo);
-
- return aDataInfo;
- }
-
- /**
- * Open HYSPLIT trajectory data file
- *
- * @param fileName HYSPLIT trajectory data file name
- * @return MeteoDataInfo
- */
- public MeteoDataInfo openHYSPLITTrajData(String fileName) {
- MeteoDataInfo aDataInfo = new MeteoDataInfo();
- aDataInfo.openHYSPLITTrajData(fileName);
- addMeteoData(aDataInfo);
-
- return aDataInfo;
- }
-
-// /**
-// * Open HYSPLIT trajectory data files
-// *
-// * @param fileNames HYSPLIT trajectory data file names
-// * @return MeteoDataInfo
-// */
-// public MeteoDataInfo openHYSPLITTrajData(String[] fileNames) {
-// MeteoDataInfo aDataInfo = new MeteoDataInfo();
-// aDataInfo.openHYSPLITTrajData(fileNames);
-// addMeteoData(aDataInfo);
-//
-// return aDataInfo;
-// }
-
- /**
- * Open NetCDF, GRIB, HDF... data file
- *
- * @param fileName NetCDF, GRIB, HDF... data file name
- * @return MeteoDataInfo
- */
- public MeteoDataInfo openNetCDFData(String fileName) {
- MeteoDataInfo aDataInfo = new MeteoDataInfo();
- aDataInfo.openNetCDFData(fileName);
- addMeteoData(aDataInfo);
-
- return aDataInfo;
- }
-
- /**
- * Open Lon/Lat station data file
- *
- * @param fileName Lon/Lat station data file name
- * @return MeteoDataInfo
- */
- public MeteoDataInfo openLonLatData(String fileName) {
- MeteoDataInfo aDataInfo = new MeteoDataInfo();
- aDataInfo.openLonLatData(fileName);
- addMeteoData(aDataInfo);
-
- return aDataInfo;
- }
-
- /**
- * Open MICAPS data file
- *
- * @param fileName MICAPS data file name
- * @return MeteoDataInfo
- */
- public MeteoDataInfo openMICAPSData(String fileName) {
- MeteoDataInfo aDataInfo = new MeteoDataInfo();
- aDataInfo.openMICAPSData(fileName);
- addMeteoData(aDataInfo);
-
- return aDataInfo;
- }
-
- /**
- * Open MM5 output data file
- *
- * @param fileName MM5 output data file name
- * @return MeteoDataInfo
- */
- public MeteoDataInfo openMM5Data(String fileName) {
- MeteoDataInfo aDataInfo = new MeteoDataInfo();
- aDataInfo.openMM5Data(fileName);
- addMeteoData(aDataInfo);
-
- return aDataInfo;
- }
-
- /**
- * Open MM5 intermedia data file
- *
- * @param fileName MM5 intermedia data file name
- * @return MeteoDataInfo
- */
- public MeteoDataInfo openMM5IMData(String fileName) {
- MeteoDataInfo aDataInfo = new MeteoDataInfo();
- aDataInfo.openMM5IMData(fileName);
- addMeteoData(aDataInfo);
-
- return aDataInfo;
- }
-
- //
- //
- /**
- * Get grid data
- * @param varName Variable name
- * @return Grid data
- */
- public GridData getGridData(String varName){
- return this.currentDataInfo.getGridData(varName);
- }
- //
- //
- /**
- * Get line space data list
- * @param min Minimum
- * @param max Maximum
- * @param n Number
- * @return Data list
- */
- public List linespace(double min, double max, int n){
- List values = new ArrayList();
- double delta = (max - min) / (n - 1);
- for (int i = 0; i < n; i++){
- values.add(min + delta * i);
- }
-
- return values;
- }
-
- /**
- * Get sine values
- * @param values Input values
- * @return Sine values
- */
- public List sin(List values){
- List rvalues = new ArrayList();
- for (Double v : values){
- rvalues.add(Math.sin(v));
- }
-
- return rvalues;
- }
- //
- //
-}
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.meteoinfo.script;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.meteoinfo.data.GridData;
+import org.meteoinfo.data.meteodata.MeteoDataInfo;
+
+/**
+ *
+ * @author yaqiang
+ */
+public class MeteoInfoData {
+ //
+ private List dataInfoList;
+ private MeteoDataInfo currentDataInfo;
+
+ //
+ //
+ /**
+ * Constructor
+ */
+ public MeteoInfoData() {
+ dataInfoList = new ArrayList();
+ }
+
+ //
+ //
+ //
+ //
+ //
+ /**
+ * Add a meteo data info
+ *
+ * @param aDataInfo The meteo data info
+ */
+ public void addMeteoData(MeteoDataInfo aDataInfo) {
+ dataInfoList.add(aDataInfo);
+ currentDataInfo = aDataInfo;
+ }
+
+ /**
+ * Open GrADS data file
+ *
+ * @param fileName GrADS data file name
+ * @return MeteoDataInfo
+ */
+ public MeteoDataInfo openGrADSData(String fileName) {
+ MeteoDataInfo aDataInfo = new MeteoDataInfo();
+ aDataInfo.openGrADSData(fileName);
+ addMeteoData(aDataInfo);
+
+ return aDataInfo;
+ }
+
+ /**
+ * Open ARL data file
+ *
+ * @param fileName ARL data file name
+ * @return MeteoDataInfo
+ */
+ public MeteoDataInfo openARLData(String fileName) {
+ MeteoDataInfo aDataInfo = new MeteoDataInfo();
+ aDataInfo.openARLData(fileName);
+ addMeteoData(aDataInfo);
+
+ return aDataInfo;
+ }
+
+ /**
+ * Open ASCII grid data file
+ *
+ * @param fileName ASCII grid data file name
+ * @return MeteoDataInfo
+ */
+ public MeteoDataInfo openASCIIGridData(String fileName) {
+ MeteoDataInfo aDataInfo = new MeteoDataInfo();
+ aDataInfo.openASCIIGridData(fileName);
+ addMeteoData(aDataInfo);
+
+ return aDataInfo;
+ }
+
+ /**
+ * Open Surfer grid data file
+ *
+ * @param fileName Surfer grid data file name
+ * @return MeteoDataInfo
+ */
+ public MeteoDataInfo openSurferGridData(String fileName) {
+ MeteoDataInfo aDataInfo = new MeteoDataInfo();
+ aDataInfo.openSurferGridData(fileName);
+ addMeteoData(aDataInfo);
+
+ return aDataInfo;
+ }
+
+ /**
+ * Open HYSPLIT concentration data file
+ *
+ * @param fileName HYSPLIT concentration data file name
+ * @return MeteoDataInfo
+ */
+ public MeteoDataInfo openHYSPLITConcData(String fileName) {
+ MeteoDataInfo aDataInfo = new MeteoDataInfo();
+ aDataInfo.openHYSPLITConcData(fileName);
+ addMeteoData(aDataInfo);
+
+ return aDataInfo;
+ }
+
+ /**
+ * Open HYSPLIT particle data file
+ *
+ * @param fileName HYSPLIT particle data file name
+ * @return MeteoDataInfo
+ */
+ public MeteoDataInfo openHYSPITPartData(String fileName) {
+ MeteoDataInfo aDataInfo = new MeteoDataInfo();
+ aDataInfo.openHYSPLITPartData(fileName);
+ addMeteoData(aDataInfo);
+
+ return aDataInfo;
+ }
+
+ /**
+ * Open HYSPLIT trajectory data file
+ *
+ * @param fileName HYSPLIT trajectory data file name
+ * @return MeteoDataInfo
+ */
+ public MeteoDataInfo openHYSPLITTrajData(String fileName) {
+ MeteoDataInfo aDataInfo = new MeteoDataInfo();
+ aDataInfo.openHYSPLITTrajData(fileName);
+ addMeteoData(aDataInfo);
+
+ return aDataInfo;
+ }
+
+// /**
+// * Open HYSPLIT trajectory data files
+// *
+// * @param fileNames HYSPLIT trajectory data file names
+// * @return MeteoDataInfo
+// */
+// public MeteoDataInfo openHYSPLITTrajData(String[] fileNames) {
+// MeteoDataInfo aDataInfo = new MeteoDataInfo();
+// aDataInfo.openHYSPLITTrajData(fileNames);
+// addMeteoData(aDataInfo);
+//
+// return aDataInfo;
+// }
+
+ /**
+ * Open NetCDF, GRIB, HDF... data file
+ *
+ * @param fileName NetCDF, GRIB, HDF... data file name
+ * @return MeteoDataInfo
+ */
+ public MeteoDataInfo openNetCDFData(String fileName) {
+ MeteoDataInfo aDataInfo = new MeteoDataInfo();
+ aDataInfo.openNetCDFData(fileName);
+ addMeteoData(aDataInfo);
+
+ return aDataInfo;
+ }
+
+ /**
+ * Open Lon/Lat station data file
+ *
+ * @param fileName Lon/Lat station data file name
+ * @return MeteoDataInfo
+ */
+ public MeteoDataInfo openLonLatData(String fileName) {
+ MeteoDataInfo aDataInfo = new MeteoDataInfo();
+ aDataInfo.openLonLatData(fileName);
+ addMeteoData(aDataInfo);
+
+ return aDataInfo;
+ }
+
+ /**
+ * Open MICAPS data file
+ *
+ * @param fileName MICAPS data file name
+ * @return MeteoDataInfo
+ */
+ public MeteoDataInfo openMICAPSData(String fileName) {
+ MeteoDataInfo aDataInfo = new MeteoDataInfo();
+ aDataInfo.openMICAPSData(fileName);
+ addMeteoData(aDataInfo);
+
+ return aDataInfo;
+ }
+
+ /**
+ * Open MM5 output data file
+ *
+ * @param fileName MM5 output data file name
+ * @return MeteoDataInfo
+ */
+ public MeteoDataInfo openMM5Data(String fileName) {
+ MeteoDataInfo aDataInfo = new MeteoDataInfo();
+ aDataInfo.openMM5Data(fileName);
+ addMeteoData(aDataInfo);
+
+ return aDataInfo;
+ }
+
+ /**
+ * Open MM5 intermedia data file
+ *
+ * @param fileName MM5 intermedia data file name
+ * @return MeteoDataInfo
+ */
+ public MeteoDataInfo openMM5IMData(String fileName) {
+ MeteoDataInfo aDataInfo = new MeteoDataInfo();
+ aDataInfo.openMM5IMData(fileName);
+ addMeteoData(aDataInfo);
+
+ return aDataInfo;
+ }
+
+ //
+ //
+ /**
+ * Get grid data
+ * @param varName Variable name
+ * @return Grid data
+ */
+ public GridData getGridData(String varName){
+ return this.currentDataInfo.getGridData(varName);
+ }
+ //
+ //
+ /**
+ * Get line space data list
+ * @param min Minimum
+ * @param max Maximum
+ * @param n Number
+ * @return Data list
+ */
+ public List linespace(double min, double max, int n){
+ List values = new ArrayList();
+ double delta = (max - min) / (n - 1);
+ for (int i = 0; i < n; i++){
+ values.add(min + delta * i);
+ }
+
+ return values;
+ }
+
+ /**
+ * Get sine values
+ * @param values Input values
+ * @return Sine values
+ */
+ public List sin(List values){
+ List rvalues = new ArrayList();
+ for (Double v : values){
+ rvalues.add(Math.sin(v));
+ }
+
+ return rvalues;
+ }
+ //
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/script/MeteoInfoPlot.java b/MeteoInfoLib/src/main/java/org/meteoinfo/script/MeteoInfoPlot.java
index fc01c42b..9d2ed5ce 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/script/MeteoInfoPlot.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/script/MeteoInfoPlot.java
@@ -1,276 +1,276 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.meteoinfo.script;
-
-import java.awt.Color;
-import java.util.ArrayList;
-import java.util.List;
-import javax.swing.WindowConstants;
-import org.meteoinfo.chart.ChartPanel;
-import org.meteoinfo.chart.plot.XY1DPlot;
-import org.meteoinfo.legend.PointStyle;
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.legend.LineStyles;
-
-/**
- *
- * @author yaqiang
- */
-public class MeteoInfoPlot {
-
- //
- private boolean batchMode;
- private ChartPanel charPanel;
-
- //
- //
- /**
- * Constructor
- */
- public MeteoInfoPlot() {
- this.batchMode = true;
- this.charPanel = new ChartPanel(null);
- }
-
- //
- //
- //
- //
-
- //
-// /**
-// * Plot
-// *
-// * @param yValues Y values
-// */
-// public void plot(List yValues) {
-// List xValues = new ArrayList();
-// for (int i = 0; i < yValues.size(); i++) {
-// xValues.add(i);
-// }
-//
-// this.plot(xValues, yValues);
-// }
-
-// /**
-// * Plot
-// *
-// * @param xValues X values
-// * @param yValues Y values
-// */
-// public void plot(List xValues, List yValues) {
-// this.plot(xValues, yValues, "");
-// }
-
-// /**
-// * Plot
-// *
-// * @param xValues X values
-// * @param yValues Y values
-// * @param style Plot style
-// */
-// public void plot(List xValues, List yValues, String style) {
-// if (xValues.size() != yValues.size()) {
-// System.out.println("The size of x and y values are not same!");
-// return;
-// }
-//
-// XYArrayDataset dataset = new XYArrayDataset(xValues, yValues, "S_1");
-// XY1DPlot plot = new XY1DPlot(dataset);
-//
-// if (!style.isEmpty()) {
-// Color color = this.getColor(style);
-// PointStyle ps = this.getPointStyle(style);
-// LineStyles ls = this.getLineStyle(style);
-// if (ps != null) {
-// if (ls == null){
-// plot.setChartPlotMethod(ChartPlotMethod.POINT);
-// PointBreak pb = plot.getPointBreak(0);
-// pb.setSize(8);
-// pb.setStyle(this.getPointStyle(style));
-// if (color != null) {
-// pb.setColor(color);
-// }
-// } else {
-// plot.setChartPlotMethod(ChartPlotMethod.LINE_POINT);
-// PolylineBreak plb = plot.getPolylineBreak(0);
-// plb.setStyle(ls);
-// plb.setDrawSymbol(true);
-// plb.setSymbolStyle(ps);
-// plb.setSymbolInterval(this.getSymbolInterval(xValues.size()));
-// if (color != null) {
-// plb.setColor(color);
-// plb.setSymbolColor(color);
-// }
-// }
-// } else {
-// plot.setChartPlotMethod(ChartPlotMethod.LINE);
-// PolylineBreak plb = plot.getPolylineBreak(0);
-// if (color != null) {
-// plb.setColor(color);
-// }
-// if (ls != null){
-// plb.setStyle(ls);
-// }
-// }
-// }
-//
-// Chart chart = new Chart(plot);
-// chart.setAntiAlias(true);
-// this.charPanel.setChart(chart);
-// this.charPanel.paintGraphics();
-// }
-
- private LineStyles getLineStyle(String style){
- LineStyles ls = null;
- if (style.contains("--")){
- ls = LineStyles.DASH;
- } else if (style.contains(":")){
- ls = LineStyles.DOT;
- } else if (style.contains("-.")) {
- ls = LineStyles.DASHDOT;
- } else if (style.contains("-")) {
- ls = LineStyles.SOLID;
- }
-
- return ls;
- }
-
- private PointStyle getPointStyle(String style) {
- PointStyle ps = null;
- if (style.contains("o")) {
- ps = PointStyle.Circle;
- } else if (style.contains("D")){
- ps = PointStyle.Diamond;
- } else if (style.contains("+")){
- ps = PointStyle.Plus;
- } else if (style.contains("s")){
- ps = PointStyle.Square;
- } else if (style.contains("*")){
- ps = PointStyle.StarLines;
- } else if (style.contains("^")){
- ps = PointStyle.UpTriangle;
- } else if (style.contains("x")){
- ps = PointStyle.XCross;
- }
-
- return ps;
- }
-
- private Color getColor(String style) {
- if (style.contains("r")) {
- return Color.red;
- } else if (style.contains("k")) {
- return Color.black;
- } else if (style.contains("b")) {
- return Color.blue;
- } else if (style.contains("g")) {
- return Color.green;
- } else if (style.contains("g")) {
- return Color.white;
- } else {
- return null;
- }
- }
-
- private int getSymbolInterval(int n){
- int i;
- int v = 20;
- if (n < v)
- i = 1;
- else {
- i = n / v;
- }
-
- return i;
- }
-
- /**
- * Set axis limits
- * @param limits Limits
- */
- public void axis(List limits){
- if (limits.size() == 4){
- double xmin = Double.parseDouble(limits.get(0).toString());
- double xmax = Double.parseDouble(limits.get(1).toString());
- double ymin = Double.parseDouble(limits.get(2).toString());
- double ymax = Double.parseDouble(limits.get(3).toString());
- XY1DPlot plot = (XY1DPlot)this.charPanel.getChart().getPlot();
- plot.setDrawExtent(new Extent(xmin, xmax, ymin, ymax));
- this.charPanel.paintGraphics();
- }
- }
-
- /**
- * Set y axis label
- * @param label Y axis label
- */
- public void ylabel(String label){
- XY1DPlot plot = (XY1DPlot)this.charPanel.getChart().getPlot();
- plot.getYAxis().setLabel(label);
- plot.getYAxis().setDrawLabel(true);
- this.charPanel.paintGraphics();
- }
-
- /**
- * Set y axis label
- * @param label Y axis label
- */
- public void xlabel(String label){
- XY1DPlot plot = (XY1DPlot)this.charPanel.getChart().getPlot();
- plot.getXAxis().setLabel(label);
- plot.getXAxis().setDrawLabel(true);
- this.charPanel.paintGraphics();
- }
-
- //
- //
- /**
- * Show figure form
- */
- public void show() {
- ChartForm form = new ChartForm(this.charPanel);
- form.setSize(600, 500);
- form.setLocationRelativeTo(null);
- form.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
- form.setVisible(true);
- this.charPanel.paintGraphics();
- }
- //
- //
- /**
- * Get line space data list
- * @param min Minimum
- * @param max Maximum
- * @param n Number
- * @return Data list
- */
- public List linespace(double min, double max, int n){
- List values = new ArrayList();
- double delta = (max - min) / (n - 1);
- for (int i = 0; i < n; i++){
- values.add(min + delta * i);
- }
-
- return values;
- }
-
- /**
- * Get sine values
- * @param values Input values
- * @return Sine values
- */
- public List sin(List values){
- List rvalues = new ArrayList();
- for (Double v : values){
- rvalues.add(Math.sin(v));
- }
-
- return rvalues;
- }
- //
- //
-}
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.meteoinfo.script;
+
+import java.awt.Color;
+import java.util.ArrayList;
+import java.util.List;
+import javax.swing.WindowConstants;
+import org.meteoinfo.chart.ChartPanel;
+import org.meteoinfo.chart.plot.XY1DPlot;
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.legend.PointStyle;
+import org.meteoinfo.legend.LineStyles;
+
+/**
+ *
+ * @author yaqiang
+ */
+public class MeteoInfoPlot {
+
+ //
+ private boolean batchMode;
+ private ChartPanel charPanel;
+
+ //
+ //
+ /**
+ * Constructor
+ */
+ public MeteoInfoPlot() {
+ this.batchMode = true;
+ this.charPanel = new ChartPanel(null);
+ }
+
+ //
+ //
+ //
+ //
+
+ //
+// /**
+// * Plot
+// *
+// * @param yValues Y values
+// */
+// public void plot(List yValues) {
+// List xValues = new ArrayList();
+// for (int i = 0; i < yValues.size(); i++) {
+// xValues.add(i);
+// }
+//
+// this.plot(xValues, yValues);
+// }
+
+// /**
+// * Plot
+// *
+// * @param xValues X values
+// * @param yValues Y values
+// */
+// public void plot(List xValues, List yValues) {
+// this.plot(xValues, yValues, "");
+// }
+
+// /**
+// * Plot
+// *
+// * @param xValues X values
+// * @param yValues Y values
+// * @param style Plot style
+// */
+// public void plot(List xValues, List yValues, String style) {
+// if (xValues.size() != yValues.size()) {
+// System.out.println("The size of x and y values are not same!");
+// return;
+// }
+//
+// XYArrayDataset dataset = new XYArrayDataset(xValues, yValues, "S_1");
+// XY1DPlot plot = new XY1DPlot(dataset);
+//
+// if (!style.isEmpty()) {
+// Color color = this.getColor(style);
+// PointStyle ps = this.getPointStyle(style);
+// LineStyles ls = this.getLineStyle(style);
+// if (ps != null) {
+// if (ls == null){
+// plot.setChartPlotMethod(ChartPlotMethod.POINT);
+// PointBreak pb = plot.getPointBreak(0);
+// pb.setSize(8);
+// pb.setStyle(this.getPointStyle(style));
+// if (color != null) {
+// pb.setColor(color);
+// }
+// } else {
+// plot.setChartPlotMethod(ChartPlotMethod.LINE_POINT);
+// PolylineBreak plb = plot.getPolylineBreak(0);
+// plb.setStyle(ls);
+// plb.setDrawSymbol(true);
+// plb.setSymbolStyle(ps);
+// plb.setSymbolInterval(this.getSymbolInterval(xValues.size()));
+// if (color != null) {
+// plb.setColor(color);
+// plb.setSymbolColor(color);
+// }
+// }
+// } else {
+// plot.setChartPlotMethod(ChartPlotMethod.LINE);
+// PolylineBreak plb = plot.getPolylineBreak(0);
+// if (color != null) {
+// plb.setColor(color);
+// }
+// if (ls != null){
+// plb.setStyle(ls);
+// }
+// }
+// }
+//
+// Chart chart = new Chart(plot);
+// chart.setAntiAlias(true);
+// this.charPanel.setChart(chart);
+// this.charPanel.paintGraphics();
+// }
+
+ private LineStyles getLineStyle(String style){
+ LineStyles ls = null;
+ if (style.contains("--")){
+ ls = LineStyles.DASH;
+ } else if (style.contains(":")){
+ ls = LineStyles.DOT;
+ } else if (style.contains("-.")) {
+ ls = LineStyles.DASHDOT;
+ } else if (style.contains("-")) {
+ ls = LineStyles.SOLID;
+ }
+
+ return ls;
+ }
+
+ private PointStyle getPointStyle(String style) {
+ PointStyle ps = null;
+ if (style.contains("o")) {
+ ps = PointStyle.Circle;
+ } else if (style.contains("D")){
+ ps = PointStyle.Diamond;
+ } else if (style.contains("+")){
+ ps = PointStyle.Plus;
+ } else if (style.contains("s")){
+ ps = PointStyle.Square;
+ } else if (style.contains("*")){
+ ps = PointStyle.StarLines;
+ } else if (style.contains("^")){
+ ps = PointStyle.UpTriangle;
+ } else if (style.contains("x")){
+ ps = PointStyle.XCross;
+ }
+
+ return ps;
+ }
+
+ private Color getColor(String style) {
+ if (style.contains("r")) {
+ return Color.red;
+ } else if (style.contains("k")) {
+ return Color.black;
+ } else if (style.contains("b")) {
+ return Color.blue;
+ } else if (style.contains("g")) {
+ return Color.green;
+ } else if (style.contains("g")) {
+ return Color.white;
+ } else {
+ return null;
+ }
+ }
+
+ private int getSymbolInterval(int n){
+ int i;
+ int v = 20;
+ if (n < v)
+ i = 1;
+ else {
+ i = n / v;
+ }
+
+ return i;
+ }
+
+ /**
+ * Set axis limits
+ * @param limits Limits
+ */
+ public void axis(List limits){
+ if (limits.size() == 4){
+ double xmin = Double.parseDouble(limits.get(0).toString());
+ double xmax = Double.parseDouble(limits.get(1).toString());
+ double ymin = Double.parseDouble(limits.get(2).toString());
+ double ymax = Double.parseDouble(limits.get(3).toString());
+ XY1DPlot plot = (XY1DPlot)this.charPanel.getChart().getPlot();
+ plot.setDrawExtent(new Extent(xmin, xmax, ymin, ymax));
+ this.charPanel.paintGraphics();
+ }
+ }
+
+ /**
+ * Set y axis label
+ * @param label Y axis label
+ */
+ public void ylabel(String label){
+ XY1DPlot plot = (XY1DPlot)this.charPanel.getChart().getPlot();
+ plot.getYAxis().setLabel(label);
+ plot.getYAxis().setDrawLabel(true);
+ this.charPanel.paintGraphics();
+ }
+
+ /**
+ * Set y axis label
+ * @param label Y axis label
+ */
+ public void xlabel(String label){
+ XY1DPlot plot = (XY1DPlot)this.charPanel.getChart().getPlot();
+ plot.getXAxis().setLabel(label);
+ plot.getXAxis().setDrawLabel(true);
+ this.charPanel.paintGraphics();
+ }
+
+ //
+ //
+ /**
+ * Show figure form
+ */
+ public void show() {
+ ChartForm form = new ChartForm(this.charPanel);
+ form.setSize(600, 500);
+ form.setLocationRelativeTo(null);
+ form.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
+ form.setVisible(true);
+ this.charPanel.paintGraphics();
+ }
+ //
+ //
+ /**
+ * Get line space data list
+ * @param min Minimum
+ * @param max Maximum
+ * @param n Number
+ * @return Data list
+ */
+ public List linespace(double min, double max, int n){
+ List values = new ArrayList();
+ double delta = (max - min) / (n - 1);
+ for (int i = 0; i < n; i++){
+ values.add(min + delta * i);
+ }
+
+ return values;
+ }
+
+ /**
+ * Get sine values
+ * @param values Input values
+ * @return Sine values
+ */
+ public List sin(List values){
+ List rvalues = new ArrayList();
+ for (Double v : values){
+ rvalues.add(Math.sin(v));
+ }
+
+ return rvalues;
+ }
+ //
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/script/MeteoInfoScript.java b/MeteoInfoLib/src/main/java/org/meteoinfo/script/MeteoInfoScript.java
index c813e171..95629950 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/script/MeteoInfoScript.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/script/MeteoInfoScript.java
@@ -1,624 +1,624 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.meteoinfo.script;
-
-import java.awt.Color;
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import javax.swing.WindowConstants;
-import org.meteoinfo.chart.ChartPanel;
-import org.meteoinfo.chart.ChartText;
-import org.meteoinfo.chart.plot.XY1DPlot;
-import org.meteoinfo.data.GridData;
-import org.meteoinfo.data.mapdata.MapDataManage;
-import org.meteoinfo.data.meteodata.DimensionSet;
-import org.meteoinfo.data.meteodata.DrawMeteoData;
-import org.meteoinfo.data.meteodata.DrawType2D;
-import org.meteoinfo.data.meteodata.MeteoDataInfo;
-import org.meteoinfo.data.meteodata.PlotDimension;
-import org.meteoinfo.legend.PointStyle;
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.layer.MapLayer;
-import org.meteoinfo.layout.MapLayout;
-import org.meteoinfo.legend.LineStyles;
-import org.meteoinfo.legend.MapFrame;
-import org.meteoinfo.legend.PolygonBreak;
-import org.meteoinfo.map.MapView;
-
-/**
- *
- * @author yaqiang
- */
-public class MeteoInfoScript {
-
- //
- private boolean batchMode;
- private List dataInfoList;
- private MeteoDataInfo currentDataInfo;
- private MapLayout mapLayout;
- private ChartPanel chartPanel;
- private DrawType2D drawType2D;
- private PlotDimension plotDimension;
- private String startUpPath;
- private boolean isMap;
- private DimensionSet dimensionSet;
-
- //
- //
- /**
- * Constructor
- * @param path Start up path
- */
- public MeteoInfoScript(String path) {
- this.startUpPath = path;
- this.batchMode = true;
- this.mapLayout = new MapLayout();
- this.chartPanel = new ChartPanel(null);
- dataInfoList = new ArrayList();
- drawType2D = DrawType2D.Contour;
- this.plotDimension = PlotDimension.Lat_Lon;
- this.isMap = true;
-
- //Add default map layer
- //String fn = path + File.separator + "map" + File.separator + "country1.shp";
- String fn = "D:/Temp/map/country1.shp";
- if (new File(fn).exists()){
- try {
- MapLayer layer = MapDataManage.loadLayer(fn);
- PolygonBreak pgb = (PolygonBreak)layer.getLegendScheme().getLegendBreaks().get(0);
- pgb.setDrawFill(false);
- MapFrame mapFrame = mapLayout.getActiveMapFrame();
- MapView mapView = mapFrame.getMapView();
- mapView.setLockViewUpdate(true);
- mapFrame.addLayer(layer);
- mapFrame.setGridXDelt(60);
- mapFrame.setGridYDelt(30);
- mapLayout.getActiveLayoutMap().zoomToExtentLonLatEx(mapView.getLayersWholeExtent());
- mapView.setLockViewUpdate(false);
- } catch (Exception ex) {
- Logger.getLogger(MeteoInfoScript.class.getName()).log(Level.SEVERE, null, ex);
- }
- }
- }
-
- //
- //
- //
- //
- //
- /**
- * Add a meteo data info
- *
- * @param aDataInfo The meteo data info
- */
- public void addMeteoData(MeteoDataInfo aDataInfo) {
- dataInfoList.add(aDataInfo);
- currentDataInfo = aDataInfo;
- }
-
- /**
- * Open GrADS data file
- *
- * @param fileName GrADS data file name
- * @return MeteoDataInfo
- */
- public MeteoDataInfo openGrADSData(String fileName) {
- MeteoDataInfo aDataInfo = new MeteoDataInfo();
- aDataInfo.openGrADSData(fileName);
- addMeteoData(aDataInfo);
-
- return aDataInfo;
- }
-
- /**
- * Open ARL data file
- *
- * @param fileName ARL data file name
- * @return MeteoDataInfo
- */
- public MeteoDataInfo openARLData(String fileName) {
- MeteoDataInfo aDataInfo = new MeteoDataInfo();
- aDataInfo.openARLData(fileName);
- addMeteoData(aDataInfo);
-
- return aDataInfo;
- }
-
- /**
- * Open ASCII grid data file
- *
- * @param fileName ASCII grid data file name
- * @return MeteoDataInfo
- */
- public MeteoDataInfo openASCIIGridData(String fileName) {
- MeteoDataInfo aDataInfo = new MeteoDataInfo();
- aDataInfo.openASCIIGridData(fileName);
- addMeteoData(aDataInfo);
-
- return aDataInfo;
- }
-
- /**
- * Open Surfer grid data file
- *
- * @param fileName Surfer grid data file name
- * @return MeteoDataInfo
- */
- public MeteoDataInfo openSurferGridData(String fileName) {
- MeteoDataInfo aDataInfo = new MeteoDataInfo();
- aDataInfo.openSurferGridData(fileName);
- addMeteoData(aDataInfo);
-
- return aDataInfo;
- }
-
- /**
- * Open HYSPLIT concentration data file
- *
- * @param fileName HYSPLIT concentration data file name
- * @return MeteoDataInfo
- */
- public MeteoDataInfo openHYSPLITConcData(String fileName) {
- MeteoDataInfo aDataInfo = new MeteoDataInfo();
- aDataInfo.openHYSPLITConcData(fileName);
- addMeteoData(aDataInfo);
-
- return aDataInfo;
- }
-
- /**
- * Open HYSPLIT particle data file
- *
- * @param fileName HYSPLIT particle data file name
- * @return MeteoDataInfo
- */
- public MeteoDataInfo openHYSPITPartData(String fileName) {
- MeteoDataInfo aDataInfo = new MeteoDataInfo();
- aDataInfo.openHYSPLITPartData(fileName);
- addMeteoData(aDataInfo);
-
- return aDataInfo;
- }
-
- /**
- * Open HYSPLIT trajectory data file
- *
- * @param fileName HYSPLIT trajectory data file name
- * @return MeteoDataInfo
- */
- public MeteoDataInfo openHYSPLITTrajData(String fileName) {
- MeteoDataInfo aDataInfo = new MeteoDataInfo();
- aDataInfo.openHYSPLITTrajData(fileName);
- addMeteoData(aDataInfo);
-
- return aDataInfo;
- }
-
-// /**
-// * Open HYSPLIT trajectory data files
-// *
-// * @param fileNames HYSPLIT trajectory data file names
-// * @return MeteoDataInfo
-// */
-// public MeteoDataInfo openHYSPLITTrajData(String[] fileNames) {
-// MeteoDataInfo aDataInfo = new MeteoDataInfo();
-// aDataInfo.openHYSPLITTrajData(fileNames);
-// addMeteoData(aDataInfo);
-//
-// return aDataInfo;
-// }
-
- /**
- * Open NetCDF, GRIB, HDF... data file
- *
- * @param fileName NetCDF, GRIB, HDF... data file name
- * @return MeteoDataInfo
- */
- public MeteoDataInfo openNetCDFData(String fileName) {
- MeteoDataInfo aDataInfo = new MeteoDataInfo();
- aDataInfo.openNetCDFData(fileName);
- addMeteoData(aDataInfo);
-
- return aDataInfo;
- }
-
- /**
- * Open Lon/Lat station data file
- *
- * @param fileName Lon/Lat station data file name
- * @return MeteoDataInfo
- */
- public MeteoDataInfo openLonLatData(String fileName) {
- MeteoDataInfo aDataInfo = new MeteoDataInfo();
- aDataInfo.openLonLatData(fileName);
- addMeteoData(aDataInfo);
-
- return aDataInfo;
- }
-
- /**
- * Open MICAPS data file
- *
- * @param fileName MICAPS data file name
- * @return MeteoDataInfo
- */
- public MeteoDataInfo openMICAPSData(String fileName) {
- MeteoDataInfo aDataInfo = new MeteoDataInfo();
- aDataInfo.openMICAPSData(fileName);
- addMeteoData(aDataInfo);
-
- return aDataInfo;
- }
-
- /**
- * Open MM5 output data file
- *
- * @param fileName MM5 output data file name
- * @return MeteoDataInfo
- */
- public MeteoDataInfo openMM5Data(String fileName) {
- MeteoDataInfo aDataInfo = new MeteoDataInfo();
- aDataInfo.openMM5Data(fileName);
- addMeteoData(aDataInfo);
-
- return aDataInfo;
- }
-
- /**
- * Open MM5 intermedia data file
- *
- * @param fileName MM5 intermedia data file name
- * @return MeteoDataInfo
- */
- public MeteoDataInfo openMM5IMData(String fileName) {
- MeteoDataInfo aDataInfo = new MeteoDataInfo();
- aDataInfo.openMM5IMData(fileName);
- addMeteoData(aDataInfo);
-
- return aDataInfo;
- }
-
- /**
- * Set plot dimension
- * @param pdStr Plot dimension
- */
- public void setPlotDimension(String pdStr){
- PlotDimension pd = null;
- if (pdStr.equalsIgnoreCase("lat_lon"))
- pd = PlotDimension.Lat_Lon;
-
- if (pd != null)
- this.currentDataInfo.setDimensionSet(pd);
- }
-
- //
- //
- public void title(String title){
- if (this.isMap){
- this.mapLayout.addText(title, 280, 20, 16);
- this.mapLayout.paintGraphics();
- } else {
- this.chartPanel.getChart().setTitle(new ChartText(title));
- this.chartPanel.paintGraphics();
- }
- }
- //
- //
- /**
- * Dislay
- *
- * @param varName Variable name
- */
- public void display(String varName) {
- if (!this.isMap)
- this.map();
-
- if (currentDataInfo.isGridData()) {
- GridData gdata = this.currentDataInfo.getGridData(varName);
- MapLayer layer = DrawMeteoData.createContourLayer(gdata, varName, varName);
- if (mapLayout == null) {
- mapLayout = new MapLayout();
- }
-
- MapFrame mapFrame = mapLayout.getActiveMapFrame();
- MapView mapView = mapFrame.getMapView();
- mapView.setLockViewUpdate(true);
- mapFrame.addLayer(layer);
- mapLayout.getActiveLayoutMap().zoomToExtentLonLatEx(mapView.getMeteoLayersExtent());
- mapView.setLockViewUpdate(false);
- mapLayout.paintGraphics();
- }
- }
-
- //
- //
-// /**
-// * Plot
-// *
-// * @param yValues Y values
-// */
-// public void plot(List yValues) {
-// List xValues = new ArrayList();
-// for (int i = 0; i < yValues.size(); i++) {
-// xValues.add(i);
-// }
-//
-// this.plot(xValues, yValues);
-// }
-//
-// /**
-// * Plot
-// *
-// * @param xValues X values
-// * @param yValues Y values
-// */
-// public void plot(List xValues, List yValues) {
-// this.plot(xValues, yValues, "");
-// }
-//
-// /**
-// * Plot
-// *
-// * @param xValues X values
-// * @param yValues Y values
-// * @param style Plot style
-// */
-// public void plot(List xValues, List yValues, String style) {
-// if (this.isMap)
-// this.figure();
-//
-// if (xValues.size() != yValues.size()) {
-// System.out.println("The size of x and y values are not same!");
-// return;
-// }
-//
-// XYArrayDataset dataset = new XYArrayDataset(xValues, yValues, "S_1");
-// XY1DPlot plot = new XY1DPlot(dataset);
-//
-// if (!style.isEmpty()) {
-// Color color = this.getColor(style);
-// PointStyle ps = this.getPointStyle(style);
-// LineStyles ls = this.getLineStyle(style);
-// if (ps != null) {
-// if (ls == null){
-// plot.setChartPlotMethod(ChartPlotMethod.POINT);
-// PointBreak pb = plot.getPointBreak(0);
-// pb.setSize(8);
-// pb.setStyle(ps);
-// if (color != null) {
-// pb.setColor(color);
-// }
-// } else {
-// plot.setChartPlotMethod(ChartPlotMethod.LINE_POINT);
-// PolylineBreak plb = plot.getPolylineBreak(0);
-// plb.setStyle(ls);
-// plb.setDrawSymbol(true);
-// plb.setSymbolStyle(ps);
-// plb.setSymbolInterval(this.getSymbolInterval(xValues.size()));
-// if (color != null) {
-// plb.setColor(color);
-// plb.setSymbolColor(color);
-// }
-// }
-// } else {
-// plot.setChartPlotMethod(ChartPlotMethod.LINE);
-// PolylineBreak plb = plot.getPolylineBreak(0);
-// if (color != null) {
-// plb.setColor(color);
-// }
-// if (ls != null){
-// plb.setStyle(ls);
-// }
-// }
-// }
-//
-// Chart chart = new Chart(plot);
-// chart.setAntiAlias(true);
-// this.chartPanel.setChart(chart);
-// this.chartPanel.paintGraphics();
-// }
-
- private LineStyles getLineStyle(String style){
- LineStyles ls = null;
- if (style.contains("--")){
- ls = LineStyles.DASH;
- } else if (style.contains(":")){
- ls = LineStyles.DOT;
- } else if (style.contains("-.")) {
- ls = LineStyles.DASHDOT;
- } else if (style.contains("-")) {
- ls = LineStyles.SOLID;
- }
-
- return ls;
- }
-
- private PointStyle getPointStyle(String style) {
- PointStyle ps = null;
- if (style.contains("o")) {
- ps = PointStyle.Circle;
- } else if (style.contains("D")){
- ps = PointStyle.Diamond;
- } else if (style.contains("+")){
- ps = PointStyle.Plus;
- } else if (style.contains("s")){
- ps = PointStyle.Square;
- } else if (style.contains("*")){
- ps = PointStyle.StarLines;
- } else if (style.contains("^")){
- ps = PointStyle.UpTriangle;
- } else if (style.contains("x")){
- ps = PointStyle.XCross;
- }
-
- return ps;
- }
-
- private Color getColor(String style) {
- if (style.contains("r")) {
- return Color.red;
- } else if (style.contains("k")) {
- return Color.black;
- } else if (style.contains("b")) {
- return Color.blue;
- } else if (style.contains("g")) {
- return Color.green;
- } else if (style.contains("w")) {
- return Color.white;
- } else {
- return null;
- }
- }
-
- private int getSymbolInterval(int n){
- int i;
- int v = 20;
- if (n < v)
- i = 1;
- else {
- i = n / v;
- }
-
- return i;
- }
-
- /**
- * Set axis limits
- * @param limits Limits
- */
- public void axis(List limits){
- if (limits.size() == 4){
- double xmin = Double.parseDouble(limits.get(0).toString());
- double xmax = Double.parseDouble(limits.get(1).toString());
- double ymin = Double.parseDouble(limits.get(2).toString());
- double ymax = Double.parseDouble(limits.get(3).toString());
- XY1DPlot plot = (XY1DPlot)this.chartPanel.getChart().getPlot();
- plot.setDrawExtent(new Extent(xmin, xmax, ymin, ymax));
- this.chartPanel.paintGraphics();
- }
- }
-
- /**
- * Set y axis label
- * @param label Y axis label
- */
- public void ylabel(String label){
- XY1DPlot plot = (XY1DPlot)this.chartPanel.getChart().getPlot();
- plot.getYAxis().setLabel(label);
- plot.getYAxis().setDrawLabel(true);
- this.chartPanel.paintGraphics();
- }
-
- /**
- * Set y axis label
- * @param label Y axis label
- */
- public void xlabel(String label){
- XY1DPlot plot = (XY1DPlot)this.chartPanel.getChart().getPlot();
- plot.getXAxis().setLabel(label);
- plot.getXAxis().setDrawLabel(true);
- this.chartPanel.paintGraphics();
- }
-
- //
- //
- /**
- * Show figure form
- */
- public void showfigure() {
- ChartForm form = new ChartForm(this.chartPanel);
- form.setSize(600, 500);
- form.setLocationRelativeTo(null);
- form.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
- form.setVisible(true);
- this.chartPanel.paintGraphics();
- }
-
- /**
- * Show map form
- */
- public void show(){
- if (this.isMap)
- this.showmap();
- else
- this.showfigure();
- }
-
- /**
- * Show map or figure form
- * @param i I
- */
- public void show(int i){
- if (i == 0){
- this.showmap();
- } else
- this.showfigure();
- }
-
- /**
- * Switch to map mode
- */
- public void map(){
- this.isMap = true;
- System.out.println("Switch to map mode");
- }
-
- /**
- * Switch to figure mode
- */
- public void figure() {
- this.isMap = false;
- System.out.println("Switch to figure mode");
- }
-
- /**
- * Create and show map figure form
- */
- public void showmap() {
- MapForm frame = new MapForm(this.mapLayout);
- frame.setSize(750, 540);
- frame.setLocationRelativeTo(null);
- frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
- frame.setVisible(true);
- }
- //
- //
- /**
- * Get line space data list
- * @param min Minimum
- * @param max Maximum
- * @param n Number
- * @return Data list
- */
- public List linespace(double min, double max, int n){
- List values = new ArrayList();
- double delta = (max - min) / (n - 1);
- for (int i = 0; i < n; i++){
- values.add(min + delta * i);
- }
-
- return values;
- }
-
- /**
- * Get sine values
- * @param values Input values
- * @return Sine values
- */
- public List sin(List values){
- List rvalues = new ArrayList();
- for (Double v : values){
- rvalues.add(Math.sin(v));
- }
-
- return rvalues;
- }
- //
- //
-}
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.meteoinfo.script;
+
+import java.awt.Color;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.WindowConstants;
+import org.meteoinfo.chart.ChartPanel;
+import org.meteoinfo.chart.ChartText;
+import org.meteoinfo.chart.plot.XY1DPlot;
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.data.GridData;
+import org.meteoinfo.data.mapdata.MapDataManage;
+import org.meteoinfo.data.meteodata.DimensionSet;
+import org.meteoinfo.data.meteodata.DrawMeteoData;
+import org.meteoinfo.data.meteodata.DrawType2D;
+import org.meteoinfo.data.meteodata.MeteoDataInfo;
+import org.meteoinfo.data.meteodata.PlotDimension;
+import org.meteoinfo.legend.PointStyle;
+import org.meteoinfo.layer.MapLayer;
+import org.meteoinfo.layout.MapLayout;
+import org.meteoinfo.legend.LineStyles;
+import org.meteoinfo.legend.MapFrame;
+import org.meteoinfo.legend.PolygonBreak;
+import org.meteoinfo.map.MapView;
+
+/**
+ *
+ * @author yaqiang
+ */
+public class MeteoInfoScript {
+
+ //
+ private boolean batchMode;
+ private List dataInfoList;
+ private MeteoDataInfo currentDataInfo;
+ private MapLayout mapLayout;
+ private ChartPanel chartPanel;
+ private DrawType2D drawType2D;
+ private PlotDimension plotDimension;
+ private String startUpPath;
+ private boolean isMap;
+ private DimensionSet dimensionSet;
+
+ //
+ //
+ /**
+ * Constructor
+ * @param path Start up path
+ */
+ public MeteoInfoScript(String path) {
+ this.startUpPath = path;
+ this.batchMode = true;
+ this.mapLayout = new MapLayout();
+ this.chartPanel = new ChartPanel(null);
+ dataInfoList = new ArrayList();
+ drawType2D = DrawType2D.Contour;
+ this.plotDimension = PlotDimension.Lat_Lon;
+ this.isMap = true;
+
+ //Add default map layer
+ //String fn = path + File.separator + "map" + File.separator + "country1.shp";
+ String fn = "D:/Temp/map/country1.shp";
+ if (new File(fn).exists()){
+ try {
+ MapLayer layer = MapDataManage.loadLayer(fn);
+ PolygonBreak pgb = (PolygonBreak)layer.getLegendScheme().getLegendBreaks().get(0);
+ pgb.setDrawFill(false);
+ MapFrame mapFrame = mapLayout.getActiveMapFrame();
+ MapView mapView = mapFrame.getMapView();
+ mapView.setLockViewUpdate(true);
+ mapFrame.addLayer(layer);
+ mapFrame.setGridXDelt(60);
+ mapFrame.setGridYDelt(30);
+ mapLayout.getActiveLayoutMap().zoomToExtentLonLatEx(mapView.getLayersWholeExtent());
+ mapView.setLockViewUpdate(false);
+ } catch (Exception ex) {
+ Logger.getLogger(MeteoInfoScript.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+ }
+
+ //
+ //
+ //
+ //
+ //
+ /**
+ * Add a meteo data info
+ *
+ * @param aDataInfo The meteo data info
+ */
+ public void addMeteoData(MeteoDataInfo aDataInfo) {
+ dataInfoList.add(aDataInfo);
+ currentDataInfo = aDataInfo;
+ }
+
+ /**
+ * Open GrADS data file
+ *
+ * @param fileName GrADS data file name
+ * @return MeteoDataInfo
+ */
+ public MeteoDataInfo openGrADSData(String fileName) {
+ MeteoDataInfo aDataInfo = new MeteoDataInfo();
+ aDataInfo.openGrADSData(fileName);
+ addMeteoData(aDataInfo);
+
+ return aDataInfo;
+ }
+
+ /**
+ * Open ARL data file
+ *
+ * @param fileName ARL data file name
+ * @return MeteoDataInfo
+ */
+ public MeteoDataInfo openARLData(String fileName) {
+ MeteoDataInfo aDataInfo = new MeteoDataInfo();
+ aDataInfo.openARLData(fileName);
+ addMeteoData(aDataInfo);
+
+ return aDataInfo;
+ }
+
+ /**
+ * Open ASCII grid data file
+ *
+ * @param fileName ASCII grid data file name
+ * @return MeteoDataInfo
+ */
+ public MeteoDataInfo openASCIIGridData(String fileName) {
+ MeteoDataInfo aDataInfo = new MeteoDataInfo();
+ aDataInfo.openASCIIGridData(fileName);
+ addMeteoData(aDataInfo);
+
+ return aDataInfo;
+ }
+
+ /**
+ * Open Surfer grid data file
+ *
+ * @param fileName Surfer grid data file name
+ * @return MeteoDataInfo
+ */
+ public MeteoDataInfo openSurferGridData(String fileName) {
+ MeteoDataInfo aDataInfo = new MeteoDataInfo();
+ aDataInfo.openSurferGridData(fileName);
+ addMeteoData(aDataInfo);
+
+ return aDataInfo;
+ }
+
+ /**
+ * Open HYSPLIT concentration data file
+ *
+ * @param fileName HYSPLIT concentration data file name
+ * @return MeteoDataInfo
+ */
+ public MeteoDataInfo openHYSPLITConcData(String fileName) {
+ MeteoDataInfo aDataInfo = new MeteoDataInfo();
+ aDataInfo.openHYSPLITConcData(fileName);
+ addMeteoData(aDataInfo);
+
+ return aDataInfo;
+ }
+
+ /**
+ * Open HYSPLIT particle data file
+ *
+ * @param fileName HYSPLIT particle data file name
+ * @return MeteoDataInfo
+ */
+ public MeteoDataInfo openHYSPITPartData(String fileName) {
+ MeteoDataInfo aDataInfo = new MeteoDataInfo();
+ aDataInfo.openHYSPLITPartData(fileName);
+ addMeteoData(aDataInfo);
+
+ return aDataInfo;
+ }
+
+ /**
+ * Open HYSPLIT trajectory data file
+ *
+ * @param fileName HYSPLIT trajectory data file name
+ * @return MeteoDataInfo
+ */
+ public MeteoDataInfo openHYSPLITTrajData(String fileName) {
+ MeteoDataInfo aDataInfo = new MeteoDataInfo();
+ aDataInfo.openHYSPLITTrajData(fileName);
+ addMeteoData(aDataInfo);
+
+ return aDataInfo;
+ }
+
+// /**
+// * Open HYSPLIT trajectory data files
+// *
+// * @param fileNames HYSPLIT trajectory data file names
+// * @return MeteoDataInfo
+// */
+// public MeteoDataInfo openHYSPLITTrajData(String[] fileNames) {
+// MeteoDataInfo aDataInfo = new MeteoDataInfo();
+// aDataInfo.openHYSPLITTrajData(fileNames);
+// addMeteoData(aDataInfo);
+//
+// return aDataInfo;
+// }
+
+ /**
+ * Open NetCDF, GRIB, HDF... data file
+ *
+ * @param fileName NetCDF, GRIB, HDF... data file name
+ * @return MeteoDataInfo
+ */
+ public MeteoDataInfo openNetCDFData(String fileName) {
+ MeteoDataInfo aDataInfo = new MeteoDataInfo();
+ aDataInfo.openNetCDFData(fileName);
+ addMeteoData(aDataInfo);
+
+ return aDataInfo;
+ }
+
+ /**
+ * Open Lon/Lat station data file
+ *
+ * @param fileName Lon/Lat station data file name
+ * @return MeteoDataInfo
+ */
+ public MeteoDataInfo openLonLatData(String fileName) {
+ MeteoDataInfo aDataInfo = new MeteoDataInfo();
+ aDataInfo.openLonLatData(fileName);
+ addMeteoData(aDataInfo);
+
+ return aDataInfo;
+ }
+
+ /**
+ * Open MICAPS data file
+ *
+ * @param fileName MICAPS data file name
+ * @return MeteoDataInfo
+ */
+ public MeteoDataInfo openMICAPSData(String fileName) {
+ MeteoDataInfo aDataInfo = new MeteoDataInfo();
+ aDataInfo.openMICAPSData(fileName);
+ addMeteoData(aDataInfo);
+
+ return aDataInfo;
+ }
+
+ /**
+ * Open MM5 output data file
+ *
+ * @param fileName MM5 output data file name
+ * @return MeteoDataInfo
+ */
+ public MeteoDataInfo openMM5Data(String fileName) {
+ MeteoDataInfo aDataInfo = new MeteoDataInfo();
+ aDataInfo.openMM5Data(fileName);
+ addMeteoData(aDataInfo);
+
+ return aDataInfo;
+ }
+
+ /**
+ * Open MM5 intermedia data file
+ *
+ * @param fileName MM5 intermedia data file name
+ * @return MeteoDataInfo
+ */
+ public MeteoDataInfo openMM5IMData(String fileName) {
+ MeteoDataInfo aDataInfo = new MeteoDataInfo();
+ aDataInfo.openMM5IMData(fileName);
+ addMeteoData(aDataInfo);
+
+ return aDataInfo;
+ }
+
+ /**
+ * Set plot dimension
+ * @param pdStr Plot dimension
+ */
+ public void setPlotDimension(String pdStr){
+ PlotDimension pd = null;
+ if (pdStr.equalsIgnoreCase("lat_lon"))
+ pd = PlotDimension.Lat_Lon;
+
+ if (pd != null)
+ this.currentDataInfo.setDimensionSet(pd);
+ }
+
+ //
+ //
+ public void title(String title){
+ if (this.isMap){
+ this.mapLayout.addText(title, 280, 20, 16);
+ this.mapLayout.paintGraphics();
+ } else {
+ this.chartPanel.getChart().setTitle(new ChartText(title));
+ this.chartPanel.paintGraphics();
+ }
+ }
+ //
+ //
+ /**
+ * Dislay
+ *
+ * @param varName Variable name
+ */
+ public void display(String varName) {
+ if (!this.isMap)
+ this.map();
+
+ if (currentDataInfo.isGridData()) {
+ GridData gdata = this.currentDataInfo.getGridData(varName);
+ MapLayer layer = DrawMeteoData.createContourLayer(gdata, varName, varName);
+ if (mapLayout == null) {
+ mapLayout = new MapLayout();
+ }
+
+ MapFrame mapFrame = mapLayout.getActiveMapFrame();
+ MapView mapView = mapFrame.getMapView();
+ mapView.setLockViewUpdate(true);
+ mapFrame.addLayer(layer);
+ mapLayout.getActiveLayoutMap().zoomToExtentLonLatEx(mapView.getMeteoLayersExtent());
+ mapView.setLockViewUpdate(false);
+ mapLayout.paintGraphics();
+ }
+ }
+
+ //
+ //
+// /**
+// * Plot
+// *
+// * @param yValues Y values
+// */
+// public void plot(List yValues) {
+// List xValues = new ArrayList();
+// for (int i = 0; i < yValues.size(); i++) {
+// xValues.add(i);
+// }
+//
+// this.plot(xValues, yValues);
+// }
+//
+// /**
+// * Plot
+// *
+// * @param xValues X values
+// * @param yValues Y values
+// */
+// public void plot(List xValues, List yValues) {
+// this.plot(xValues, yValues, "");
+// }
+//
+// /**
+// * Plot
+// *
+// * @param xValues X values
+// * @param yValues Y values
+// * @param style Plot style
+// */
+// public void plot(List xValues, List yValues, String style) {
+// if (this.isMap)
+// this.figure();
+//
+// if (xValues.size() != yValues.size()) {
+// System.out.println("The size of x and y values are not same!");
+// return;
+// }
+//
+// XYArrayDataset dataset = new XYArrayDataset(xValues, yValues, "S_1");
+// XY1DPlot plot = new XY1DPlot(dataset);
+//
+// if (!style.isEmpty()) {
+// Color color = this.getColor(style);
+// PointStyle ps = this.getPointStyle(style);
+// LineStyles ls = this.getLineStyle(style);
+// if (ps != null) {
+// if (ls == null){
+// plot.setChartPlotMethod(ChartPlotMethod.POINT);
+// PointBreak pb = plot.getPointBreak(0);
+// pb.setSize(8);
+// pb.setStyle(ps);
+// if (color != null) {
+// pb.setColor(color);
+// }
+// } else {
+// plot.setChartPlotMethod(ChartPlotMethod.LINE_POINT);
+// PolylineBreak plb = plot.getPolylineBreak(0);
+// plb.setStyle(ls);
+// plb.setDrawSymbol(true);
+// plb.setSymbolStyle(ps);
+// plb.setSymbolInterval(this.getSymbolInterval(xValues.size()));
+// if (color != null) {
+// plb.setColor(color);
+// plb.setSymbolColor(color);
+// }
+// }
+// } else {
+// plot.setChartPlotMethod(ChartPlotMethod.LINE);
+// PolylineBreak plb = plot.getPolylineBreak(0);
+// if (color != null) {
+// plb.setColor(color);
+// }
+// if (ls != null){
+// plb.setStyle(ls);
+// }
+// }
+// }
+//
+// Chart chart = new Chart(plot);
+// chart.setAntiAlias(true);
+// this.chartPanel.setChart(chart);
+// this.chartPanel.paintGraphics();
+// }
+
+ private LineStyles getLineStyle(String style){
+ LineStyles ls = null;
+ if (style.contains("--")){
+ ls = LineStyles.DASH;
+ } else if (style.contains(":")){
+ ls = LineStyles.DOT;
+ } else if (style.contains("-.")) {
+ ls = LineStyles.DASHDOT;
+ } else if (style.contains("-")) {
+ ls = LineStyles.SOLID;
+ }
+
+ return ls;
+ }
+
+ private PointStyle getPointStyle(String style) {
+ PointStyle ps = null;
+ if (style.contains("o")) {
+ ps = PointStyle.Circle;
+ } else if (style.contains("D")){
+ ps = PointStyle.Diamond;
+ } else if (style.contains("+")){
+ ps = PointStyle.Plus;
+ } else if (style.contains("s")){
+ ps = PointStyle.Square;
+ } else if (style.contains("*")){
+ ps = PointStyle.StarLines;
+ } else if (style.contains("^")){
+ ps = PointStyle.UpTriangle;
+ } else if (style.contains("x")){
+ ps = PointStyle.XCross;
+ }
+
+ return ps;
+ }
+
+ private Color getColor(String style) {
+ if (style.contains("r")) {
+ return Color.red;
+ } else if (style.contains("k")) {
+ return Color.black;
+ } else if (style.contains("b")) {
+ return Color.blue;
+ } else if (style.contains("g")) {
+ return Color.green;
+ } else if (style.contains("w")) {
+ return Color.white;
+ } else {
+ return null;
+ }
+ }
+
+ private int getSymbolInterval(int n){
+ int i;
+ int v = 20;
+ if (n < v)
+ i = 1;
+ else {
+ i = n / v;
+ }
+
+ return i;
+ }
+
+ /**
+ * Set axis limits
+ * @param limits Limits
+ */
+ public void axis(List limits){
+ if (limits.size() == 4){
+ double xmin = Double.parseDouble(limits.get(0).toString());
+ double xmax = Double.parseDouble(limits.get(1).toString());
+ double ymin = Double.parseDouble(limits.get(2).toString());
+ double ymax = Double.parseDouble(limits.get(3).toString());
+ XY1DPlot plot = (XY1DPlot)this.chartPanel.getChart().getPlot();
+ plot.setDrawExtent(new Extent(xmin, xmax, ymin, ymax));
+ this.chartPanel.paintGraphics();
+ }
+ }
+
+ /**
+ * Set y axis label
+ * @param label Y axis label
+ */
+ public void ylabel(String label){
+ XY1DPlot plot = (XY1DPlot)this.chartPanel.getChart().getPlot();
+ plot.getYAxis().setLabel(label);
+ plot.getYAxis().setDrawLabel(true);
+ this.chartPanel.paintGraphics();
+ }
+
+ /**
+ * Set y axis label
+ * @param label Y axis label
+ */
+ public void xlabel(String label){
+ XY1DPlot plot = (XY1DPlot)this.chartPanel.getChart().getPlot();
+ plot.getXAxis().setLabel(label);
+ plot.getXAxis().setDrawLabel(true);
+ this.chartPanel.paintGraphics();
+ }
+
+ //
+ //
+ /**
+ * Show figure form
+ */
+ public void showfigure() {
+ ChartForm form = new ChartForm(this.chartPanel);
+ form.setSize(600, 500);
+ form.setLocationRelativeTo(null);
+ form.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
+ form.setVisible(true);
+ this.chartPanel.paintGraphics();
+ }
+
+ /**
+ * Show map form
+ */
+ public void show(){
+ if (this.isMap)
+ this.showmap();
+ else
+ this.showfigure();
+ }
+
+ /**
+ * Show map or figure form
+ * @param i I
+ */
+ public void show(int i){
+ if (i == 0){
+ this.showmap();
+ } else
+ this.showfigure();
+ }
+
+ /**
+ * Switch to map mode
+ */
+ public void map(){
+ this.isMap = true;
+ System.out.println("Switch to map mode");
+ }
+
+ /**
+ * Switch to figure mode
+ */
+ public void figure() {
+ this.isMap = false;
+ System.out.println("Switch to figure mode");
+ }
+
+ /**
+ * Create and show map figure form
+ */
+ public void showmap() {
+ MapForm frame = new MapForm(this.mapLayout);
+ frame.setSize(750, 540);
+ frame.setLocationRelativeTo(null);
+ frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
+ frame.setVisible(true);
+ }
+ //
+ //
+ /**
+ * Get line space data list
+ * @param min Minimum
+ * @param max Maximum
+ * @param n Number
+ * @return Data list
+ */
+ public List linespace(double min, double max, int n){
+ List values = new ArrayList();
+ double delta = (max - min) / (n - 1);
+ for (int i = 0; i < n; i++){
+ values.add(min + delta * i);
+ }
+
+ return values;
+ }
+
+ /**
+ * Get sine values
+ * @param values Input values
+ * @return Sine values
+ */
+ public List sin(List values){
+ List rvalues = new ArrayList();
+ for (Double v : values){
+ rvalues.add(Math.sin(v));
+ }
+
+ return rvalues;
+ }
+ //
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/shape/ChartGraphic.java b/MeteoInfoLib/src/main/java/org/meteoinfo/shape/ChartGraphic.java
index 288a6b7a..db70f604 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/shape/ChartGraphic.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/shape/ChartGraphic.java
@@ -1,143 +1,143 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.meteoinfo.shape;
-
-import org.meteoinfo.global.PointD;
-import org.meteoinfo.legend.ChartBreak;
-import org.w3c.dom.Attr;
-import org.w3c.dom.DOMException;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-
-/**
- *
- * @author Yaqiang Wang
- */
-public class ChartGraphic extends Graphic {
-
- //
- private PointD startPosition;
-
- //
- //
- /**
- * Constructor
- */
- public ChartGraphic() {
-
- }
-
- /**
- * Constructor
- *
- * @param shape Point shape
- * @param legend Chart break
- */
- public ChartGraphic(PointShape shape, ChartBreak legend) {
- super(shape, legend);
- startPosition = (PointD) shape.getPoint().clone();
- }
-
- //
- //
- /**
- * Get start position
- *
- * @return Start position
- */
- public PointD getStartPosition() {
- return startPosition;
- }
-
- /**
- * Set start postion
- *
- * @param value Start position
- */
- public void setStartPosition(PointD value) {
- startPosition = value;
- }
-
- /**
- * Set point shape
- *
- * @param aShape Point shape
- */
- public void setShape(PointShape aShape) {
- super.setShape(aShape);
- startPosition = (PointD) aShape.getPoint().clone();
- }
-
- //
- //
- /**
- * Export to XML document
- *
- * @param doc XML document
- * @param parent Parent XML element
- */
- @Override
- public void exportToXML(Document doc, Element parent) {
- Element graphic = doc.createElement("Graphic");
- this.addShape(doc, graphic, this.getShape());
- this.addLegend(doc, graphic, this.getLegend(), this.getShape().getShapeType());
- this.addStartPosition(doc, graphic, startPosition);
-
- parent.appendChild(graphic);
- }
-
- private void addStartPosition(Document doc, Element parent, PointD pos) {
- Element startPos = doc.createElement("StartPosition");
-
- Attr xAttr = doc.createAttribute("X");
- Attr yAttr = doc.createAttribute("Y");
-
- xAttr.setValue(String.valueOf(pos.X));
- yAttr.setValue(String.valueOf(pos.Y));
-
- startPos.setAttributeNode(xAttr);
- startPos.setAttributeNode(yAttr);
-
- parent.appendChild(startPos);
- }
-
- /**
- * Import from xml node
- *
- * @param graphicNode Graphic xml node
- */
- @Override
- public void importFromXML(Element graphicNode) {
- Node shape = graphicNode.getElementsByTagName("Shape").item(0);
- this.setShape((PointShape)loadShape(shape));
-
- Node legend = graphicNode.getElementsByTagName("Legend").item(0);
- this.setLegend(loadLegend(legend, this.getShape().getShapeType()));
-
- Node startPos = graphicNode.getElementsByTagName("StartPosition").item(0);
- if (startPos != null) {
- PointD sP = this.loadStartPosition(startPos);
- if (sP != null) {
- this.startPosition = sP;
- }
- }
- }
-
- private PointD loadStartPosition(Node startPosNode) {
- PointD sP = null;
- try {
- double x = Double.parseDouble(startPosNode.getAttributes().getNamedItem("X").getNodeValue());
- double y = Double.parseDouble(startPosNode.getAttributes().getNamedItem("Y").getNodeValue());
- sP = new PointD(x, y);
- } catch (DOMException e) {
- } catch (NumberFormatException e) {
- }
-
- return sP;
- }
- //
-}
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.meteoinfo.shape;
+
+import org.meteoinfo.common.PointD;
+import org.meteoinfo.legend.ChartBreak;
+import org.w3c.dom.Attr;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ *
+ * @author Yaqiang Wang
+ */
+public class ChartGraphic extends Graphic {
+
+ //
+ private PointD startPosition;
+
+ //
+ //
+ /**
+ * Constructor
+ */
+ public ChartGraphic() {
+
+ }
+
+ /**
+ * Constructor
+ *
+ * @param shape Point shape
+ * @param legend Chart break
+ */
+ public ChartGraphic(PointShape shape, ChartBreak legend) {
+ super(shape, legend);
+ startPosition = (PointD) shape.getPoint().clone();
+ }
+
+ //
+ //
+ /**
+ * Get start position
+ *
+ * @return Start position
+ */
+ public PointD getStartPosition() {
+ return startPosition;
+ }
+
+ /**
+ * Set start postion
+ *
+ * @param value Start position
+ */
+ public void setStartPosition(PointD value) {
+ startPosition = value;
+ }
+
+ /**
+ * Set point shape
+ *
+ * @param aShape Point shape
+ */
+ public void setShape(PointShape aShape) {
+ super.setShape(aShape);
+ startPosition = (PointD) aShape.getPoint().clone();
+ }
+
+ //
+ //
+ /**
+ * Export to XML document
+ *
+ * @param doc XML document
+ * @param parent Parent XML element
+ */
+ @Override
+ public void exportToXML(Document doc, Element parent) {
+ Element graphic = doc.createElement("Graphic");
+ this.addShape(doc, graphic, this.getShape());
+ this.addLegend(doc, graphic, this.getLegend(), this.getShape().getShapeType());
+ this.addStartPosition(doc, graphic, startPosition);
+
+ parent.appendChild(graphic);
+ }
+
+ private void addStartPosition(Document doc, Element parent, PointD pos) {
+ Element startPos = doc.createElement("StartPosition");
+
+ Attr xAttr = doc.createAttribute("X");
+ Attr yAttr = doc.createAttribute("Y");
+
+ xAttr.setValue(String.valueOf(pos.X));
+ yAttr.setValue(String.valueOf(pos.Y));
+
+ startPos.setAttributeNode(xAttr);
+ startPos.setAttributeNode(yAttr);
+
+ parent.appendChild(startPos);
+ }
+
+ /**
+ * Import from xml node
+ *
+ * @param graphicNode Graphic xml node
+ */
+ @Override
+ public void importFromXML(Element graphicNode) {
+ Node shape = graphicNode.getElementsByTagName("Shape").item(0);
+ this.setShape((PointShape)loadShape(shape));
+
+ Node legend = graphicNode.getElementsByTagName("Legend").item(0);
+ this.setLegend(loadLegend(legend, this.getShape().getShapeType()));
+
+ Node startPos = graphicNode.getElementsByTagName("StartPosition").item(0);
+ if (startPos != null) {
+ PointD sP = this.loadStartPosition(startPos);
+ if (sP != null) {
+ this.startPosition = sP;
+ }
+ }
+ }
+
+ private PointD loadStartPosition(Node startPosNode) {
+ PointD sP = null;
+ try {
+ double x = Double.parseDouble(startPosNode.getAttributes().getNamedItem("X").getNodeValue());
+ double y = Double.parseDouble(startPosNode.getAttributes().getNamedItem("Y").getNodeValue());
+ sP = new PointD(x, y);
+ } catch (DOMException e) {
+ } catch (NumberFormatException e) {
+ }
+
+ return sP;
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/shape/CircleShape.java b/MeteoInfoLib/src/main/java/org/meteoinfo/shape/CircleShape.java
index dbfa1ecc..c5267487 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/shape/CircleShape.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/shape/CircleShape.java
@@ -15,10 +15,11 @@ package org.meteoinfo.shape;
import java.util.ArrayList;
import java.util.List;
-import org.meteoinfo.geoprocess.GeoComputation;
-import org.meteoinfo.global.PointD;
-/**
+import org.meteoinfo.common.PointD;
+import org.meteoinfo.geoprocess.GeoComputation;
+
+ /**
* Circle shape class
*
* @author Yaqiang Wang
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/shape/CloudCoverage.java b/MeteoInfoLib/src/main/java/org/meteoinfo/shape/CloudCoverage.java
index aced7d3b..7f3b061e 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/shape/CloudCoverage.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/shape/CloudCoverage.java
@@ -13,9 +13,9 @@
*/
package org.meteoinfo.shape;
-import org.meteoinfo.global.PointD;
+ import org.meteoinfo.common.PointD;
-/**
+ /**
* Cloud coverage class
*
* @author Yaqiang Wang
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/shape/CubicShape.java b/MeteoInfoLib/src/main/java/org/meteoinfo/shape/CubicShape.java
index bbf6ed45..ee74fc53 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/shape/CubicShape.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/shape/CubicShape.java
@@ -2,8 +2,8 @@ package org.meteoinfo.shape;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
-import org.meteoinfo.global.MIMath;
-import org.meteoinfo.global.PointD;
+import org.meteoinfo.common.PointD;
+import org.meteoinfo.geoprocess.GeometryUtil;
import java.util.ArrayList;
import java.util.List;
@@ -41,7 +41,7 @@ public class CubicShape extends Shape{
for (int i = 0; i < 8; i++) {
this.points.add(new PointZ());
}
- this.setExtent(MIMath.getPointsExtent(this.points));
+ this.setExtent(GeometryUtil.getPointsExtent(this.points));
}
/**
@@ -50,7 +50,7 @@ public class CubicShape extends Shape{
public CubicShape(List points) {
super();
this.points = points;
- this.setExtent(MIMath.getPointsExtent(this.points));
+ this.setExtent(GeometryUtil.getPointsExtent(this.points));
}
@Override
@@ -77,7 +77,7 @@ public class CubicShape extends Shape{
*/
public void setPoints(List extends PointD> value) {
this.points = (List)value;
- this.setExtent(MIMath.getPointsExtent(this.points));
+ this.setExtent(GeometryUtil.getPointsExtent(this.points));
}
/**
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/shape/CylinderShape.java b/MeteoInfoLib/src/main/java/org/meteoinfo/shape/CylinderShape.java
index 59e3044e..51f60966 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/shape/CylinderShape.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/shape/CylinderShape.java
@@ -2,8 +2,8 @@ package org.meteoinfo.shape;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
-import org.meteoinfo.global.MIMath;
-import org.meteoinfo.global.PointD;
+import org.meteoinfo.common.PointD;
+import org.meteoinfo.geoprocess.GeometryUtil;
import java.util.ArrayList;
import java.util.List;
@@ -21,7 +21,7 @@ public class CylinderShape extends Shape {
this.points = new ArrayList<>();
this.points.add(new PointZ());
this.points.add(new PointZ());
- this.setExtent(MIMath.getPointsExtent(this.points));
+ this.setExtent(GeometryUtil.getPointsExtent(this.points));
}
/**
@@ -33,7 +33,7 @@ public class CylinderShape extends Shape {
super();
this.points = points;
this.radius = radius;
- this.setExtent(MIMath.getPointsExtent(this.points));
+ this.setExtent(GeometryUtil.getPointsExtent(this.points));
}
/**
@@ -48,7 +48,7 @@ public class CylinderShape extends Shape {
this.points.add(p1);
this.points.add(p2);
this.radius = radius;
- this.setExtent(MIMath.getPointsExtent(this.points));
+ this.setExtent(GeometryUtil.getPointsExtent(this.points));
}
@Override
@@ -84,7 +84,7 @@ public class CylinderShape extends Shape {
*/
public void setPoints(List extends PointD> value) {
this.points = (List)value;
- this.setExtent(MIMath.getPointsExtent(this.points));
+ this.setExtent(GeometryUtil.getPointsExtent(this.points));
}
/**
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/shape/Graphic.java b/MeteoInfoLib/src/main/java/org/meteoinfo/shape/Graphic.java
index 5c3d1b95..04c74d6d 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/shape/Graphic.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/shape/Graphic.java
@@ -1,710 +1,711 @@
- /* Copyright 2012 Yaqiang Wang,
- * yaqiang.wang@gmail.com
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.shape;
-
-import org.meteoinfo.legend.MarkerType;
-import org.meteoinfo.legend.PointStyle;
-import org.meteoinfo.global.colors.ColorUtil;
-import org.meteoinfo.global.PointD;
-import org.meteoinfo.layout.ResizeAbility;
-import org.meteoinfo.legend.BreakTypes;
-import org.meteoinfo.legend.ChartBreak;
-import org.meteoinfo.legend.ChartTypes;
-import org.meteoinfo.legend.ColorBreak;
-import org.meteoinfo.legend.LabelBreak;
-import org.meteoinfo.legend.LineStyles;
-import org.meteoinfo.legend.PointBreak;
-import org.meteoinfo.legend.PolygonBreak;
-import org.meteoinfo.legend.PolylineBreak;
-import org.meteoinfo.legend.VectorBreak;
-import java.awt.Color;
-import java.awt.Font;
-import java.util.ArrayList;
-import java.util.List;
-import org.meteoinfo.global.Extent;
-import org.w3c.dom.Attr;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-/**
- * Graphic class
- *
- * @author Yaqiang Wang
- */
-public class Graphic {
- //
-
- private Shape _shape = null;
- private ColorBreak _legend = null;
- private ResizeAbility _resizeAbility = ResizeAbility.ResizeAll;
- //
- //
-
- /**
- * Constructor
- */
- public Graphic() {
- }
-
- /**
- * Constructor
- *
- * @param shape a shape
- * @param legend a legend
- */
- public Graphic(Shape shape, ColorBreak legend) {
- _shape = shape;
- _legend = legend;
- updateResizeAbility();
- }
- //
- //
-
- /**
- * Get shape
- *
- * @return Shape
- */
- public Shape getShape() {
- return _shape;
- }
-
- /**
- * Set shape
- *
- * @param aShape a shape
- */
- public void setShape(Shape aShape) {
- _shape = aShape;
- updateResizeAbility();
- }
-
- /**
- * Get legend
- *
- * @return Legend
- */
- public ColorBreak getLegend() {
- return _legend;
- }
-
- public void setLegend(ColorBreak legend) {
- _legend = legend;
- updateResizeAbility();
- updateResizeAbility();
- }
-
- /**
- * Get resize ability
- *
- * @return Resize ability
- */
- public ResizeAbility getResizeAbility() {
- return _resizeAbility;
- }
-
- /**
- * Get extent
- *
- * @return The extent
- */
- public Extent getExtent() {
- return this._shape.getExtent();
- }
-
- /**
- * Set extent
- * @param value The extent
- */
- public void setExtent(Extent value){
- this._shape.setExtent(value);
- }
-
- /**
- * Get is single legend or not
- * @return Boolean
- */
- public boolean isSingleLegend(){
- return true;
- }
-
- /**
- * Get if is GraphicCollection
- * @return Boolean
- */
- public boolean isCollection(){
- return false;
- }
-
- //
- //
- /**
- * Get graphics number
- * @return 1
- */
- public int getNumGraphics(){
- return 1;
- }
-
- /**
- * Get Graphic by index
- * @param idx Index
- * @return Graphic
- */
- public Graphic getGraphicN(int idx){
- return this;
- }
-
- /**
- * Get graphic list
- * @return Graphic list
- */
- public List getGraphics(){
- List gs = new ArrayList<>();
- gs.add(this);
- return gs;
- }
-
- private void updateResizeAbility() {
- if (_shape != null && _legend != null) {
- switch (_shape.getShapeType()) {
- case Point:
- switch (_legend.getBreakType()) {
- case PointBreak:
- _resizeAbility = ResizeAbility.SameWidthHeight;
- break;
- case LabelBreak:
- case ChartBreak:
- _resizeAbility = ResizeAbility.None;
- break;
- }
- break;
- case Circle:
- _resizeAbility = ResizeAbility.SameWidthHeight;
- break;
- default:
- _resizeAbility = ResizeAbility.ResizeAll;
- break;
- }
- }
- }
-
- /**
- * Vertice edited update
- *
- * @param vIdx Vertice index
- * @param newX New X
- * @param newY New Y
- */
- public void verticeMoveUpdate(int vIdx, double newX, double newY) {
- List points = (List)_shape.getPoints();
- switch (_shape.getShapeType()){
- case Polygon:
- case CurvePolygon:
- case Rectangle:
- int last = points.size() - 1;
- if (vIdx == 0) {
- if (points.get(0).X == points.get(last).X && points.get(0).Y == points.get(last).Y) {
- points.get(last).X = newX;
- points.get(last).Y = newY;
- }
- } else if (vIdx == last){
- if (points.get(0).X == points.get(last).X && points.get(0).Y == points.get(last).Y) {
- points.get(0).X = newX;
- points.get(0).Y = newY;
- }
- }
- break;
- }
-
- PointD aP = points.get(vIdx);
- aP.X = newX;
- aP.Y = newY;
- //points.set(vIdx, aP);
- _shape.setPoints(points);
- }
-
- /**
- * Vertice edited update
- *
- * @param vIdx Vertice index
- * @param point The add vertice
- */
- public void verticeAddUpdate(int vIdx, PointD point) {
- List points = (List)_shape.getPoints();
- points.add(vIdx, point);
- _shape.setPoints(points);
- }
-
- /**
- * Vertice edited update
- *
- * @param vIdx Vertice index
- */
- public void verticeRemoveUpdate(int vIdx) {
- List points = (List)_shape.getPoints();
- points.remove(vIdx);
- _shape.setPoints(points);
- }
-
- /**
- * Export to XML document
- * @param doc XML document
- * @param parent Parent XML element
- */
- public void exportToXML(Document doc, Element parent) {
- Element graphic = doc.createElement("Graphic");
- addShape(doc, graphic, _shape);
- addLegend(doc, graphic, _legend, _shape.getShapeType());
-
- parent.appendChild(graphic);
- }
-
- /**
- * Add shape to XML document
- * @param doc XML document
- * @param parent Parent XML element
- * @param aShape The shape
- */
- protected void addShape(Document doc, Element parent, Shape aShape) {
- Element shape = doc.createElement("Shape");
- boolean hasAngle = aShape.getShapeType() == ShapeTypes.Ellipse;
-
- //Add general attribute
- Attr shapeType = doc.createAttribute("ShapeType");
- Attr visible = doc.createAttribute("Visible");
- Attr selected = doc.createAttribute("Selected");
-
- //shapeType.InnerText = Enum.GetName(typeof(ShapeTypes), aShape.ShapeType);
- shapeType.setValue(aShape.getShapeType().toString());
- visible.setValue(String.valueOf(aShape.isVisible()));
- selected.setValue(String.valueOf(aShape.isSelected()));
-
- shape.setAttributeNode(shapeType);
- shape.setAttributeNode(visible);
- shape.setAttributeNode(selected);
-
- if (hasAngle){
- Attr angle = doc.createAttribute("Angle");
- angle.setValue(String.valueOf(((EllipseShape)aShape).getAngle()));
- shape.setAttributeNode(angle);
- }
-
- //Add points
- Element points = doc.createElement("Points");
- List pointList = (List)aShape.getPoints();
- for (PointD aPoint : pointList) {
- Element point = doc.createElement("Point");
- Attr x = doc.createAttribute("X");
- Attr y = doc.createAttribute("Y");
- x.setValue(String.valueOf(aPoint.X));
- y.setValue(String.valueOf(aPoint.Y));
- point.setAttributeNode(x);
- point.setAttributeNode(y);
-
- points.appendChild(point);
- }
-
- shape.appendChild(points);
-
- parent.appendChild(shape);
- }
-
- /**
- * Add legend to XML document
- * @param doc XML document
- * @param parent Parent XML element
- * @param aLegend The legend
- * @param shapeType The shape type
- */
- protected void addLegend(Document doc, Element parent, ColorBreak aLegend, ShapeTypes shapeType) {
- Element legend = doc.createElement("Legend");
- Attr color = doc.createAttribute("Color");
- color.setValue(ColorUtil.toHexEncoding(aLegend.getColor()));
- legend.setAttributeNode(color);
-
- Attr legendType = doc.createAttribute("LegendType");
- Attr size;
- Attr style;
- Attr outlineColor;
- Attr drawOutline;
- Attr drawFill;
- legendType.setValue(aLegend.getBreakType().toString());
- switch (aLegend.getBreakType()) {
- case PointBreak:
- PointBreak aPB = (PointBreak) aLegend;
- outlineColor = doc.createAttribute("OutlineColor");
- size = doc.createAttribute("Size");
- style = doc.createAttribute("Style");
- drawOutline = doc.createAttribute("DrawOutline");
- drawFill = doc.createAttribute("DrawFill");
- Attr markerType = doc.createAttribute("MarkerType");
- Attr fontName = doc.createAttribute("FontName");
- Attr charIndex = doc.createAttribute("CharIndex");
- Attr imagePath = doc.createAttribute("ImagePath");
- Attr angle = doc.createAttribute("Angle");
-
- //legendType.InnerText = "PointBreak";
- outlineColor.setValue(ColorUtil.toHexEncoding(aPB.getOutlineColor()));
- size.setValue(String.valueOf(aPB.getSize()));
- style.setValue(aPB.getStyle().toString());
- drawOutline.setValue(String.valueOf(aPB.isDrawOutline()));
- drawFill.setValue(String.valueOf(aPB.isDrawFill()));
- markerType.setValue(aPB.getMarkerType().toString());
- fontName.setValue(aPB.getFontName());
- charIndex.setValue(String.valueOf(aPB.getCharIndex()));
- imagePath.setValue(aPB.getImagePath());
- angle.setValue(String.valueOf(aPB.getAngle()));
-
- legend.setAttributeNode(legendType);
- legend.setAttributeNode(outlineColor);
- legend.setAttributeNode(size);
- legend.setAttributeNode(style);
- legend.setAttributeNode(drawOutline);
- legend.setAttributeNode(drawFill);
- legend.setAttributeNode(markerType);
- legend.setAttributeNode(fontName);
- legend.setAttributeNode(charIndex);
- legend.setAttributeNode(imagePath);
- legend.setAttributeNode(angle);
- break;
- case LabelBreak:
- LabelBreak aLB = (LabelBreak) aLegend;
- Attr text = doc.createAttribute("Text");
- angle = doc.createAttribute("Angle");
- fontName = doc.createAttribute("FontName");
- Attr fontSize = doc.createAttribute("FontSize");
- Attr fontBold = doc.createAttribute("FontBold");
- Attr yShift = doc.createAttribute("YShift");
-
- //legendType.InnerText = "LabelBreak";
- text.setValue(aLB.getText());
- angle.setValue(String.valueOf(aLB.getAngle()));
- fontName.setValue(aLB.getFont().getName());
- fontSize.setValue(String.valueOf(aLB.getFont().getSize()));
- fontBold.setValue(String.valueOf(aLB.getFont().isBold()));
- yShift.setValue(String.valueOf(aLB.getYShift()));
-
- legend.setAttributeNode(legendType);
- legend.setAttributeNode(text);
- legend.setAttributeNode(angle);
- legend.setAttributeNode(fontName);
- legend.setAttributeNode(fontSize);
- legend.setAttributeNode(fontBold);
- legend.setAttributeNode(yShift);
- break;
- case ChartBreak:
- ChartBreak aChB = (ChartBreak) aLegend;
- Attr shapeIndex = doc.createAttribute("ShapeIndex");
- Attr chartType = doc.createAttribute("ChartType");
- Attr chartData = doc.createAttribute("ChartData");
- Attr xShift = doc.createAttribute("XShift");
- yShift = doc.createAttribute("YShift");
- fontName = doc.createAttribute("FontName");
- fontSize = doc.createAttribute("FontSize");
- Attr labelColor = doc.createAttribute("LabelColor");
-
- shapeIndex.setValue(String.valueOf(aChB.getShapeIndex()));
- //legendType.InnerText = "ChartBreak";
- chartType.setValue(aChB.getChartType().toString());
- String cdata = "";
- for (int i = 0; i < aChB.getItemNum(); i++) {
- if (i == 0) {
- cdata = String.valueOf(aChB.getChartData().get(i));
- } else {
- cdata += "," + String.valueOf(aChB.getChartData().get(i));
- }
- }
- chartData.setValue(cdata);
- xShift.setValue(String.valueOf(aChB.getXShift()));
- yShift.setValue(String.valueOf(aChB.getYShift()));
- fontName.setValue(aChB.getLabelFont().getFontName());
- fontSize.setValue(String.valueOf(aChB.getLabelFont().getSize()));
- labelColor.setValue(ColorUtil.toHexEncoding(aChB.getLabelColor()));
-
- legend.setAttributeNode(legendType);
- legend.setAttributeNode(shapeIndex);
- legend.setAttributeNode(chartType);
- legend.setAttributeNode(chartData);
- legend.setAttributeNode(xShift);
- legend.setAttributeNode(yShift);
- legend.setAttributeNode(fontName);
- legend.setAttributeNode(fontSize);
- legend.setAttributeNode(labelColor);
- break;
- case VectorBreak:
- //legendType.InnerText = "VectorBreak";
- legend.setAttributeNode(legendType);
- break;
- case PolylineBreak:
- PolylineBreak aPLB = (PolylineBreak) aLegend;
- size = doc.createAttribute("Size");
- style = doc.createAttribute("Style");
- Attr drawSymbol = doc.createAttribute("DrawSymbol");
- Attr symbolSize = doc.createAttribute("SymbolSize");
- Attr symbolStyle = doc.createAttribute("SymbolStyle");
- Attr symbolColor = doc.createAttribute("SymbolColor");
- Attr symbolInterval = doc.createAttribute("SymbolInterval");
-
- //legendType.InnerText = "PolylineBreak";
- size.setValue(String.valueOf(aPLB.getWidth()));
- style.setValue(aPLB.getStyle().toString());
- drawSymbol.setValue(String.valueOf(aPLB.getDrawSymbol()));
- symbolSize.setValue(String.valueOf(aPLB.getSymbolSize()));
- symbolStyle.setValue(String.valueOf(aPLB.getSymbolStyle()));
- symbolColor.setValue(ColorUtil.toHexEncoding(aPLB.getSymbolColor()));
- symbolInterval.setValue(String.valueOf(aPLB.getSymbolInterval()));
-
- legend.setAttributeNode(legendType);
- legend.setAttributeNode(size);
- legend.setAttributeNode(style);
- legend.setAttributeNode(drawSymbol);
- legend.setAttributeNode(symbolSize);
- legend.setAttributeNode(symbolStyle);
- legend.setAttributeNode(symbolColor);
- legend.setAttributeNode(symbolInterval);
- break;
- case PolygonBreak:
- PolygonBreak aPGB = (PolygonBreak) aLegend;
- outlineColor = doc.createAttribute("OutlineColor");
- drawOutline = doc.createAttribute("DrawOutline");
- drawFill = doc.createAttribute("DrawFill");
- Attr outlineSize = doc.createAttribute("OutlineSize");
- //Attr usingHatchStyle = doc.createAttribute("UsingHatchStyle");
- //style = doc.createAttribute("Style");
- Attr backColor = doc.createAttribute("BackColor");
- //Attr transparencyPer = doc.createAttribute("TransparencyPercent");
- Attr isMaskout = doc.createAttribute("IsMaskout");
-
- //legendType.InnerText = "PolygonBreak";
- outlineColor.setValue(ColorUtil.toHexEncoding(aPGB.getOutlineColor()));
- drawOutline.setValue(String.valueOf(aPGB.isDrawOutline()));
- drawFill.setValue(String.valueOf(aPGB.isDrawFill()));
- outlineSize.setValue(String.valueOf(aPGB.getOutlineSize()));
- //usingHatchStyle.setValue(String.valueOf(aPGB.getUsingHatchStyle()));
- //style.setValue(String.valueOf(aPGB.getStyle()));
- backColor.setValue(ColorUtil.toHexEncoding(aPGB.getBackColor()));
- //transparencyPer.InnerText = aPGB.TransparencyPercent.ToString();
- isMaskout.setValue(String.valueOf(aPGB.isMaskout()));
-
- legend.setAttributeNode(legendType);
- legend.setAttributeNode(outlineColor);
- legend.setAttributeNode(drawOutline);
- legend.setAttributeNode(drawFill);
- legend.setAttributeNode(outlineSize);
- //legend.setAttributeNode(usingHatchStyle);
- //legend.setAttributeNode(style);
- legend.setAttributeNode(backColor);
- //legend.setAttributeNode(transparencyPer);
- legend.setAttributeNode(isMaskout);
- break;
- }
-
- parent.appendChild(legend);
- }
-
- /**
- * Import from xml node
- *
- * @param graphicNode Graphic xml node
- */
- public void importFromXML(Element graphicNode) {
- Node shape = graphicNode.getElementsByTagName("Shape").item(0);
- _shape = loadShape(shape);
-
- Node legend = graphicNode.getElementsByTagName("Legend").item(0);
- _legend = loadLegend(legend, _shape.getShapeType());
-
- updateResizeAbility();
- }
-
- protected Shape loadShape(Node shapeNode) {
- Shape aShape = null;
- try {
- ShapeTypes shapeType = ShapeTypes.valueOf(shapeNode.getAttributes().getNamedItem("ShapeType").getNodeValue());
- switch (shapeType) {
- case Point:
- aShape = new PointShape();
- break;
- case WindArraw:
- aShape = new WindArrow();
- break;
- case Polyline:
- aShape = new PolylineShape();
- break;
- case CurveLine:
- aShape = new CurveLineShape();
- break;
- case Circle:
- aShape = new CircleShape();
- break;
- case Polygon:
- case Rectangle:
- aShape = new PolygonShape();
- break;
- case CurvePolygon:
- aShape = new CurvePolygonShape();
- break;
- case Ellipse:
- aShape = new EllipseShape();
- break;
- }
-
- aShape.setVisible(Boolean.parseBoolean(shapeNode.getAttributes().getNamedItem("Visible").getNodeValue()));
- aShape.setSelected(Boolean.parseBoolean(shapeNode.getAttributes().getNamedItem("Selected").getNodeValue()));
- if (aShape.getShapeType() == ShapeTypes.Ellipse){
- Node angleNode = shapeNode.getAttributes().getNamedItem("Angle");
- if (angleNode != null)
- ((EllipseShape)aShape).setAngle(Float.parseFloat(angleNode.getNodeValue()));
- }
-
- List pointList = new ArrayList<>();
- Node pointsNode = ((Element)shapeNode).getElementsByTagName("Points").item(0);
- NodeList nl = ((Element)pointsNode).getElementsByTagName("Point");
- for (int i = 0; i < nl.getLength(); i++) {
- Node pNode = nl.item(i);
- PointD aPoint = new PointD(Double.parseDouble(pNode.getAttributes().getNamedItem("X").getNodeValue()),
- Double.parseDouble(pNode.getAttributes().getNamedItem("Y").getNodeValue()));
- pointList.add(aPoint);
- }
- aShape.setPoints(pointList);
- } catch (Exception e) {
- }
-
- return aShape;
- }
-
- protected ColorBreak loadLegend(Node legendNode, ShapeTypes shapeType) {
- ColorBreak legend = new ColorBreak();
- try {
- Color color = ColorUtil.parseToColor(legendNode.getAttributes().getNamedItem("Color").getNodeValue());
- String legendType = legendNode.getAttributes().getNamedItem("LegendType").getNodeValue();
- BreakTypes breakType = BreakTypes.valueOf(legendType);
- switch (breakType) {
- case PointBreak:
- PointBreak aPB = new PointBreak();
- try {
- aPB.setColor(color);
- aPB.setDrawFill(Boolean.parseBoolean(legendNode.getAttributes().getNamedItem("DrawFill").getNodeValue()));
- aPB.setDrawOutline(Boolean.parseBoolean(legendNode.getAttributes().getNamedItem("DrawOutline").getNodeValue()));
- aPB.setOutlineColor(ColorUtil.parseToColor(legendNode.getAttributes().getNamedItem("OutlineColor").getNodeValue()));
- aPB.setSize(Float.parseFloat(legendNode.getAttributes().getNamedItem("Size").getNodeValue()));
- aPB.setStyle(PointStyle.valueOf(legendNode.getAttributes().getNamedItem("Style").getNodeValue()));
- aPB.setMarkerType(MarkerType.valueOf(legendNode.getAttributes().getNamedItem("MarkerType").getNodeValue()));
- aPB.setFontName(legendNode.getAttributes().getNamedItem("FontName").getNodeValue());
- aPB.setCharIndex(Integer.parseInt(legendNode.getAttributes().getNamedItem("CharIndex").getNodeValue()));
- aPB.setImagePath(legendNode.getAttributes().getNamedItem("ImagePath").getNodeValue());
- aPB.setAngle(Float.parseFloat(legendNode.getAttributes().getNamedItem("Angle").getNodeValue()));
- } catch (Exception e) {
- } finally {
- legend = aPB;
- }
- break;
- case LabelBreak:
- LabelBreak aLB = new LabelBreak();
- try {
- aLB.setColor(color);
- aLB.setAngle(Float.parseFloat(legendNode.getAttributes().getNamedItem("Angle").getNodeValue()));
- aLB.setText(legendNode.getAttributes().getNamedItem("Text").getNodeValue());
- String fontName = legendNode.getAttributes().getNamedItem("FontName").getNodeValue();
- float fontSize = Float.parseFloat(legendNode.getAttributes().getNamedItem("FontSize").getNodeValue());
- boolean fontBold = Boolean.parseBoolean(legendNode.getAttributes().getNamedItem("FontBold").getNodeValue());
- if (fontBold) {
- aLB.setFont(new Font(fontName, Font.BOLD, (int) fontSize));
- } else {
- aLB.setFont(new Font(fontName, Font.PLAIN, (int) fontSize));
- }
-
- aLB.setYShift(Float.parseFloat(legendNode.getAttributes().getNamedItem("YShift").getNodeValue()));
- } catch (Exception e) {
- } finally {
- legend = aLB;
- }
- break;
- case ChartBreak:
- ChartBreak aChB = new ChartBreak(ChartTypes.BarChart);
- try {
- ChartTypes chartType = ChartTypes.valueOf(legendNode.getAttributes().getNamedItem("ChartType").getNodeValue());
- aChB = new ChartBreak(chartType);
- aChB.setShapeIndex(Integer.parseInt(legendNode.getAttributes().getNamedItem("ShapeIndex").getNodeValue()));
- List cData = new ArrayList();
- String[] cDataStr = legendNode.getAttributes().getNamedItem("ChartData").getNodeValue().split(",");
- for (int i = 0; i < cDataStr.length; i++) {
- cData.add(Float.parseFloat(cDataStr[i]));
- }
-
- aChB.setChartData(cData);
- aChB.setXShift(Integer.parseInt(legendNode.getAttributes().getNamedItem("XShift").getNodeValue()));
- aChB.setYShift(Integer.parseInt(legendNode.getAttributes().getNamedItem("YShift").getNodeValue()));
- String fontName = legendNode.getAttributes().getNamedItem("FontName").getNodeValue();
- float fontSize = Float.parseFloat(legendNode.getAttributes().getNamedItem("FontSize").getNodeValue());
- aChB.setLabelFont(new Font(fontName, Font.PLAIN, (int)fontSize));
- aChB.setLabelColor(ColorUtil.parseToColor(legendNode.getAttributes().getNamedItem("LabelColor").getNodeValue()));
- } catch (Exception e) {
- } finally {
- legend = aChB;
- }
- break;
- case VectorBreak:
- VectorBreak aVB = new VectorBreak();
- try {
- aVB.setColor(color);
- } catch (Exception e) {
- } finally {
- legend = aVB;
- }
- break;
- case PolylineBreak:
- PolylineBreak aPLB = new PolylineBreak();
- try {
- aPLB.setColor(color);
- aPLB.setWidth(Float.parseFloat(legendNode.getAttributes().getNamedItem("Size").getNodeValue()));
- aPLB.setStyle(LineStyles.valueOf(legendNode.getAttributes().getNamedItem("Style").getNodeValue()));
- aPLB.setDrawSymbol(Boolean.parseBoolean(legendNode.getAttributes().getNamedItem("DrawSymbol").getNodeValue()));
- aPLB.setSymbolSize(Float.parseFloat(legendNode.getAttributes().getNamedItem("SymbolSize").getNodeValue()));
- aPLB.setSymbolStyle(PointStyle.valueOf(legendNode.getAttributes().getNamedItem("SymbolStyle").getNodeValue()));
- aPLB.setSymbolColor(ColorUtil.parseToColor(legendNode.getAttributes().getNamedItem("SymbolColor").getNodeValue()));
- aPLB.setSymbolInterval(Integer.parseInt(legendNode.getAttributes().getNamedItem("SymbolInterval").getNodeValue()));
- } catch (Exception e) {
- } finally {
- legend = aPLB;
- }
- break;
- case PolygonBreak:
- PolygonBreak aPGB = new PolygonBreak();
- try {
- aPGB.setColor(color);
- aPGB.setDrawFill(Boolean.parseBoolean(legendNode.getAttributes().getNamedItem("DrawFill").getNodeValue()));
- aPGB.setDrawOutline(Boolean.parseBoolean(legendNode.getAttributes().getNamedItem("DrawOutline").getNodeValue()));
- aPGB.setOutlineSize(Float.parseFloat(legendNode.getAttributes().getNamedItem("OutlineSize").getNodeValue()));
- aPGB.setOutlineColor(ColorUtil.parseToColor(legendNode.getAttributes().getNamedItem("OutlineColor").getNodeValue()));
- //aPGB.UsingHatchStyle = bool.Parse(legendNode.Attributes["UsingHatchStyle"].InnerText);
- //aPGB.Style = (HatchStyle)Enum.Parse(typeof(HatchStyle), legendNode.Attributes["Style"].InnerText, true);
- aPGB.setBackColor(ColorUtil.parseToColor(legendNode.getAttributes().getNamedItem("BackColor").getNodeValue()));
- //aPGB.TransparencyPercent = int.Parse(legendNode.Attributes["TransparencyPercent"].InnerText);
- aPGB.setMaskout(Boolean.parseBoolean(legendNode.getAttributes().getNamedItem("IsMaskout").getNodeValue()));
- } catch (Exception e) {
- } {
- legend = aPGB;
- }
- break;
- }
- } catch (Exception e) {
- }
- return legend;
- }
- //
-}
+ /* Copyright 2012 Yaqiang Wang,
+ * yaqiang.wang@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ */
+package org.meteoinfo.shape;
+
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.PointD;
+import org.meteoinfo.legend.MarkerType;
+import org.meteoinfo.legend.PointStyle;
+import org.meteoinfo.global.colors.ColorUtil;
+import org.meteoinfo.layout.ResizeAbility;
+import org.meteoinfo.legend.BreakTypes;
+import org.meteoinfo.legend.ChartBreak;
+import org.meteoinfo.legend.ChartTypes;
+import org.meteoinfo.legend.ColorBreak;
+import org.meteoinfo.legend.LabelBreak;
+import org.meteoinfo.legend.LineStyles;
+import org.meteoinfo.legend.PointBreak;
+import org.meteoinfo.legend.PolygonBreak;
+import org.meteoinfo.legend.PolylineBreak;
+import org.meteoinfo.legend.VectorBreak;
+import java.awt.Color;
+import java.awt.Font;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * Graphic class
+ *
+ * @author Yaqiang Wang
+ */
+public class Graphic {
+ //
+
+ private Shape _shape = null;
+ private ColorBreak _legend = null;
+ private ResizeAbility _resizeAbility = ResizeAbility.ResizeAll;
+ //
+ //
+
+ /**
+ * Constructor
+ */
+ public Graphic() {
+ }
+
+ /**
+ * Constructor
+ *
+ * @param shape a shape
+ * @param legend a legend
+ */
+ public Graphic(Shape shape, ColorBreak legend) {
+ _shape = shape;
+ _legend = legend;
+ updateResizeAbility();
+ }
+ //
+ //
+
+ /**
+ * Get shape
+ *
+ * @return Shape
+ */
+ public Shape getShape() {
+ return _shape;
+ }
+
+ /**
+ * Set shape
+ *
+ * @param aShape a shape
+ */
+ public void setShape(Shape aShape) {
+ _shape = aShape;
+ updateResizeAbility();
+ }
+
+ /**
+ * Get legend
+ *
+ * @return Legend
+ */
+ public ColorBreak getLegend() {
+ return _legend;
+ }
+
+ public void setLegend(ColorBreak legend) {
+ _legend = legend;
+ updateResizeAbility();
+ updateResizeAbility();
+ }
+
+ /**
+ * Get resize ability
+ *
+ * @return Resize ability
+ */
+ public ResizeAbility getResizeAbility() {
+ return _resizeAbility;
+ }
+
+ /**
+ * Get extent
+ *
+ * @return The extent
+ */
+ public Extent getExtent() {
+ return this._shape.getExtent();
+ }
+
+ /**
+ * Set extent
+ * @param value The extent
+ */
+ public void setExtent(Extent value){
+ this._shape.setExtent(value);
+ }
+
+ /**
+ * Get is single legend or not
+ * @return Boolean
+ */
+ public boolean isSingleLegend(){
+ return true;
+ }
+
+ /**
+ * Get if is GraphicCollection
+ * @return Boolean
+ */
+ public boolean isCollection(){
+ return false;
+ }
+
+ //
+ //
+ /**
+ * Get graphics number
+ * @return 1
+ */
+ public int getNumGraphics(){
+ return 1;
+ }
+
+ /**
+ * Get Graphic by index
+ * @param idx Index
+ * @return Graphic
+ */
+ public Graphic getGraphicN(int idx){
+ return this;
+ }
+
+ /**
+ * Get graphic list
+ * @return Graphic list
+ */
+ public List getGraphics(){
+ List gs = new ArrayList<>();
+ gs.add(this);
+ return gs;
+ }
+
+ private void updateResizeAbility() {
+ if (_shape != null && _legend != null) {
+ switch (_shape.getShapeType()) {
+ case Point:
+ switch (_legend.getBreakType()) {
+ case PointBreak:
+ _resizeAbility = ResizeAbility.SameWidthHeight;
+ break;
+ case LabelBreak:
+ case ChartBreak:
+ _resizeAbility = ResizeAbility.None;
+ break;
+ }
+ break;
+ case Circle:
+ _resizeAbility = ResizeAbility.SameWidthHeight;
+ break;
+ default:
+ _resizeAbility = ResizeAbility.ResizeAll;
+ break;
+ }
+ }
+ }
+
+ /**
+ * Vertice edited update
+ *
+ * @param vIdx Vertice index
+ * @param newX New X
+ * @param newY New Y
+ */
+ public void verticeMoveUpdate(int vIdx, double newX, double newY) {
+ List points = (List)_shape.getPoints();
+ switch (_shape.getShapeType()){
+ case Polygon:
+ case CurvePolygon:
+ case Rectangle:
+ int last = points.size() - 1;
+ if (vIdx == 0) {
+ if (points.get(0).X == points.get(last).X && points.get(0).Y == points.get(last).Y) {
+ points.get(last).X = newX;
+ points.get(last).Y = newY;
+ }
+ } else if (vIdx == last){
+ if (points.get(0).X == points.get(last).X && points.get(0).Y == points.get(last).Y) {
+ points.get(0).X = newX;
+ points.get(0).Y = newY;
+ }
+ }
+ break;
+ }
+
+ PointD aP = points.get(vIdx);
+ aP.X = newX;
+ aP.Y = newY;
+ //points.set(vIdx, aP);
+ _shape.setPoints(points);
+ }
+
+ /**
+ * Vertice edited update
+ *
+ * @param vIdx Vertice index
+ * @param point The add vertice
+ */
+ public void verticeAddUpdate(int vIdx, PointD point) {
+ List points = (List)_shape.getPoints();
+ points.add(vIdx, point);
+ _shape.setPoints(points);
+ }
+
+ /**
+ * Vertice edited update
+ *
+ * @param vIdx Vertice index
+ */
+ public void verticeRemoveUpdate(int vIdx) {
+ List points = (List)_shape.getPoints();
+ points.remove(vIdx);
+ _shape.setPoints(points);
+ }
+
+ /**
+ * Export to XML document
+ * @param doc XML document
+ * @param parent Parent XML element
+ */
+ public void exportToXML(Document doc, Element parent) {
+ Element graphic = doc.createElement("Graphic");
+ addShape(doc, graphic, _shape);
+ addLegend(doc, graphic, _legend, _shape.getShapeType());
+
+ parent.appendChild(graphic);
+ }
+
+ /**
+ * Add shape to XML document
+ * @param doc XML document
+ * @param parent Parent XML element
+ * @param aShape The shape
+ */
+ protected void addShape(Document doc, Element parent, Shape aShape) {
+ Element shape = doc.createElement("Shape");
+ boolean hasAngle = aShape.getShapeType() == ShapeTypes.Ellipse;
+
+ //Add general attribute
+ Attr shapeType = doc.createAttribute("ShapeType");
+ Attr visible = doc.createAttribute("Visible");
+ Attr selected = doc.createAttribute("Selected");
+
+ //shapeType.InnerText = Enum.GetName(typeof(ShapeTypes), aShape.ShapeType);
+ shapeType.setValue(aShape.getShapeType().toString());
+ visible.setValue(String.valueOf(aShape.isVisible()));
+ selected.setValue(String.valueOf(aShape.isSelected()));
+
+ shape.setAttributeNode(shapeType);
+ shape.setAttributeNode(visible);
+ shape.setAttributeNode(selected);
+
+ if (hasAngle){
+ Attr angle = doc.createAttribute("Angle");
+ angle.setValue(String.valueOf(((EllipseShape)aShape).getAngle()));
+ shape.setAttributeNode(angle);
+ }
+
+ //Add points
+ Element points = doc.createElement("Points");
+ List pointList = (List)aShape.getPoints();
+ for (PointD aPoint : pointList) {
+ Element point = doc.createElement("Point");
+ Attr x = doc.createAttribute("X");
+ Attr y = doc.createAttribute("Y");
+ x.setValue(String.valueOf(aPoint.X));
+ y.setValue(String.valueOf(aPoint.Y));
+ point.setAttributeNode(x);
+ point.setAttributeNode(y);
+
+ points.appendChild(point);
+ }
+
+ shape.appendChild(points);
+
+ parent.appendChild(shape);
+ }
+
+ /**
+ * Add legend to XML document
+ * @param doc XML document
+ * @param parent Parent XML element
+ * @param aLegend The legend
+ * @param shapeType The shape type
+ */
+ protected void addLegend(Document doc, Element parent, ColorBreak aLegend, ShapeTypes shapeType) {
+ Element legend = doc.createElement("Legend");
+ Attr color = doc.createAttribute("Color");
+ color.setValue(ColorUtil.toHexEncoding(aLegend.getColor()));
+ legend.setAttributeNode(color);
+
+ Attr legendType = doc.createAttribute("LegendType");
+ Attr size;
+ Attr style;
+ Attr outlineColor;
+ Attr drawOutline;
+ Attr drawFill;
+ legendType.setValue(aLegend.getBreakType().toString());
+ switch (aLegend.getBreakType()) {
+ case PointBreak:
+ PointBreak aPB = (PointBreak) aLegend;
+ outlineColor = doc.createAttribute("OutlineColor");
+ size = doc.createAttribute("Size");
+ style = doc.createAttribute("Style");
+ drawOutline = doc.createAttribute("DrawOutline");
+ drawFill = doc.createAttribute("DrawFill");
+ Attr markerType = doc.createAttribute("MarkerType");
+ Attr fontName = doc.createAttribute("FontName");
+ Attr charIndex = doc.createAttribute("CharIndex");
+ Attr imagePath = doc.createAttribute("ImagePath");
+ Attr angle = doc.createAttribute("Angle");
+
+ //legendType.InnerText = "PointBreak";
+ outlineColor.setValue(ColorUtil.toHexEncoding(aPB.getOutlineColor()));
+ size.setValue(String.valueOf(aPB.getSize()));
+ style.setValue(aPB.getStyle().toString());
+ drawOutline.setValue(String.valueOf(aPB.isDrawOutline()));
+ drawFill.setValue(String.valueOf(aPB.isDrawFill()));
+ markerType.setValue(aPB.getMarkerType().toString());
+ fontName.setValue(aPB.getFontName());
+ charIndex.setValue(String.valueOf(aPB.getCharIndex()));
+ imagePath.setValue(aPB.getImagePath());
+ angle.setValue(String.valueOf(aPB.getAngle()));
+
+ legend.setAttributeNode(legendType);
+ legend.setAttributeNode(outlineColor);
+ legend.setAttributeNode(size);
+ legend.setAttributeNode(style);
+ legend.setAttributeNode(drawOutline);
+ legend.setAttributeNode(drawFill);
+ legend.setAttributeNode(markerType);
+ legend.setAttributeNode(fontName);
+ legend.setAttributeNode(charIndex);
+ legend.setAttributeNode(imagePath);
+ legend.setAttributeNode(angle);
+ break;
+ case LabelBreak:
+ LabelBreak aLB = (LabelBreak) aLegend;
+ Attr text = doc.createAttribute("Text");
+ angle = doc.createAttribute("Angle");
+ fontName = doc.createAttribute("FontName");
+ Attr fontSize = doc.createAttribute("FontSize");
+ Attr fontBold = doc.createAttribute("FontBold");
+ Attr yShift = doc.createAttribute("YShift");
+
+ //legendType.InnerText = "LabelBreak";
+ text.setValue(aLB.getText());
+ angle.setValue(String.valueOf(aLB.getAngle()));
+ fontName.setValue(aLB.getFont().getName());
+ fontSize.setValue(String.valueOf(aLB.getFont().getSize()));
+ fontBold.setValue(String.valueOf(aLB.getFont().isBold()));
+ yShift.setValue(String.valueOf(aLB.getYShift()));
+
+ legend.setAttributeNode(legendType);
+ legend.setAttributeNode(text);
+ legend.setAttributeNode(angle);
+ legend.setAttributeNode(fontName);
+ legend.setAttributeNode(fontSize);
+ legend.setAttributeNode(fontBold);
+ legend.setAttributeNode(yShift);
+ break;
+ case ChartBreak:
+ ChartBreak aChB = (ChartBreak) aLegend;
+ Attr shapeIndex = doc.createAttribute("ShapeIndex");
+ Attr chartType = doc.createAttribute("ChartType");
+ Attr chartData = doc.createAttribute("ChartData");
+ Attr xShift = doc.createAttribute("XShift");
+ yShift = doc.createAttribute("YShift");
+ fontName = doc.createAttribute("FontName");
+ fontSize = doc.createAttribute("FontSize");
+ Attr labelColor = doc.createAttribute("LabelColor");
+
+ shapeIndex.setValue(String.valueOf(aChB.getShapeIndex()));
+ //legendType.InnerText = "ChartBreak";
+ chartType.setValue(aChB.getChartType().toString());
+ String cdata = "";
+ for (int i = 0; i < aChB.getItemNum(); i++) {
+ if (i == 0) {
+ cdata = String.valueOf(aChB.getChartData().get(i));
+ } else {
+ cdata += "," + String.valueOf(aChB.getChartData().get(i));
+ }
+ }
+ chartData.setValue(cdata);
+ xShift.setValue(String.valueOf(aChB.getXShift()));
+ yShift.setValue(String.valueOf(aChB.getYShift()));
+ fontName.setValue(aChB.getLabelFont().getFontName());
+ fontSize.setValue(String.valueOf(aChB.getLabelFont().getSize()));
+ labelColor.setValue(ColorUtil.toHexEncoding(aChB.getLabelColor()));
+
+ legend.setAttributeNode(legendType);
+ legend.setAttributeNode(shapeIndex);
+ legend.setAttributeNode(chartType);
+ legend.setAttributeNode(chartData);
+ legend.setAttributeNode(xShift);
+ legend.setAttributeNode(yShift);
+ legend.setAttributeNode(fontName);
+ legend.setAttributeNode(fontSize);
+ legend.setAttributeNode(labelColor);
+ break;
+ case VectorBreak:
+ //legendType.InnerText = "VectorBreak";
+ legend.setAttributeNode(legendType);
+ break;
+ case PolylineBreak:
+ PolylineBreak aPLB = (PolylineBreak) aLegend;
+ size = doc.createAttribute("Size");
+ style = doc.createAttribute("Style");
+ Attr drawSymbol = doc.createAttribute("DrawSymbol");
+ Attr symbolSize = doc.createAttribute("SymbolSize");
+ Attr symbolStyle = doc.createAttribute("SymbolStyle");
+ Attr symbolColor = doc.createAttribute("SymbolColor");
+ Attr symbolInterval = doc.createAttribute("SymbolInterval");
+
+ //legendType.InnerText = "PolylineBreak";
+ size.setValue(String.valueOf(aPLB.getWidth()));
+ style.setValue(aPLB.getStyle().toString());
+ drawSymbol.setValue(String.valueOf(aPLB.getDrawSymbol()));
+ symbolSize.setValue(String.valueOf(aPLB.getSymbolSize()));
+ symbolStyle.setValue(String.valueOf(aPLB.getSymbolStyle()));
+ symbolColor.setValue(ColorUtil.toHexEncoding(aPLB.getSymbolColor()));
+ symbolInterval.setValue(String.valueOf(aPLB.getSymbolInterval()));
+
+ legend.setAttributeNode(legendType);
+ legend.setAttributeNode(size);
+ legend.setAttributeNode(style);
+ legend.setAttributeNode(drawSymbol);
+ legend.setAttributeNode(symbolSize);
+ legend.setAttributeNode(symbolStyle);
+ legend.setAttributeNode(symbolColor);
+ legend.setAttributeNode(symbolInterval);
+ break;
+ case PolygonBreak:
+ PolygonBreak aPGB = (PolygonBreak) aLegend;
+ outlineColor = doc.createAttribute("OutlineColor");
+ drawOutline = doc.createAttribute("DrawOutline");
+ drawFill = doc.createAttribute("DrawFill");
+ Attr outlineSize = doc.createAttribute("OutlineSize");
+ //Attr usingHatchStyle = doc.createAttribute("UsingHatchStyle");
+ //style = doc.createAttribute("Style");
+ Attr backColor = doc.createAttribute("BackColor");
+ //Attr transparencyPer = doc.createAttribute("TransparencyPercent");
+ Attr isMaskout = doc.createAttribute("IsMaskout");
+
+ //legendType.InnerText = "PolygonBreak";
+ outlineColor.setValue(ColorUtil.toHexEncoding(aPGB.getOutlineColor()));
+ drawOutline.setValue(String.valueOf(aPGB.isDrawOutline()));
+ drawFill.setValue(String.valueOf(aPGB.isDrawFill()));
+ outlineSize.setValue(String.valueOf(aPGB.getOutlineSize()));
+ //usingHatchStyle.setValue(String.valueOf(aPGB.getUsingHatchStyle()));
+ //style.setValue(String.valueOf(aPGB.getStyle()));
+ backColor.setValue(ColorUtil.toHexEncoding(aPGB.getBackColor()));
+ //transparencyPer.InnerText = aPGB.TransparencyPercent.ToString();
+ isMaskout.setValue(String.valueOf(aPGB.isMaskout()));
+
+ legend.setAttributeNode(legendType);
+ legend.setAttributeNode(outlineColor);
+ legend.setAttributeNode(drawOutline);
+ legend.setAttributeNode(drawFill);
+ legend.setAttributeNode(outlineSize);
+ //legend.setAttributeNode(usingHatchStyle);
+ //legend.setAttributeNode(style);
+ legend.setAttributeNode(backColor);
+ //legend.setAttributeNode(transparencyPer);
+ legend.setAttributeNode(isMaskout);
+ break;
+ }
+
+ parent.appendChild(legend);
+ }
+
+ /**
+ * Import from xml node
+ *
+ * @param graphicNode Graphic xml node
+ */
+ public void importFromXML(Element graphicNode) {
+ Node shape = graphicNode.getElementsByTagName("Shape").item(0);
+ _shape = loadShape(shape);
+
+ Node legend = graphicNode.getElementsByTagName("Legend").item(0);
+ _legend = loadLegend(legend, _shape.getShapeType());
+
+ updateResizeAbility();
+ }
+
+ protected Shape loadShape(Node shapeNode) {
+ Shape aShape = null;
+ try {
+ ShapeTypes shapeType = ShapeTypes.valueOf(shapeNode.getAttributes().getNamedItem("ShapeType").getNodeValue());
+ switch (shapeType) {
+ case Point:
+ aShape = new PointShape();
+ break;
+ case WindArraw:
+ aShape = new WindArrow();
+ break;
+ case Polyline:
+ aShape = new PolylineShape();
+ break;
+ case CurveLine:
+ aShape = new CurveLineShape();
+ break;
+ case Circle:
+ aShape = new CircleShape();
+ break;
+ case Polygon:
+ case Rectangle:
+ aShape = new PolygonShape();
+ break;
+ case CurvePolygon:
+ aShape = new CurvePolygonShape();
+ break;
+ case Ellipse:
+ aShape = new EllipseShape();
+ break;
+ }
+
+ aShape.setVisible(Boolean.parseBoolean(shapeNode.getAttributes().getNamedItem("Visible").getNodeValue()));
+ aShape.setSelected(Boolean.parseBoolean(shapeNode.getAttributes().getNamedItem("Selected").getNodeValue()));
+ if (aShape.getShapeType() == ShapeTypes.Ellipse){
+ Node angleNode = shapeNode.getAttributes().getNamedItem("Angle");
+ if (angleNode != null)
+ ((EllipseShape)aShape).setAngle(Float.parseFloat(angleNode.getNodeValue()));
+ }
+
+ List pointList = new ArrayList<>();
+ Node pointsNode = ((Element)shapeNode).getElementsByTagName("Points").item(0);
+ NodeList nl = ((Element)pointsNode).getElementsByTagName("Point");
+ for (int i = 0; i < nl.getLength(); i++) {
+ Node pNode = nl.item(i);
+ PointD aPoint = new PointD(Double.parseDouble(pNode.getAttributes().getNamedItem("X").getNodeValue()),
+ Double.parseDouble(pNode.getAttributes().getNamedItem("Y").getNodeValue()));
+ pointList.add(aPoint);
+ }
+ aShape.setPoints(pointList);
+ } catch (Exception e) {
+ }
+
+ return aShape;
+ }
+
+ protected ColorBreak loadLegend(Node legendNode, ShapeTypes shapeType) {
+ ColorBreak legend = new ColorBreak();
+ try {
+ Color color = ColorUtil.parseToColor(legendNode.getAttributes().getNamedItem("Color").getNodeValue());
+ String legendType = legendNode.getAttributes().getNamedItem("LegendType").getNodeValue();
+ BreakTypes breakType = BreakTypes.valueOf(legendType);
+ switch (breakType) {
+ case PointBreak:
+ PointBreak aPB = new PointBreak();
+ try {
+ aPB.setColor(color);
+ aPB.setDrawFill(Boolean.parseBoolean(legendNode.getAttributes().getNamedItem("DrawFill").getNodeValue()));
+ aPB.setDrawOutline(Boolean.parseBoolean(legendNode.getAttributes().getNamedItem("DrawOutline").getNodeValue()));
+ aPB.setOutlineColor(ColorUtil.parseToColor(legendNode.getAttributes().getNamedItem("OutlineColor").getNodeValue()));
+ aPB.setSize(Float.parseFloat(legendNode.getAttributes().getNamedItem("Size").getNodeValue()));
+ aPB.setStyle(PointStyle.valueOf(legendNode.getAttributes().getNamedItem("Style").getNodeValue()));
+ aPB.setMarkerType(MarkerType.valueOf(legendNode.getAttributes().getNamedItem("MarkerType").getNodeValue()));
+ aPB.setFontName(legendNode.getAttributes().getNamedItem("FontName").getNodeValue());
+ aPB.setCharIndex(Integer.parseInt(legendNode.getAttributes().getNamedItem("CharIndex").getNodeValue()));
+ aPB.setImagePath(legendNode.getAttributes().getNamedItem("ImagePath").getNodeValue());
+ aPB.setAngle(Float.parseFloat(legendNode.getAttributes().getNamedItem("Angle").getNodeValue()));
+ } catch (Exception e) {
+ } finally {
+ legend = aPB;
+ }
+ break;
+ case LabelBreak:
+ LabelBreak aLB = new LabelBreak();
+ try {
+ aLB.setColor(color);
+ aLB.setAngle(Float.parseFloat(legendNode.getAttributes().getNamedItem("Angle").getNodeValue()));
+ aLB.setText(legendNode.getAttributes().getNamedItem("Text").getNodeValue());
+ String fontName = legendNode.getAttributes().getNamedItem("FontName").getNodeValue();
+ float fontSize = Float.parseFloat(legendNode.getAttributes().getNamedItem("FontSize").getNodeValue());
+ boolean fontBold = Boolean.parseBoolean(legendNode.getAttributes().getNamedItem("FontBold").getNodeValue());
+ if (fontBold) {
+ aLB.setFont(new Font(fontName, Font.BOLD, (int) fontSize));
+ } else {
+ aLB.setFont(new Font(fontName, Font.PLAIN, (int) fontSize));
+ }
+
+ aLB.setYShift(Float.parseFloat(legendNode.getAttributes().getNamedItem("YShift").getNodeValue()));
+ } catch (Exception e) {
+ } finally {
+ legend = aLB;
+ }
+ break;
+ case ChartBreak:
+ ChartBreak aChB = new ChartBreak(ChartTypes.BarChart);
+ try {
+ ChartTypes chartType = ChartTypes.valueOf(legendNode.getAttributes().getNamedItem("ChartType").getNodeValue());
+ aChB = new ChartBreak(chartType);
+ aChB.setShapeIndex(Integer.parseInt(legendNode.getAttributes().getNamedItem("ShapeIndex").getNodeValue()));
+ List cData = new ArrayList();
+ String[] cDataStr = legendNode.getAttributes().getNamedItem("ChartData").getNodeValue().split(",");
+ for (int i = 0; i < cDataStr.length; i++) {
+ cData.add(Float.parseFloat(cDataStr[i]));
+ }
+
+ aChB.setChartData(cData);
+ aChB.setXShift(Integer.parseInt(legendNode.getAttributes().getNamedItem("XShift").getNodeValue()));
+ aChB.setYShift(Integer.parseInt(legendNode.getAttributes().getNamedItem("YShift").getNodeValue()));
+ String fontName = legendNode.getAttributes().getNamedItem("FontName").getNodeValue();
+ float fontSize = Float.parseFloat(legendNode.getAttributes().getNamedItem("FontSize").getNodeValue());
+ aChB.setLabelFont(new Font(fontName, Font.PLAIN, (int)fontSize));
+ aChB.setLabelColor(ColorUtil.parseToColor(legendNode.getAttributes().getNamedItem("LabelColor").getNodeValue()));
+ } catch (Exception e) {
+ } finally {
+ legend = aChB;
+ }
+ break;
+ case VectorBreak:
+ VectorBreak aVB = new VectorBreak();
+ try {
+ aVB.setColor(color);
+ } catch (Exception e) {
+ } finally {
+ legend = aVB;
+ }
+ break;
+ case PolylineBreak:
+ PolylineBreak aPLB = new PolylineBreak();
+ try {
+ aPLB.setColor(color);
+ aPLB.setWidth(Float.parseFloat(legendNode.getAttributes().getNamedItem("Size").getNodeValue()));
+ aPLB.setStyle(LineStyles.valueOf(legendNode.getAttributes().getNamedItem("Style").getNodeValue()));
+ aPLB.setDrawSymbol(Boolean.parseBoolean(legendNode.getAttributes().getNamedItem("DrawSymbol").getNodeValue()));
+ aPLB.setSymbolSize(Float.parseFloat(legendNode.getAttributes().getNamedItem("SymbolSize").getNodeValue()));
+ aPLB.setSymbolStyle(PointStyle.valueOf(legendNode.getAttributes().getNamedItem("SymbolStyle").getNodeValue()));
+ aPLB.setSymbolColor(ColorUtil.parseToColor(legendNode.getAttributes().getNamedItem("SymbolColor").getNodeValue()));
+ aPLB.setSymbolInterval(Integer.parseInt(legendNode.getAttributes().getNamedItem("SymbolInterval").getNodeValue()));
+ } catch (Exception e) {
+ } finally {
+ legend = aPLB;
+ }
+ break;
+ case PolygonBreak:
+ PolygonBreak aPGB = new PolygonBreak();
+ try {
+ aPGB.setColor(color);
+ aPGB.setDrawFill(Boolean.parseBoolean(legendNode.getAttributes().getNamedItem("DrawFill").getNodeValue()));
+ aPGB.setDrawOutline(Boolean.parseBoolean(legendNode.getAttributes().getNamedItem("DrawOutline").getNodeValue()));
+ aPGB.setOutlineSize(Float.parseFloat(legendNode.getAttributes().getNamedItem("OutlineSize").getNodeValue()));
+ aPGB.setOutlineColor(ColorUtil.parseToColor(legendNode.getAttributes().getNamedItem("OutlineColor").getNodeValue()));
+ //aPGB.UsingHatchStyle = bool.Parse(legendNode.Attributes["UsingHatchStyle"].InnerText);
+ //aPGB.Style = (HatchStyle)Enum.Parse(typeof(HatchStyle), legendNode.Attributes["Style"].InnerText, true);
+ aPGB.setBackColor(ColorUtil.parseToColor(legendNode.getAttributes().getNamedItem("BackColor").getNodeValue()));
+ //aPGB.TransparencyPercent = int.Parse(legendNode.Attributes["TransparencyPercent"].InnerText);
+ aPGB.setMaskout(Boolean.parseBoolean(legendNode.getAttributes().getNamedItem("IsMaskout").getNodeValue()));
+ } catch (Exception e) {
+ } {
+ legend = aPGB;
+ }
+ break;
+ }
+ } catch (Exception e) {
+ }
+ return legend;
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/shape/GraphicCollection.java b/MeteoInfoLib/src/main/java/org/meteoinfo/shape/GraphicCollection.java
index 0cdfa515..292f482a 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/shape/GraphicCollection.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/shape/GraphicCollection.java
@@ -1,688 +1,689 @@
-/* Copyright 2012 Yaqiang Wang,
- * yaqiang.wang@gmail.com
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.shape;
-
-import org.meteoinfo.geoprocess.GeoComputation;
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.global.MIMath;
-import org.meteoinfo.global.PointD;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.NoSuchElementException;
-import org.meteoinfo.layer.LabelSet;
-import org.meteoinfo.legend.BreakTypes;
-import org.meteoinfo.legend.ColorBreak;
-import org.meteoinfo.legend.LabelBreak;
-import org.meteoinfo.legend.LegendScheme;
-import org.meteoinfo.legend.PointBreak;
-
-/**
- *
- * @author Yaqiang Wang
- */
-public class GraphicCollection extends Graphic implements Iterator {
-
- //
- private List graphics = new ArrayList<>();
- private Extent _extent = new Extent();
- protected boolean singleLegend = true;
- private int index;
- private LabelSet labelSet;
- private List labelPoints;
- protected LegendScheme legendScheme;
- protected ColorBreak legendBreak;
- //
- //
-
- /**
- * Constructor
- */
- public GraphicCollection() {
- this.index = 0;
- labelSet = new LabelSet();
- labelPoints = new ArrayList<>();
- }
-
- //
- //
- /**
- * Get graphic list
- *
- * @return Graphic list
- */
- @Override
- public List getGraphics() {
- return this.graphics;
- }
-
- /**
- * Set graphic list
- *
- * @param value Graphic list
- */
- public void setGraphics(List value) {
- this.graphics = value;
- }
-
- /**
- * Get extent
- *
- * @return The extent
- */
- @Override
- public Extent getExtent() {
- return _extent;
- }
-
- /**
- * Set extent
- *
- * @param value Extent
- */
- @Override
- public void setExtent(Extent value) {
- this._extent = value;
- }
-
- /**
- * Get is single legend or not
- *
- * @return Boolean
- */
- @Override
- public boolean isSingleLegend() {
- return this.singleLegend;
- }
-
- /**
- * Set is single legend or not
- *
- * @param value Boolean
- */
- public void setSingleLegend(boolean value) {
- this.singleLegend = value;
- }
-
- /**
- * Get label set
- *
- * @return Label set
- */
- public LabelSet getLabelSet() {
- return labelSet;
- }
-
- /**
- * Set label set
- *
- * @param ls Label set
- */
- public void setLabelSet(LabelSet ls) {
- labelSet = ls;
- }
-
- /**
- * Get label points
- *
- * @return The lable points
- */
- public List getLabelPoints() {
- return this.labelPoints;
- }
-
- /**
- * Set label points
- *
- * @param lps The lable points
- */
- public void setLabelPoints(List lps) {
- this.labelPoints = lps;
- }
-
- /**
- * Get legend scheme
- *
- * @return Legend scheme
- */
- public LegendScheme getLegendScheme() {
- return this.legendScheme;
- }
-
- /**
- * Set legend scheme
- *
- * @param value Legend scheme
- */
- public void setLegendScheme(LegendScheme value) {
- this.legendScheme = value;
- }
-
- /**
- * Get legend break
- *
- * @return Legend break
- */
- public ColorBreak getLegendBreak() {
- return this.legendBreak;
- }
-
- /**
- * Set legend break
- *
- * @param value Legend break
- */
- public void setLegendBreak(ColorBreak value) {
- this.legendBreak = value;
- }
-
- /**
- * Get is 3D or not
- *
- * @return Boolean
- */
- public boolean is3D() {
- return false;
- }
-
- /**
- * Get if is GraphicCollection
- *
- * @return Boolean
- */
- @Override
- public boolean isCollection() {
- return true;
- }
-
- //
- //
- /**
- * Update extent
- */
- public void updateExtent() {
- int i = 0;
- Extent extent;
- for (Graphic g : this.graphics) {
- if (g instanceof GraphicCollection) {
- extent = g.getExtent();
- } else {
- extent = g.getShape().getExtent();
- }
- if (i == 0) {
- _extent = extent;
- } else {
- _extent = MIMath.getLagerExtent(_extent, extent);
- }
-
- i += 1;
- }
- }
-
- /**
- * Add a graphic
- *
- * @param aGraphic The graphic
- * @return Boolean
- */
- public boolean add(Graphic aGraphic) {
- boolean istrue = this.graphics.add(aGraphic);
-
- //Update extent
- if (this.graphics.size() == 1) {
- _extent = aGraphic.getExtent();
- } else {
- _extent = MIMath.getLagerExtent(_extent, aGraphic.getExtent());
- }
-
- return istrue;
- }
-
- /**
- * Inset a graphic
- *
- * @param index Index
- * @param aGraphic The graphic
- */
- public void add(int index, Graphic aGraphic) {
- this.graphics.add(index, aGraphic);
-
- //Update extent
- if (this.graphics.size() == 1) {
- _extent = aGraphic.getShape().getExtent();
- } else {
- _extent = MIMath.getLagerExtent(_extent, aGraphic.getShape().getExtent());
- }
- }
-
- /**
- * Get a graphic by index
- *
- * @param idx Index
- * @return Graphic
- */
- public Graphic get(int idx) {
- return this.graphics.get(idx);
- }
-
- /**
- * Index of
- *
- * @param g Graphic
- * @return Index
- */
- public int indexOf(Graphic g) {
- return this.graphics.indexOf(g);
- }
-
- /**
- * Contains or not
- *
- * @param g Graphic
- * @return Boolean
- */
- public boolean contains(Graphic g) {
- return this.graphics.contains(g);
- }
-
- /**
- * Get graphic list size
- *
- * @return Gaphic list size
- */
- public int size() {
- return this.graphics.size();
- }
-
- /**
- * Get is empty or not
- *
- * @return Boolean
- */
- public boolean isEmpty() {
- return this.graphics.isEmpty();
- }
-
- /**
- * Get graphics number
- *
- * @return 1
- */
- @Override
- public int getNumGraphics() {
- return this.size();
- }
-
- /**
- * Get Graphic by index
- *
- * @param idx Index
- * @return Graphic
- */
- @Override
- public Graphic getGraphicN(int idx) {
- return this.get(idx);
- }
-
- /**
- * Remove a graphic
- *
- * @param aGraphic The graphic
- * @return Boolean
- */
- public boolean remove(Graphic aGraphic) {
- boolean istrue = this.graphics.remove(aGraphic);
- this.updateExtent();
-
- return istrue;
- }
-
- /**
- * Remove a graphic by index
- *
- * @param index The index
- * @return The removed graphic
- */
- public Graphic remove(int index) {
- Graphic ag = this.graphics.remove(index);
- this.updateExtent();
-
- return ag;
- }
-
- /**
- * Clear graphics
- */
- public void clear() {
- this.graphics.clear();
- }
-
- /**
- * Add all
- *
- * @param gs Graphic list
- */
- public void addAll(List gs) {
- this.graphics.addAll(gs);
- }
-
- /**
- * Join this graphics with other graphics
- *
- * @param graphic Other graphics
- */
- public void join(Graphic graphic) {
- if (graphic.isCollection()) {
- //Update extent
- if (this.isEmpty()) {
- _extent = graphic.getExtent();
- } else {
- _extent = MIMath.getLagerExtent(_extent, graphic.getExtent());
- }
- for (int i = 0; i < graphic.getNumGraphics(); i++) {
- this.graphics.add(graphic.getGraphicN(i));
- }
- } else {
- this.add(graphic);
- }
- }
-
- /**
- * Remove all
- *
- * @param gs Graphic list
- */
- public void removeAll(List gs) {
- this.graphics.removeAll(gs);
- }
-
- /**
- * Get legend
- *
- * @return Legend
- */
- @Override
- public ColorBreak getLegend() {
- if (this.legendBreak != null) {
- return this.legendBreak;
- } else {
- return this.graphics.get(0).getLegend();
- }
- }
-
- /**
- * Select graphics by an extent
- *
- * @param aExtent The extent
- * @return Selected graphics
- */
- public GraphicCollection selectGraphics(Extent aExtent) {
- GraphicCollection selectedGraphics = new GraphicCollection();
- int i, j;
- PointD aPoint = new PointD();
- aPoint.X = (aExtent.minX + aExtent.maxX) / 2;
- aPoint.Y = (aExtent.minY + aExtent.maxY) / 2;
-
- for (Graphic aGraphic : this.graphics) {
- switch (aGraphic.getShape().getShapeType()) {
- case Point:
- PointShape aPS = (PointShape) aGraphic.getShape();
- if (MIMath.pointInExtent(aPS.getPoint(), aExtent)) {
- selectedGraphics.add(aGraphic);
- }
- break;
- case Polyline:
- case PolylineZ:
- PolylineShape aPLS = (PolylineShape) aGraphic.getShape();
- if (MIMath.isExtentCross(aExtent, aPLS.getExtent())) {
- for (j = 0; j < aPLS.getPoints().size(); j++) {
- aPoint = aPLS.getPoints().get(j);
- if (MIMath.pointInExtent(aPoint, aExtent)) {
- selectedGraphics.add(aGraphic);
- break;
- }
- }
- }
- break;
- case Polygon:
- case Rectangle:
- PolygonShape aPGS = (PolygonShape) aGraphic.getShape();
- if (!(aPGS.getPartNum() > 1)) {
- if (GeoComputation.pointInPolygon((List) aPGS.getPoints(), aPoint)) {
- selectedGraphics.add(aGraphic);
- }
- } else {
- for (int p = 0; p < aPGS.getPartNum(); p++) {
- ArrayList pList = new ArrayList();
- if (p == aPGS.getPartNum() - 1) {
- for (int pp = aPGS.parts[p]; pp < aPGS.getPointNum(); pp++) {
- pList.add(aPGS.getPoints().get(pp));
- }
- } else {
- for (int pp = aPGS.parts[p]; pp < aPGS.parts[p + 1]; pp++) {
- pList.add(aPGS.getPoints().get(pp));
- }
- }
- if (GeoComputation.pointInPolygon(pList, aPoint)) {
- selectedGraphics.add(aGraphic);
- break;
- }
- }
- }
- break;
- }
- }
-
- return selectedGraphics;
- }
-
- @Override
- public boolean hasNext() {
- return index <= this.size() - 1;
- }
-
- @Override
- public Object next() {
- if (index >= this.size()) {
- throw new NoSuchElementException();
- }
-
- return this.get(index++);
- }
-
- /**
- * Add labels
- */
- public void addLabels() {
- addLabelsByColor();
-
- labelSet.setDrawLabels(true);
- }
-
- /**
- * Get shapes
- *
- * @return Shapes
- */
- public List getShapes() {
- List shapes = new ArrayList<>();
- for (Graphic g : this.graphics) {
- shapes.add(g.getShape());
- }
- return shapes;
- }
-
- /**
- * Get shape type
- *
- * @return Shape type
- */
- public ShapeTypes getShapeType() {
- return this.graphics.get(0).getShape().getShapeType();
- }
-
- private double getMinValue() {
- double min = Double.MAX_VALUE;
- for (Graphic graphic : this.graphics) {
- Shape shape = graphic.getShape();
- if (min > shape.getValue()) {
- min = shape.getValue();
- }
- }
- return min;
- }
-
- /**
- * Add labels
- */
- private void addLabelsByColor() {
- if (labelSet.isAutoDecimal()) {
- double min = getMinValue();
- labelSet.setDecimalDigits(MIMath.getDecimalNum(min));
- }
- String dFormat = "%1$." + String.valueOf(labelSet.getDecimalDigits()) + "f";
- PointD aPoint;
- for (Graphic graphic : this.graphics) {
- ColorBreak cb = graphic.getLegend();
- Shape shape = graphic.getShape();
- PointShape aPS = new PointShape();
- switch (shape.getShapeType()) {
- case Point:
- case PointM:
- case PointZ:
- aPS.setPoint((PointD) ((PointShape) shape).getPoint().clone());
- break;
- case Polyline:
- case PolylineM:
- case PolylineZ:
- int pIdx = ((PolylineShape) shape).getPoints().size() / 2;
- aPS.setPoint((PointD) ((PolylineShape) shape).getPoints().get(pIdx - 1).clone());
- break;
- case Polygon:
- case PolygonM:
- Extent aExtent = shape.getExtent();
- aPoint = new PointD();
- aPoint.X = ((aExtent.minX + aExtent.maxX) / 2);
- aPoint.Y = ((aExtent.minY + aExtent.maxY) / 2);
- aPS.setPoint(aPoint);
- break;
- }
-
- LabelBreak aLP = new LabelBreak();
- //aLP.setText(DataConvert.removeTailingZeros(String.valueOf(shape.getValue())));
- aLP.setText(String.format(dFormat, shape.getValue()));
- if (labelSet.isColorByLegend()) {
- aLP.setColor(cb.getColor());
- } else {
- aLP.setColor(labelSet.getLabelColor());
- }
- aLP.setFont(labelSet.getLabelFont());
- aLP.setAlignType(labelSet.getLabelAlignType());
- aLP.setYShift(labelSet.getYOffset());
- aLP.setXShift(labelSet.getXOffset());
- Graphic aGraphic = new Graphic(aPS, aLP);
- addLabel(aGraphic);
- }
- }
-
- /**
- * Add label point
- *
- * @param aLP Label point
- */
- public void addLabel(Graphic aLP) {
- labelPoints.add(aLP);
- }
-
- /**
- * Add labels of contour layer dynamicly
- *
- * @param sExtent View extent of MapView
- */
- public void addLabelsContourDynamic(Extent sExtent) {
- if (labelSet.isAutoDecimal()) {
- double min = getMinValue();
- labelSet.setDecimalDigits(MIMath.getDecimalNum(min));
- }
- String dFormat = "%1$." + String.valueOf(labelSet.getDecimalDigits()) + "f";
- String text;
- for (Graphic graphic : this.graphics) {
- Shape shape = graphic.getShape();
- ColorBreak cb = graphic.getLegend();
- PolylineShape aPLS = (PolylineShape) shape;
- Extent IExtent = aPLS.getExtent();
- if (IExtent.maxX - IExtent.minX > (sExtent.maxX - sExtent.minX) / 10
- || IExtent.maxY - IExtent.minY > (sExtent.maxY - sExtent.minY) / 10) {
- LabelBreak aLP = new LabelBreak();
- int pIdx = aPLS.getPoints().size() / 2;
- //PointF aPoint = new PointF(0, 0);
- PointShape aPS = new PointShape();
- aPS.setPoint(aPLS.getPoints().get(pIdx - 1));
- //text = DataConvert.removeTailingZeros(String.valueOf(aPLS.getValue()));
- text = String.format(dFormat, aPLS.getValue());
- aLP.setText(text);
- aLP.setFont(labelSet.getLabelFont());
- aLP.setAlignType(labelSet.getLabelAlignType());
- aLP.setYShift(labelSet.getYOffset());
- if (labelSet.isColorByLegend()) {
- aLP.setColor(cb.getColor());
- } else {
- aLP.setColor(labelSet.getLabelColor());
- }
- Graphic aGraphic = new Graphic(aPS, aLP);
- addLabel(aGraphic);
- }
- }
-
- labelSet.setDrawLabels(true);
- }
-
- /**
- * Get arrow zoom
- *
- * @return Arrow zoom
- */
- public float getArrowZoom() {
- if (this.getLegend().getBreakType() == BreakTypes.PointBreak) {
- float size = ((PointBreak) this.getLegend()).getSize();
- return size / 10;
- }
-
- return 1.0f;
- }
-
- /**
- * Clip
- *
- * @param clipPolys Clipping polygons
- * @return Clipped graphics
- */
- public GraphicCollection clip(List clipPolys) {
- GraphicCollection cgraphics = new GraphicCollection();
- for (PolygonShape aPGS : clipPolys) {
- for (int i = 0; i < this.graphics.size(); i++) {
- Shape bShape = this.graphics.get(i).getShape();
- Shape clipShape = bShape.intersection(aPGS);
- if (clipShape != null) {
- cgraphics.add(new Graphic(clipShape, this.graphics.get(i).getLegend()));
- }
- }
- }
- cgraphics.setSingleLegend(this.singleLegend);
- cgraphics.setLegendScheme((LegendScheme) this.getLegendScheme().clone());
-
- return cgraphics;
- }
- //
-}
+/* Copyright 2012 Yaqiang Wang,
+ * yaqiang.wang@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ */
+package org.meteoinfo.shape;
+
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.MIMath;
+import org.meteoinfo.common.PointD;
+import org.meteoinfo.geoprocess.GeoComputation;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import org.meteoinfo.layer.LabelSet;
+import org.meteoinfo.legend.BreakTypes;
+import org.meteoinfo.legend.ColorBreak;
+import org.meteoinfo.legend.LabelBreak;
+import org.meteoinfo.legend.LegendScheme;
+import org.meteoinfo.legend.PointBreak;
+
+/**
+ *
+ * @author Yaqiang Wang
+ */
+public class GraphicCollection extends Graphic implements Iterator {
+
+ //
+ private List graphics = new ArrayList<>();
+ private Extent _extent = new Extent();
+ protected boolean singleLegend = true;
+ private int index;
+ private LabelSet labelSet;
+ private List labelPoints;
+ protected LegendScheme legendScheme;
+ protected ColorBreak legendBreak;
+ //
+ //
+
+ /**
+ * Constructor
+ */
+ public GraphicCollection() {
+ this.index = 0;
+ labelSet = new LabelSet();
+ labelPoints = new ArrayList<>();
+ }
+
+ //
+ //
+ /**
+ * Get graphic list
+ *
+ * @return Graphic list
+ */
+ @Override
+ public List getGraphics() {
+ return this.graphics;
+ }
+
+ /**
+ * Set graphic list
+ *
+ * @param value Graphic list
+ */
+ public void setGraphics(List value) {
+ this.graphics = value;
+ }
+
+ /**
+ * Get extent
+ *
+ * @return The extent
+ */
+ @Override
+ public Extent getExtent() {
+ return _extent;
+ }
+
+ /**
+ * Set extent
+ *
+ * @param value Extent
+ */
+ @Override
+ public void setExtent(Extent value) {
+ this._extent = value;
+ }
+
+ /**
+ * Get is single legend or not
+ *
+ * @return Boolean
+ */
+ @Override
+ public boolean isSingleLegend() {
+ return this.singleLegend;
+ }
+
+ /**
+ * Set is single legend or not
+ *
+ * @param value Boolean
+ */
+ public void setSingleLegend(boolean value) {
+ this.singleLegend = value;
+ }
+
+ /**
+ * Get label set
+ *
+ * @return Label set
+ */
+ public LabelSet getLabelSet() {
+ return labelSet;
+ }
+
+ /**
+ * Set label set
+ *
+ * @param ls Label set
+ */
+ public void setLabelSet(LabelSet ls) {
+ labelSet = ls;
+ }
+
+ /**
+ * Get label points
+ *
+ * @return The lable points
+ */
+ public List getLabelPoints() {
+ return this.labelPoints;
+ }
+
+ /**
+ * Set label points
+ *
+ * @param lps The lable points
+ */
+ public void setLabelPoints(List lps) {
+ this.labelPoints = lps;
+ }
+
+ /**
+ * Get legend scheme
+ *
+ * @return Legend scheme
+ */
+ public LegendScheme getLegendScheme() {
+ return this.legendScheme;
+ }
+
+ /**
+ * Set legend scheme
+ *
+ * @param value Legend scheme
+ */
+ public void setLegendScheme(LegendScheme value) {
+ this.legendScheme = value;
+ }
+
+ /**
+ * Get legend break
+ *
+ * @return Legend break
+ */
+ public ColorBreak getLegendBreak() {
+ return this.legendBreak;
+ }
+
+ /**
+ * Set legend break
+ *
+ * @param value Legend break
+ */
+ public void setLegendBreak(ColorBreak value) {
+ this.legendBreak = value;
+ }
+
+ /**
+ * Get is 3D or not
+ *
+ * @return Boolean
+ */
+ public boolean is3D() {
+ return false;
+ }
+
+ /**
+ * Get if is GraphicCollection
+ *
+ * @return Boolean
+ */
+ @Override
+ public boolean isCollection() {
+ return true;
+ }
+
+ //
+ //
+ /**
+ * Update extent
+ */
+ public void updateExtent() {
+ int i = 0;
+ Extent extent;
+ for (Graphic g : this.graphics) {
+ if (g instanceof GraphicCollection) {
+ extent = g.getExtent();
+ } else {
+ extent = g.getShape().getExtent();
+ }
+ if (i == 0) {
+ _extent = extent;
+ } else {
+ _extent = MIMath.getLagerExtent(_extent, extent);
+ }
+
+ i += 1;
+ }
+ }
+
+ /**
+ * Add a graphic
+ *
+ * @param aGraphic The graphic
+ * @return Boolean
+ */
+ public boolean add(Graphic aGraphic) {
+ boolean istrue = this.graphics.add(aGraphic);
+
+ //Update extent
+ if (this.graphics.size() == 1) {
+ _extent = aGraphic.getExtent();
+ } else {
+ _extent = MIMath.getLagerExtent(_extent, aGraphic.getExtent());
+ }
+
+ return istrue;
+ }
+
+ /**
+ * Inset a graphic
+ *
+ * @param index Index
+ * @param aGraphic The graphic
+ */
+ public void add(int index, Graphic aGraphic) {
+ this.graphics.add(index, aGraphic);
+
+ //Update extent
+ if (this.graphics.size() == 1) {
+ _extent = aGraphic.getShape().getExtent();
+ } else {
+ _extent = MIMath.getLagerExtent(_extent, aGraphic.getShape().getExtent());
+ }
+ }
+
+ /**
+ * Get a graphic by index
+ *
+ * @param idx Index
+ * @return Graphic
+ */
+ public Graphic get(int idx) {
+ return this.graphics.get(idx);
+ }
+
+ /**
+ * Index of
+ *
+ * @param g Graphic
+ * @return Index
+ */
+ public int indexOf(Graphic g) {
+ return this.graphics.indexOf(g);
+ }
+
+ /**
+ * Contains or not
+ *
+ * @param g Graphic
+ * @return Boolean
+ */
+ public boolean contains(Graphic g) {
+ return this.graphics.contains(g);
+ }
+
+ /**
+ * Get graphic list size
+ *
+ * @return Gaphic list size
+ */
+ public int size() {
+ return this.graphics.size();
+ }
+
+ /**
+ * Get is empty or not
+ *
+ * @return Boolean
+ */
+ public boolean isEmpty() {
+ return this.graphics.isEmpty();
+ }
+
+ /**
+ * Get graphics number
+ *
+ * @return 1
+ */
+ @Override
+ public int getNumGraphics() {
+ return this.size();
+ }
+
+ /**
+ * Get Graphic by index
+ *
+ * @param idx Index
+ * @return Graphic
+ */
+ @Override
+ public Graphic getGraphicN(int idx) {
+ return this.get(idx);
+ }
+
+ /**
+ * Remove a graphic
+ *
+ * @param aGraphic The graphic
+ * @return Boolean
+ */
+ public boolean remove(Graphic aGraphic) {
+ boolean istrue = this.graphics.remove(aGraphic);
+ this.updateExtent();
+
+ return istrue;
+ }
+
+ /**
+ * Remove a graphic by index
+ *
+ * @param index The index
+ * @return The removed graphic
+ */
+ public Graphic remove(int index) {
+ Graphic ag = this.graphics.remove(index);
+ this.updateExtent();
+
+ return ag;
+ }
+
+ /**
+ * Clear graphics
+ */
+ public void clear() {
+ this.graphics.clear();
+ }
+
+ /**
+ * Add all
+ *
+ * @param gs Graphic list
+ */
+ public void addAll(List gs) {
+ this.graphics.addAll(gs);
+ }
+
+ /**
+ * Join this graphics with other graphics
+ *
+ * @param graphic Other graphics
+ */
+ public void join(Graphic graphic) {
+ if (graphic.isCollection()) {
+ //Update extent
+ if (this.isEmpty()) {
+ _extent = graphic.getExtent();
+ } else {
+ _extent = MIMath.getLagerExtent(_extent, graphic.getExtent());
+ }
+ for (int i = 0; i < graphic.getNumGraphics(); i++) {
+ this.graphics.add(graphic.getGraphicN(i));
+ }
+ } else {
+ this.add(graphic);
+ }
+ }
+
+ /**
+ * Remove all
+ *
+ * @param gs Graphic list
+ */
+ public void removeAll(List gs) {
+ this.graphics.removeAll(gs);
+ }
+
+ /**
+ * Get legend
+ *
+ * @return Legend
+ */
+ @Override
+ public ColorBreak getLegend() {
+ if (this.legendBreak != null) {
+ return this.legendBreak;
+ } else {
+ return this.graphics.get(0).getLegend();
+ }
+ }
+
+ /**
+ * Select graphics by an extent
+ *
+ * @param aExtent The extent
+ * @return Selected graphics
+ */
+ public GraphicCollection selectGraphics(Extent aExtent) {
+ GraphicCollection selectedGraphics = new GraphicCollection();
+ int i, j;
+ PointD aPoint = new PointD();
+ aPoint.X = (aExtent.minX + aExtent.maxX) / 2;
+ aPoint.Y = (aExtent.minY + aExtent.maxY) / 2;
+
+ for (Graphic aGraphic : this.graphics) {
+ switch (aGraphic.getShape().getShapeType()) {
+ case Point:
+ PointShape aPS = (PointShape) aGraphic.getShape();
+ if (MIMath.pointInExtent(aPS.getPoint(), aExtent)) {
+ selectedGraphics.add(aGraphic);
+ }
+ break;
+ case Polyline:
+ case PolylineZ:
+ PolylineShape aPLS = (PolylineShape) aGraphic.getShape();
+ if (MIMath.isExtentCross(aExtent, aPLS.getExtent())) {
+ for (j = 0; j < aPLS.getPoints().size(); j++) {
+ aPoint = aPLS.getPoints().get(j);
+ if (MIMath.pointInExtent(aPoint, aExtent)) {
+ selectedGraphics.add(aGraphic);
+ break;
+ }
+ }
+ }
+ break;
+ case Polygon:
+ case Rectangle:
+ PolygonShape aPGS = (PolygonShape) aGraphic.getShape();
+ if (!(aPGS.getPartNum() > 1)) {
+ if (GeoComputation.pointInPolygon((List) aPGS.getPoints(), aPoint)) {
+ selectedGraphics.add(aGraphic);
+ }
+ } else {
+ for (int p = 0; p < aPGS.getPartNum(); p++) {
+ ArrayList pList = new ArrayList();
+ if (p == aPGS.getPartNum() - 1) {
+ for (int pp = aPGS.parts[p]; pp < aPGS.getPointNum(); pp++) {
+ pList.add(aPGS.getPoints().get(pp));
+ }
+ } else {
+ for (int pp = aPGS.parts[p]; pp < aPGS.parts[p + 1]; pp++) {
+ pList.add(aPGS.getPoints().get(pp));
+ }
+ }
+ if (GeoComputation.pointInPolygon(pList, aPoint)) {
+ selectedGraphics.add(aGraphic);
+ break;
+ }
+ }
+ }
+ break;
+ }
+ }
+
+ return selectedGraphics;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return index <= this.size() - 1;
+ }
+
+ @Override
+ public Object next() {
+ if (index >= this.size()) {
+ throw new NoSuchElementException();
+ }
+
+ return this.get(index++);
+ }
+
+ /**
+ * Add labels
+ */
+ public void addLabels() {
+ addLabelsByColor();
+
+ labelSet.setDrawLabels(true);
+ }
+
+ /**
+ * Get shapes
+ *
+ * @return Shapes
+ */
+ public List getShapes() {
+ List shapes = new ArrayList<>();
+ for (Graphic g : this.graphics) {
+ shapes.add(g.getShape());
+ }
+ return shapes;
+ }
+
+ /**
+ * Get shape type
+ *
+ * @return Shape type
+ */
+ public ShapeTypes getShapeType() {
+ return this.graphics.get(0).getShape().getShapeType();
+ }
+
+ private double getMinValue() {
+ double min = Double.MAX_VALUE;
+ for (Graphic graphic : this.graphics) {
+ Shape shape = graphic.getShape();
+ if (min > shape.getValue()) {
+ min = shape.getValue();
+ }
+ }
+ return min;
+ }
+
+ /**
+ * Add labels
+ */
+ private void addLabelsByColor() {
+ if (labelSet.isAutoDecimal()) {
+ double min = getMinValue();
+ labelSet.setDecimalDigits(MIMath.getDecimalNum(min));
+ }
+ String dFormat = "%1$." + String.valueOf(labelSet.getDecimalDigits()) + "f";
+ PointD aPoint;
+ for (Graphic graphic : this.graphics) {
+ ColorBreak cb = graphic.getLegend();
+ Shape shape = graphic.getShape();
+ PointShape aPS = new PointShape();
+ switch (shape.getShapeType()) {
+ case Point:
+ case PointM:
+ case PointZ:
+ aPS.setPoint((PointD) ((PointShape) shape).getPoint().clone());
+ break;
+ case Polyline:
+ case PolylineM:
+ case PolylineZ:
+ int pIdx = ((PolylineShape) shape).getPoints().size() / 2;
+ aPS.setPoint((PointD) ((PolylineShape) shape).getPoints().get(pIdx - 1).clone());
+ break;
+ case Polygon:
+ case PolygonM:
+ Extent aExtent = shape.getExtent();
+ aPoint = new PointD();
+ aPoint.X = ((aExtent.minX + aExtent.maxX) / 2);
+ aPoint.Y = ((aExtent.minY + aExtent.maxY) / 2);
+ aPS.setPoint(aPoint);
+ break;
+ }
+
+ LabelBreak aLP = new LabelBreak();
+ //aLP.setText(DataConvert.removeTailingZeros(String.valueOf(shape.getValue())));
+ aLP.setText(String.format(dFormat, shape.getValue()));
+ if (labelSet.isColorByLegend()) {
+ aLP.setColor(cb.getColor());
+ } else {
+ aLP.setColor(labelSet.getLabelColor());
+ }
+ aLP.setFont(labelSet.getLabelFont());
+ aLP.setAlignType(labelSet.getLabelAlignType());
+ aLP.setYShift(labelSet.getYOffset());
+ aLP.setXShift(labelSet.getXOffset());
+ Graphic aGraphic = new Graphic(aPS, aLP);
+ addLabel(aGraphic);
+ }
+ }
+
+ /**
+ * Add label point
+ *
+ * @param aLP Label point
+ */
+ public void addLabel(Graphic aLP) {
+ labelPoints.add(aLP);
+ }
+
+ /**
+ * Add labels of contour layer dynamicly
+ *
+ * @param sExtent View extent of MapView
+ */
+ public void addLabelsContourDynamic(Extent sExtent) {
+ if (labelSet.isAutoDecimal()) {
+ double min = getMinValue();
+ labelSet.setDecimalDigits(MIMath.getDecimalNum(min));
+ }
+ String dFormat = "%1$." + String.valueOf(labelSet.getDecimalDigits()) + "f";
+ String text;
+ for (Graphic graphic : this.graphics) {
+ Shape shape = graphic.getShape();
+ ColorBreak cb = graphic.getLegend();
+ PolylineShape aPLS = (PolylineShape) shape;
+ Extent IExtent = aPLS.getExtent();
+ if (IExtent.maxX - IExtent.minX > (sExtent.maxX - sExtent.minX) / 10
+ || IExtent.maxY - IExtent.minY > (sExtent.maxY - sExtent.minY) / 10) {
+ LabelBreak aLP = new LabelBreak();
+ int pIdx = aPLS.getPoints().size() / 2;
+ //PointF aPoint = new PointF(0, 0);
+ PointShape aPS = new PointShape();
+ aPS.setPoint(aPLS.getPoints().get(pIdx - 1));
+ //text = DataConvert.removeTailingZeros(String.valueOf(aPLS.getValue()));
+ text = String.format(dFormat, aPLS.getValue());
+ aLP.setText(text);
+ aLP.setFont(labelSet.getLabelFont());
+ aLP.setAlignType(labelSet.getLabelAlignType());
+ aLP.setYShift(labelSet.getYOffset());
+ if (labelSet.isColorByLegend()) {
+ aLP.setColor(cb.getColor());
+ } else {
+ aLP.setColor(labelSet.getLabelColor());
+ }
+ Graphic aGraphic = new Graphic(aPS, aLP);
+ addLabel(aGraphic);
+ }
+ }
+
+ labelSet.setDrawLabels(true);
+ }
+
+ /**
+ * Get arrow zoom
+ *
+ * @return Arrow zoom
+ */
+ public float getArrowZoom() {
+ if (this.getLegend().getBreakType() == BreakTypes.PointBreak) {
+ float size = ((PointBreak) this.getLegend()).getSize();
+ return size / 10;
+ }
+
+ return 1.0f;
+ }
+
+ /**
+ * Clip
+ *
+ * @param clipPolys Clipping polygons
+ * @return Clipped graphics
+ */
+ public GraphicCollection clip(List clipPolys) {
+ GraphicCollection cgraphics = new GraphicCollection();
+ for (PolygonShape aPGS : clipPolys) {
+ for (int i = 0; i < this.graphics.size(); i++) {
+ Shape bShape = this.graphics.get(i).getShape();
+ Shape clipShape = bShape.intersection(aPGS);
+ if (clipShape != null) {
+ cgraphics.add(new Graphic(clipShape, this.graphics.get(i).getLegend()));
+ }
+ }
+ }
+ cgraphics.setSingleLegend(this.singleLegend);
+ cgraphics.setLegendScheme((LegendScheme) this.getLegendScheme().clone());
+
+ return cgraphics;
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/shape/Line.java b/MeteoInfoLib/src/main/java/org/meteoinfo/shape/Line.java
index df83830d..6e5874bc 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/shape/Line.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/shape/Line.java
@@ -1,49 +1,49 @@
- /* Copyright 2012 Yaqiang Wang,
- * yaqiang.wang@gmail.com
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.shape;
-
-import org.meteoinfo.global.MIMath;
-import org.meteoinfo.global.PointD;
-
-/**
- *
- * @author Yaqiang Wang
- */
-public class Line {
- ///
- /// Point 1
- ///
-
- public PointD P1 = new PointD();
- ///
- /// Point 2
- ///
- public PointD P2 = new PointD();
-
- /**
- * Determine if the line is horizontal
- * @return Boolean
- */
- public boolean isHorizontal(){
- return (MIMath.doubleEquals(P1.Y, P2.Y));
- }
-
- /**
- * Determine if the line is vertical
- * @return Boolean
- */
- public boolean isVertical(){
- return (MIMath.doubleEquals(P1.X, P2.X));
- }
-}
+ /* Copyright 2012 Yaqiang Wang,
+ * yaqiang.wang@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ */
+package org.meteoinfo.shape;
+
+ import org.meteoinfo.common.MIMath;
+ import org.meteoinfo.common.PointD;
+
+ /**
+ *
+ * @author Yaqiang Wang
+ */
+public class Line {
+ ///
+ /// Point 1
+ ///
+
+ public PointD P1 = new PointD();
+ ///
+ /// Point 2
+ ///
+ public PointD P2 = new PointD();
+
+ /**
+ * Determine if the line is horizontal
+ * @return Boolean
+ */
+ public boolean isHorizontal(){
+ return (MIMath.doubleEquals(P1.Y, P2.Y));
+ }
+
+ /**
+ * Determine if the line is vertical
+ * @return Boolean
+ */
+ public boolean isVertical(){
+ return (MIMath.doubleEquals(P1.X, P2.X));
+ }
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/shape/PointM.java b/MeteoInfoLib/src/main/java/org/meteoinfo/shape/PointM.java
index 71a0740b..ef6bfe18 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/shape/PointM.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/shape/PointM.java
@@ -1,63 +1,63 @@
-/* Copyright 2012 Yaqiang Wang,
- * yaqiang.wang@gmail.com
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.shape;
-
-import org.meteoinfo.global.PointD;
-
-/**
- *
- * @author yaqiang
- */
-public class PointM extends PointD {
- //
- /**
- * Measure
- */
- public double M;
- //
- //
-
- /**
- * Constructor
- */
- public PointM() {
- }
-
- /**
- * Constructor
- *
- * @param x X
- * @param y Y
- * @param m M
- */
- public PointM(double x, double y, double m) {
- X = x;
- Y = y;
- M = m;
- }
- //
- //
- //
- //
-
- /**
- * Convert to PointD
- *
- * @return PointD
- */
- public PointD toPointD() {
- return new PointD(X, Y);
- }
- //
-}
+/* Copyright 2012 Yaqiang Wang,
+ * yaqiang.wang@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ */
+package org.meteoinfo.shape;
+
+import org.meteoinfo.common.PointD;
+
+/**
+ *
+ * @author yaqiang
+ */
+public class PointM extends PointD {
+ //
+ /**
+ * Measure
+ */
+ public double M;
+ //
+ //
+
+ /**
+ * Constructor
+ */
+ public PointM() {
+ }
+
+ /**
+ * Constructor
+ *
+ * @param x X
+ * @param y Y
+ * @param m M
+ */
+ public PointM(double x, double y, double m) {
+ X = x;
+ Y = y;
+ M = m;
+ }
+ //
+ //
+ //
+ //
+
+ /**
+ * Convert to PointD
+ *
+ * @return PointD
+ */
+ public PointD toPointD() {
+ return new PointD(X, Y);
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/shape/PointShape.java b/MeteoInfoLib/src/main/java/org/meteoinfo/shape/PointShape.java
index 1ae87684..2e2c5090 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/shape/PointShape.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/shape/PointShape.java
@@ -14,13 +14,13 @@
*/
package org.meteoinfo.shape;
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.global.PointD;
import java.util.ArrayList;
import java.util.List;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.PointD;
/**
* Point shape class
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/shape/PointZ.java b/MeteoInfoLib/src/main/java/org/meteoinfo/shape/PointZ.java
index e8745408..1fbd25d0 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/shape/PointZ.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/shape/PointZ.java
@@ -1,111 +1,111 @@
-/* Copyright 2012 Yaqiang Wang,
- * yaqiang.wang@gmail.com
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.shape;
-
-import org.meteoinfo.global.PointD;
-
-/**
- *
- * @author yaqiang
- */
-public class PointZ extends PointD implements Cloneable{
- //
-
- /**
- * Z coordinate
- */
- public double Z;
- /**
- * Measure
- */
- public double M;
- //
- //
-
- /**
- * Constructor
- */
- public PointZ() {
- }
-
- /**
- * Constructor
- *
- * @param x X
- * @param y Y
- * @param z Z
- */
- public PointZ(double x, double y, double z) {
- X = x;
- Y = y;
- Z = z;
- }
-
- /**
- * Constructor
- * @param coord Coordinate array
- */
- public PointZ(double[] coord) {
- X = coord[0];
- Y = coord[1];
- Z = coord[2];
- }
-
- /**
- * Constructor
- *
- * @param x X
- * @param y Y
- * @param z Z
- * @param m M
- */
- public PointZ(double x, double y, double z, double m) {
- X = x;
- Y = y;
- Z = z;
- M = m;
- }
- //
- //
- //
- //
-
- /**
- * Convert to PointD
- *
- * @return PointD
- */
- public PointD toPointD() {
- return new PointD(X, Y);
- }
-
- /**
- * To double array
- * @return Double array
- */
- public double[] toArray() {
- return new double[]{X, Y, Z};
- }
-
- /**
- * Clone
- *
- * @return PointZ object
- */
- @Override
- public Object clone() {
- return (PointZ)super.clone();
- }
- //
-}
+/* Copyright 2012 Yaqiang Wang,
+ * yaqiang.wang@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ */
+package org.meteoinfo.shape;
+
+import org.meteoinfo.common.PointD;
+
+/**
+ *
+ * @author yaqiang
+ */
+public class PointZ extends PointD implements Cloneable{
+ //
+
+ /**
+ * Z coordinate
+ */
+ public double Z;
+ /**
+ * Measure
+ */
+ public double M;
+ //
+ //
+
+ /**
+ * Constructor
+ */
+ public PointZ() {
+ }
+
+ /**
+ * Constructor
+ *
+ * @param x X
+ * @param y Y
+ * @param z Z
+ */
+ public PointZ(double x, double y, double z) {
+ X = x;
+ Y = y;
+ Z = z;
+ }
+
+ /**
+ * Constructor
+ * @param coord Coordinate array
+ */
+ public PointZ(double[] coord) {
+ X = coord[0];
+ Y = coord[1];
+ Z = coord[2];
+ }
+
+ /**
+ * Constructor
+ *
+ * @param x X
+ * @param y Y
+ * @param z Z
+ * @param m M
+ */
+ public PointZ(double x, double y, double z, double m) {
+ X = x;
+ Y = y;
+ Z = z;
+ M = m;
+ }
+ //
+ //
+ //
+ //
+
+ /**
+ * Convert to PointD
+ *
+ * @return PointD
+ */
+ public PointD toPointD() {
+ return new PointD(X, Y);
+ }
+
+ /**
+ * To double array
+ * @return Double array
+ */
+ public double[] toArray() {
+ return new double[]{X, Y, Z};
+ }
+
+ /**
+ * Clone
+ *
+ * @return PointZ object
+ */
+ @Override
+ public Object clone() {
+ return (PointZ)super.clone();
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/shape/PointZShape.java b/MeteoInfoLib/src/main/java/org/meteoinfo/shape/PointZShape.java
index 470bc40d..ab4c1936 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/shape/PointZShape.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/shape/PointZShape.java
@@ -1,155 +1,155 @@
-/*
- * Copyright 2012 Yaqiang Wang,
- * yaqiang.wang@gmail.com
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.shape;
-
-import org.meteoinfo.global.Extent3D;
-import org.meteoinfo.global.PointD;
-import org.locationtech.jts.geom.CoordinateXYZM;
-import org.locationtech.jts.geom.Geometry;
-
-/**
- *
- * @author yaqiang
- */
-public class PointZShape extends PointShape {
- //
-
- //private PointZ _point = new PointZ();
- //private double z;
- //private double m;
- //
- //
- /**
- * Constructor
- */
- public PointZShape(){
- this.point = new PointZ();
- this.updateExtent((PointZ)this.point);
- }
-
- /**
- * Constructor
- * @param geometry Geometry
- */
- public PointZShape(Geometry geometry) {
- CoordinateXYZM c = (CoordinateXYZM)geometry.getCoordinate();
- this.setPoint(new PointZ(c.x, c.y, c.getZ(), c.getM()));
- }
- //
- //
-
- @Override
- public ShapeTypes getShapeType(){
- return ShapeTypes.PointZ;
- }
-
-// /**
-// * Get point
-// *
-// * @return Point
-// */
-// @Override
-// public PointZ getPoint() {
-// return _point;
-// }
-//
-// /**
-// * Set point
-// *
-// * @param point Point
-// */
-// public void setPoint(PointZ point) {
-// _point = point;
-// }
-
- //
- //
- /**
- * Set point
- *
- * @param aPoint point
- */
- @Override
- public void setPoint(PointD aPoint) {
- if (aPoint instanceof PointZ){
- this.point = aPoint;
- } else {
- this.point.X = aPoint.X;
- this.point.Y = aPoint.Y;
- }
- this.updateExtent((PointZ)this.point);
- }
-
- /**
- * Set point
- * @param p PointZ
- */
- public void setPoint(PointZ p){
- this.point = p;
- this.updateExtent(p);
- }
-
- /**
- * Update extent
- * @param p PointZ
- */
- public void updateExtent(PointZ p){
- Extent3D aExtent = new Extent3D();
- aExtent.minX = p.X;
- aExtent.maxX = p.X;
- aExtent.minY = p.Y;
- aExtent.maxY = p.Y;
- aExtent.minZ = p.Z;
- aExtent.maxZ = p.Z;
- this.setExtent(aExtent);
- }
-
- /**
- * Get M value
- * @return M value
- */
- public double getM(){
- return ((PointZ)this.getPoint()).M;
- }
-
- /**
- * Get Z value
- * @return Z value
- */
- public double getZ(){
- return ((PointZ)this.getPoint()).Z;
- }
-
- /**
- * Clone
- *
- * @return PolylineZShape object
- */
- @Override
- public Object clone() {
- PointZShape aPS = new PointZShape();
- //aPS = (PointZShape)base.Clone();
- aPS.setPoint((PointZ)this.getPoint().clone());
- //aPS.Z = Z;
- //aPS.M = M;
- aPS.setValue(getValue());
- aPS.setVisible(this.isVisible());
- aPS.setSelected(this.isSelected());
- aPS.setLegendIndex(this.getLegendIndex());
-
- return aPS;
- }
- //
-}
+/*
+ * Copyright 2012 Yaqiang Wang,
+ * yaqiang.wang@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ */
+package org.meteoinfo.shape;
+
+import org.locationtech.jts.geom.CoordinateXYZM;
+import org.locationtech.jts.geom.Geometry;
+import org.meteoinfo.common.Extent3D;
+import org.meteoinfo.common.PointD;
+
+/**
+ *
+ * @author yaqiang
+ */
+public class PointZShape extends PointShape {
+ //
+
+ //private PointZ _point = new PointZ();
+ //private double z;
+ //private double m;
+ //
+ //
+ /**
+ * Constructor
+ */
+ public PointZShape(){
+ this.point = new PointZ();
+ this.updateExtent((PointZ)this.point);
+ }
+
+ /**
+ * Constructor
+ * @param geometry Geometry
+ */
+ public PointZShape(Geometry geometry) {
+ CoordinateXYZM c = (CoordinateXYZM)geometry.getCoordinate();
+ this.setPoint(new PointZ(c.x, c.y, c.getZ(), c.getM()));
+ }
+ //
+ //
+
+ @Override
+ public ShapeTypes getShapeType(){
+ return ShapeTypes.PointZ;
+ }
+
+// /**
+// * Get point
+// *
+// * @return Point
+// */
+// @Override
+// public PointZ getPoint() {
+// return _point;
+// }
+//
+// /**
+// * Set point
+// *
+// * @param point Point
+// */
+// public void setPoint(PointZ point) {
+// _point = point;
+// }
+
+ //
+ //
+ /**
+ * Set point
+ *
+ * @param aPoint point
+ */
+ @Override
+ public void setPoint(PointD aPoint) {
+ if (aPoint instanceof PointZ){
+ this.point = aPoint;
+ } else {
+ this.point.X = aPoint.X;
+ this.point.Y = aPoint.Y;
+ }
+ this.updateExtent((PointZ)this.point);
+ }
+
+ /**
+ * Set point
+ * @param p PointZ
+ */
+ public void setPoint(PointZ p){
+ this.point = p;
+ this.updateExtent(p);
+ }
+
+ /**
+ * Update extent
+ * @param p PointZ
+ */
+ public void updateExtent(PointZ p){
+ Extent3D aExtent = new Extent3D();
+ aExtent.minX = p.X;
+ aExtent.maxX = p.X;
+ aExtent.minY = p.Y;
+ aExtent.maxY = p.Y;
+ aExtent.minZ = p.Z;
+ aExtent.maxZ = p.Z;
+ this.setExtent(aExtent);
+ }
+
+ /**
+ * Get M value
+ * @return M value
+ */
+ public double getM(){
+ return ((PointZ)this.getPoint()).M;
+ }
+
+ /**
+ * Get Z value
+ * @return Z value
+ */
+ public double getZ(){
+ return ((PointZ)this.getPoint()).Z;
+ }
+
+ /**
+ * Clone
+ *
+ * @return PolylineZShape object
+ */
+ @Override
+ public Object clone() {
+ PointZShape aPS = new PointZShape();
+ //aPS = (PointZShape)base.Clone();
+ aPS.setPoint((PointZ)this.getPoint().clone());
+ //aPS.Z = Z;
+ //aPS.M = M;
+ aPS.setValue(getValue());
+ aPS.setVisible(this.isVisible());
+ aPS.setSelected(this.isSelected());
+ aPS.setLegendIndex(this.getLegendIndex());
+
+ return aPS;
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/shape/Polygon.java b/MeteoInfoLib/src/main/java/org/meteoinfo/shape/Polygon.java
index 7eaaed7c..c561cbb8 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/shape/Polygon.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/shape/Polygon.java
@@ -13,13 +13,15 @@
*/
package org.meteoinfo.shape;
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.PointD;
import org.meteoinfo.geoprocess.GeoComputation;
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.global.MIMath;
-import org.meteoinfo.global.PointD;
+
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+
+import org.meteoinfo.geoprocess.GeometryUtil;
import org.meteoinfo.global.DataConvert;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
@@ -63,7 +65,7 @@ public class Polygon {
*/
public void setOutLine(List extends PointD> outLine) {
_outLine = outLine;
- _extent = MIMath.getPointsExtent(outLine);
+ _extent = GeometryUtil.getPointsExtent(outLine);
}
/**
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/shape/PolygonMShape.java b/MeteoInfoLib/src/main/java/org/meteoinfo/shape/PolygonMShape.java
index b73d311f..9b25640e 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/shape/PolygonMShape.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/shape/PolygonMShape.java
@@ -1,74 +1,75 @@
-/*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.meteoinfo.shape;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.meteoinfo.global.MIMath;
-import org.locationtech.jts.geom.Coordinate;
-import org.locationtech.jts.geom.CoordinateXYM;
-import org.locationtech.jts.geom.Geometry;
-
-/**
- *
- * @author yaqiang
- */
-public class PolygonMShape extends PolygonShape{
- //
- //
- //
- /**
- * Constructor
- */
- public PolygonMShape(){
- super();
- }
-
- /**
- * Constructor
- * @param geometry Geometry
- */
- public PolygonMShape(Geometry geometry) {
- Coordinate[] cs = geometry.getCoordinates();
- List points = new ArrayList();
- for (Coordinate c1 : cs) {
- CoordinateXYM c = (CoordinateXYM) c1;
- points.add(new PointZ(c.x, c.y, c.getZ(), c.getM()));
- }
- this.setPoints(points);
- }
- //
- //
- @Override
- public ShapeTypes getShapeType(){
- return ShapeTypes.PolygonM;
- }
-
- /**
- * Get M Array
- *
- * @return M value array
- */
- public double[] getMArray() {
- double[] mArray = new double[this.getPoints().size()];
- for (int i = 0; i < this.getPoints().size(); i++) {
- mArray[i] = ((PointM)this.getPoints().get(i)).M;
- }
-
- return mArray;
- }
-
- /**
- * Get M range - min, max
- *
- * @return M min, max
- */
- public double[] getMRange() {
- return MIMath.arrayMinMax(getMArray());
- }
- //
- //
- //
-}
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.meteoinfo.shape;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.locationtech.jts.geom.Coordinate;
+import org.locationtech.jts.geom.CoordinateXYM;
+import org.locationtech.jts.geom.Geometry;
+import org.meteoinfo.common.MIMath;
+
+/**
+ *
+ * @author yaqiang
+ */
+public class PolygonMShape extends PolygonShape{
+ //
+ //
+ //
+ /**
+ * Constructor
+ */
+ public PolygonMShape(){
+ super();
+ }
+
+ /**
+ * Constructor
+ * @param geometry Geometry
+ */
+ public PolygonMShape(Geometry geometry) {
+ Coordinate[] cs = geometry.getCoordinates();
+ List points = new ArrayList();
+ for (Coordinate c1 : cs) {
+ CoordinateXYM c = (CoordinateXYM) c1;
+ points.add(new PointZ(c.x, c.y, c.getZ(), c.getM()));
+ }
+ this.setPoints(points);
+ }
+ //
+ //
+ @Override
+ public ShapeTypes getShapeType(){
+ return ShapeTypes.PolygonM;
+ }
+
+ /**
+ * Get M Array
+ *
+ * @return M value array
+ */
+ public double[] getMArray() {
+ double[] mArray = new double[this.getPoints().size()];
+ for (int i = 0; i < this.getPoints().size(); i++) {
+ mArray[i] = ((PointM)this.getPoints().get(i)).M;
+ }
+
+ return mArray;
+ }
+
+ /**
+ * Get M range - min, max
+ *
+ * @return M min, max
+ */
+ public double[] getMRange() {
+ return MIMath.arrayMinMax(getMArray());
+ }
+ //
+ //
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/shape/PolygonShape.java b/MeteoInfoLib/src/main/java/org/meteoinfo/shape/PolygonShape.java
index 150a3aa9..66c65644 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/shape/PolygonShape.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/shape/PolygonShape.java
@@ -13,18 +13,21 @@
*/
package org.meteoinfo.shape;
+import org.meteoinfo.common.MIMath;
+import org.meteoinfo.common.PointD;
+import org.meteoinfo.common.PointF;
import org.meteoinfo.geoprocess.GeoComputation;
-import org.meteoinfo.global.MIMath;
-import org.meteoinfo.global.PointD;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
-import org.meteoinfo.global.PointF;
+
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.MultiPolygon;
+import org.meteoinfo.geoprocess.GeometryUtil;
/**
* PolygonShape class
@@ -137,7 +140,7 @@ public class PolygonShape extends Shape implements Cloneable {
((List)this._polygons).add(polygon);
break;
}
- this.setExtent(MIMath.getPointsExtent(_points));
+ this.setExtent(GeometryUtil.getPointsExtent(_points));
}
//
//
@@ -184,7 +187,7 @@ public class PolygonShape extends Shape implements Cloneable {
@Override
public void setPoints(List extends PointD> points) {
_points = points;
- this.setExtent(MIMath.getPointsExtent(_points));
+ this.setExtent(GeometryUtil.getPointsExtent(_points));
updatePolygons();
}
@@ -198,7 +201,7 @@ public class PolygonShape extends Shape implements Cloneable {
ps.add(new PointD(points[i].X, points[i].Y));
}
_points = ps;
- this.setExtent(MIMath.getPointsExtent(_points));
+ this.setExtent(GeometryUtil.getPointsExtent(_points));
updatePolygons_keep();
}
@@ -390,7 +393,7 @@ public class PolygonShape extends Shape implements Cloneable {
parts[i] = partList.get(i);
}
if (_points.size() > 0)
- this.setExtent(MIMath.getPointsExtent(_points));
+ this.setExtent(GeometryUtil.getPointsExtent(_points));
}
/**
@@ -462,7 +465,7 @@ public class PolygonShape extends Shape implements Cloneable {
}
((List) _points).add(vIdx, vertice);
- this.setExtent(MIMath.getPointsExtent(_points));
+ this.setExtent(GeometryUtil.getPointsExtent(_points));
this.updatePolygons();
}
@@ -479,7 +482,7 @@ public class PolygonShape extends Shape implements Cloneable {
}
((List) _points).remove(vIdx);
- this.setExtent(MIMath.getPointsExtent(_points));
+ this.setExtent(GeometryUtil.getPointsExtent(_points));
this.updatePolygons();
}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/shape/PolygonZShape.java b/MeteoInfoLib/src/main/java/org/meteoinfo/shape/PolygonZShape.java
index 7972f04e..7fd00ed8 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/shape/PolygonZShape.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/shape/PolygonZShape.java
@@ -1,112 +1,113 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.meteoinfo.shape;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import org.meteoinfo.geoprocess.GeoComputation;
-import org.meteoinfo.global.MIMath;
-
-/**
- *
- * @author Yaqiang Wang
- */
-public class PolygonZShape extends PolygonShape{
- @Override
- public ShapeTypes getShapeType(){
- return ShapeTypes.PolygonZ;
- }
-
- /**
- * Get Z Array
- *
- * @return Z value array
- */
- public double[] getZArray() {
- double[] zArray = new double[this.getPoints().size()];
- for (int i = 0; i < this.getPoints().size(); i++) {
- zArray[i] = ((PointZ)this.getPoints().get(i)).Z;
- }
-
- return zArray;
- }
-
- /**
- * Get Z range - min, max
- *
- * @return Z min, max
- */
- public double[] getZRange() {
- return MIMath.arrayMinMax(getZArray());
- }
-
- /**
- * Get M Array
- *
- * @return M value array
- */
- public double[] getMArray() {
- double[] mArray = new double[this.getPoints().size()];
- for (int i = 0; i < this.getPoints().size(); i++) {
- mArray[i] = ((PointZ)this.getPoints().get(i)).M;
- }
-
- return mArray;
- }
-
- /**
- * Get M range - min, max
- *
- * @return M min, max
- */
- public double[] getMRange() {
- return MIMath.arrayMinMax(getMArray());
- }
-
- @Override
- protected void updatePolygons() {
- _polygons = new ArrayList<>();
- if (_numParts == 1) {
- PolygonZ aPolygon = new PolygonZ();
- aPolygon.setOutLine(_points);
- ((List)_polygons).add(aPolygon);
- } else {
- PointZ[] Pointps;
- PolygonZ aPolygon = null;
- int numPoints = this.getPointNum();
- for (int p = 0; p < _numParts; p++) {
- if (p == _numParts - 1) {
- Pointps = new PointZ[numPoints - parts[p]];
- for (int pp = parts[p]; pp < numPoints; pp++) {
- Pointps[pp - parts[p]] = (PointZ)_points.get(pp);
- }
- } else {
- Pointps = new PointZ[parts[p + 1] - parts[p]];
- for (int pp = parts[p]; pp < parts[p + 1]; pp++) {
- Pointps[pp - parts[p]] = (PointZ)_points.get(pp);
- }
- }
-
- if (GeoComputation.isClockwise(Pointps)) {
- if (p > 0) {
- ((List)_polygons).add(aPolygon);
- }
-
- aPolygon = new PolygonZ();
- aPolygon.setOutLine(Arrays.asList(Pointps));
- } else if (aPolygon == null) {
- MIMath.arrayReverse(Pointps);
- aPolygon = new PolygonZ();
- aPolygon.setOutLine(Arrays.asList(Pointps));
- } else {
- aPolygon.addHole(Arrays.asList(Pointps));
- }
- }
- ((List)_polygons).add(aPolygon);
- }
- }
-}
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.meteoinfo.shape;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.meteoinfo.common.MIMath;
+import org.meteoinfo.geoprocess.GeoComputation;
+
+/**
+ *
+ * @author Yaqiang Wang
+ */
+public class PolygonZShape extends PolygonShape{
+ @Override
+ public ShapeTypes getShapeType(){
+ return ShapeTypes.PolygonZ;
+ }
+
+ /**
+ * Get Z Array
+ *
+ * @return Z value array
+ */
+ public double[] getZArray() {
+ double[] zArray = new double[this.getPoints().size()];
+ for (int i = 0; i < this.getPoints().size(); i++) {
+ zArray[i] = ((PointZ)this.getPoints().get(i)).Z;
+ }
+
+ return zArray;
+ }
+
+ /**
+ * Get Z range - min, max
+ *
+ * @return Z min, max
+ */
+ public double[] getZRange() {
+ return MIMath.arrayMinMax(getZArray());
+ }
+
+ /**
+ * Get M Array
+ *
+ * @return M value array
+ */
+ public double[] getMArray() {
+ double[] mArray = new double[this.getPoints().size()];
+ for (int i = 0; i < this.getPoints().size(); i++) {
+ mArray[i] = ((PointZ)this.getPoints().get(i)).M;
+ }
+
+ return mArray;
+ }
+
+ /**
+ * Get M range - min, max
+ *
+ * @return M min, max
+ */
+ public double[] getMRange() {
+ return MIMath.arrayMinMax(getMArray());
+ }
+
+ @Override
+ protected void updatePolygons() {
+ _polygons = new ArrayList<>();
+ if (_numParts == 1) {
+ PolygonZ aPolygon = new PolygonZ();
+ aPolygon.setOutLine(_points);
+ ((List)_polygons).add(aPolygon);
+ } else {
+ PointZ[] Pointps;
+ PolygonZ aPolygon = null;
+ int numPoints = this.getPointNum();
+ for (int p = 0; p < _numParts; p++) {
+ if (p == _numParts - 1) {
+ Pointps = new PointZ[numPoints - parts[p]];
+ for (int pp = parts[p]; pp < numPoints; pp++) {
+ Pointps[pp - parts[p]] = (PointZ)_points.get(pp);
+ }
+ } else {
+ Pointps = new PointZ[parts[p + 1] - parts[p]];
+ for (int pp = parts[p]; pp < parts[p + 1]; pp++) {
+ Pointps[pp - parts[p]] = (PointZ)_points.get(pp);
+ }
+ }
+
+ if (GeoComputation.isClockwise(Pointps)) {
+ if (p > 0) {
+ ((List)_polygons).add(aPolygon);
+ }
+
+ aPolygon = new PolygonZ();
+ aPolygon.setOutLine(Arrays.asList(Pointps));
+ } else if (aPolygon == null) {
+ MIMath.arrayReverse(Pointps);
+ aPolygon = new PolygonZ();
+ aPolygon.setOutLine(Arrays.asList(Pointps));
+ } else {
+ aPolygon.addHole(Arrays.asList(Pointps));
+ }
+ }
+ ((List)_polygons).add(aPolygon);
+ }
+ }
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/shape/Polyline.java b/MeteoInfoLib/src/main/java/org/meteoinfo/shape/Polyline.java
index cf5dc10f..4c7ee00e 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/shape/Polyline.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/shape/Polyline.java
@@ -14,10 +14,12 @@
*/
package org.meteoinfo.shape;
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.global.MIMath;
-import org.meteoinfo.global.PointD;
-import org.meteoinfo.global.PointF;
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.MIMath;
+import org.meteoinfo.common.PointD;
+import org.meteoinfo.common.PointF;
+import org.meteoinfo.geoprocess.GeometryUtil;
+
import java.util.ArrayList;
import java.util.List;
@@ -55,7 +57,7 @@ public class Polyline {
*/
public void setPointList(List extends PointD> points) {
_pointList = points;
- _extent = MIMath.getPointsExtent(_pointList);
+ _extent = GeometryUtil.getPointsExtent(_pointList);
}
/**
@@ -80,7 +82,7 @@ public class Polyline {
}
_pointList = pointList;
- _extent = MIMath.getPointsExtent(_pointList);
+ _extent = GeometryUtil.getPointsExtent(_pointList);
}
/**
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/shape/PolylineShape.java b/MeteoInfoLib/src/main/java/org/meteoinfo/shape/PolylineShape.java
index 2b6b57cc..05479d89 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/shape/PolylineShape.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/shape/PolylineShape.java
@@ -13,8 +13,6 @@
*/
package org.meteoinfo.shape;
-import org.meteoinfo.global.MIMath;
-import org.meteoinfo.global.PointD;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -24,6 +22,9 @@ import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.LineString;
import org.locationtech.jts.geom.MultiLineString;
+import org.meteoinfo.common.MIMath;
+import org.meteoinfo.common.PointD;
+import org.meteoinfo.geoprocess.GeometryUtil;
/**
* Poyline shape class
@@ -93,7 +94,7 @@ public class PolylineShape extends Shape implements Cloneable {
for (int i = 0; i < parts.length; i++) {
parts[i] = partlist.get(i);
}
- this.setExtent(MIMath.getPointsExtent(_points));
+ this.setExtent(GeometryUtil.getPointsExtent(_points));
break;
default:
this.setPoints(points);
@@ -160,7 +161,7 @@ public class PolylineShape extends Shape implements Cloneable {
@Override
public void setPoints(List extends PointD> points) {
_points = points;
- this.setExtent(MIMath.getPointsExtent(_points));
+ this.setExtent(GeometryUtil.getPointsExtent(_points));
updatePolyLines();
}
@@ -274,7 +275,7 @@ public class PolylineShape extends Shape implements Cloneable {
for (int i = 0; i < partList.size(); i++) {
parts[i] = partList.get(i);
}
- this.setExtent(MIMath.getPointsExtent(_points));
+ this.setExtent(GeometryUtil.getPointsExtent(_points));
}
/**
@@ -310,7 +311,7 @@ public class PolylineShape extends Shape implements Cloneable {
}
((List) _points).add(vIdx, vertice);
- this.setExtent(MIMath.getPointsExtent(_points));
+ this.setExtent(GeometryUtil.getPointsExtent(_points));
updatePolyLines();
}
@@ -327,7 +328,7 @@ public class PolylineShape extends Shape implements Cloneable {
}
((List) _points).remove(vIdx);
- this.setExtent(MIMath.getPointsExtent(_points));
+ this.setExtent(GeometryUtil.getPointsExtent(_points));
updatePolyLines();
}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/shape/PolylineZ.java b/MeteoInfoLib/src/main/java/org/meteoinfo/shape/PolylineZ.java
index cf104f83..65d0a0af 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/shape/PolylineZ.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/shape/PolylineZ.java
@@ -1,99 +1,93 @@
-/* Copyright 2012 Yaqiang Wang,
- * yaqiang.wang@gmail.com
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.shape;
-
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.global.MIMath;
-import org.meteoinfo.global.PointD;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- *
- * @author yaqiang
- */
-public class PolylineZ extends Polyline{
- //
-
- //private Extent _extent;
- //private List _pointList;
- //
- //
-
- /**
- * Constructor
- */
- public PolylineZ() {
- super();
- //_extent = new Extent();
- //_pointList = new ArrayList<>();
- }
- //
- //
-
-// /**
-// * Get points
-// *
-// * @return Point list
-// */
-// public List getPoints() {
-// return _pointList;
-// }
-//
-// /**
-// * Set points
-// *
-// * @param points Point list
-// */
-// public void setPoints(List points) {
-// _pointList = points;
-// _extent = MIMath.getPointsExtent((getPointDList()));
-// }
-//
-// /**
-// * Get extent
-// *
-// * @return Extent
-// */
-// public Extent getExtent() {
-// return _extent;
-// }
-//
-// //
-// //
-// private List getPointDList() {
-// List pList = new ArrayList<>();
-// for (PointZ aP : _pointList) {
-// pList.add(aP.toPointD());
-// }
-//
-// return pList;
-// }
-
-// /**
-// * Determine if the polyline is closed
-// *
-// * @return Boolean
-// */
-// public boolean isClosed() {
-// PointZ sPoint = _pointList.get(0);
-// PointZ ePoint = _pointList.get(_pointList.size() - 1);
-// if (MIMath.doubleEquals(sPoint.X, ePoint.X) && MIMath.doubleEquals(sPoint.Y, ePoint.Y)) {
-// return true;
-// } else {
-// return false;
-// }
-// }
- //
-}
+/* Copyright 2012 Yaqiang Wang,
+ * yaqiang.wang@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ */
+package org.meteoinfo.shape;
+
+/**
+ *
+ * @author yaqiang
+ */
+public class PolylineZ extends Polyline{
+ //
+
+ //private Extent _extent;
+ //private List _pointList;
+ //
+ //
+
+ /**
+ * Constructor
+ */
+ public PolylineZ() {
+ super();
+ //_extent = new Extent();
+ //_pointList = new ArrayList<>();
+ }
+ //
+ //
+
+// /**
+// * Get points
+// *
+// * @return Point list
+// */
+// public List getPoints() {
+// return _pointList;
+// }
+//
+// /**
+// * Set points
+// *
+// * @param points Point list
+// */
+// public void setPoints(List points) {
+// _pointList = points;
+// _extent = MIMath.getPointsExtent((getPointDList()));
+// }
+//
+// /**
+// * Get extent
+// *
+// * @return Extent
+// */
+// public Extent getExtent() {
+// return _extent;
+// }
+//
+// //
+// //
+// private List getPointDList() {
+// List pList = new ArrayList<>();
+// for (PointZ aP : _pointList) {
+// pList.add(aP.toPointD());
+// }
+//
+// return pList;
+// }
+
+// /**
+// * Determine if the polyline is closed
+// *
+// * @return Boolean
+// */
+// public boolean isClosed() {
+// PointZ sPoint = _pointList.get(0);
+// PointZ ePoint = _pointList.get(_pointList.size() - 1);
+// if (MIMath.doubleEquals(sPoint.X, ePoint.X) && MIMath.doubleEquals(sPoint.Y, ePoint.Y)) {
+// return true;
+// } else {
+// return false;
+// }
+// }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/shape/PolylineZShape.java b/MeteoInfoLib/src/main/java/org/meteoinfo/shape/PolylineZShape.java
index 45489a24..44ff5dad 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/shape/PolylineZShape.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/shape/PolylineZShape.java
@@ -1,167 +1,168 @@
- /* Copyright 2012 Yaqiang Wang,
- * yaqiang.wang@gmail.com
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.shape;
-
-import org.meteoinfo.global.MIMath;
-import java.util.ArrayList;
-import java.util.List;
-import org.meteoinfo.global.Extent;
-import org.locationtech.jts.geom.Coordinate;
-import org.locationtech.jts.geom.CoordinateXYZM;
-import org.locationtech.jts.geom.Geometry;
-
-/**
- * PolylineZ shape class
- *
- * @author yaqiang
- */
-public class PolylineZShape extends PolylineShape {
- //
-
- //private List _points = new ArrayList();
- //private List _polylines = new ArrayList();
- //
- //
-
- /**
- * Constructor
- */
- public PolylineZShape() {
- super();
- }
-
- /**
- * Constructor
- * @param geometry Geometry
- */
- public PolylineZShape(Geometry geometry) {
- Coordinate[] cs = geometry.getCoordinates();
- List points = new ArrayList();
- for (Coordinate c1 : cs) {
- CoordinateXYZM c = (CoordinateXYZM) c1;
- points.add(new PointZ(c.x, c.y, c.getZ(), c.getM()));
- }
- this.setPoints(points);
- }
- //
- //
-
- @Override
- public ShapeTypes getShapeType(){
- return ShapeTypes.PolylineZ;
- }
-
- /**
- * Get Z Array
- *
- * @return Z array
- */
- public double[] getZArray() {
- double[] zArray = new double[this.getPoints().size()];
- for (int i = 0; i < this.getPoints().size(); i++) {
- zArray[i] = ((PointZ)this.getPoints().get(i)).Z;
- }
-
- return zArray;
- }
-
- /**
- * Get Z Array
- *
- * @return Z value array
- */
- public double[] getMArray() {
- double[] mArray = new double[this.getPoints().size()];
- for (int i = 0; i < this.getPoints().size(); i++) {
- mArray[i] = ((PointZ)this.getPoints().get(i)).M;
- }
-
- return mArray;
- }
-
- /**
- * Get Z range - min, max
- *
- * @return Z min, max
- */
- public double[] getZRange() {
- return MIMath.arrayMinMax(getZArray());
- }
-
- /**
- * Get M range - min, max
- *
- * @return M min, max
- */
- public double[] getMRange() {
- return MIMath.arrayMinMax(getMArray());
- }
-
- //@Override
- public Object clone_back(){
- PolylineZShape o = (PolylineZShape)super.clone();
-// List points = new ArrayList<>();
-// for (PointZ point : (List)this.getPoints()){
-// points.add((PointZ)point.clone());
-// }
-// o.setPoints(points);
-
- return o;
- }
-
- /**
- * Clone
- *
- * @return PolylineZShape object
- */
- @Override
- public Object clone() {
- PolylineZShape aPLS = new PolylineZShape();
- aPLS.setValue(this.getValue());
- aPLS.setExtent((Extent)this.getExtent().clone());
- aPLS.setPartNum(this.getPartNum());
- aPLS.parts = (int[]) parts.clone();
- List points = new ArrayList<>();
- for (PointZ point : (List)this.getPoints()){
- points.add((PointZ)point.clone());
- }
- aPLS.setPoints(points);
- aPLS.setVisible(this.isVisible());
- aPLS.setSelected(this.isSelected());
- aPLS.setLegendIndex(this.getLegendIndex());
- //aPLS.ZRange = (double[])ZRange.Clone();
- //aPLS.MRange = (double[])MRange.Clone();
- //aPLS.ZArray = (double[])ZArray.Clone();
- //aPLS.MArray = (double[])MArray.Clone();
-
- return aPLS;
- }
-
- /**
- * Value clone
- *
- * @return PolylineZShape object
- */
- @Override
- public Object valueClone() {
- PolylineZShape aPLS = new PolylineZShape();
- aPLS.setValue(this.getValue());
- aPLS.setVisible(this.isVisible());
- aPLS.setSelected(this.isSelected());
- aPLS.setLegendIndex(this.getLegendIndex());
-
- return aPLS;
- }
- //
-}
+ /* Copyright 2012 Yaqiang Wang,
+ * yaqiang.wang@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ */
+package org.meteoinfo.shape;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.locationtech.jts.geom.Coordinate;
+import org.locationtech.jts.geom.CoordinateXYZM;
+import org.locationtech.jts.geom.Geometry;
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.MIMath;
+
+ /**
+ * PolylineZ shape class
+ *
+ * @author yaqiang
+ */
+public class PolylineZShape extends PolylineShape {
+ //
+
+ //private List _points = new ArrayList();
+ //private List _polylines = new ArrayList();
+ //
+ //
+
+ /**
+ * Constructor
+ */
+ public PolylineZShape() {
+ super();
+ }
+
+ /**
+ * Constructor
+ * @param geometry Geometry
+ */
+ public PolylineZShape(Geometry geometry) {
+ Coordinate[] cs = geometry.getCoordinates();
+ List points = new ArrayList();
+ for (Coordinate c1 : cs) {
+ CoordinateXYZM c = (CoordinateXYZM) c1;
+ points.add(new PointZ(c.x, c.y, c.getZ(), c.getM()));
+ }
+ this.setPoints(points);
+ }
+ //
+ //
+
+ @Override
+ public ShapeTypes getShapeType(){
+ return ShapeTypes.PolylineZ;
+ }
+
+ /**
+ * Get Z Array
+ *
+ * @return Z array
+ */
+ public double[] getZArray() {
+ double[] zArray = new double[this.getPoints().size()];
+ for (int i = 0; i < this.getPoints().size(); i++) {
+ zArray[i] = ((PointZ)this.getPoints().get(i)).Z;
+ }
+
+ return zArray;
+ }
+
+ /**
+ * Get Z Array
+ *
+ * @return Z value array
+ */
+ public double[] getMArray() {
+ double[] mArray = new double[this.getPoints().size()];
+ for (int i = 0; i < this.getPoints().size(); i++) {
+ mArray[i] = ((PointZ)this.getPoints().get(i)).M;
+ }
+
+ return mArray;
+ }
+
+ /**
+ * Get Z range - min, max
+ *
+ * @return Z min, max
+ */
+ public double[] getZRange() {
+ return MIMath.arrayMinMax(getZArray());
+ }
+
+ /**
+ * Get M range - min, max
+ *
+ * @return M min, max
+ */
+ public double[] getMRange() {
+ return MIMath.arrayMinMax(getMArray());
+ }
+
+ //@Override
+ public Object clone_back(){
+ PolylineZShape o = (PolylineZShape)super.clone();
+// List points = new ArrayList<>();
+// for (PointZ point : (List)this.getPoints()){
+// points.add((PointZ)point.clone());
+// }
+// o.setPoints(points);
+
+ return o;
+ }
+
+ /**
+ * Clone
+ *
+ * @return PolylineZShape object
+ */
+ @Override
+ public Object clone() {
+ PolylineZShape aPLS = new PolylineZShape();
+ aPLS.setValue(this.getValue());
+ aPLS.setExtent((Extent)this.getExtent().clone());
+ aPLS.setPartNum(this.getPartNum());
+ aPLS.parts = (int[]) parts.clone();
+ List points = new ArrayList<>();
+ for (PointZ point : (List)this.getPoints()){
+ points.add((PointZ)point.clone());
+ }
+ aPLS.setPoints(points);
+ aPLS.setVisible(this.isVisible());
+ aPLS.setSelected(this.isSelected());
+ aPLS.setLegendIndex(this.getLegendIndex());
+ //aPLS.ZRange = (double[])ZRange.Clone();
+ //aPLS.MRange = (double[])MRange.Clone();
+ //aPLS.ZArray = (double[])ZArray.Clone();
+ //aPLS.MArray = (double[])MArray.Clone();
+
+ return aPLS;
+ }
+
+ /**
+ * Value clone
+ *
+ * @return PolylineZShape object
+ */
+ @Override
+ public Object valueClone() {
+ PolylineZShape aPLS = new PolylineZShape();
+ aPLS.setValue(this.getValue());
+ aPLS.setVisible(this.isVisible());
+ aPLS.setSelected(this.isSelected());
+ aPLS.setLegendIndex(this.getLegendIndex());
+
+ return aPLS;
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/shape/RectangleShape.java b/MeteoInfoLib/src/main/java/org/meteoinfo/shape/RectangleShape.java
index 7c1ce496..4ec2f790 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/shape/RectangleShape.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/shape/RectangleShape.java
@@ -1,124 +1,125 @@
-/* Copyright 2012 Yaqiang Wang,
- * yaqiang.wang@gmail.com
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.shape;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.meteoinfo.global.PointD;
-
-/**
- *
- * @author yaqiang
- */
-public class RectangleShape extends PolygonShape {
- //
- private boolean round = false;
- private double roundX = 0;
- private double roundY = 0;
- //
- //
- /**
- * Constructor
- */
- public RectangleShape(){
- super();
- }
-
- /**
- * Constructor
- * @param x X
- * @param y Y
- * @param width Width
- * @param height Height
- */
- public RectangleShape(double x, double y, double width, double height){
- super();
- List points = new ArrayList<>();
- points.add(new PointD(x, y));
- points.add(new PointD(x, y + height));
- points.add(new PointD(x + width, y + height));
- points.add(new PointD(x + width, y));
- this.setPoints(points);
- }
- //
- //
- @Override
- public ShapeTypes getShapeType(){
- return ShapeTypes.Rectangle;
- }
-
- /**
- * Get is round or not
- * @return Boolean
- */
- public boolean isRound(){
- return this.round;
- }
-
- /**
- * Get round x
- * @return Round x
- */
- public double getRoundX(){
- return this.roundX;
- }
-
- /**
- * Set round y
- * @param value Round y
- */
- public void setRoundX(double value){
- this.roundX = value;
- this.round = true;
- }
-
- /**
- * Get round y
- * @return Round y
- */
- public double getRoundY(){
- return this.roundY;
- }
-
- /**
- * Set round y
- * @param value Round y
- */
- public void setRoundY(double value){
- this.roundY = value;
- this.round = true;
- }
- //
- //
-
- /**
- * Clone
- *
- * @return RectangleShape object
- */
- @Override
- public Object clone() {
- RectangleShape aPGS = new RectangleShape();
- aPGS.setExtent(this.getExtent());
- aPGS.setPoints(new ArrayList<>(this.getPoints()));
- aPGS.setVisible(this.isVisible());
- aPGS.setSelected(this.isSelected());
- aPGS.round = this.round;
- aPGS.roundX = this.roundX;
- aPGS.roundY = this.roundY;
-
- return aPGS;
- }
- //
-}
+/* Copyright 2012 Yaqiang Wang,
+ * yaqiang.wang@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ * General Public License for more details.
+ */
+package org.meteoinfo.shape;
+
+import org.meteoinfo.common.PointD;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ * @author yaqiang
+ */
+public class RectangleShape extends PolygonShape {
+ //
+ private boolean round = false;
+ private double roundX = 0;
+ private double roundY = 0;
+ //
+ //
+ /**
+ * Constructor
+ */
+ public RectangleShape(){
+ super();
+ }
+
+ /**
+ * Constructor
+ * @param x X
+ * @param y Y
+ * @param width Width
+ * @param height Height
+ */
+ public RectangleShape(double x, double y, double width, double height){
+ super();
+ List points = new ArrayList<>();
+ points.add(new PointD(x, y));
+ points.add(new PointD(x, y + height));
+ points.add(new PointD(x + width, y + height));
+ points.add(new PointD(x + width, y));
+ this.setPoints(points);
+ }
+ //
+ //
+ @Override
+ public ShapeTypes getShapeType(){
+ return ShapeTypes.Rectangle;
+ }
+
+ /**
+ * Get is round or not
+ * @return Boolean
+ */
+ public boolean isRound(){
+ return this.round;
+ }
+
+ /**
+ * Get round x
+ * @return Round x
+ */
+ public double getRoundX(){
+ return this.roundX;
+ }
+
+ /**
+ * Set round y
+ * @param value Round y
+ */
+ public void setRoundX(double value){
+ this.roundX = value;
+ this.round = true;
+ }
+
+ /**
+ * Get round y
+ * @return Round y
+ */
+ public double getRoundY(){
+ return this.roundY;
+ }
+
+ /**
+ * Set round y
+ * @param value Round y
+ */
+ public void setRoundY(double value){
+ this.roundY = value;
+ this.round = true;
+ }
+ //
+ //
+
+ /**
+ * Clone
+ *
+ * @return RectangleShape object
+ */
+ @Override
+ public Object clone() {
+ RectangleShape aPGS = new RectangleShape();
+ aPGS.setExtent(this.getExtent());
+ aPGS.setPoints(new ArrayList<>(this.getPoints()));
+ aPGS.setVisible(this.isVisible());
+ aPGS.setSelected(this.isSelected());
+ aPGS.round = this.round;
+ aPGS.roundX = this.roundX;
+ aPGS.roundY = this.roundY;
+
+ return aPGS;
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/shape/Shape.java b/MeteoInfoLib/src/main/java/org/meteoinfo/shape/Shape.java
index 503ea286..c5a7980f 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/shape/Shape.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/shape/Shape.java
@@ -15,8 +15,7 @@
package org.meteoinfo.shape;
import java.util.ArrayList;
-import org.meteoinfo.global.Extent;
-import org.meteoinfo.global.PointD;
+
import java.util.List;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
@@ -25,6 +24,8 @@ import org.locationtech.jts.geom.LinearRing;
import org.locationtech.jts.operation.polygonize.Polygonizer;
import org.locationtech.jts.operation.union.CascadedPolygonUnion;
import org.locationtech.jts.operation.union.UnaryUnionOp;
+import org.meteoinfo.common.Extent;
+import org.meteoinfo.common.PointD;
/**
* Shape class
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/shape/ShapeUtil.java b/MeteoInfoLib/src/main/java/org/meteoinfo/shape/ShapeUtil.java
index 50f2d18a..f2aaa57d 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/shape/ShapeUtil.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/shape/ShapeUtil.java
@@ -1,323 +1,324 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.meteoinfo.shape;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.meteoinfo.global.PointD;
-import org.meteoinfo.ndarray.Array;
-
-/**
- *
- * @author wyq
- */
-public class ShapeUtil {
-
- /**
- * Create point shapes
- *
- * @param x X coordinates
- * @param y Y coordinates
- * @return Point shapes
- */
- public static List createPointShapes(List x, List y) {
- double xx, yy;
- PointShape ps;
- List shapes = new ArrayList<>();
- for (int i = 0; i < x.size(); i++) {
- ps = new PointShape();
- xx = x.get(i).doubleValue();
- yy = y.get(i).doubleValue();
- ps.setPoint(new PointD(xx, yy));
- shapes.add(ps);
- }
- return shapes;
- }
-
- /**
- * Create point shapes
- *
- * @param x X coordinates
- * @param y Y coordinates
- * @return Point shapes
- */
- public static List createPointShapes(Array x, Array y) {
- double xx, yy;
- PointShape ps;
- List shapes = new ArrayList<>();
- for (int i = 0; i < x.getSize(); i++) {
- ps = new PointShape();
- xx = x.getDouble(i);
- yy = y.getDouble(i);
- ps.setPoint(new PointD(xx, yy));
- shapes.add(ps);
- }
- return shapes;
- }
-
- /**
- * Create PointZ shapes
- *
- * @param x X coordinates
- * @param y Y coordinates
- * @param z Z coordinates
- * @param m M coordinates
- * @return PointZ shapes
- */
- public static List createPointShapes(Array x, Array y, Array z, Array m) {
- double xx, yy;
- PointZShape ps;
- List shapes = new ArrayList<>();
- for (int i = 0; i < x.getSize(); i++) {
- ps = new PointZShape();
- xx = x.getDouble(i);
- yy = y.getDouble(i);
-
- ps.setPoint(new PointZ(xx, yy, z.getDouble(i), m.getDouble(i)));
- shapes.add(ps);
- }
- return shapes;
- }
-
- /**
- * Create polyline shapes
- *
- * @param x X coordinates
- * @param y Y coordinates
- * @return Polyline shapes
- */
- public static List createPolylineShapes(List x, List y) {
- double xx, yy;
- List points = new ArrayList<>();
- PolylineShape pls;
- List shapes = new ArrayList<>();
- for (int i = 0; i < x.size(); i++) {
- xx = x.get(i).doubleValue();
- yy = y.get(i).doubleValue();
- if (Double.isNaN(xx)) {
- if (points.size() >= 2) {
- pls = new PolylineShape();
- pls.setPoints(points);
- shapes.add(pls);
- }
- points = new ArrayList<>();
- } else {
- points.add(new PointD(xx, yy));
- }
- }
- if (points.size() >= 2) {
- pls = new PolylineShape();
- pls.setPoints(points);
- shapes.add(pls);
- }
-
- return shapes;
- }
-
- /**
- * Create polyline shapes
- *
- * @param x X coordinates
- * @param y Y coordinates
- * @return Polyline shapes
- */
- public static List createPolylineShapes(Array x, Array y) {
- double xx, yy;
- List points = new ArrayList<>();
- PolylineShape pls;
- List shapes = new ArrayList<>();
- for (int i = 0; i < x.getSize(); i++) {
- xx = x.getDouble(i);
- yy = y.getDouble(i);
- if (Double.isNaN(xx)) {
- if (points.size() >= 2) {
- pls = new PolylineShape();
- pls.setPoints(points);
- shapes.add(pls);
- }
- points = new ArrayList<>();
- } else {
- points.add(new PointD(xx, yy));
- }
- }
- if (points.size() >= 2) {
- pls = new PolylineShape();
- pls.setPoints(points);
- shapes.add(pls);
- }
-
- return shapes;
- }
-
- /**
- * Create polylineZ shapes
- *
- * @param x X coordinates
- * @param y Y coordinates
- * @param z Z coordinates
- * @param m M coordinates
- * @return PolylineZ shapes
- */
- public static List createPolylineShapes(Array x, Array y, Array z, Array m) {
- double xx, yy;
- List points = new ArrayList<>();
- PolylineZShape pls;
- List shapes = new ArrayList<>();
- for (int i = 0; i < x.getSize(); i++) {
- xx = x.getDouble(i);
- yy = y.getDouble(i);
- if (Double.isNaN(xx)) {
- if (points.size() >= 2) {
- pls = new PolylineZShape();
- pls.setPoints(points);
- shapes.add(pls);
- }
- points = new ArrayList<>();
- } else {
- points.add(new PointZ(xx, yy, z.getDouble(i), m.getDouble(i)));
- }
- }
- if (points.size() >= 2) {
- pls = new PolylineZShape();
- pls.setPoints(points);
- shapes.add(pls);
- }
-
- return shapes;
- }
-
- /**
- * Create polygon shapes
- *
- * @param x X coordinates
- * @param y Y coordinates
- * @return Polygon shapes
- */
- public static List createPolygonShapes(List x, List y) {
- double xx, yy;
- List points = new ArrayList<>();
- PolygonShape pls;
- List shapes = new ArrayList<>();
- for (int i = 0; i < x.size(); i++) {
- xx = x.get(i).doubleValue();
- yy = y.get(i).doubleValue();
- if (Double.isNaN(xx)) {
- if (points.size() > 2) {
- pls = new PolygonShape();
- pls.setPoints(points);
- shapes.add(pls);
- }
- points = new ArrayList<>();
- } else {
- points.add(new PointD(xx, yy));
- }
- }
- if (points.size() > 2) {
- pls = new PolygonShape();
- pls.setPoints(points);
- shapes.add(pls);
- }
-
- return shapes;
- }
-
- /**
- * Create polygon shapes
- *
- * @param x X coordinates
- * @param y Y coordinates
- * @return Polygon shapes
- */
- public static List createPolygonShapes(Array x, Array y) {
- double xx, yy;
- List points = new ArrayList<>();
- PolygonShape pls;
- List shapes = new ArrayList<>();
- for (int i = 0; i < x.getSize(); i++) {
- xx = x.getDouble(i);
- yy = y.getDouble(i);
- if (Double.isNaN(xx)) {
- if (points.size() > 2) {
- pls = new PolygonShape();
- pls.setPoints(points);
- shapes.add(pls);
- }
- points = new ArrayList<>();
- } else {
- points.add(new PointD(xx, yy));
- }
- }
- if (points.size() > 2) {
- pls = new PolygonShape();
- pls.setPoints(points);
- shapes.add(pls);
- }
-
- return shapes;
- }
-
- /**
- * Create polygon shape
- *
- * @param x_p X coordinate list
- * @param y_p Y coordinate list
- * @return Polygon shape
- */
- public static PolygonShape createPolygonShape(List x_p, List y_p) {
- PolygonShape ps = new PolygonShape();
- List points = new ArrayList<>();
- for (int i = 0; i < x_p.size(); i++) {
- points.add(new PointD(x_p.get(i).doubleValue(), y_p.get(i).doubleValue()));
- }
- if (!points.get(points.size() - 1).equals(points.get(0))) {
- points.add((PointD) points.get(0).clone());
- }
- ps.setPoints(points);
-
- return ps;
- }
-
- /**
- * Create polygon shape
- *
- * @param xy X/Y coordinates
- * @return Polygon shape
- */
- public static PolygonShape createPolygonShape(List> xy) {
- PolygonShape ps = new PolygonShape();
- List points = new ArrayList<>();
- for (List xy1 : xy) {
- points.add(new PointD(xy1.get(0).doubleValue(), xy1.get(1).doubleValue()));
- }
- if (!points.get(points.size() - 1).equals(points.get(0))) {
- points.add((PointD) points.get(0).clone());
- }
- ps.setPoints(points);
-
- return ps;
- }
-
- /**
- * Add a circle
- *
- * @param x Center x
- * @param y Center y
- * @param radius
- * @return Graphic
- */
- public static CircleShape createCircleShape(float x, float y, float radius) {
- List points = new ArrayList<>();
- points.add(new PointD(x - radius, y));
- points.add(new PointD(x, y - radius));
- points.add(new PointD(x + radius, y));
- points.add(new PointD(x, y + radius));
-
- CircleShape aPGS = new CircleShape();
- aPGS.setPoints(points);
-
- return aPGS;
- }
-}
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.meteoinfo.shape;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.meteoinfo.common.PointD;
+import org.meteoinfo.ndarray.Array;
+
+/**
+ *
+ * @author wyq
+ */
+public class ShapeUtil {
+
+ /**
+ * Create point shapes
+ *
+ * @param x X coordinates
+ * @param y Y coordinates
+ * @return Point shapes
+ */
+ public static List createPointShapes(List x, List y) {
+ double xx, yy;
+ PointShape ps;
+ List shapes = new ArrayList<>();
+ for (int i = 0; i < x.size(); i++) {
+ ps = new PointShape();
+ xx = x.get(i).doubleValue();
+ yy = y.get(i).doubleValue();
+ ps.setPoint(new PointD(xx, yy));
+ shapes.add(ps);
+ }
+ return shapes;
+ }
+
+ /**
+ * Create point shapes
+ *
+ * @param x X coordinates
+ * @param y Y coordinates
+ * @return Point shapes
+ */
+ public static List createPointShapes(Array x, Array y) {
+ double xx, yy;
+ PointShape ps;
+ List shapes = new ArrayList<>();
+ for (int i = 0; i < x.getSize(); i++) {
+ ps = new PointShape();
+ xx = x.getDouble(i);
+ yy = y.getDouble(i);
+ ps.setPoint(new PointD(xx, yy));
+ shapes.add(ps);
+ }
+ return shapes;
+ }
+
+ /**
+ * Create PointZ shapes
+ *
+ * @param x X coordinates
+ * @param y Y coordinates
+ * @param z Z coordinates
+ * @param m M coordinates
+ * @return PointZ shapes
+ */
+ public static List createPointShapes(Array x, Array y, Array z, Array m) {
+ double xx, yy;
+ PointZShape ps;
+ List shapes = new ArrayList<>();
+ for (int i = 0; i < x.getSize(); i++) {
+ ps = new PointZShape();
+ xx = x.getDouble(i);
+ yy = y.getDouble(i);
+
+ ps.setPoint(new PointZ(xx, yy, z.getDouble(i), m.getDouble(i)));
+ shapes.add(ps);
+ }
+ return shapes;
+ }
+
+ /**
+ * Create polyline shapes
+ *
+ * @param x X coordinates
+ * @param y Y coordinates
+ * @return Polyline shapes
+ */
+ public static List createPolylineShapes(List x, List y) {
+ double xx, yy;
+ List points = new ArrayList<>();
+ PolylineShape pls;
+ List shapes = new ArrayList<>();
+ for (int i = 0; i < x.size(); i++) {
+ xx = x.get(i).doubleValue();
+ yy = y.get(i).doubleValue();
+ if (Double.isNaN(xx)) {
+ if (points.size() >= 2) {
+ pls = new PolylineShape();
+ pls.setPoints(points);
+ shapes.add(pls);
+ }
+ points = new ArrayList<>();
+ } else {
+ points.add(new PointD(xx, yy));
+ }
+ }
+ if (points.size() >= 2) {
+ pls = new PolylineShape();
+ pls.setPoints(points);
+ shapes.add(pls);
+ }
+
+ return shapes;
+ }
+
+ /**
+ * Create polyline shapes
+ *
+ * @param x X coordinates
+ * @param y Y coordinates
+ * @return Polyline shapes
+ */
+ public static List createPolylineShapes(Array x, Array y) {
+ double xx, yy;
+ List points = new ArrayList<>();
+ PolylineShape pls;
+ List shapes = new ArrayList<>();
+ for (int i = 0; i < x.getSize(); i++) {
+ xx = x.getDouble(i);
+ yy = y.getDouble(i);
+ if (Double.isNaN(xx)) {
+ if (points.size() >= 2) {
+ pls = new PolylineShape();
+ pls.setPoints(points);
+ shapes.add(pls);
+ }
+ points = new ArrayList<>();
+ } else {
+ points.add(new PointD(xx, yy));
+ }
+ }
+ if (points.size() >= 2) {
+ pls = new PolylineShape();
+ pls.setPoints(points);
+ shapes.add(pls);
+ }
+
+ return shapes;
+ }
+
+ /**
+ * Create polylineZ shapes
+ *
+ * @param x X coordinates
+ * @param y Y coordinates
+ * @param z Z coordinates
+ * @param m M coordinates
+ * @return PolylineZ shapes
+ */
+ public static List createPolylineShapes(Array x, Array y, Array z, Array m) {
+ double xx, yy;
+ List points = new ArrayList<>();
+ PolylineZShape pls;
+ List shapes = new ArrayList<>();
+ for (int i = 0; i < x.getSize(); i++) {
+ xx = x.getDouble(i);
+ yy = y.getDouble(i);
+ if (Double.isNaN(xx)) {
+ if (points.size() >= 2) {
+ pls = new PolylineZShape();
+ pls.setPoints(points);
+ shapes.add(pls);
+ }
+ points = new ArrayList<>();
+ } else {
+ points.add(new PointZ(xx, yy, z.getDouble(i), m.getDouble(i)));
+ }
+ }
+ if (points.size() >= 2) {
+ pls = new PolylineZShape();
+ pls.setPoints(points);
+ shapes.add(pls);
+ }
+
+ return shapes;
+ }
+
+ /**
+ * Create polygon shapes
+ *
+ * @param x X coordinates
+ * @param y Y coordinates
+ * @return Polygon shapes
+ */
+ public static List createPolygonShapes(List x, List y) {
+ double xx, yy;
+ List points = new ArrayList<>();
+ PolygonShape pls;
+ List shapes = new ArrayList<>();
+ for (int i = 0; i < x.size(); i++) {
+ xx = x.get(i).doubleValue();
+ yy = y.get(i).doubleValue();
+ if (Double.isNaN(xx)) {
+ if (points.size() > 2) {
+ pls = new PolygonShape();
+ pls.setPoints(points);
+ shapes.add(pls);
+ }
+ points = new ArrayList<>();
+ } else {
+ points.add(new PointD(xx, yy));
+ }
+ }
+ if (points.size() > 2) {
+ pls = new PolygonShape();
+ pls.setPoints(points);
+ shapes.add(pls);
+ }
+
+ return shapes;
+ }
+
+ /**
+ * Create polygon shapes
+ *
+ * @param x X coordinates
+ * @param y Y coordinates
+ * @return Polygon shapes
+ */
+ public static List createPolygonShapes(Array x, Array y) {
+ double xx, yy;
+ List points = new ArrayList<>();
+ PolygonShape pls;
+ List shapes = new ArrayList<>();
+ for (int i = 0; i < x.getSize(); i++) {
+ xx = x.getDouble(i);
+ yy = y.getDouble(i);
+ if (Double.isNaN(xx)) {
+ if (points.size() > 2) {
+ pls = new PolygonShape();
+ pls.setPoints(points);
+ shapes.add(pls);
+ }
+ points = new ArrayList<>();
+ } else {
+ points.add(new PointD(xx, yy));
+ }
+ }
+ if (points.size() > 2) {
+ pls = new PolygonShape();
+ pls.setPoints(points);
+ shapes.add(pls);
+ }
+
+ return shapes;
+ }
+
+ /**
+ * Create polygon shape
+ *
+ * @param x_p X coordinate list
+ * @param y_p Y coordinate list
+ * @return Polygon shape
+ */
+ public static PolygonShape createPolygonShape(List x_p, List y_p) {
+ PolygonShape ps = new PolygonShape();
+ List points = new ArrayList<>();
+ for (int i = 0; i < x_p.size(); i++) {
+ points.add(new PointD(x_p.get(i).doubleValue(), y_p.get(i).doubleValue()));
+ }
+ if (!points.get(points.size() - 1).equals(points.get(0))) {
+ points.add((PointD) points.get(0).clone());
+ }
+ ps.setPoints(points);
+
+ return ps;
+ }
+
+ /**
+ * Create polygon shape
+ *
+ * @param xy X/Y coordinates
+ * @return Polygon shape
+ */
+ public static PolygonShape createPolygonShape(List> xy) {
+ PolygonShape ps = new PolygonShape();
+ List points = new ArrayList<>();
+ for (List xy1 : xy) {
+ points.add(new PointD(xy1.get(0).doubleValue(), xy1.get(1).doubleValue()));
+ }
+ if (!points.get(points.size() - 1).equals(points.get(0))) {
+ points.add((PointD) points.get(0).clone());
+ }
+ ps.setPoints(points);
+
+ return ps;
+ }
+
+ /**
+ * Add a circle
+ *
+ * @param x Center x
+ * @param y Center y
+ * @param radius
+ * @return Graphic
+ */
+ public static CircleShape createCircleShape(float x, float y, float radius) {
+ List points = new ArrayList<>();
+ points.add(new PointD(x - radius, y));
+ points.add(new PointD(x, y - radius));
+ points.add(new PointD(x + radius, y));
+ points.add(new PointD(x, y + radius));
+
+ CircleShape aPGS = new CircleShape();
+ aPGS.setPoints(points);
+
+ return aPGS;
+ }
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/table/ColumnData.java b/MeteoInfoLib/src/main/java/org/meteoinfo/table/ColumnData.java
index 3cc453d3..4faf74f4 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/table/ColumnData.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/table/ColumnData.java
@@ -1,1196 +1,1196 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.meteoinfo.table;
-
-import org.meteoinfo.ndarray.DataType;
-
-import java.time.LocalDateTime;
-import java.util.ArrayList;
-import java.util.List;
-import org.meteoinfo.global.util.JDateUtil;
-
-/**
- *
- * @author yaqiang
- */
-public class ColumnData {
-
- //
- private DataColumn dataColumn;
- private List data;
-
- //
- //
- /**
- * Constructor
- *
- * @param col The data column
- */
- public ColumnData(DataColumn col) {
- dataColumn = col;
- switch (col.getDataType()) {
- case INT:
- data = new ArrayList();
- break;
- case FLOAT:
- data = new ArrayList();
- break;
- case DOUBLE:
- data = new ArrayList();
- break;
- case STRING:
- data = new ArrayList();
- break;
- case DATE:
- data = new ArrayList();
- break;
- case BOOLEAN:
- data = new ArrayList();
- break;
- }
- }
-
- /**
- * Constructor
- *
- * @param colName Data column name
- * @param type Data type
- */
- public ColumnData(String colName, DataType type) {
- this(new DataColumn(colName, type));
- }
-
- //
- //
- /**
- * Get data column
- *
- * @return Data column
- */
- public DataColumn getDataColumn() {
- return this.dataColumn;
- }
-
- /**
- * Set data column
- *
- * @param value Data column
- */
- public void setDataColumn(DataColumn value) {
- dataColumn = value;
- }
-
- /**
- * Get data list
- *
- * @return Data list
- */
- public List getData() {
- return data;
- }
-
- /**
- * Set data list
- *
- * @param value Data list
- */
- public void setData(List value) {
- data = value;
- }
-
- /**
- * Get data type
- *
- * @return Data type
- */
- public DataType getDataType() {
- return dataColumn.getDataType();
- }
-
- //
- //
- /**
- * Get size of the data
- *
- * @return Size of the data
- */
- public int size() {
- return data.size();
- }
-
- /**
- * Add a object data
- *
- * @param value Data value
- */
- public void addData(Object value) {
- switch (dataColumn.getDataType()) {
- case INT:
- this.addData((Integer) value);
- break;
- case FLOAT:
- this.addData((Float) value);
- break;
- case DOUBLE:
- this.addData((Double) value);
- break;
- case STRING:
- this.addData((String) value);
- break;
- case DATE:
- this.addData((LocalDateTime) value);
- break;
- case BOOLEAN:
- this.addData((Boolean) value);
- break;
- }
- }
-
- /**
- * Add a double data value
- *
- * @param value Data value
- */
- public void addData(Double value) {
- ((List) data).add(value);
- }
-
- /**
- * Add a float data value
- *
- * @param value Data value
- */
- public void addData(Float value) {
- ((List) data).add(value);
- }
-
- /**
- * Add a integer data value
- *
- * @param value Data value
- */
- public void addData(Integer value) {
- ((List) data).add(value);
- }
-
- /**
- * Add a string data value
- *
- * @param value Data value
- */
- public void addData(String value) {
- ((List) data).add(value);
- }
-
- /**
- * Add a date data value
- *
- * @param value Data value
- */
- public void addData(LocalDateTime value) {
- ((List) data).add(value);
- }
-
- /**
- * Add a boolean data value
- *
- * @param value Data value
- */
- public void addData(boolean value) {
- ((List) data).add(value);
- }
-
- /**
- * Get data value
- *
- * @param idx Data index
- * @return Data value
- */
- public Object getValue(int idx) {
- switch (dataColumn.getDataType()) {
- case INT:
- return (Integer) data.get(idx);
- case FLOAT:
- return (Float) data.get(idx);
- case DOUBLE:
- return (Double) data.get(idx);
- case STRING:
- return (String) data.get(idx);
- case DATE:
- return (LocalDateTime) data.get(idx);
- case BOOLEAN:
- return (Boolean) data.get(idx);
- }
-
- return null;
- }
-
- /**
- * Get string data list
- * @return String data list
- */
- public List getDataStrings(){
- List r = new ArrayList<>();
- for (Object v : data){
- r.add(v.toString());
- }
-
- return r;
- }
-
- /**
- * Get number data list
- *
- * @return Number data list
- */
- public List getDataValues() {
- if (dataColumn.getDataType() == DataType.DOUBLE) {
- return ((List) data);
- } else {
- List values = new ArrayList<>();
- switch (dataColumn.getDataType()) {
- case INT:
- for (int v : (List) data) {
- values.add(v);
- }
- break;
- case FLOAT:
- for (Object v : (List) data) {
- if (v == null){
- values.add(Float.NaN);
- } else {
- values.add((float)v);
- }
- }
- break;
- case STRING:
- for (String v : (List)data){
- if (v.isEmpty())
- values.add(Double.NaN);
- else
- values.add(Double.parseDouble(v));
- }
- break;
- case DATE:
- for (LocalDateTime v : (List)data){
- values.add(JDateUtil.toOADate(v));
- }
- break;
- }
- return values;
- }
- }
-
- /**
- * Get valid number data list
- * @return Number data list
- */
- public List getValidDataValues(){
- List values = this.getDataValues();
- for (int i = 0, len = values.size(); i < len; i++) {
- if (Double.isNaN(values.get(i).doubleValue())) {
- values.remove(i);
- len--;
- i--;
- }
- }
-
- return values;
- }
-
- /**
- * Contains function
- *
- * @param value The object value
- * @return Is contains or not
- */
- public boolean contains(Object value) {
- return data.contains(value);
- }
-
- /**
- * Mean function
- *
- * @return Mean value
- */
- public Double mean() {
- double mean = 0.0;
- int n = 0;
- switch (dataColumn.getDataType()) {
- case INT:
- for (int v : (List) data) {
- mean += v;
- n++;
- }
- break;
- case FLOAT:
- for (float v : (List) data) {
- if (v != Float.NaN) {
- mean += v;
- n++;
- }
- }
- break;
- case DOUBLE:
- for (double v : (List) data) {
- if (v != Double.NaN) {
- mean += v;
- n++;
- }
- }
- break;
- }
-
- if (n > 0) {
- mean = mean / n;
- return mean;
- } else {
- return Double.NaN;
- }
- }
-
- /**
- * Add function
- *
- * @param value The object value to add
- * @param colName New column data name
- * @return Result column data
- */
- public ColumnData add(Object value, String colName) {
- DataType thisType = dataColumn.getDataType();
- if (!thisType.isNumeric()) {
- return null;
- }
-
- DataType inType = this.getDataType(value);
- if (!inType.isNumeric()){
- return null;
- }
-
- ColumnData rColData = null;
- int i;
- switch (thisType) {
- case INT:
- switch (inType) {
- case INT:
- rColData = new ColumnData(colName, DataType.INT);
- for (i = 0; i < data.size(); i++) {
- rColData.addData((float)(Integer) this.getValue(i) + (Integer) value);
- }
- break;
- case FLOAT:
- rColData = new ColumnData(colName, DataType.FLOAT);
- for (i = 0; i < data.size(); i++) {
- rColData.addData((Integer) this.getValue(i) + (Float) value);
- }
- break;
- case DOUBLE:
- rColData = new ColumnData(colName, DataType.DOUBLE);
- for (i = 0; i < data.size(); i++) {
- rColData.addData((Integer) this.getValue(i) + (Double) value);
- }
- break;
- }
- break;
- case FLOAT:
- switch (inType) {
- case INT:
- rColData = new ColumnData(colName, DataType.FLOAT);
- for (i = 0; i < data.size(); i++) {
- rColData.addData((Float) this.getValue(i) + (Integer) value);
- }
- break;
- case FLOAT:
- rColData = new ColumnData(colName, DataType.FLOAT);
- for (i = 0; i < data.size(); i++) {
- rColData.addData((Float) this.getValue(i) + (Float) value);
- }
- break;
- case DOUBLE:
- rColData = new ColumnData(colName, DataType.DOUBLE);
- for (i = 0; i < data.size(); i++) {
- rColData.addData((Float) this.getValue(i) + (Double) value);
- }
- break;
- }
- break;
- case DOUBLE:
- switch (inType) {
- case INT:
- rColData = new ColumnData(colName, DataType.DOUBLE);
- for (i = 0; i < data.size(); i++) {
- rColData.addData((Double) this.getValue(i) + (Integer) value);
- }
- break;
- case FLOAT:
- rColData = new ColumnData(colName, DataType.DOUBLE);
- for (i = 0; i < data.size(); i++) {
- rColData.addData((Double) this.getValue(i) + (Float) value);
- }
- break;
- case DOUBLE:
- rColData = new ColumnData(colName, DataType.DOUBLE);
- for (i = 0; i < data.size(); i++) {
- rColData.addData((Double) this.getValue(i) + (Double) value);
- }
- break;
- }
- break;
- }
-
- return rColData;
- }
-
- /**
- * Add function
- *
- * @param colData Anorther column data
- * @param colName New column data name
- * @return Result column data
- */
- public ColumnData add(ColumnData colData, String colName) {
- DataType thisType = dataColumn.getDataType();
- if (thisType == DataType.DATE || thisType == DataType.BOOLEAN) {
- return null;
- }
-
- DataType inType = colData.getDataType();
- if (inType == DataType.DATE || inType == DataType.BOOLEAN) {
- return null;
- }
-
- if (thisType == DataType.STRING && inType != DataType.STRING) {
- return null;
- }
-
- if (inType == DataType.STRING && thisType != DataType.STRING) {
- return null;
- }
-
- ColumnData rColData = null;
- int i;
- switch (thisType) {
- case INT:
- switch (inType) {
- case INT:
- rColData = new ColumnData(colName, DataType.INT);
- for (i = 0; i < data.size(); i++) {
- if (i < colData.size()) {
- rColData.addData((Integer) this.getValue(i) + (Integer) colData.getValue(i));
- }
- }
- break;
- case FLOAT:
- rColData = new ColumnData(colName, DataType.FLOAT);
- for (i = 0; i < data.size(); i++) {
- if (i < colData.size()) {
- rColData.addData((Integer) this.getValue(i) + (Float) colData.getValue(i));
- }
- }
- break;
- case DOUBLE:
- rColData = new ColumnData(colName, DataType.DOUBLE);
- for (i = 0; i < data.size(); i++) {
- if (i < colData.size()) {
- rColData.addData((Integer) this.getValue(i) + (Double) colData.getValue(i));
- }
- }
- break;
- }
- break;
- case FLOAT:
- switch (inType) {
- case INT:
- rColData = new ColumnData(colName, DataType.FLOAT);
- for (i = 0; i < data.size(); i++) {
- if (i < colData.size()) {
- rColData.addData((Float) this.getValue(i) + (Integer) colData.getValue(i));
- }
- }
- break;
- case FLOAT:
- rColData = new ColumnData(colName, DataType.FLOAT);
- for (i = 0; i < data.size(); i++) {
- if (i < colData.size()) {
- rColData.addData((Float) this.getValue(i) + (Float) colData.getValue(i));
- }
- }
- break;
- case DOUBLE:
- rColData = new ColumnData(colName, DataType.DOUBLE);
- for (i = 0; i < data.size(); i++) {
- if (i < colData.size()) {
- rColData.addData((Float) this.getValue(i) + (Double) colData.getValue(i));
- }
- }
- break;
- }
- break;
- case DOUBLE:
- switch (inType) {
- case INT:
- rColData = new ColumnData(colName, DataType.DOUBLE);
- for (i = 0; i < data.size(); i++) {
- if (i < colData.size()) {
- rColData.addData((Double) this.getValue(i) + (Integer) colData.getValue(i));
- }
- }
- break;
- case FLOAT:
- rColData = new ColumnData(colName, DataType.DOUBLE);
- for (i = 0; i < data.size(); i++) {
- if (i < colData.size()) {
- rColData.addData((Double) this.getValue(i) + (Float) colData.getValue(i));
- }
- }
- break;
- case DOUBLE:
- rColData = new ColumnData(colName, DataType.DOUBLE);
- for (i = 0; i < data.size(); i++) {
- if (i < colData.size()) {
- rColData.addData((Double) this.getValue(i) + (Double) colData.getValue(i));
- }
- }
- break;
- }
- break;
- case STRING:
- rColData = new ColumnData(colName, DataType.STRING);
- for (i = 0; i < data.size(); i++) {
- if (i < colData.size()) {
- rColData.addData((String) this.getValue(i) + (String) colData.getValue(i));
- }
- }
- break;
- }
-
- return rColData;
- }
-
- /**
- * Subtract function
- *
- * @param value The object value to subtract
- * @param colName New column data name
- * @return Result column data
- */
- public ColumnData sub(Object value, String colName) {
- DataType thisType = dataColumn.getDataType();
- if (!thisType.isNumeric()) {
- return null;
- }
-
- DataType inType = this.getDataType(value);
- if (!inType.isNumeric()){
- return null;
- }
-
- ColumnData rColData = null;
- int i;
- switch (thisType) {
- case INT:
- switch (inType) {
- case INT:
- rColData = new ColumnData(colName, DataType.INT);
- for (i = 0; i < data.size(); i++) {
- rColData.addData((float)(Integer) this.getValue(i) - (Integer) value);
- }
- break;
- case FLOAT:
- rColData = new ColumnData(colName, DataType.FLOAT);
- for (i = 0; i < data.size(); i++) {
- rColData.addData((Integer) this.getValue(i) - (Float) value);
- }
- break;
- case DOUBLE:
- rColData = new ColumnData(colName, DataType.DOUBLE);
- for (i = 0; i < data.size(); i++) {
- rColData.addData((Integer) this.getValue(i) - (Double) value);
- }
- break;
- }
- break;
- case FLOAT:
- switch (inType) {
- case INT:
- rColData = new ColumnData(colName, DataType.FLOAT);
- for (i = 0; i < data.size(); i++) {
- rColData.addData((Float) this.getValue(i) - (Integer) value);
- }
- break;
- case FLOAT:
- rColData = new ColumnData(colName, DataType.FLOAT);
- for (i = 0; i < data.size(); i++) {
- rColData.addData((Float) this.getValue(i) - (Float) value);
- }
- break;
- case DOUBLE:
- rColData = new ColumnData(colName, DataType.DOUBLE);
- for (i = 0; i < data.size(); i++) {
- rColData.addData((Float) this.getValue(i) - (Double) value);
- }
- break;
- }
- break;
- case DOUBLE:
- switch (inType) {
- case INT:
- rColData = new ColumnData(colName, DataType.DOUBLE);
- for (i = 0; i < data.size(); i++) {
- rColData.addData((Double) this.getValue(i) - (Integer) value);
- }
- break;
- case FLOAT:
- rColData = new ColumnData(colName, DataType.DOUBLE);
- for (i = 0; i < data.size(); i++) {
- rColData.addData((Double) this.getValue(i) - (Float) value);
- }
- break;
- case DOUBLE:
- rColData = new ColumnData(colName, DataType.DOUBLE);
- for (i = 0; i < data.size(); i++) {
- rColData.addData((Double) this.getValue(i) - (Double) value);
- }
- break;
- }
- break;
- }
-
- return rColData;
- }
-
- /**
- * Subtract function
- *
- * @param colData Anorther column data
- * @param colName New column data name
- * @return Result column data
- */
- public ColumnData sub(ColumnData colData, String colName) {
- DataType thisType = dataColumn.getDataType();
- if (!thisType.isNumeric()) {
- return null;
- }
-
- DataType inType = colData.getDataType();
- if (!inType.isNumeric()) {
- return null;
- }
-
- ColumnData rColData = null;
- int i;
- switch (thisType) {
- case INT:
- switch (inType) {
- case INT:
- rColData = new ColumnData(colName, DataType.INT);
- for (i = 0; i < data.size(); i++) {
- if (i < colData.size()) {
- rColData.addData((Integer) this.getValue(i) - (Integer) colData.getValue(i));
- }
- }
- break;
- case FLOAT:
- rColData = new ColumnData(colName, DataType.FLOAT);
- for (i = 0; i < data.size(); i++) {
- if (i < colData.size()) {
- rColData.addData((Integer) this.getValue(i) - (Float) colData.getValue(i));
- }
- }
- break;
- case DOUBLE:
- rColData = new ColumnData(colName, DataType.DOUBLE);
- for (i = 0; i < data.size(); i++) {
- if (i < colData.size()) {
- rColData.addData((Integer) this.getValue(i) - (Double) colData.getValue(i));
- }
- }
- break;
- }
- break;
- case FLOAT:
- switch (inType) {
- case INT:
- rColData = new ColumnData(colName, DataType.FLOAT);
- for (i = 0; i < data.size(); i++) {
- if (i < colData.size()) {
- rColData.addData((Float) this.getValue(i) - (Integer) colData.getValue(i));
- }
- }
- break;
- case FLOAT:
- rColData = new ColumnData(colName, DataType.FLOAT);
- for (i = 0; i < data.size(); i++) {
- if (i < colData.size()) {
- rColData.addData((Float) this.getValue(i) - (Float) colData.getValue(i));
- }
- }
- break;
- case DOUBLE:
- rColData = new ColumnData(colName, DataType.DOUBLE);
- for (i = 0; i < data.size(); i++) {
- if (i < colData.size()) {
- rColData.addData((Float) this.getValue(i) - (Double) colData.getValue(i));
- }
- }
- break;
- }
- break;
- case DOUBLE:
- switch (inType) {
- case INT:
- rColData = new ColumnData(colName, DataType.DOUBLE);
- for (i = 0; i < data.size(); i++) {
- if (i < colData.size()) {
- rColData.addData((Double) this.getValue(i) - (Integer) colData.getValue(i));
- }
- }
- break;
- case FLOAT:
- rColData = new ColumnData(colName, DataType.DOUBLE);
- for (i = 0; i < data.size(); i++) {
- if (i < colData.size()) {
- rColData.addData((Double) this.getValue(i) - (Float) colData.getValue(i));
- }
- }
- break;
- case DOUBLE:
- rColData = new ColumnData(colName, DataType.DOUBLE);
- for (i = 0; i < data.size(); i++) {
- if (i < colData.size()) {
- rColData.addData((Double) this.getValue(i) - (Double) colData.getValue(i));
- }
- }
- break;
- }
- break;
- }
-
- return rColData;
- }
-
- /**
- * Multiply function
- *
- * @param value The object value to multiply
- * @param colName New column data name
- * @return Result column data
- */
- public ColumnData mul(Object value, String colName) {
- DataType thisType = dataColumn.getDataType();
- if (!thisType.isNumeric()) {
- return null;
- }
-
- DataType inType = this.getDataType(value);
- if (!inType.isNumeric()){
- return null;
- }
-
- ColumnData rColData = null;
- int i;
- switch (thisType) {
- case INT:
- switch (inType) {
- case INT:
- rColData = new ColumnData(colName, DataType.INT);
- for (i = 0; i < data.size(); i++) {
- rColData.addData((float)(Integer) this.getValue(i) * (Integer) value);
- }
- break;
- case FLOAT:
- rColData = new ColumnData(colName, DataType.FLOAT);
- for (i = 0; i < data.size(); i++) {
- rColData.addData((Integer) this.getValue(i) * (Float) value);
- }
- break;
- case DOUBLE:
- rColData = new ColumnData(colName, DataType.DOUBLE);
- for (i = 0; i < data.size(); i++) {
- rColData.addData((Integer) this.getValue(i) * (Double) value);
- }
- break;
- }
- break;
- case FLOAT:
- switch (inType) {
- case INT:
- rColData = new ColumnData(colName, DataType.FLOAT);
- for (i = 0; i < data.size(); i++) {
- rColData.addData((Float) this.getValue(i) * (Integer) value);
- }
- break;
- case FLOAT:
- rColData = new ColumnData(colName, DataType.FLOAT);
- for (i = 0; i < data.size(); i++) {
- rColData.addData((Float) this.getValue(i) * (Float) value);
- }
- break;
- case DOUBLE:
- rColData = new ColumnData(colName, DataType.DOUBLE);
- for (i = 0; i < data.size(); i++) {
- rColData.addData((Float) this.getValue(i) * (Double) value);
- }
- break;
- }
- break;
- case DOUBLE:
- switch (inType) {
- case INT:
- rColData = new ColumnData(colName, DataType.DOUBLE);
- for (i = 0; i < data.size(); i++) {
- rColData.addData((Double) this.getValue(i) * (Integer) value);
- }
- break;
- case FLOAT:
- rColData = new ColumnData(colName, DataType.DOUBLE);
- for (i = 0; i < data.size(); i++) {
- rColData.addData((Double) this.getValue(i) * (Float) value);
- }
- break;
- case DOUBLE:
- rColData = new ColumnData(colName, DataType.DOUBLE);
- for (i = 0; i < data.size(); i++) {
- rColData.addData((Double) this.getValue(i) * (Double) value);
- }
- break;
- }
- break;
- }
-
- return rColData;
- }
-
- /**
- * Multiply function
- *
- * @param colData Anorther column data
- * @param colName New column data name
- * @return Result column data
- */
- public ColumnData mul(ColumnData colData, String colName) {
- DataType thisType = dataColumn.getDataType();
- if (!thisType.isNumeric()) {
- return null;
- }
-
- DataType inType = colData.getDataType();
- if (!inType.isNumeric()) {
- return null;
- }
-
- ColumnData rColData = null;
- int i;
- switch (thisType) {
- case INT:
- switch (inType) {
- case INT:
- rColData = new ColumnData(colName, DataType.INT);
- for (i = 0; i < data.size(); i++) {
- if (i < colData.size()) {
- rColData.addData((Integer) this.getValue(i) * (Integer) colData.getValue(i));
- }
- }
- break;
- case FLOAT:
- rColData = new ColumnData(colName, DataType.FLOAT);
- for (i = 0; i < data.size(); i++) {
- if (i < colData.size()) {
- rColData.addData((Integer) this.getValue(i) * (Float) colData.getValue(i));
- }
- }
- break;
- case DOUBLE:
- rColData = new ColumnData(colName, DataType.DOUBLE);
- for (i = 0; i < data.size(); i++) {
- if (i < colData.size()) {
- rColData.addData((Integer) this.getValue(i) * (Double) colData.getValue(i));
- }
- }
- break;
- }
- break;
- case FLOAT:
- switch (inType) {
- case INT:
- rColData = new ColumnData(colName, DataType.FLOAT);
- for (i = 0; i < data.size(); i++) {
- if (i < colData.size()) {
- rColData.addData((Float) this.getValue(i) * (Integer) colData.getValue(i));
- }
- }
- break;
- case FLOAT:
- rColData = new ColumnData(colName, DataType.FLOAT);
- for (i = 0; i < data.size(); i++) {
- if (i < colData.size()) {
- rColData.addData((Float) this.getValue(i) * (Float) colData.getValue(i));
- }
- }
- break;
- case DOUBLE:
- rColData = new ColumnData(colName, DataType.DOUBLE);
- for (i = 0; i < data.size(); i++) {
- if (i < colData.size()) {
- rColData.addData((Float) this.getValue(i) * (Double) colData.getValue(i));
- }
- }
- break;
- }
- break;
- case DOUBLE:
- switch (inType) {
- case INT:
- rColData = new ColumnData(colName, DataType.DOUBLE);
- for (i = 0; i < data.size(); i++) {
- if (i < colData.size()) {
- rColData.addData((Double) this.getValue(i) * (Integer) colData.getValue(i));
- }
- }
- break;
- case FLOAT:
- rColData = new ColumnData(colName, DataType.DOUBLE);
- for (i = 0; i < data.size(); i++) {
- if (i < colData.size()) {
- rColData.addData((Double) this.getValue(i) * (Float) colData.getValue(i));
- }
- }
- break;
- case DOUBLE:
- rColData = new ColumnData(colName, DataType.DOUBLE);
- for (i = 0; i < data.size(); i++) {
- if (i < colData.size()) {
- rColData.addData((Double) this.getValue(i) * (Double) colData.getValue(i));
- }
- }
- break;
- }
- break;
- }
-
- return rColData;
- }
-
- /**
- * Divide function
- *
- * @param colData Anorther column data
- * @param colName New column data name
- * @return Result column data
- */
- public ColumnData div(ColumnData colData, String colName) {
- DataType thisType = dataColumn.getDataType();
- if (!thisType.isNumeric()) {
- return null;
- }
-
- DataType inType = colData.getDataType();
- if (!inType.isNumeric()) {
- return null;
- }
-
- ColumnData rColData = null;
- int i;
- switch (thisType) {
- case INT:
- switch (inType) {
- case INT:
- rColData = new ColumnData(colName, DataType.FLOAT);
- for (i = 0; i < data.size(); i++) {
- if (i < colData.size()) {
- rColData.addData((float)(Integer) this.getValue(i) / (Integer) colData.getValue(i));
- }
- }
- break;
- case FLOAT:
- rColData = new ColumnData(colName, DataType.FLOAT);
- for (i = 0; i < data.size(); i++) {
- if (i < colData.size()) {
- rColData.addData((Integer) this.getValue(i) / (Float) colData.getValue(i));
- }
- }
- break;
- case DOUBLE:
- rColData = new ColumnData(colName, DataType.DOUBLE);
- for (i = 0; i < data.size(); i++) {
- if (i < colData.size()) {
- rColData.addData((Integer) this.getValue(i) / (Double) colData.getValue(i));
- }
- }
- break;
- }
- break;
- case FLOAT:
- switch (inType) {
- case INT:
- rColData = new ColumnData(colName, DataType.FLOAT);
- for (i = 0; i < data.size(); i++) {
- if (i < colData.size()) {
- rColData.addData((Float) this.getValue(i) / (Integer) colData.getValue(i));
- }
- }
- break;
- case FLOAT:
- rColData = new ColumnData(colName, DataType.FLOAT);
- for (i = 0; i < data.size(); i++) {
- if (i < colData.size()) {
- rColData.addData((Float) this.getValue(i) / (Float) colData.getValue(i));
- }
- }
- break;
- case DOUBLE:
- rColData = new ColumnData(colName, DataType.DOUBLE);
- for (i = 0; i < data.size(); i++) {
- if (i < colData.size()) {
- rColData.addData((Float) this.getValue(i) / (Double) colData.getValue(i));
- }
- }
- break;
- }
- break;
- case DOUBLE:
- switch (inType) {
- case INT:
- rColData = new ColumnData(colName, DataType.DOUBLE);
- for (i = 0; i < data.size(); i++) {
- if (i < colData.size()) {
- rColData.addData((Double) this.getValue(i) / (Integer) colData.getValue(i));
- }
- }
- break;
- case FLOAT:
- rColData = new ColumnData(colName, DataType.DOUBLE);
- for (i = 0; i < data.size(); i++) {
- if (i < colData.size()) {
- rColData.addData((Double) this.getValue(i) / (Float) colData.getValue(i));
- }
- }
- break;
- case DOUBLE:
- rColData = new ColumnData(colName, DataType.DOUBLE);
- for (i = 0; i < data.size(); i++) {
- if (i < colData.size()) {
- rColData.addData((Double) this.getValue(i) / (Double) colData.getValue(i));
- }
- }
- break;
- }
- break;
- }
-
- return rColData;
- }
-
- /**
- * Divide function
- *
- * @param value The object value to divide
- * @param colName New column data name
- * @return Result column data
- */
- public ColumnData div(Object value, String colName) {
- DataType thisType = dataColumn.getDataType();
- if (!thisType.isNumeric()) {
- return null;
- }
-
- DataType inType = this.getDataType(value);
- if (!inType.isNumeric()){
- return null;
- }
-
- ColumnData rColData = null;
- int i;
- switch (thisType) {
- case INT:
- switch (inType) {
- case INT:
- rColData = new ColumnData(colName, DataType.FLOAT);
- for (i = 0; i < data.size(); i++) {
- rColData.addData((float)(Integer) this.getValue(i) / (Integer) value);
- }
- break;
- case FLOAT:
- rColData = new ColumnData(colName, DataType.FLOAT);
- for (i = 0; i < data.size(); i++) {
- rColData.addData((Integer) this.getValue(i) / (Float) value);
- }
- break;
- case DOUBLE:
- rColData = new ColumnData(colName, DataType.DOUBLE);
- for (i = 0; i < data.size(); i++) {
- rColData.addData((Integer) this.getValue(i) / (Double) value);
- }
- break;
- }
- break;
- case FLOAT:
- switch (inType) {
- case INT:
- rColData = new ColumnData(colName, DataType.FLOAT);
- for (i = 0; i < data.size(); i++) {
- rColData.addData((Float) this.getValue(i) / (Integer) value);
- }
- break;
- case FLOAT:
- rColData = new ColumnData(colName, DataType.FLOAT);
- for (i = 0; i < data.size(); i++) {
- rColData.addData((Float) this.getValue(i) / (Float) value);
- }
- break;
- case DOUBLE:
- rColData = new ColumnData(colName, DataType.DOUBLE);
- for (i = 0; i < data.size(); i++) {
- rColData.addData((Float) this.getValue(i) / (Double) value);
- }
- break;
- }
- break;
- case DOUBLE:
- switch (inType) {
- case INT:
- rColData = new ColumnData(colName, DataType.DOUBLE);
- for (i = 0; i < data.size(); i++) {
- rColData.addData((Double) this.getValue(i) / (Integer) value);
- }
- break;
- case FLOAT:
- rColData = new ColumnData(colName, DataType.DOUBLE);
- for (i = 0; i < data.size(); i++) {
- rColData.addData((Double) this.getValue(i) / (Float) value);
- }
- break;
- case DOUBLE:
- rColData = new ColumnData(colName, DataType.DOUBLE);
- for (i = 0; i < data.size(); i++) {
- rColData.addData((Double) this.getValue(i) / (Double) value);
- }
- break;
- }
- break;
- }
-
- return rColData;
- }
-
- private DataType getDataType(Object value){
- if (value instanceof Integer)
- return DataType.INT;
- else if (value instanceof Float)
- return DataType.FLOAT;
- else if (value instanceof Double)
- return DataType.DOUBLE;
- else if (value instanceof Boolean)
- return DataType.BOOLEAN;
- else if (value instanceof String)
- return DataType.STRING;
- else if (value instanceof LocalDateTime)
- return DataType.DATE;
- else
- return null;
- }
- //
-}
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.meteoinfo.table;
+
+import org.meteoinfo.common.util.JDateUtil;
+import org.meteoinfo.ndarray.DataType;
+
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ * @author yaqiang
+ */
+public class ColumnData {
+
+ //
+ private DataColumn dataColumn;
+ private List data;
+
+ //
+ //
+ /**
+ * Constructor
+ *
+ * @param col The data column
+ */
+ public ColumnData(DataColumn col) {
+ dataColumn = col;
+ switch (col.getDataType()) {
+ case INT:
+ data = new ArrayList();
+ break;
+ case FLOAT:
+ data = new ArrayList();
+ break;
+ case DOUBLE:
+ data = new ArrayList();
+ break;
+ case STRING:
+ data = new ArrayList();
+ break;
+ case DATE:
+ data = new ArrayList();
+ break;
+ case BOOLEAN:
+ data = new ArrayList();
+ break;
+ }
+ }
+
+ /**
+ * Constructor
+ *
+ * @param colName Data column name
+ * @param type Data type
+ */
+ public ColumnData(String colName, DataType type) {
+ this(new DataColumn(colName, type));
+ }
+
+ //
+ //
+ /**
+ * Get data column
+ *
+ * @return Data column
+ */
+ public DataColumn getDataColumn() {
+ return this.dataColumn;
+ }
+
+ /**
+ * Set data column
+ *
+ * @param value Data column
+ */
+ public void setDataColumn(DataColumn value) {
+ dataColumn = value;
+ }
+
+ /**
+ * Get data list
+ *
+ * @return Data list
+ */
+ public List getData() {
+ return data;
+ }
+
+ /**
+ * Set data list
+ *
+ * @param value Data list
+ */
+ public void setData(List value) {
+ data = value;
+ }
+
+ /**
+ * Get data type
+ *
+ * @return Data type
+ */
+ public DataType getDataType() {
+ return dataColumn.getDataType();
+ }
+
+ //
+ //
+ /**
+ * Get size of the data
+ *
+ * @return Size of the data
+ */
+ public int size() {
+ return data.size();
+ }
+
+ /**
+ * Add a object data
+ *
+ * @param value Data value
+ */
+ public void addData(Object value) {
+ switch (dataColumn.getDataType()) {
+ case INT:
+ this.addData((Integer) value);
+ break;
+ case FLOAT:
+ this.addData((Float) value);
+ break;
+ case DOUBLE:
+ this.addData((Double) value);
+ break;
+ case STRING:
+ this.addData((String) value);
+ break;
+ case DATE:
+ this.addData((LocalDateTime) value);
+ break;
+ case BOOLEAN:
+ this.addData((Boolean) value);
+ break;
+ }
+ }
+
+ /**
+ * Add a double data value
+ *
+ * @param value Data value
+ */
+ public void addData(Double value) {
+ ((List) data).add(value);
+ }
+
+ /**
+ * Add a float data value
+ *
+ * @param value Data value
+ */
+ public void addData(Float value) {
+ ((List) data).add(value);
+ }
+
+ /**
+ * Add a integer data value
+ *
+ * @param value Data value
+ */
+ public void addData(Integer value) {
+ ((List) data).add(value);
+ }
+
+ /**
+ * Add a string data value
+ *
+ * @param value Data value
+ */
+ public void addData(String value) {
+ ((List) data).add(value);
+ }
+
+ /**
+ * Add a date data value
+ *
+ * @param value Data value
+ */
+ public void addData(LocalDateTime value) {
+ ((List) data).add(value);
+ }
+
+ /**
+ * Add a boolean data value
+ *
+ * @param value Data value
+ */
+ public void addData(boolean value) {
+ ((List) data).add(value);
+ }
+
+ /**
+ * Get data value
+ *
+ * @param idx Data index
+ * @return Data value
+ */
+ public Object getValue(int idx) {
+ switch (dataColumn.getDataType()) {
+ case INT:
+ return (Integer) data.get(idx);
+ case FLOAT:
+ return (Float) data.get(idx);
+ case DOUBLE:
+ return (Double) data.get(idx);
+ case STRING:
+ return (String) data.get(idx);
+ case DATE:
+ return (LocalDateTime) data.get(idx);
+ case BOOLEAN:
+ return (Boolean) data.get(idx);
+ }
+
+ return null;
+ }
+
+ /**
+ * Get string data list
+ * @return String data list
+ */
+ public List getDataStrings(){
+ List r = new ArrayList<>();
+ for (Object v : data){
+ r.add(v.toString());
+ }
+
+ return r;
+ }
+
+ /**
+ * Get number data list
+ *
+ * @return Number data list
+ */
+ public List getDataValues() {
+ if (dataColumn.getDataType() == DataType.DOUBLE) {
+ return ((List) data);
+ } else {
+ List values = new ArrayList<>();
+ switch (dataColumn.getDataType()) {
+ case INT:
+ for (int v : (List) data) {
+ values.add(v);
+ }
+ break;
+ case FLOAT:
+ for (Object v : (List) data) {
+ if (v == null){
+ values.add(Float.NaN);
+ } else {
+ values.add((float)v);
+ }
+ }
+ break;
+ case STRING:
+ for (String v : (List)data){
+ if (v.isEmpty())
+ values.add(Double.NaN);
+ else
+ values.add(Double.parseDouble(v));
+ }
+ break;
+ case DATE:
+ for (LocalDateTime v : (List)data){
+ values.add(JDateUtil.toOADate(v));
+ }
+ break;
+ }
+ return values;
+ }
+ }
+
+ /**
+ * Get valid number data list
+ * @return Number data list
+ */
+ public List getValidDataValues(){
+ List values = this.getDataValues();
+ for (int i = 0, len = values.size(); i < len; i++) {
+ if (Double.isNaN(values.get(i).doubleValue())) {
+ values.remove(i);
+ len--;
+ i--;
+ }
+ }
+
+ return values;
+ }
+
+ /**
+ * Contains function
+ *
+ * @param value The object value
+ * @return Is contains or not
+ */
+ public boolean contains(Object value) {
+ return data.contains(value);
+ }
+
+ /**
+ * Mean function
+ *
+ * @return Mean value
+ */
+ public Double mean() {
+ double mean = 0.0;
+ int n = 0;
+ switch (dataColumn.getDataType()) {
+ case INT:
+ for (int v : (List) data) {
+ mean += v;
+ n++;
+ }
+ break;
+ case FLOAT:
+ for (float v : (List) data) {
+ if (v != Float.NaN) {
+ mean += v;
+ n++;
+ }
+ }
+ break;
+ case DOUBLE:
+ for (double v : (List) data) {
+ if (v != Double.NaN) {
+ mean += v;
+ n++;
+ }
+ }
+ break;
+ }
+
+ if (n > 0) {
+ mean = mean / n;
+ return mean;
+ } else {
+ return Double.NaN;
+ }
+ }
+
+ /**
+ * Add function
+ *
+ * @param value The object value to add
+ * @param colName New column data name
+ * @return Result column data
+ */
+ public ColumnData add(Object value, String colName) {
+ DataType thisType = dataColumn.getDataType();
+ if (!thisType.isNumeric()) {
+ return null;
+ }
+
+ DataType inType = this.getDataType(value);
+ if (!inType.isNumeric()){
+ return null;
+ }
+
+ ColumnData rColData = null;
+ int i;
+ switch (thisType) {
+ case INT:
+ switch (inType) {
+ case INT:
+ rColData = new ColumnData(colName, DataType.INT);
+ for (i = 0; i < data.size(); i++) {
+ rColData.addData((float)(Integer) this.getValue(i) + (Integer) value);
+ }
+ break;
+ case FLOAT:
+ rColData = new ColumnData(colName, DataType.FLOAT);
+ for (i = 0; i < data.size(); i++) {
+ rColData.addData((Integer) this.getValue(i) + (Float) value);
+ }
+ break;
+ case DOUBLE:
+ rColData = new ColumnData(colName, DataType.DOUBLE);
+ for (i = 0; i < data.size(); i++) {
+ rColData.addData((Integer) this.getValue(i) + (Double) value);
+ }
+ break;
+ }
+ break;
+ case FLOAT:
+ switch (inType) {
+ case INT:
+ rColData = new ColumnData(colName, DataType.FLOAT);
+ for (i = 0; i < data.size(); i++) {
+ rColData.addData((Float) this.getValue(i) + (Integer) value);
+ }
+ break;
+ case FLOAT:
+ rColData = new ColumnData(colName, DataType.FLOAT);
+ for (i = 0; i < data.size(); i++) {
+ rColData.addData((Float) this.getValue(i) + (Float) value);
+ }
+ break;
+ case DOUBLE:
+ rColData = new ColumnData(colName, DataType.DOUBLE);
+ for (i = 0; i < data.size(); i++) {
+ rColData.addData((Float) this.getValue(i) + (Double) value);
+ }
+ break;
+ }
+ break;
+ case DOUBLE:
+ switch (inType) {
+ case INT:
+ rColData = new ColumnData(colName, DataType.DOUBLE);
+ for (i = 0; i < data.size(); i++) {
+ rColData.addData((Double) this.getValue(i) + (Integer) value);
+ }
+ break;
+ case FLOAT:
+ rColData = new ColumnData(colName, DataType.DOUBLE);
+ for (i = 0; i < data.size(); i++) {
+ rColData.addData((Double) this.getValue(i) + (Float) value);
+ }
+ break;
+ case DOUBLE:
+ rColData = new ColumnData(colName, DataType.DOUBLE);
+ for (i = 0; i < data.size(); i++) {
+ rColData.addData((Double) this.getValue(i) + (Double) value);
+ }
+ break;
+ }
+ break;
+ }
+
+ return rColData;
+ }
+
+ /**
+ * Add function
+ *
+ * @param colData Anorther column data
+ * @param colName New column data name
+ * @return Result column data
+ */
+ public ColumnData add(ColumnData colData, String colName) {
+ DataType thisType = dataColumn.getDataType();
+ if (thisType == DataType.DATE || thisType == DataType.BOOLEAN) {
+ return null;
+ }
+
+ DataType inType = colData.getDataType();
+ if (inType == DataType.DATE || inType == DataType.BOOLEAN) {
+ return null;
+ }
+
+ if (thisType == DataType.STRING && inType != DataType.STRING) {
+ return null;
+ }
+
+ if (inType == DataType.STRING && thisType != DataType.STRING) {
+ return null;
+ }
+
+ ColumnData rColData = null;
+ int i;
+ switch (thisType) {
+ case INT:
+ switch (inType) {
+ case INT:
+ rColData = new ColumnData(colName, DataType.INT);
+ for (i = 0; i < data.size(); i++) {
+ if (i < colData.size()) {
+ rColData.addData((Integer) this.getValue(i) + (Integer) colData.getValue(i));
+ }
+ }
+ break;
+ case FLOAT:
+ rColData = new ColumnData(colName, DataType.FLOAT);
+ for (i = 0; i < data.size(); i++) {
+ if (i < colData.size()) {
+ rColData.addData((Integer) this.getValue(i) + (Float) colData.getValue(i));
+ }
+ }
+ break;
+ case DOUBLE:
+ rColData = new ColumnData(colName, DataType.DOUBLE);
+ for (i = 0; i < data.size(); i++) {
+ if (i < colData.size()) {
+ rColData.addData((Integer) this.getValue(i) + (Double) colData.getValue(i));
+ }
+ }
+ break;
+ }
+ break;
+ case FLOAT:
+ switch (inType) {
+ case INT:
+ rColData = new ColumnData(colName, DataType.FLOAT);
+ for (i = 0; i < data.size(); i++) {
+ if (i < colData.size()) {
+ rColData.addData((Float) this.getValue(i) + (Integer) colData.getValue(i));
+ }
+ }
+ break;
+ case FLOAT:
+ rColData = new ColumnData(colName, DataType.FLOAT);
+ for (i = 0; i < data.size(); i++) {
+ if (i < colData.size()) {
+ rColData.addData((Float) this.getValue(i) + (Float) colData.getValue(i));
+ }
+ }
+ break;
+ case DOUBLE:
+ rColData = new ColumnData(colName, DataType.DOUBLE);
+ for (i = 0; i < data.size(); i++) {
+ if (i < colData.size()) {
+ rColData.addData((Float) this.getValue(i) + (Double) colData.getValue(i));
+ }
+ }
+ break;
+ }
+ break;
+ case DOUBLE:
+ switch (inType) {
+ case INT:
+ rColData = new ColumnData(colName, DataType.DOUBLE);
+ for (i = 0; i < data.size(); i++) {
+ if (i < colData.size()) {
+ rColData.addData((Double) this.getValue(i) + (Integer) colData.getValue(i));
+ }
+ }
+ break;
+ case FLOAT:
+ rColData = new ColumnData(colName, DataType.DOUBLE);
+ for (i = 0; i < data.size(); i++) {
+ if (i < colData.size()) {
+ rColData.addData((Double) this.getValue(i) + (Float) colData.getValue(i));
+ }
+ }
+ break;
+ case DOUBLE:
+ rColData = new ColumnData(colName, DataType.DOUBLE);
+ for (i = 0; i < data.size(); i++) {
+ if (i < colData.size()) {
+ rColData.addData((Double) this.getValue(i) + (Double) colData.getValue(i));
+ }
+ }
+ break;
+ }
+ break;
+ case STRING:
+ rColData = new ColumnData(colName, DataType.STRING);
+ for (i = 0; i < data.size(); i++) {
+ if (i < colData.size()) {
+ rColData.addData((String) this.getValue(i) + (String) colData.getValue(i));
+ }
+ }
+ break;
+ }
+
+ return rColData;
+ }
+
+ /**
+ * Subtract function
+ *
+ * @param value The object value to subtract
+ * @param colName New column data name
+ * @return Result column data
+ */
+ public ColumnData sub(Object value, String colName) {
+ DataType thisType = dataColumn.getDataType();
+ if (!thisType.isNumeric()) {
+ return null;
+ }
+
+ DataType inType = this.getDataType(value);
+ if (!inType.isNumeric()){
+ return null;
+ }
+
+ ColumnData rColData = null;
+ int i;
+ switch (thisType) {
+ case INT:
+ switch (inType) {
+ case INT:
+ rColData = new ColumnData(colName, DataType.INT);
+ for (i = 0; i < data.size(); i++) {
+ rColData.addData((float)(Integer) this.getValue(i) - (Integer) value);
+ }
+ break;
+ case FLOAT:
+ rColData = new ColumnData(colName, DataType.FLOAT);
+ for (i = 0; i < data.size(); i++) {
+ rColData.addData((Integer) this.getValue(i) - (Float) value);
+ }
+ break;
+ case DOUBLE:
+ rColData = new ColumnData(colName, DataType.DOUBLE);
+ for (i = 0; i < data.size(); i++) {
+ rColData.addData((Integer) this.getValue(i) - (Double) value);
+ }
+ break;
+ }
+ break;
+ case FLOAT:
+ switch (inType) {
+ case INT:
+ rColData = new ColumnData(colName, DataType.FLOAT);
+ for (i = 0; i < data.size(); i++) {
+ rColData.addData((Float) this.getValue(i) - (Integer) value);
+ }
+ break;
+ case FLOAT:
+ rColData = new ColumnData(colName, DataType.FLOAT);
+ for (i = 0; i < data.size(); i++) {
+ rColData.addData((Float) this.getValue(i) - (Float) value);
+ }
+ break;
+ case DOUBLE:
+ rColData = new ColumnData(colName, DataType.DOUBLE);
+ for (i = 0; i < data.size(); i++) {
+ rColData.addData((Float) this.getValue(i) - (Double) value);
+ }
+ break;
+ }
+ break;
+ case DOUBLE:
+ switch (inType) {
+ case INT:
+ rColData = new ColumnData(colName, DataType.DOUBLE);
+ for (i = 0; i < data.size(); i++) {
+ rColData.addData((Double) this.getValue(i) - (Integer) value);
+ }
+ break;
+ case FLOAT:
+ rColData = new ColumnData(colName, DataType.DOUBLE);
+ for (i = 0; i < data.size(); i++) {
+ rColData.addData((Double) this.getValue(i) - (Float) value);
+ }
+ break;
+ case DOUBLE:
+ rColData = new ColumnData(colName, DataType.DOUBLE);
+ for (i = 0; i < data.size(); i++) {
+ rColData.addData((Double) this.getValue(i) - (Double) value);
+ }
+ break;
+ }
+ break;
+ }
+
+ return rColData;
+ }
+
+ /**
+ * Subtract function
+ *
+ * @param colData Anorther column data
+ * @param colName New column data name
+ * @return Result column data
+ */
+ public ColumnData sub(ColumnData colData, String colName) {
+ DataType thisType = dataColumn.getDataType();
+ if (!thisType.isNumeric()) {
+ return null;
+ }
+
+ DataType inType = colData.getDataType();
+ if (!inType.isNumeric()) {
+ return null;
+ }
+
+ ColumnData rColData = null;
+ int i;
+ switch (thisType) {
+ case INT:
+ switch (inType) {
+ case INT:
+ rColData = new ColumnData(colName, DataType.INT);
+ for (i = 0; i < data.size(); i++) {
+ if (i < colData.size()) {
+ rColData.addData((Integer) this.getValue(i) - (Integer) colData.getValue(i));
+ }
+ }
+ break;
+ case FLOAT:
+ rColData = new ColumnData(colName, DataType.FLOAT);
+ for (i = 0; i < data.size(); i++) {
+ if (i < colData.size()) {
+ rColData.addData((Integer) this.getValue(i) - (Float) colData.getValue(i));
+ }
+ }
+ break;
+ case DOUBLE:
+ rColData = new ColumnData(colName, DataType.DOUBLE);
+ for (i = 0; i < data.size(); i++) {
+ if (i < colData.size()) {
+ rColData.addData((Integer) this.getValue(i) - (Double) colData.getValue(i));
+ }
+ }
+ break;
+ }
+ break;
+ case FLOAT:
+ switch (inType) {
+ case INT:
+ rColData = new ColumnData(colName, DataType.FLOAT);
+ for (i = 0; i < data.size(); i++) {
+ if (i < colData.size()) {
+ rColData.addData((Float) this.getValue(i) - (Integer) colData.getValue(i));
+ }
+ }
+ break;
+ case FLOAT:
+ rColData = new ColumnData(colName, DataType.FLOAT);
+ for (i = 0; i < data.size(); i++) {
+ if (i < colData.size()) {
+ rColData.addData((Float) this.getValue(i) - (Float) colData.getValue(i));
+ }
+ }
+ break;
+ case DOUBLE:
+ rColData = new ColumnData(colName, DataType.DOUBLE);
+ for (i = 0; i < data.size(); i++) {
+ if (i < colData.size()) {
+ rColData.addData((Float) this.getValue(i) - (Double) colData.getValue(i));
+ }
+ }
+ break;
+ }
+ break;
+ case DOUBLE:
+ switch (inType) {
+ case INT:
+ rColData = new ColumnData(colName, DataType.DOUBLE);
+ for (i = 0; i < data.size(); i++) {
+ if (i < colData.size()) {
+ rColData.addData((Double) this.getValue(i) - (Integer) colData.getValue(i));
+ }
+ }
+ break;
+ case FLOAT:
+ rColData = new ColumnData(colName, DataType.DOUBLE);
+ for (i = 0; i < data.size(); i++) {
+ if (i < colData.size()) {
+ rColData.addData((Double) this.getValue(i) - (Float) colData.getValue(i));
+ }
+ }
+ break;
+ case DOUBLE:
+ rColData = new ColumnData(colName, DataType.DOUBLE);
+ for (i = 0; i < data.size(); i++) {
+ if (i < colData.size()) {
+ rColData.addData((Double) this.getValue(i) - (Double) colData.getValue(i));
+ }
+ }
+ break;
+ }
+ break;
+ }
+
+ return rColData;
+ }
+
+ /**
+ * Multiply function
+ *
+ * @param value The object value to multiply
+ * @param colName New column data name
+ * @return Result column data
+ */
+ public ColumnData mul(Object value, String colName) {
+ DataType thisType = dataColumn.getDataType();
+ if (!thisType.isNumeric()) {
+ return null;
+ }
+
+ DataType inType = this.getDataType(value);
+ if (!inType.isNumeric()){
+ return null;
+ }
+
+ ColumnData rColData = null;
+ int i;
+ switch (thisType) {
+ case INT:
+ switch (inType) {
+ case INT:
+ rColData = new ColumnData(colName, DataType.INT);
+ for (i = 0; i < data.size(); i++) {
+ rColData.addData((float)(Integer) this.getValue(i) * (Integer) value);
+ }
+ break;
+ case FLOAT:
+ rColData = new ColumnData(colName, DataType.FLOAT);
+ for (i = 0; i < data.size(); i++) {
+ rColData.addData((Integer) this.getValue(i) * (Float) value);
+ }
+ break;
+ case DOUBLE:
+ rColData = new ColumnData(colName, DataType.DOUBLE);
+ for (i = 0; i < data.size(); i++) {
+ rColData.addData((Integer) this.getValue(i) * (Double) value);
+ }
+ break;
+ }
+ break;
+ case FLOAT:
+ switch (inType) {
+ case INT:
+ rColData = new ColumnData(colName, DataType.FLOAT);
+ for (i = 0; i < data.size(); i++) {
+ rColData.addData((Float) this.getValue(i) * (Integer) value);
+ }
+ break;
+ case FLOAT:
+ rColData = new ColumnData(colName, DataType.FLOAT);
+ for (i = 0; i < data.size(); i++) {
+ rColData.addData((Float) this.getValue(i) * (Float) value);
+ }
+ break;
+ case DOUBLE:
+ rColData = new ColumnData(colName, DataType.DOUBLE);
+ for (i = 0; i < data.size(); i++) {
+ rColData.addData((Float) this.getValue(i) * (Double) value);
+ }
+ break;
+ }
+ break;
+ case DOUBLE:
+ switch (inType) {
+ case INT:
+ rColData = new ColumnData(colName, DataType.DOUBLE);
+ for (i = 0; i < data.size(); i++) {
+ rColData.addData((Double) this.getValue(i) * (Integer) value);
+ }
+ break;
+ case FLOAT:
+ rColData = new ColumnData(colName, DataType.DOUBLE);
+ for (i = 0; i < data.size(); i++) {
+ rColData.addData((Double) this.getValue(i) * (Float) value);
+ }
+ break;
+ case DOUBLE:
+ rColData = new ColumnData(colName, DataType.DOUBLE);
+ for (i = 0; i < data.size(); i++) {
+ rColData.addData((Double) this.getValue(i) * (Double) value);
+ }
+ break;
+ }
+ break;
+ }
+
+ return rColData;
+ }
+
+ /**
+ * Multiply function
+ *
+ * @param colData Anorther column data
+ * @param colName New column data name
+ * @return Result column data
+ */
+ public ColumnData mul(ColumnData colData, String colName) {
+ DataType thisType = dataColumn.getDataType();
+ if (!thisType.isNumeric()) {
+ return null;
+ }
+
+ DataType inType = colData.getDataType();
+ if (!inType.isNumeric()) {
+ return null;
+ }
+
+ ColumnData rColData = null;
+ int i;
+ switch (thisType) {
+ case INT:
+ switch (inType) {
+ case INT:
+ rColData = new ColumnData(colName, DataType.INT);
+ for (i = 0; i < data.size(); i++) {
+ if (i < colData.size()) {
+ rColData.addData((Integer) this.getValue(i) * (Integer) colData.getValue(i));
+ }
+ }
+ break;
+ case FLOAT:
+ rColData = new ColumnData(colName, DataType.FLOAT);
+ for (i = 0; i < data.size(); i++) {
+ if (i < colData.size()) {
+ rColData.addData((Integer) this.getValue(i) * (Float) colData.getValue(i));
+ }
+ }
+ break;
+ case DOUBLE:
+ rColData = new ColumnData(colName, DataType.DOUBLE);
+ for (i = 0; i < data.size(); i++) {
+ if (i < colData.size()) {
+ rColData.addData((Integer) this.getValue(i) * (Double) colData.getValue(i));
+ }
+ }
+ break;
+ }
+ break;
+ case FLOAT:
+ switch (inType) {
+ case INT:
+ rColData = new ColumnData(colName, DataType.FLOAT);
+ for (i = 0; i < data.size(); i++) {
+ if (i < colData.size()) {
+ rColData.addData((Float) this.getValue(i) * (Integer) colData.getValue(i));
+ }
+ }
+ break;
+ case FLOAT:
+ rColData = new ColumnData(colName, DataType.FLOAT);
+ for (i = 0; i < data.size(); i++) {
+ if (i < colData.size()) {
+ rColData.addData((Float) this.getValue(i) * (Float) colData.getValue(i));
+ }
+ }
+ break;
+ case DOUBLE:
+ rColData = new ColumnData(colName, DataType.DOUBLE);
+ for (i = 0; i < data.size(); i++) {
+ if (i < colData.size()) {
+ rColData.addData((Float) this.getValue(i) * (Double) colData.getValue(i));
+ }
+ }
+ break;
+ }
+ break;
+ case DOUBLE:
+ switch (inType) {
+ case INT:
+ rColData = new ColumnData(colName, DataType.DOUBLE);
+ for (i = 0; i < data.size(); i++) {
+ if (i < colData.size()) {
+ rColData.addData((Double) this.getValue(i) * (Integer) colData.getValue(i));
+ }
+ }
+ break;
+ case FLOAT:
+ rColData = new ColumnData(colName, DataType.DOUBLE);
+ for (i = 0; i < data.size(); i++) {
+ if (i < colData.size()) {
+ rColData.addData((Double) this.getValue(i) * (Float) colData.getValue(i));
+ }
+ }
+ break;
+ case DOUBLE:
+ rColData = new ColumnData(colName, DataType.DOUBLE);
+ for (i = 0; i < data.size(); i++) {
+ if (i < colData.size()) {
+ rColData.addData((Double) this.getValue(i) * (Double) colData.getValue(i));
+ }
+ }
+ break;
+ }
+ break;
+ }
+
+ return rColData;
+ }
+
+ /**
+ * Divide function
+ *
+ * @param colData Anorther column data
+ * @param colName New column data name
+ * @return Result column data
+ */
+ public ColumnData div(ColumnData colData, String colName) {
+ DataType thisType = dataColumn.getDataType();
+ if (!thisType.isNumeric()) {
+ return null;
+ }
+
+ DataType inType = colData.getDataType();
+ if (!inType.isNumeric()) {
+ return null;
+ }
+
+ ColumnData rColData = null;
+ int i;
+ switch (thisType) {
+ case INT:
+ switch (inType) {
+ case INT:
+ rColData = new ColumnData(colName, DataType.FLOAT);
+ for (i = 0; i < data.size(); i++) {
+ if (i < colData.size()) {
+ rColData.addData((float)(Integer) this.getValue(i) / (Integer) colData.getValue(i));
+ }
+ }
+ break;
+ case FLOAT:
+ rColData = new ColumnData(colName, DataType.FLOAT);
+ for (i = 0; i < data.size(); i++) {
+ if (i < colData.size()) {
+ rColData.addData((Integer) this.getValue(i) / (Float) colData.getValue(i));
+ }
+ }
+ break;
+ case DOUBLE:
+ rColData = new ColumnData(colName, DataType.DOUBLE);
+ for (i = 0; i < data.size(); i++) {
+ if (i < colData.size()) {
+ rColData.addData((Integer) this.getValue(i) / (Double) colData.getValue(i));
+ }
+ }
+ break;
+ }
+ break;
+ case FLOAT:
+ switch (inType) {
+ case INT:
+ rColData = new ColumnData(colName, DataType.FLOAT);
+ for (i = 0; i < data.size(); i++) {
+ if (i < colData.size()) {
+ rColData.addData((Float) this.getValue(i) / (Integer) colData.getValue(i));
+ }
+ }
+ break;
+ case FLOAT:
+ rColData = new ColumnData(colName, DataType.FLOAT);
+ for (i = 0; i < data.size(); i++) {
+ if (i < colData.size()) {
+ rColData.addData((Float) this.getValue(i) / (Float) colData.getValue(i));
+ }
+ }
+ break;
+ case DOUBLE:
+ rColData = new ColumnData(colName, DataType.DOUBLE);
+ for (i = 0; i < data.size(); i++) {
+ if (i < colData.size()) {
+ rColData.addData((Float) this.getValue(i) / (Double) colData.getValue(i));
+ }
+ }
+ break;
+ }
+ break;
+ case DOUBLE:
+ switch (inType) {
+ case INT:
+ rColData = new ColumnData(colName, DataType.DOUBLE);
+ for (i = 0; i < data.size(); i++) {
+ if (i < colData.size()) {
+ rColData.addData((Double) this.getValue(i) / (Integer) colData.getValue(i));
+ }
+ }
+ break;
+ case FLOAT:
+ rColData = new ColumnData(colName, DataType.DOUBLE);
+ for (i = 0; i < data.size(); i++) {
+ if (i < colData.size()) {
+ rColData.addData((Double) this.getValue(i) / (Float) colData.getValue(i));
+ }
+ }
+ break;
+ case DOUBLE:
+ rColData = new ColumnData(colName, DataType.DOUBLE);
+ for (i = 0; i < data.size(); i++) {
+ if (i < colData.size()) {
+ rColData.addData((Double) this.getValue(i) / (Double) colData.getValue(i));
+ }
+ }
+ break;
+ }
+ break;
+ }
+
+ return rColData;
+ }
+
+ /**
+ * Divide function
+ *
+ * @param value The object value to divide
+ * @param colName New column data name
+ * @return Result column data
+ */
+ public ColumnData div(Object value, String colName) {
+ DataType thisType = dataColumn.getDataType();
+ if (!thisType.isNumeric()) {
+ return null;
+ }
+
+ DataType inType = this.getDataType(value);
+ if (!inType.isNumeric()){
+ return null;
+ }
+
+ ColumnData rColData = null;
+ int i;
+ switch (thisType) {
+ case INT:
+ switch (inType) {
+ case INT:
+ rColData = new ColumnData(colName, DataType.FLOAT);
+ for (i = 0; i < data.size(); i++) {
+ rColData.addData((float)(Integer) this.getValue(i) / (Integer) value);
+ }
+ break;
+ case FLOAT:
+ rColData = new ColumnData(colName, DataType.FLOAT);
+ for (i = 0; i < data.size(); i++) {
+ rColData.addData((Integer) this.getValue(i) / (Float) value);
+ }
+ break;
+ case DOUBLE:
+ rColData = new ColumnData(colName, DataType.DOUBLE);
+ for (i = 0; i < data.size(); i++) {
+ rColData.addData((Integer) this.getValue(i) / (Double) value);
+ }
+ break;
+ }
+ break;
+ case FLOAT:
+ switch (inType) {
+ case INT:
+ rColData = new ColumnData(colName, DataType.FLOAT);
+ for (i = 0; i < data.size(); i++) {
+ rColData.addData((Float) this.getValue(i) / (Integer) value);
+ }
+ break;
+ case FLOAT:
+ rColData = new ColumnData(colName, DataType.FLOAT);
+ for (i = 0; i < data.size(); i++) {
+ rColData.addData((Float) this.getValue(i) / (Float) value);
+ }
+ break;
+ case DOUBLE:
+ rColData = new ColumnData(colName, DataType.DOUBLE);
+ for (i = 0; i < data.size(); i++) {
+ rColData.addData((Float) this.getValue(i) / (Double) value);
+ }
+ break;
+ }
+ break;
+ case DOUBLE:
+ switch (inType) {
+ case INT:
+ rColData = new ColumnData(colName, DataType.DOUBLE);
+ for (i = 0; i < data.size(); i++) {
+ rColData.addData((Double) this.getValue(i) / (Integer) value);
+ }
+ break;
+ case FLOAT:
+ rColData = new ColumnData(colName, DataType.DOUBLE);
+ for (i = 0; i < data.size(); i++) {
+ rColData.addData((Double) this.getValue(i) / (Float) value);
+ }
+ break;
+ case DOUBLE:
+ rColData = new ColumnData(colName, DataType.DOUBLE);
+ for (i = 0; i < data.size(); i++) {
+ rColData.addData((Double) this.getValue(i) / (Double) value);
+ }
+ break;
+ }
+ break;
+ }
+
+ return rColData;
+ }
+
+ private DataType getDataType(Object value){
+ if (value instanceof Integer)
+ return DataType.INT;
+ else if (value instanceof Float)
+ return DataType.FLOAT;
+ else if (value instanceof Double)
+ return DataType.DOUBLE;
+ else if (value instanceof Boolean)
+ return DataType.BOOLEAN;
+ else if (value instanceof String)
+ return DataType.STRING;
+ else if (value instanceof LocalDateTime)
+ return DataType.DATE;
+ else
+ return null;
+ }
+ //
+}
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/table/DataColumn.java b/MeteoInfoLib/src/main/java/org/meteoinfo/table/DataColumn.java
index 0cf8e3fa..63314c8c 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/table/DataColumn.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/table/DataColumn.java
@@ -16,7 +16,7 @@ package org.meteoinfo.table;
import java.time.format.DateTimeFormatter;
import java.time.LocalDateTime;
-import org.meteoinfo.global.util.JDateUtil;
+import org.meteoinfo.common.util.JDateUtil;
import org.meteoinfo.ndarray.DataType;
/**
diff --git a/MeteoInfoLib/src/main/java/org/meteoinfo/table/DataTable.java b/MeteoInfoLib/src/main/java/org/meteoinfo/table/DataTable.java
index baada3bd..545b5346 100644
--- a/MeteoInfoLib/src/main/java/org/meteoinfo/table/DataTable.java
+++ b/MeteoInfoLib/src/main/java/org/meteoinfo/table/DataTable.java
@@ -1,1613 +1,1613 @@
-/* Copyright 2012 Yaqiang Wang,
- * yaqiang.wang@gmail.com
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- */
-package org.meteoinfo.table;
-
-import org.meteoinfo.ndarray.DataType;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.time.LocalDateTime;
-import java.time.format.DateTimeFormatter;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import org.meteoinfo.data.TableUtil;
-import org.meteoinfo.data.mapdata.Field;
-import org.meteoinfo.global.MIMath;
-import ucar.ma2.Range;
-
-/**
- *
- * @author Yaqiang Wang
- */
-public class DataTable {
-
- protected DataRowCollection rows;
- protected DataColumnCollection columns;
- protected String tableName;
- protected boolean readOnly = false;
- protected int nextRowIndex = 0;
-//private DataExpression dataExpression;
- protected Object tag;
-
- /**
- * Constructor
- */
- public DataTable() {
- this.columns = new DataColumnCollection();
- this.rows = new DataRowCollection();
- this.rows.setColumns(columns);
- //dataExpression = new DataExpression(this);
- }
-
- /**
- * Constructor
- *
- * @param dataTableName The data table name
- */
- public DataTable(String dataTableName) {
- this();
- this.tableName = dataTableName;
- }
-
- /**
- * Get total row count
- *
- * @return Row number
- */
- public int getTotalCount() {
- return rows.size();
- }
-
- /**
- * Get row count
- *
- * @return Row count
- */
- public int getRowCount() {
- return rows.size();
- }
-
- /**
- * Get column count
- *
- * @return Column count
- */
- public int getColumnCount() {
- return columns.size();
- }
-
- /**
- * Get if is read only
- *
- * @return Boolean
- */
- public boolean isReadOnly() {
- return this.readOnly;
- }
-
- /**
- * Set if is read only
- *
- * @param readOnly Read only
- */
- public void setReadOnly(boolean readOnly) {
- this.readOnly = readOnly;
- }
-
- /**
- * Get table name
- *
- * @return Table name
- */
- public String getTableName() {
- return this.tableName;
- }
-
- /**
- * Set tabel name
- *
- * @param tableName Table name
- */
- public void setTableName(String tableName) {
- this.tableName = tableName;
- }
-
- /**
- * Get data rows
- *
- * @return DataRowCollection The data rows
- */
- public DataRowCollection getRows() {
- return this.rows;
- }
-
- /**
- * Get data rows
- *
- * @param idx Index
- * @return DataRowCollection The data rows
- */
- public DataRowCollection getRows(List idx) {
- DataRowCollection r = new DataRowCollection();
- for (int i : idx){
- r.add(this.rows.get(i));
- }
- return r;
- }
-
- /**
- * Get data rows
- *
- * @param range Range
- * @return DataRowCollection The data rows
- */
- public DataRowCollection getRows(Range range) {
- DataRowCollection r = new DataRowCollection();
- for (int i = range.first(); i < range.last(); i++){
- r.add(this.rows.get(i));
- }
- return r;
- }
-
- /**
- * Get data columns
- *
- * @return The data columns
- */
- public DataColumnCollection getColumns() {
- return this.columns;
- }
-
- /**
- * Get column names
- *
- * @return Column names
- */
- public List getColumnNames() {
- return this.columns.getColumnNames();
- }
-
- /**
- * Get the value by row index and column name
- *
- * @param row Row index
- * @param colName Column name
- * @return Object The value
- */
- public Object getValue(int row, String colName) {
- return this.rows.get(row).getValue(colName);
- }
-
- /**
- * Get the value by row and column index
- *
- * @param row Row index
- * @param col Column index
- * @return Object The value
- */
- public Object getValue(int row, int col) {
- return this.rows.get(row).getValue(col);
- }
-
- /**
- * Create a new data row
- *
- * @return DataRow The new data row
- * @throws java.lang.Exception
- */
- public DataRow newRow() throws Exception {
- DataRow tempRow = new DataRow(this);
- nextRowIndex = nextRowIndex < this.rows.size() ? this.rows.size()
- : nextRowIndex;
- tempRow.setColumns(this.columns);
- tempRow.setRowIndex(nextRowIndex++);
- for (DataColumn col : columns) {
- switch (col.getDataType()) {
- case STRING:
- tempRow.setValue(col.getColumnName(), "");
- break;
- case DATE:
- tempRow.setValue(col.getColumnName(), LocalDateTime.now());
- break;
- case BOOLEAN:
- tempRow.setValue(col.getColumnName(), Boolean.TRUE);
- break;
- default:
- tempRow.setValue(col.getColumnName(), 0);
- break;
- }
- }
- return tempRow;
- }
-
- /**
- * Set a vlaue by row and column index
- *
- * @param row Row index
- * @param col Column index
- * @param value The value
- */
- public void setValue(int row, int col, Object value) {
- this.rows.get(row).setValue(col, value);
- }
-
- /**
- * Set a value
- *
- * @param row Row index
- * @param colName Column name
- * @param value The value
- */
- public void setValue(int row, String colName, Object value) {
- this.rows.get(row).setValue(colName, value);
- }
-
- /**
- * Set values
- *
- * @param colName Column name
- * @param values Values
- */
- public void setValues(String colName, List values) {
- for (int i = 0; i < values.size(); i++) {
- this.rows.get(i).setValue(colName, values.get(i));
- }
- }
-
- /**
- * Set tag
- *
- * @param tag The tag
- */
- public void setTag(Object tag) {
- this.tag = tag;
- }
-
- /**
- * Get tag
- *
- * @return the tag
- */
- public Object getTag() {
- return tag;
- }
-
- /**
- * Find column by name
- *
- * @param colName The column name
- * @return The data column
- */
- public DataColumn findColumn(String colName) {
- if (colName == null)
- return null;
-
- for (DataColumn col : this.columns) {
- if (col.getColumnName().equals(colName)) {
- return col;
- }
- }
-
- return null;
- }
-
- /**
- * Get data columns by names
- *
- * @param colNames Data column names
- * @return Data columns
- */
- public List findColumns(List colNames) {
- List cols = new ArrayList<>();
- for (DataColumn col : this.getColumns()) {
- for (String colName : colNames) {
- if (col.getColumnName().equals(colName)) {
- cols.add(col);
- break;
- }
- }
- }
-
- return cols;
- }
-
- /**
- * Get data columns by index
- *
- * @param colIndex Data column index
- * @return Data columns
- */
- public List findColumns_Index(List colIndex) {
- List cols = new ArrayList<>();
- int n = this.getColumnCount();
- for (int i : colIndex) {
- if (i < 0)
- i = n + i;
- if (i < n)
- cols.add(this.columns.get(i));
- }
-
- return cols;
- }
-
- /**
- * Check if the table has time column
- * @return Boolean
- */
- public boolean hasTimeColumn(){
- for (DataColumn col : this.columns){
- if (col.getDataType() == DataType.DATE){
- return true;
- }
- }
- return false;
- }
-
- /**
- * Add a data column
- *
- * @param columnName Data column name
- * @param dataType Data type
- * @return The data column
- * @throws Exception
- */
- public DataColumn addColumn(String columnName, DataType dataType) throws Exception {
- DataColumn col = new DataColumn(columnName, dataType);
- addColumn(col);
- return col;
- }
-
- /**
- * Add a data column
- *
- * @param index The index
- * @param columnName Data column name
- * @param dataType Data type
- * @return The data column
- * @throws Exception
- */
- public DataColumn addColumn(int index, String columnName, DataType dataType) throws Exception {
- DataColumn col = new DataColumn(columnName, dataType);
- addColumn(index, col);
- return col;
- }
-
- /**
- * Add a data column by index
- *
- * @param index The index
- * @param column Data column
- */
- public void addColumn(int index, DataColumn column) {
- this.columns.add(index, column);
- for (DataRow row : this.rows) {
- row.setColumns(columns);
- row.addColumn(column);
- }
- }
-
- /**
- * Add a data column
- *
- * @param column Data column
- */
- public void addColumn(DataColumn column) {
- this.columns.add(column);
- for (DataRow row : this.rows) {
- row.setColumns(columns);
- row.addColumn(column);
- }
- }
-
- /**
- * Remove a data column
- *
- * @param column The data column
- */
- public void removeColumn(DataColumn column) {
- this.columns.remove(column);
- for (DataRow row : this.rows) {
- row.setColumns(columns);
- row.removeColumn(column);
- }
- }
-
- /**
- * Rename column
- *
- * @param column The column
- * @param fieldName The new column name
- */
- public void renameColumn(DataColumn column, String fieldName) {
- String oldName = column.getColumnName();
- this.columns.renameColumn(column, fieldName);
- for (DataRow row : this.rows) {
- row.setColumns(columns);
- row.renameColumn(oldName, fieldName);
- }
- }
-
- /**
- * Rename column
- *
- * @param oldName The old column name
- * @param newName The new column name
- */
- public void renameColumn(String oldName, String newName) {
- DataColumn column = findColumn(oldName);
- this.columns.renameColumn(column, newName);
- for (DataRow row : this.rows) {
- row.setColumns(columns);
- row.renameColumn(oldName, newName);
- }
- }
-
- /**
- * Rename column
- *
- * @param colIdx The column index
- * @param fieldName The new column name
- */
- public void renameColumn(int colIdx, String fieldName) {
- DataColumn column = this.columns.get(colIdx);
- this.renameColumn(column, fieldName);
- }
-
- /**
- * Add a data row
- *
- * @param row The data row
- * @return Boolean
- * @throws Exception
- */
- public boolean addRow(DataRow row) throws Exception {
- nextRowIndex = nextRowIndex < this.rows.size() ? this.rows.size()
- : nextRowIndex;
- row.setColumns(this.columns);
- row.setRowIndex(nextRowIndex++);
- row.setTable(this);
- return this.rows.add(row);
- }
-
- /**
- * Add data row
- *
- * @return Data row
- * @throws Exception
- */
- public DataRow addRow() throws Exception {
- DataRow row = new DataRow();
- this.addRow(row);
- return row;
- }
-
- /**
- * Add data rows
- *
- * @param rows Data rows
- * @throws Exception
- */
- public void addRows(List rows) throws Exception {
- for (DataRow row : rows) {
- addRow(row);
- }
- }
-
- /**
- * Append a data row
- *
- * @param row Data row
- * @return Boolean
- */
- public boolean appendRow(DataRow row) {
- List colNames = row.getColumns().getColumnNames();
- nextRowIndex = nextRowIndex < this.rows.size() ? this.rows.size()
- : nextRowIndex;
- row.setColumns(this.columns);
- row.setRowIndex(nextRowIndex++);
- row.setTable(this);
- for (DataColumn col : this.columns) {
- if (!colNames.contains(col.getColumnName())) {
- row.setValue(col, null);
- }
- }
- return this.rows.add(row);
- }
-
- /**
- * Remove a row
- *
- * @param rowIdx Row index
- */
- public void removeRow(int rowIdx) {
- this.rows.remove(rowIdx);
- }
-
- /**
- * Remove a row
- *
- * @param row The row will be removed
- */
- public void removeRow(DataRow row) {
- this.rows.remove(row);
- }
-
- /**
- * Remove rows
- *
- * @param rows The rows will be removed
- */
- public void removeRows(List rows) {
- this.rows.removeAll(rows);
- }
-
- /**
- * Set data rows
- *
- * @param rows The data rows
- */
- public void setRows(List rows) {
- this.rows.clear();
- for (DataRow row : rows) {
- this.rows.add(row);
- }
- }
-
- /**
- * Add column data
- *
- * @param col The column
- * @param colData The column data
- * @throws Exception
- */
- public void setColumnData(DataColumn col, List colData) throws Exception {
- if (this.getRowCount() == 0) {
- for (int i = 0; i < colData.size(); i++){
- DataRow row = this.addRow();
- row.setValue(col, colData.get(i));
- }
- } else {
- int i = 0;
- for (DataRow row : this.rows) {
- if (i < colData.size()) {
- row.setValue(col, colData.get(i));
- }
- i++;
- }
- }
- }
-
- /**
- * Add column data
- *
- * @param colName Column name
- * @param colData The column data
- * @throws Exception
- */
- public void setColumnData(String colName, List colData) throws Exception {
- DataColumn col = this.findColumn(colName);
- if (col == null){
- System.out.println("The column not exists: " + colName + "!");
- return;
- }
-
- setColumnData(col, colData);
- }
-
- /**
- * Add column data
- *
- * @param colData The column data
- * @throws Exception
- */
- public void addColumnData(ColumnData colData) throws Exception {
- DataColumn col = this.addColumn(colData.getDataColumn().getColumnName(), colData.getDataType());
- int i = 0;
- for (DataRow row : this.rows) {
- if (i < colData.size()) {
- row.setValue(col, colData.getValue(i));
- }
- i++;
- }
- }
-
- /**
- * Add column data
- *
- * @param colName Column name
- * @param dataType Data type
- * @param colData The column data
- * @throws Exception
- */
- public void addColumnData(String colName, DataType dataType, List colData) throws Exception {
- DataColumn col = this.addColumn(colName, dataType);
- setColumnData(col, colData);
- }
-
- /**
- * Add column data
- *
- * @param index Column index
- * @param colName Column name
- * @param dataType Data type
- * @param colData The column data
- * @throws Exception
- */
- public void addColumnData(int index, String colName, DataType dataType, List colData) throws Exception {
- DataColumn col = this.addColumn(index, colName, dataType);
- setColumnData(col, colData);
- }
-
- /**
- * Add column data
- *
- * @param colName Column name
- * @param dt Data type string
- * @param colData The column data
- * @throws Exception
- */
- public void addColumnData(String colName, String dt, List colData) throws Exception {
- DataType dataType = TableUtil.toDataTypes(dt);
- this.addColumnData(colName, dataType, colData);
- }
-
- /**
- * Get column data
- *
- * @param colName The column name
- * @return Column data
- */
- public ColumnData getColumnData(String colName) {
- return this.getColumnData(this.getRows(), colName);
- }
-
- /**
- * Get column data
- *
- * @param col The data column
- * @return Column data
- */
- public ColumnData getColumnData(DataColumn col) {
- return this.getColumnData(col.getColumnName());
- }
-
- /**
- * Get column data
- *
- * @param rows The data row list
- * @param colName The data column name
- * @return Column values
- */
- public ColumnData getColumnData(List rows, String colName) {
- ColumnData colData = new ColumnData(this.findColumn(colName));
- for (DataRow row : rows) {
- colData.addData(row.getValue(colName));
- }
-
- return colData;
- }
-
- /**
- * Select data rows
- *
- * @param expression SQL expression
- * @return Selected data rows
- */
- public List select(String expression) {
- SQLExpression e = new SQLExpression(expression);
- List dataRows = new ArrayList<>();
- for (int i = 0; i < this.rows.size(); i++) {
- DataRow row = this.rows.get(i);
- row.setRowIndex(i);
- if (e.eval(row.getItemMap())) {
- dataRows.add(row);
- }
- }
-
- return dataRows;
- }
-
- /**
- * Select and form a new data table
- *
- * @param expression SQL expression
- * @param dataColumns Data columns
- * @return Selected data table
- */
- public DataTable select(String expression, DataColumn[] dataColumns) {
- DataTable result = new DataTable();
- List dataRows = this.select(expression);
- for (DataColumn dc : dataColumns) {
- DataColumn newDc = (DataColumn)dc.clone();
- result.columns.add(newDc);
- }
-
- for (DataRow r : dataRows) {
- try {
- DataRow newRow = result.newRow();
- newRow.copyFrom(r);
- result.addRow(newRow);
- } catch (Exception ex) {
- Logger.getLogger(DataTable.class.getName()).log(Level.SEVERE, null, ex);
- }
- }
-
- return result;
- }
-
- /**
- * Get a new table by row range
- * @param rowRange Row range
- * @return
- * @throws Exception
- */
- public DataTable select(Range rowRange) throws Exception{
- return select(rowRange.first(), rowRange.last(), rowRange.stride());
- }
-
- /**
- * Get a new table by select rows
- * @param r_start row start
- * @param r_stop row stop
- * @param r_step row step
- * @return Result table
- * @throws Exception
- */
- public DataTable select(int r_start, int r_stop, int r_step) throws Exception {
- DataTable r = new DataTable();
- for (DataColumn dc : this.columns) {
- DataColumn newDc = (DataColumn)dc.clone();
- r.columns.add(newDc);
- }
-
- for (int i = r_start; i < r_stop; i+=r_step) {
- if (i >= this.getRowCount())
- break;
- DataRow newRow = r.newRow();
- newRow.copyFrom(this.rows.get(i));
- r.addRow(newRow);
- }
-
- return r;
- }
-
- /**
- * Get a new table by row index
- * @param rowIndex Row index
- * @return Result table
- * @throws Exception
- */
- public DataTable select(List rowIndex) throws Exception {
- DataTable r = new DataTable();
- for (DataColumn dc : this.columns) {
- DataColumn newDc = (DataColumn)dc.clone();
- r.columns.add(newDc);
- }
-
- for (int i : rowIndex) {
- if (i >= this.getRowCount())
- break;
- DataRow newRow = r.newRow();
- newRow.copyFrom(this.rows.get(i));
- r.addRow(newRow);
- }
-
- return r;
- }
-
- /**
- * Get a new table by row range and column range
- * @param rowRange Row range
- * @param colRange Column range
- * @return Result table
- * @throws Exception
- */
- public DataTable select(Range rowRange, Range colRange) throws Exception {
- return select(rowRange.first(), rowRange.last(), rowRange.stride(), colRange.first(), colRange.last(), colRange.stride());
- }
-
- /**
- * Get a new table by select rows
- * @param r_start Row start
- * @param r_stop Row stop
- * @param r_step Row step
- * @param c_start Column start
- * @param c_stop Column stop
- * @param c_step Column step
- * @return Result table
- * @throws Exception
- */
- public DataTable select(int r_start, int r_stop, int r_step, int c_start, int c_stop, int c_step) throws Exception {
- List cols = new ArrayList<>();
- for (int i = c_start; i < c_stop; i+= c_step){
- if (i >= this.getColumnCount())
- break;
- cols.add(this.columns.get(i));
- }
-
- return this.select(r_start, r_stop, r_step, cols);
- }
-
- /**
- * Get a new table by row index and column range
- * @param rowIndex Row index
- * @param colRange Column range
- * @return Result table
- * @throws Exception
- */
- public DataTable select(List rowIndex, Range colRange) throws Exception {
- return select(rowIndex, colRange.first(), colRange.last(), colRange.stride());
- }
-
- /**
- * Get a new table by row index and column slice
- * @param rowIndex Row index
- * @param c_start Column start
- * @param c_stop Column stop
- * @param c_step Column step
- * @return Result table
- * @throws Exception
- */
- public DataTable select(List rowIndex, int c_start, int c_stop, int c_step) throws Exception {
- List cols = new ArrayList<>();
- for (int i = c_start; i < c_stop; i+= c_step){
- if (i >= this.getColumnCount())
- break;
- cols.add(this.columns.get(i));
- }
-
- return this.select(rowIndex, cols);
- }
-
- /**
- * Get a new table by row range and columns
- * @param rowRange Row range
- * @param cols Columns
- * @return Result table
- * @throws Exception
- */
- public DataTable select(Range rowRange, List cols) throws Exception {
- return select(rowRange.first(), rowRange.last(), rowRange.stride(), cols);
- }
-
- /**
- * Get a new table by select rows
- * @param r_start Row start
- * @param r_stop Row stop
- * @param r_step Row step
- * @param cols Columns
- * @return Result table
- * @throws Exception
- */
- public DataTable select(int r_start, int r_stop, int r_step, List cols) throws Exception {
- DataTable r = new DataTable();
- for (DataColumn dc : cols) {
- DataColumn newDc = (DataColumn)dc.clone();
- r.columns.add(newDc);
- }
-
- DataColumnCollection dcc = new DataColumnCollection(cols);
- for (int i = r_start; i < r_stop; i+=r_step) {
- if (i >= this.getRowCount())
- break;
- DataRow newRow = this.rows.get(i).colSelect(dcc);
- r.addRow(newRow);
- }
-
- return r;
- }
-
- /**
- * Get a new table by row index and columns
- * @param rowIndex Row index
- * @param cols Columns
- * @return Result table
- * @throws Exception
- */
- public DataTable select(List rowIndex, List cols) throws Exception {
- DataTable r = new DataTable();
- for (DataColumn dc : cols) {
- DataColumn newDc = (DataColumn)dc.clone();
- r.columns.add(newDc);
- }
-
- DataColumnCollection dcc = new DataColumnCollection(cols);
- for (int i : rowIndex) {
- if (i >= this.getRowCount())
- break;
- DataRow newRow = this.rows.get(i).colSelect(dcc);
- r.addRow(newRow);
- }
-
- return r;
- }
-
- /**
- * Create a new data table using selected columns
- * @param cols The columns
- * @return Selected data table
- * @throws java.lang.Exception
- */
- public DataTable colSelect(List cols) throws Exception {
- DataTable r = new DataTable();
- for (DataColumn dc : cols) {
- DataColumn newDc = (DataColumn)dc.clone();
- r.columns.add(dc);
- }
-
- DataColumnCollection dcc = new DataColumnCollection(cols);
- for (DataRow dr : this.rows) {
- DataRow ndr = dr.colSelect(dcc);
- r.addRow(ndr);
- }
-
- return r;
- }
-
- /**
- * Select and form a new data table
- *
- * @param expression SQL expression
- * @return Selected data table
- */
- public DataTable sqlSelect(String expression) {
- DataTable result = new DataTable();
- List dataRows = this.select(expression);
- for (DataColumn dc : this.columns) {
- DataColumn newDc = (DataColumn)dc.clone();
- result.columns.add(newDc);
- }
-
- for (DataRow r : dataRows) {
- try {
- DataRow newRow = result.newRow();
- newRow.copyFrom(r);
- result.addRow(newRow);
- } catch (Exception ex) {
- Logger.getLogger(DataTable.class.getName()).log(Level.SEVERE, null, ex);
- }
- }
-
- return result;
- }
-
-// //以下为数据表扩展方法实现集合
-// /**
-// * 功能描述: 返回符合过滤条件的数据行集合,并返回
-// * @param
-// * @return: DataTable
-// */
-// public List select(String filterString) {
-// List rows = new ArrayList();
-// if (StringUtil.isNotEmpty(filterString)) {
-// for (Object row : this.rows) {
-// DataRow currentRow = (DataRow) row;
-// if ((Boolean) dataExpression.compute(filterString,
-// currentRow.getItemMap())) {
-// rows.add(currentRow);
-// }
-// }
-// return rows;
-// } else {
-// return this.rows;
-// }
-// }
-// /**
-// * 功能描述: 对当前表进行查询 过滤,并返回指定列集合拼装的DataTable对象
-// * @param
-// * @return: DataTable
-// */
-// public DataTable select(String filterString,
-// String[] columns,
-// boolean distinct) throws Exception {
-// DataTable result = new DataTable();
-// List rows = select(filterString);
-// //构造表结构
-// for (String c : columns) {
-// DataColumn dc = this.columns.get(c);
-// DataColumn newDc = new DataColumn(dc.getColumnName(),
-// dc.getDataType());
-// newDc.setCaptionName(dc.getCaptionName());
-// result.columns.add(newDc);
-// }
-// //填充数据
-// for (DataRow r : rows) {
-// DataRow newRow = result.newRow();
-// newRow.copyFrom(r);
-// result.addRow(newRow);
-// }
-// return result;
-// }
-// /**
-// * 功能描述: 根据指定表达式对符合过滤条件的数据进行计算
-// * @param
-// * @return: Object
-// * @author: James Cheung
-// * @version: 2.0
-// */
-// public Object compute(String expression,
-// String filter) {
-// return dataExpression.compute(expression, select(filter));
-// }
- public Object max(String columns,
- String filter) {
- return null;
- }
-
- public Object min(String columns,
- String filter) {
- return null;
- }
-
- public Object avg(String columns,
- String filter) {
- return null;
- }
-
- public Object max(String columns,
- String filter,
- String groupBy) {
- return null;
- }
-
- public Object min(String columns,
- String filter,
- String groupBy) {
- return null;
- }
-
- public Object avg(String columns,
- String filter,
- String groupBy) {
- return null;
- }
-
- /**
- * Clone
- *
- * @return Cloned DataTable object
- */
- @Override
- public Object clone() {
- DataTable table = new DataTable();
- table.tableName = this.tableName;
- table.tag = this.tag;
- table.readOnly = this.readOnly;
- for (DataColumn col : this.columns) {
- DataColumn newcol = (DataColumn) col.clone();
- //newcol.setTable(table);
- table.addColumn(new Field(newcol));
- }
-
- for (DataRow row : this.rows) {
- try {
- DataRow newrow = this.newRow();
- newrow.copyFrom(row);
- table.addRow(newrow);
- } catch (Exception ex) {
- Logger.getLogger(DataTable.class.getName()).log(Level.SEVERE, null, ex);
- }
- }
-
- return table;
- }
-
- /**
- * Clone table - Vectorlayer with fields
- *
- * @return DataTable
- */
- public DataTable cloneTable_Field() {
- DataTable table = new DataTable();
- table.tableName = this.tableName;
- table.tag = this.tag;
- table.readOnly = this.readOnly;
- for (DataColumn col : this.columns) {
- Field newcol = new Field(col.getColumnName(), col.getDataType());
- newcol.setCaptionName(col.getCaptionName());
- newcol.setColumnIndex(col.getColumnIndex());
- newcol.setReadOnly(col.isReadOnly());
- //newcol.setTable(table);
- table.addColumn(newcol);
- }
-
- for (DataRow row : this.rows) {
- try {
- DataRow newrow = this.newRow();
- newrow.copyFrom(row);
- table.addRow(newrow);
- } catch (Exception ex) {
- Logger.getLogger(DataTable.class.getName()).log(Level.SEVERE, null, ex);
- }
- }
-
- return table;
- }
-
- /**
- * Convert to string - head
- *
- * @param n Head row number
- * @return The string
- */
- public String head(int n) {
- StringBuilder sb = new StringBuilder();
- for (DataColumn col : this.columns) {
- if (sb.length() == 0) {
- sb.append(col.getColumnName());
- } else {
- sb.append("\t");
- sb.append(col.getColumnName());
- }
- }
- sb.append("\n");
-
- DateTimeFormatter format;
- int rn = this.getRowCount();
- if (n > rn) {
- n = rn;
- }
- Object v;
- for (int r = 0; r < n; r++) {
- DataRow row = this.rows.get(r);
- int i = 0;
- for (DataColumn col : this.columns) {
- if (i > 0) {
- sb.append("\t");
- }
- switch (col.getDataType()) {
- case DATE:
- format = DateTimeFormatter.ofPattern(col.getFormat());
- sb.append(format.format((LocalDateTime) row.getValue(col.getColumnName())));
- break;
- case STRING:
- sb.append("'").append(row.getValue(col.getColumnName()).toString()).append("'");
- break;
- default:
- v = row.getValue(col.getColumnName());
- if (v == null) {
- sb.append("null");
- } else {
- sb.append(v.toString());
- }
- break;
- }
- i += 1;
- }
- sb.append("\n");
- }
- if (n < rn) {
- sb.append("...");
- }
-
- return sb.toString();
- }
-
- /**
- * Convert to string - tail
- *
- * @param n Tail row number
- * @return The string
- */
- public String tail(int n) {
- StringBuilder sb = new StringBuilder();
- for (DataColumn col : this.columns) {
- if (sb.length() == 0) {
- sb.append(col.getColumnName());
- } else {
- sb.append("\t");
- sb.append(col.getColumnName());
- }
- }
- sb.append("\n");
-
- DateTimeFormatter format;
- int rn = this.getRowCount();
- if (n > rn) {
- n = rn;
- }
- Object v;
- for (int r = rn - n; r < rn; r++) {
- DataRow row = this.rows.get(r);
- int i = 0;
- for (DataColumn col : this.columns) {
- if (i > 0) {
- sb.append("\t");
- }
- switch (col.getDataType()) {
- case DATE:
- format = DateTimeFormatter.ofPattern(col.getFormat());
- sb.append(format.format((LocalDateTime) row.getValue(col.getColumnName())));
- break;
- case STRING:
- sb.append("'").append(row.getValue(col.getColumnName()).toString()).append("'");
- break;
- default:
- v = row.getValue(col.getColumnName());
- if (v == null) {
- sb.append("null");
- } else {
- sb.append(v.toString());
- }
- break;
- }
- i += 1;
- }
- sb.append("\n");
- }
-
- return sb.toString();
- }
-
- /**
- * Convert to string
- *
- * @return The string
- */
- @Override
- public String toString() {
- return head(100);
- }
-
- /**
- * Convert to string
- *
- * @param dateFormat Date format string
- * @return The string
- */
- public String toString(String dateFormat) {
- String str = "";
- for (DataColumn col : this.columns) {
- str += "," + col.getColumnName();
- }
- str = str.substring(1);
- DateTimeFormatter format = DateTimeFormatter.ofPattern(dateFormat);
- for (DataRow row : this.rows) {
- String line = "";
- for (DataColumn col : this.columns) {
- if (col.getDataType() == DataType.DATE) {
- line += "," + format.format((LocalDateTime) row.getValue(col.getColumnName()));
- } else {
- line += "," + row.getValue(col.getColumnName()).toString();
- }
- }
- line = line.substring(1);
- str += System.getProperty("line.separator") + line;
- }
-
- return str;
- }
-
- /**
- * Convert to string
- *
- * @param decimalNum Decimal number
- * @return The string
- */
- public String toString(int decimalNum) {
- return this.toString("yyyyMMddHH", decimalNum);
- }
-
- /**
- * Convert to string
- *
- * @param dateFormat Date format string
- * @param decimalNum Decimal number
- * @return The string
- */
- public String toString(String dateFormat, int decimalNum) {
- DateTimeFormatter format = DateTimeFormatter.ofPattern(dateFormat);
- String dFormat = "%1$." + String.valueOf(decimalNum) + "f";
- String str = "";
- for (DataColumn col : this.columns) {
- str += "," + col.getColumnName();
- }
- str = str.substring(1);
- String vstr;
- for (DataRow row : this.rows) {
- String line = "";
- for (DataColumn col : this.columns) {
- vstr = row.getValue(col.getColumnName()).toString();
- switch (col.getDataType()) {
- case FLOAT:
- case DOUBLE:
- if (MIMath.isNumeric(vstr)) {
- line += "," + String.format(dFormat, Double.parseDouble(vstr));
- } else {
- line += ",";
- }
- break;
- case DATE:
- line += "," + format.format((LocalDateTime) row.getValue(col.getColumnName()));
- break;
- default:
- line += "," + vstr;
- break;
- }
- }
- line = line.substring(1);
- str += System.getProperty("line.separator") + line;
- }
-
- return str;
- }
-
- /**
- * Save as csv file
- *
- * @param fileName File name
- * @throws java.io.IOException
- */
- public void saveAsCSVFile(String fileName) throws IOException {
- this.saveAsCSVFile(fileName, null);
- }
-
- /**
- * Save as csv file
- *
- * @param fileName File name
- * @param format Format string
- * @throws java.io.IOException
- */
- public void saveAsCSVFile(String fileName, String format) throws IOException {
- List formats = TableUtil.getFormats(format);
- int n = this.getColumnCount();
- if (formats != null) {
- if (formats.size() < n) {
- while (formats.size() < n) {
- formats.add(null);
- }
- }
- }
-
- if (!fileName.endsWith(".csv")) {
- fileName = fileName + ".csv";
- }
-
- BufferedWriter sw = new BufferedWriter(new FileWriter(new File(fileName)));
- String str = "";
- for (DataColumn col : this.columns) {
- str += "," + col.getColumnName();
- }
- str = str.substring(1);
- sw.write(str);
-
- String line, vstr;
- DataColumn col;
- String formatStr;
- for (DataRow row : this.rows) {
- line = "";
- for (int i = 0; i < n; i++) {
- col = this.columns.get(i);
- if (formats == null){
- vstr = row.getValueStr(col.getColumnName());
- } else {
- formatStr = formats.get(i);
- vstr = row.getValueStr(col.getColumnName(), formatStr);
- }
- if (vstr.equalsIgnoreCase("NaN") || vstr.equalsIgnoreCase("null")){
- vstr = "";
- }
- line += "," + vstr;
- }
- line = line.substring(1);
- sw.newLine();
- sw.write(line);
- }
- sw.flush();
- sw.close();
- }
-
- /**
- * Save as ASCII file
- *
- * @param fileName File name
- * @throws java.io.IOException
- */
- public void saveAsASCIIFile(String fileName) throws IOException {
- this.saveAsASCIIFile(fileName, ",", null, null);
- }
-
- /**
- * Save as ASCII file
- *
- * @param fileName File name
- * @param delimiter Delimiter
- * @param dateFormat Date format string
- * @param floatFormat Float format string
- * @throws java.io.IOException
- */
- public void saveAsASCIIFile(String fileName, String delimiter, String dateFormat, String floatFormat) throws IOException {
- BufferedWriter sw = new BufferedWriter(new FileWriter(new File(fileName)));
- int n = this.getColumnCount();
- String str = "";
- for (int i = 0; i < n; i++){
- if (i == 0)
- str = this.columns.get(i).getColumnName();
- else
- str = str + delimiter + this.columns.get(i).getColumnName();
- };
- sw.write(str);
-
- String line, vstr;
- DataColumn col;
- for (DataRow row : this.rows) {
- line = "";
- for (int i = 0; i < n; i++) {
- col = this.columns.get(i);
- switch (col.getDataType()){
- case DATE:
- vstr = row.getValueStr(col.getColumnName(), dateFormat);
- break;
- case FLOAT:
- case DOUBLE:
- vstr = row.getValueStr(col.getColumnName(), floatFormat);
- break;
- default:
- vstr = row.getValueStr(col.getColumnName());
- break;
- }
-
- line += delimiter + vstr;
- }
- line = line.substring(1);
- sw.newLine();
- sw.write(line);
- }
- sw.flush();
- sw.close();
- }
-
- /**
- * Save as ASCII file
- *
- * @param fileName File name
- * @param format Format string
- * @throws java.io.IOException
- */
- public void saveAsASCIIFile_format(String fileName, String format) throws IOException {
- List formats = TableUtil.getFormats(format);
- int n = this.getColumnCount();
- if (formats != null) {
- if (formats.size() < n) {
- while (formats.size() < n) {
- formats.add(null);
- }
- }
- }
-
- BufferedWriter sw = new BufferedWriter(new FileWriter(new File(fileName)));
- String str = "";
- for (DataColumn col : this.columns) {
- str += " " + col.getColumnName();
- }
- str = str.substring(1);
- sw.write(str);
-
- String line, vstr;
- DataColumn col;
- String formatStr;
- for (DataRow row : this.rows) {
- line = "";
- for (int i = 0; i < n; i++) {
- col = this.columns.get(i);
- if (formats == null)
- vstr = row.getValueStr(col.getColumnName());
- else {
- formatStr = formats.get(i);
- vstr = row.getValueStr(col.getColumnName(), formatStr);
- }
- line += " " + vstr;
- }
- line = line.substring(1);
- sw.newLine();
- sw.write(line);
- }
- sw.flush();
- sw.close();
- }
-
- /**
- * Join data table
- *
- * @param dataTable The input data table
- * @param colName The column name for join
- */
- public void join(DataTable dataTable, String colName) {
- this.join(dataTable, colName, colName, false);
- }
-
- /**
- * Join data table
- *
- * @param dataTable The input data table
- * @param colName The column name for join
- * @param isUpdate If update the existing values with same column name
- */
- public void join(DataTable dataTable, String colName, boolean isUpdate) {
- this.join(dataTable, colName, colName, isUpdate);
- }
-
- /**
- * Join data table
- *
- * @param dataTable The input data table
- * @param colName_this The column name of this data table for join
- * @param colName_in The column name of the input data table for join
- * @param isUpdate If update the existing values with same column name
- */
- public void join(DataTable dataTable, String colName_this, String colName_in, boolean isUpdate) {
- DataColumn col_this = this.findColumn(colName_this);
- if (col_this == null) {
- System.out.println("There is no column of " + colName_this + " in this table");
- return;
- }
- DataColumn col_in = dataTable.findColumn(colName_in);
- if (col_in == null) {
- System.out.println("There is no column of " + colName_in + " in this table");
- return;
- }
-
- List values_this = this.getColumnData(colName_this).getDataStrings();
- List values_in = dataTable.getColumnData(colName_in).getDataStrings();
-
- List