/* * GTOPO30Tile.java * * Copyright (c) 2002-2015 Alexei Drummond, Andrew Rambaut and Marc Suchard * * This file is part of BEAST. * See the NOTICE file distributed with this work for additional * information regarding copyright ownership and licensing. * * BEAST 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 * of the License, or (at your option) any later version. * * BEAST 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. * * You should have received a copy of the GNU Lesser General Public * License along with BEAST; if not, write to the * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301 USA */ package dr.geo; import dr.app.gui.ColorFunction; import javax.imageio.ImageIO; import javax.imageio.stream.ImageInputStream; import javax.swing.*; import java.awt.*; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.io.*; import java.nio.ByteOrder; import java.util.HashMap; import java.util.Map; import java.util.StringTokenizer; /** * @author Alexei Drummond * @author Remco Bouckaert */ public class GTOPO30Tile extends JComponent { static final int NROWS = 6000; static final int NCOLS = 4800; static final int NODATA = -9999; short[][] height; BufferedImage image; ColorFunction colorFunction; double ulxmap, ulymap, xdim, ydim; Rectangle2D bounds; boolean createImage = true; public GTOPO30Tile(String filename, ColorFunction function) throws IOException { String headerFileName = filename.substring(0, filename.lastIndexOf('.')) + ".HDR"; File headerFile = new File(headerFileName); if (headerFile.isFile()) { try { readHeader(headerFile); } catch (FileNotFoundException e) { System.err.println("No header file named " + headerFile.toString() + " found"); } } height = new short[NROWS][NCOLS]; colorFunction = function; read(filename); } private void readHeader(File headerFile) throws IOException { BufferedReader reader = new BufferedReader(new FileReader(headerFile)); Map<String, String> properties = new HashMap<String, String>(); String line = reader.readLine(); while (line != null) { StringTokenizer tokens = new StringTokenizer(line); if (tokens.countTokens() == 2) { properties.put(tokens.nextToken(), tokens.nextToken()); } line = reader.readLine(); } ulxmap = Double.parseDouble(properties.get("ULXMAP")); ulymap = Double.parseDouble(properties.get("ULYMAP")); xdim = Double.parseDouble(properties.get("XDIM")); ydim = Double.parseDouble(properties.get("YDIM")); bounds = new Rectangle2D.Double(ulxmap - xdim / 2.0, ulymap + ydim / 2.0 - ydim * NROWS, xdim * NCOLS, ydim * NROWS); if (NROWS != Integer.parseInt(properties.get("NROWS"))) { throw new RuntimeException("Expected NROWS to be " + NROWS + " in header file " + headerFile); } if (NCOLS != Integer.parseInt(properties.get("NCOLS"))) { throw new RuntimeException("Expected NCOLS to be " + NCOLS + " in header file " + headerFile); } } void read(String sFile) { if (createImage) { image = new BufferedImage(NCOLS, NROWS, BufferedImage.TYPE_INT_RGB); } try { ImageInputStream iis = ImageIO.createImageInputStream(new File(sFile)); iis.setByteOrder(ByteOrder.BIG_ENDIAN); for (int y = 0; y < NROWS; y++) { iis.readFully(height[y], 0, NCOLS); if (createImage) { for (int x = 0; x < NCOLS; x++) { int color = height[y][x];//iis.readShort(); if (color == -9999) { image.setRGB(x, y, Color.blue.darker().getRGB()); } else { image.setRGB(x, y, colorFunction.getColor((float) color).getRGB()); } } } } } catch (Exception e) { e.printStackTrace(); } System.err.println(); } // read protected void paintComponent(Graphics g) { int nW = getWidth(); int nH = getHeight(); g.drawImage(image, 0, 0, nW, nH, 0, 0, NCOLS, NROWS, null); } /** * @param y latitudinal pixel, increasing south from north edge * @param x longitudinal pixel index, increasing east from west edge * @return the height of the pixel at y,x */ public short getHeight(int y, int x) { return height[y][x]; } boolean contains(double longitude, double latitude) { return bounds.contains(longitude, latitude); } public int getMinLongitude() { return (int) Math.round(bounds.getMinX()); } public int getMaxLongitude() { return (int) Math.round(bounds.getMaxX()); } public int getMinLatitude() { return (int) Math.round(bounds.getMinY()); } public int getMaxLatitude() { return (int) Math.round(bounds.getMaxY()); } }