/* * Geotoolkit.org - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2002-2012, Open Source Geospatial Foundation (OSGeo) * (C) 2009-2012, Geomatys * * 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; * version 2.1 of the License. * * 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.geotoolkit.coverage.grid; import java.util.Locale; import java.io.PrintWriter; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.geom.AffineTransform; import java.awt.image.ColorModel; import java.awt.image.IndexColorModel; import java.awt.image.RenderedImage; import javax.swing.JPanel; import javax.swing.JFrame; import javax.swing.JComponent; import javax.media.jai.GraphicsJAI; import javax.media.jai.PlanarImage; import org.opengis.util.InternationalString; import org.apache.sis.util.CharSequences; import org.apache.sis.util.Classes; import org.geotoolkit.coverage.GridSampleDimension; /** * A very simple viewer for {@link GridCoverage2D}. This viewer provides no zoom * capability, no user interaction and ignores the coordinate system. It is just * for quick test of grid coverage. * * @author Martin Desruisseaux (IRD) * @version 3.00 * * @since 2.1 */ @SuppressWarnings("serial") public strictfp class Viewer extends JPanel { /** * The image to display. */ private final RenderedImage image; /** * The main sample dimension, or {@code null} if none. * Used by {@link #printPalette} for printing categories. */ private GridSampleDimension categories; /** * The transform from grid to coordinate system. * Usually an identity transform for this simple viewer. */ private final AffineTransform gridToCoordinateSystem = new AffineTransform(); /** * The location for the next frame window. */ private static int location; /** * Constructs a viewer for the specified image. * * @param image The image to display. */ public Viewer(RenderedImage image) { image = this.image = PlanarImage.wrapRenderedImage(image); gridToCoordinateSystem.translate(-image.getMinX(), -image.getMinY()); setPreferredSize(new Dimension(image.getWidth(), image.getHeight())); } /** * Constructs a viewer for the specified grid coverage. * * @param coverage The coverage to display. */ public Viewer(final GridCoverage2D coverage) { this(coverage.getRenderedImage()); categories = coverage.getSampleDimension(0); } /** * Paints this component. * * @param graphics The graphics handler. */ @Override public void paintComponent(final Graphics graphics) { super.paintComponent(graphics); final GraphicsJAI g = GraphicsJAI.createGraphicsJAI((Graphics2D) graphics, this); g.drawRenderedImage(image, gridToCoordinateSystem); } /** * A convenience method showing an image. The application * will be terminated when the user close the frame. * * @param image The coverage to display. * @return The viewer, for information. */ public static Viewer show(final RenderedImage image) { return show(new Viewer(image), null); } /** * A convenience method showing an image. The application * will be terminated when the user close the frame. * * @param image The coverage to display. * @param title The windows title, or {@code null} for a default one. * @return The viewer, for information. */ public static Viewer show(final RenderedImage image, final String title) { return show(new Viewer(image), title); } /** * A convenience method showing a grid coverage. The application * will be terminated when the user close the frame. * * @param coverage The coverage to display. * @return The viewer, for information. */ public static Viewer show(final GridCoverage2D coverage) { return show(coverage, null); } /** * A convenience method showing a grid coverage. The application * will be terminated when the user close the frame. * * @param coverage The coverage to display. * @param title The window title. * @return The viewer, for information. */ public static Viewer show(final GridCoverage2D coverage, final String title) { final StringBuilder buffer = new StringBuilder(); if (title != null) { buffer.append(title); buffer.append(" - "); } final InternationalString name = coverage.getName(); if (name != null) { buffer.append(name.toString(JComponent.getDefaultLocale())); } if (coverage != coverage.view(ViewType.GEOPHYSICS)) { buffer.append(" (packed)"); } else if (coverage != coverage.view(ViewType.RENDERED)) { buffer.append(" (geophysics)"); } return show(new Viewer(coverage), buffer.toString()); } /** * A convenience method showing a grid coverage. The application * will be terminated when the user close the frame. * * @param viewer The viewer to display. * @param title The frame title, or {@code null} if none. * @return The viewer, for convenience. */ private static Viewer show(final Viewer viewer, final String title) { final JFrame frame = new JFrame(title); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLocation(location, location); frame.getContentPane().add(viewer); frame.pack(); frame.setVisible(true); location += 16; return viewer; } /** * Prints the color palette to the specified output stream. First, the color model * name is displayed. Next, if the color model is an {@link IndexColorModel}, then the * RGB codes are written for all samples values. Category names or geophysics values, * if any are written after each sample values. * * @param out The writer where to print the palette. */ public void printPalette(final PrintWriter out) { final Locale locale = getLocale(); final ColorModel model = image.getColorModel(); out.print(Classes.getShortClassName(model)); out.println(':'); if (model instanceof IndexColorModel) { out.println(); out.println("Sample Colors Category or geophysics value"); out.println("------ ---------------- ----------------------------"); final IndexColorModel palette = (IndexColorModel) model; final int size = palette.getMapSize(); final byte[] R = new byte[size]; final byte[] G = new byte[size]; final byte[] B = new byte[size]; palette.getReds (R); palette.getGreens(G); palette.getBlues (B); for (int i=0; i<size; i++) { format(out, i); out.print(": RGB["); format(out, R[i]); out.print(','); format(out, G[i]); out.print(','); format(out, R[i]); out.print(']'); if (categories != null) { final String label = categories.getLabel(i, locale); if (label != null) { out.print(" "); out.print(label); } } out.println(); } } else { out.println(model.getColorSpace()); } } /** * Format a unsigned byte to the specified output stream. * The number will be right-justified in a cell of 3 spaces width. * * @param The writer where to print the number. * @param value The number to format. */ private static void format(final PrintWriter out, final byte value) { format(out, ((int)value) & 0xFF); } /** * Format an integer to the specified output stream. * The number will be right-justified in a cell of 3 spaces width. * * @param The writer where to print the number. * @param value The number to format. */ private static void format(final PrintWriter out, final int value) { final String str = String.valueOf(value); out.print(CharSequences.spaces(3 - str.length())); out.print(str); } }