Mercurial > dive4elements > river
changeset 8218:ed8c1a0b4cfb
Merged
author | Sascha L. Teichmann <teichmann@intevation.de> |
---|---|
date | Mon, 08 Sep 2014 12:28:16 +0200 |
parents | a12e0245643b (diff) cb25ea4d4551 (current diff) |
children | 9667900536b6 |
files | |
diffstat | 1 files changed, 0 insertions(+), 702 deletions(-) [+] |
line wrap: on
line diff
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/charts/CrossSectionApp.java Mon Sep 08 12:25:47 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,702 +0,0 @@ -/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde - * Software engineering by Intevation GmbH - * - * This file is Free Software under the GNU AGPL (>=v3) - * and comes with ABSOLUTELY NO WARRANTY! Check out the - * documentation coming with Dive4Elements River for details. - */ - -package org.dive4elements.river.artifacts.charts; - -import org.dive4elements.river.backend.SessionFactoryProvider; - -import org.dive4elements.river.artifacts.geom.Lines; - -import org.dive4elements.river.model.CrossSection; -import org.dive4elements.river.model.CrossSectionLine; -import org.dive4elements.river.model.CrossSectionPoint; - -import org.dive4elements.river.utils.Pair; - -import org.dive4elements.river.jfree.StableXYDifferenceRenderer; - -import java.awt.BorderLayout; -import java.awt.Dimension; -import java.awt.FlowLayout; - -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.ItemEvent; -import java.awt.event.ItemListener; - -import java.awt.geom.Point2D; -import java.awt.geom.Rectangle2D; - -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.io.PrintWriter; - -import java.math.BigDecimal; -import java.math.MathContext; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; - -import java.awt.Color; -import java.awt.Paint; -import java.awt.TexturePaint; - -import java.awt.image.BufferedImage; - -import javax.swing.DefaultComboBoxModel; -import javax.swing.JButton; -import javax.swing.JComboBox; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JTable; -import javax.swing.JTextField; - -import javax.swing.event.TableModelEvent; -import javax.swing.event.TableModelListener; - -import javax.swing.table.AbstractTableModel; - -import org.hibernate.Query; -import org.hibernate.Session; - -import org.jfree.chart.ChartFactory; -import org.jfree.chart.ChartPanel; -import org.jfree.chart.ChartUtilities; -import org.jfree.chart.JFreeChart; - -import org.jfree.chart.axis.NumberAxis; - -import org.jfree.chart.plot.PlotOrientation; -import org.jfree.chart.plot.XYPlot; - -import org.jfree.data.xy.DefaultXYDataset; -import org.jfree.data.xy.XYSeries; -import org.jfree.data.xy.XYDataset; -import org.jfree.data.xy.XYSeriesCollection; -import org.jfree.chart.renderer.xy.XYItemRenderer; - -import org.jfree.ui.ApplicationFrame; -import org.jfree.ui.RefineryUtilities; - - -/** - * Standalone tech-demo. - */ -public class CrossSectionApp -extends ApplicationFrame -{ - public static final String RIVER = System.getProperty("river", "Saar"); - - public static final String WATER_LEVEL = System.getProperty("waterlevel"); - - public static final String KM = System.getProperty("km"); - - public static final double EPSILON = 1e-4; - - protected Session session; - - protected JComboBox crossSectionLinesCB; - protected JTextField waterlevelTF; - - protected ChartPanel chartPanel; - - protected Double lastWaterLevel; - - protected List<CrossSection> crossSections; - protected boolean [] drawCrossSection; - protected boolean [] drawWaterLevel; - protected boolean [] drawGround; - protected boolean [] drawFill; - - protected Map<Double, List<Pair<CrossSection, CrossSectionLine>>> km2lines; - - protected static final Paint TRANSPARENT = createTransparentPaint(); - - public class CrossSectionTableModel extends AbstractTableModel { - - @Override - public String getColumnName(int col) { - switch (col) { - case 0: return "Peilungsname"; - case 1: return "Peilung"; - case 2: return "Wasserstand"; - case 3: return "Boden"; - case 4: return "Wasser"; - } - return ""; - } - - @Override - public int getColumnCount() { - return 5; - } - - @Override - public int getRowCount() { - return crossSections != null ? crossSections.size() : 0; - } - - @Override - public Object getValueAt(int row, int col) { - if (crossSections == null) return null; - switch (col) { - case 0: return crossSections.get(row).getDescription(); - case 1: return drawCrossSection[row]; - case 2: return drawWaterLevel[row]; - case 3: return drawGround[row]; - case 4: return drawFill[row]; - } - return null; - } - - @Override - public void setValueAt(Object value, int row, int col) { - switch (col) { - case 1: - if (change(drawCrossSection, row, (Boolean)value)) { - fireTableCellUpdated(row, col); - } - break; - case 2: - if (change(drawWaterLevel, row, (Boolean)value)) { - fireTableCellUpdated(row, col); - } - break; - case 3: - if (change(drawGround, row, (Boolean)value)) { - fireTableCellUpdated(row, col); - } - break; - case 4: - if (change(drawFill, row, (Boolean)value)) { - fireTableCellUpdated(row, col); - } - break; - } - } - - @Override - public Class<?> getColumnClass(int columnIndex) { - switch (columnIndex) { - case 0: return String.class; - case 1: - case 2: - case 3: - case 4: return Boolean.class; - } - return null; - } - - @Override - public boolean isCellEditable( - int rowIndex, - int columnIndex - ) { - return columnIndex >= 1 && columnIndex <= 4; - } - } // class CrossSectionTableModel - - private static boolean change( - boolean [] values, - int index, - boolean value - ) { - if (values[index] != value) { - values[index] = value; - return true; - } - return false; - } - - public static class CrossSectionLineItem { - - Double km; - List<Pair<CrossSection, CrossSectionLine>> lines; - - public CrossSectionLineItem( - Double km, - List<Pair<CrossSection, CrossSectionLine>> lines - ) { - this.km = km; - this.lines = lines; - } - - public String toString() { - return String.valueOf(km); - } - } // CrossSectionLineItem - - public CrossSectionApp(String title) { - super(title); - - session = SessionFactoryProvider - .createSessionFactory() - .openSession(); - - JPanel content = createContent(); - content.setPreferredSize(new Dimension(800, 480)); - setContentPane(content); - } - - - /** Query and return CrossSections for named river. */ - public List<CrossSection> crossSections(String river) { - Query query = session.createQuery( - "from CrossSection where river.name = :river"); - query.setParameter("river", river); - return query.list(); - } - - protected Map<Double, List<Pair<CrossSection, CrossSectionLine>>> - loadAllLines(List<CrossSection> crossSections) { - Map<Double, List<Pair<CrossSection, CrossSectionLine>>> km2lines = - new TreeMap<Double, List<Pair<CrossSection, CrossSectionLine>>>(); - for (CrossSection cs: crossSections) { - List<CrossSectionLine> lines = cs.getLines(); - for (CrossSectionLine csl: lines) { - Double km = Math.round(csl.getKm().doubleValue() * 1000d)/1000d; - List<Pair<CrossSection, CrossSectionLine>> ls - = km2lines.get(km); - if (ls == null) { - ls = new ArrayList<Pair<CrossSection, CrossSectionLine>>(2); - km2lines.put(km, ls); - } - ls.add(new Pair<CrossSection, CrossSectionLine>(cs, csl)); - } - } - return km2lines; - } - - public JPanel createContent() { - JPanel panel = new JPanel(new BorderLayout()); - - JPanel nav = new JPanel(new FlowLayout()); - - crossSections = crossSections(RIVER); - km2lines = loadAllLines(crossSections); - - int CS = crossSections.size(); - Arrays.fill(drawCrossSection = new boolean[CS], true); - drawWaterLevel = new boolean[CS]; - drawGround = new boolean[CS]; - drawFill = new boolean[CS]; - - Object [] clis = createCrossSectionLineItems(km2lines); - - DefaultComboBoxModel dcbm = new DefaultComboBoxModel(clis); - - crossSectionLinesCB = new JComboBox(dcbm); - - if (KM != null) { - try { - double km = Double.parseDouble(KM); - - CrossSectionLineItem found = null; - - for (Object o: clis) { - CrossSectionLineItem csli = (CrossSectionLineItem)o; - if (Math.abs(csli.km - km) < EPSILON) { - found = csli; - break; - } - } - - if (found != null) { - crossSectionLinesCB.setSelectedItem(found); - } - } - catch (NumberFormatException nfe) { - System.err.println("km is not a number: " - + nfe.getMessage()); - } - } - - nav.add(crossSectionLinesCB); - - crossSectionLinesCB.addItemListener(new ItemListener() { - @Override - public void itemStateChanged(ItemEvent ie) { - if (ie.getStateChange() == ItemEvent.SELECTED) { - updateChart(); - } - } - }); - - waterlevelTF = new JTextField(5); - - if (WATER_LEVEL != null) { - try { - waterlevelTF.setText( - (lastWaterLevel = Double.valueOf(WATER_LEVEL)).toString()); - } - catch (NumberFormatException nfe) { - System.err.println("Water level not a number: " + - nfe.getMessage()); - } - } - - waterlevelTF.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent ae) { - waterLevelChanged(); - } - }); - - nav.add(waterlevelTF); - - JButton dump = new JButton("dump"); - - dump.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent ae) { - dumpData(); - } - }); - - nav.add(dump); - - - chartPanel = createChartPanel(); - - panel.add(chartPanel, BorderLayout.CENTER); - - - CrossSectionTableModel cstm = new CrossSectionTableModel(); - - cstm.addTableModelListener(new TableModelListener() { - @Override - public void tableChanged(TableModelEvent e) { - updateChart(); - } - }); - - JTable crossTable = new JTable(cstm); - - JPanel west = new JPanel(new BorderLayout()); - JScrollPane scrollPane = new JScrollPane(crossTable); - west.add(scrollPane); - - west.add(nav, BorderLayout.SOUTH); - - panel.add(west, BorderLayout.WEST); - - return panel; - } - - protected void waterLevelChanged() { - String value = waterlevelTF.getText(); - try { - lastWaterLevel = Double.valueOf(value); - } - catch (NumberFormatException nfe) { - waterlevelTF.setText( - lastWaterLevel != null ? lastWaterLevel.toString() : ""); - return; - } - updateChart(); - } - - protected void updateChart() { - - JFreeChart chart = createChart(); - - chartPanel.setChart(chart); - } - - protected ChartPanel createChartPanel() { - - JFreeChart chart = createChart(); - - return new ChartPanel(chart); - } - - protected void dumpData() { - - CrossSectionLineItem csli = - (CrossSectionLineItem)crossSectionLinesCB.getSelectedItem(); - - if (csli == null) { - return; - } - - double km = Math.round(csli.km.doubleValue() * 1000d)/1000d; - - String kmS = String.valueOf(km).replace(".", "-"); - - int i = 1; - File file = new File("cross-section-" + kmS + ".txt"); - while (file.exists()) { - file = new File("cross-section-" + kmS + "[" + (i++) + "].txt"); - } - - System.err.println("dump points to file '" + file + "'"); - - PrintWriter out = null; - - MathContext mc = new MathContext(3); - - try { - out = - new PrintWriter( - new FileWriter(file)); - - for (Pair<CrossSection, CrossSectionLine> pair: csli.lines) { - out.println("# " + pair.getA().getDescription()); - for (CrossSectionPoint point: pair.getB().getPoints()) { - out.println( - new BigDecimal(point.getX()).round(mc) + " " + - new BigDecimal(point.getY()).round(mc)); - } - } - - out.flush(); - } - catch (IOException ioe) { - ioe.printStackTrace(); - } - finally { - if (out != null) { - out.close(); - } - } - } - - public void generateWaterLevels( - List<Point2D> points, - List<Pair<XYDataset, XYItemRenderer>> datasets - ) { - if (points == null || points.isEmpty() || lastWaterLevel == null) { - return; - } - - double [][] data = Lines.createWaterLines(points, lastWaterLevel).points; - XYSeries series = - new XYSeries(String.valueOf(lastWaterLevel), false); - - double [] x = data[0]; - double [] y = data[1]; - for (int i = 0; i < x.length; ++i) { - series.add(x[i], y[i], false); - } - - datasets.add(new Pair<XYDataset, XYItemRenderer>( - new XYSeriesCollection(series), null)); - } - - public void generateFill( - List<Point2D> points, - String legend, - List<Pair<XYDataset, XYItemRenderer>> datasets - ) { - if (points == null || points.isEmpty() || lastWaterLevel == null) { - return; - } - - double [][] data = Lines.createWaterLines(points, lastWaterLevel).points; - double [][] values = CrossSectionLine.fetchCrossSectionProfile(points); - - DefaultXYDataset dataset = new DefaultXYDataset(); - - dataset.addSeries(legend + "-Linie", values); - dataset.addSeries(legend + "-Fl\u00e4che", data); - - datasets.add(new Pair<XYDataset, XYItemRenderer>( - dataset, - new StableXYDifferenceRenderer( - TRANSPARENT, Color.blue, false))); - } - - public void generateProfile( - List<Point2D> points, - String legend, - List<Pair<XYDataset, XYItemRenderer>> datasets - ) { - if (points == null || points.isEmpty()) { - return; - } - - double [][] values = CrossSectionLine.fetchCrossSectionProfile(points); - - XYSeries series = new XYSeries(legend, false); - - double [] x = values[0]; - double [] y = values[1]; - for (int i = 0; i < x.length; ++i) { - series.add(x[i], y[i], false); - } - - datasets.add(new Pair<XYDataset, XYItemRenderer>( - new XYSeriesCollection(series), null));; - } - - - /** - * @param legend the legend entry. - */ - public void generateGround( - List<Point2D> points, - String legend, - List<Pair<XYDataset, XYItemRenderer>> datasets - ) { - if (points == null || points.isEmpty()) { - return; - } - - double [][] values = CrossSectionLine.fetchCrossSectionProfile(points); - - DefaultXYDataset dataset = new DefaultXYDataset(); - - dataset.addSeries(legend, values); - - StableXYDifferenceRenderer renderer = - new StableXYDifferenceRenderer(); - - datasets.add(new Pair<XYDataset, XYItemRenderer>( - dataset, renderer)); - } - - public List<Pair<XYDataset, XYItemRenderer>> generateDatasets() { - - List<Pair<XYDataset, XYItemRenderer>> datasets = - new ArrayList<Pair<XYDataset, XYItemRenderer>>(); - - CrossSectionLineItem csli = - (CrossSectionLineItem)crossSectionLinesCB.getSelectedItem(); - - for (int i = 0; i < drawCrossSection.length; ++i) { - List<Point2D> points = null; - CrossSection cs = crossSections.get(i); - - if (drawGround[i]) { - for (Pair<CrossSection, CrossSectionLine> csl: csli.lines) { - if (csl.getA() == cs) { - if (points == null) { - points = csl.getB().fetchCrossSectionLinesPoints(); - } - generateGround( - points, - cs.getDescription() + "/Boden", - datasets); - break; - } - } - } - - if (drawFill[i]) { - for (Pair<CrossSection, CrossSectionLine> csl: csli.lines) { - if (csl.getA() == cs) { - if (points == null) { - points = csl.getB().fetchCrossSectionLinesPoints(); - } - - generateFill( - points, cs.getDescription(), datasets); - break; - } - } - } - - if (drawCrossSection[i]) { - for (Pair<CrossSection, CrossSectionLine> csl: csli.lines) { - if (csl.getA() == cs) { - if (points == null) { - points = csl.getB().fetchCrossSectionLinesPoints(); - } - - generateProfile( - points, cs.getDescription(), datasets); - break; - } - } - } - - if (drawWaterLevel[i]) { - for (Pair<CrossSection, CrossSectionLine> csl: csli.lines) { - if (csl.getA() == cs) { - if (points == null) { - points = csl.getB().fetchCrossSectionLinesPoints(); - } - generateWaterLevels(points, datasets); - break; - } - } - } - - } - - return datasets; - } - - protected Object [] createCrossSectionLineItems( - Map<Double, List<Pair<CrossSection, CrossSectionLine>>> km2lines - ) { - Object [] result = new Object[km2lines.size()]; - int i = 0; - for (Map.Entry<Double, List<Pair<CrossSection, CrossSectionLine>>> entry: - km2lines.entrySet()) { - result[i++] = new CrossSectionLineItem( - entry.getKey(), - entry.getValue()); - } - return result; - } - - - public JFreeChart createChart() { - JFreeChart chart = ChartFactory.createXYLineChart( - null, - "Abstand [m]", - "H\u00f6he [m]", - null, - PlotOrientation.VERTICAL, - true, - true, - false); - - List<Pair<XYDataset, XYItemRenderer>> datasets = - generateDatasets(); - - XYPlot plot = chart.getXYPlot(); - - for (int i = 0, N = datasets.size(); i < N; ++i) { - Pair<XYDataset, XYItemRenderer> p = datasets.get(i); - plot.setDataset(i, p.getA()); - plot.mapDatasetToRangeAxis(i, 0); - XYItemRenderer renderer = p.getB(); - if (renderer != null) { - plot.setRenderer(i, renderer); - } - } - - NumberAxis yAxis = (NumberAxis)plot.getRangeAxis(); - yAxis.setAutoRangeIncludesZero(false); - - ChartUtilities.applyCurrentTheme(chart); - return chart; - } - - protected static Paint createTransparentPaint() { - BufferedImage texture = new BufferedImage( - 1, 1, BufferedImage.TYPE_4BYTE_ABGR); - - return new TexturePaint( - texture, new Rectangle2D.Double(0d, 0d, 0d, 0d)); - } - - public static void main(String [] args) { - CrossSectionApp csa = new CrossSectionApp("Querprofile"); - csa.pack(); - RefineryUtilities.centerFrameOnScreen(csa); - csa.setVisible(true); - } -} -// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :