// // Vis5DTopoForm.java // /* VisAD system for interactive analysis and visualization of numerical data. Copyright (C) 1996 - 2017 Bill Hibbard, Curtis Rueden, Tom Rink, Dave Glowacki, Steve Emmerson, Tom Whittaker, Don Murray, and Tommy Jasmin. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ package visad.data.vis5d; import visad.*; import visad.data.*; import java.io.*; import java.net.URL; import java.rmi.RemoteException; /** Vis5DTopoForm is the VisAD data format adapter for Vis5D topography files.<P> */ public class Vis5DTopoForm extends Form implements FormFileInformer { private static int num = 0; /** * Create a new Vis5DTopoForm */ public Vis5DTopoForm() { super("Vis5DTopoForm" + num++); } /** * Check to see if the file name might be right for this form. * @param name name of the file * @return true if it might be a Vis5D topography file based on the name. */ public boolean isThisType(String name) { return name.endsWith(".v5d") || name.endsWith("TOPO"); } /** * Check to see if the block contains the magic number * @param block block of bytes from file * @return true if the first 4 bytes correspond to "TOPO" */ public boolean isThisType(byte[] block) { String topo = new String(block, 0, 4); return topo.equals("TOPO"); } /** * Get default suffixes for Vis5D topography files * @return array of suffixes (.v5d, .TOPO) */ public String[] getDefaultSuffixes() { String[] suff = { "v5d", "TOPO" }; return suff; } /** * Save a VisAD data object in this form. * @param id file id * @param data Data object to save * @param replace true to replace the existing file * @throws UnimplementedException not implemented for this form */ public synchronized void save(String id, Data data, boolean replace) throws BadFormException, IOException, RemoteException, VisADException { throw new UnimplementedException("Vis5DTopoForm.save"); } /** * Add data to an existing data object. * @param id file id * @param data Data object to append to * @param replace true to replace the existing file * @throws BadFormException not applicable to this form */ public synchronized void add(String id, Data data, boolean replace) throws BadFormException { throw new BadFormException("Vis5DTopoForm.add"); } /** * Return the data forms that are compatible with a data object. * @param data Data object in question * @return null for this Form since it doesn't support save. */ public synchronized FormNode getForms(Data data) { return null; } /** * Returns a VisAD data object corresponding to a URL pointing to a * Vis5D topography file. * * @param url URL pointing to the Vis5D topography * @return A VisAD data object corresponding to the Vis5D * topography file. * @throws BadFormException if not a Vis5D topo file. * @throws VisADException if a problem occurs in core VisAD. Probably a * VisAD object couldn't be created. * @throws IOException if an I/O failure occurs. */ public synchronized DataImpl open(URL url) throws BadFormException, VisADException, IOException { return open(url.openStream()); } /** * Returns a VisAD data object corresponding to a Vis5D topography file. * * @param id path to the existing Vis5D file. * @return A VisAD data object corresponding to the Vis5D * dataset. * @throws BadFormException if not a Vis5D topo file. * @throws VisADException if a problem occurs in core VisAD. Probably a * VisAD object couldn't be created. * @throws IOException if an I/O failure occurs. */ public synchronized DataImpl open(String id) throws BadFormException, IOException, VisADException { return open(new FileInputStream(id)); } /** * Returns a VisAD data object corresponding to an input stream for * a Vis5DTopography file. * * @param in Input stream * @return A VisAD data object corresponding to the Vis5D * topo file. * @throws BadFormException if not a Vis5D topo file. * @throws VisADException if a problem occurs in core VisAD. Probably a * VisAD object couldn't be created. * @throws IOException if an I/O failure occurs. */ public synchronized DataImpl open(InputStream in) throws BadFormException, IOException, VisADException { DataInputStream din = new DataInputStream (new BufferedInputStream(in)); byte[] type = new byte[40]; int ok = din.read(type, 0, 40); String header = new String(type); boolean oldStyle; if (header.startsWith("TOPO2")) { oldStyle = false; } else if (header.startsWith("TOPO")) { oldStyle = true; } else { throw new BadFormException("Vis5DTopoForm.open: not a Vis5D TOPO file"); } float westLon, eastLon, northLat, southLat; if (oldStyle) { westLon = din.readInt()/100.f; eastLon = din.readInt()/100.f; northLat = din.readInt()/100.f; southLat = din.readInt()/100.f; } else { westLon = din.readFloat(); eastLon = din.readFloat(); northLat = din.readFloat(); southLat = din.readFloat(); } int rows = din.readInt(); int cols = din.readInt(); /* System.out.println( "Bounds: " + "\n\tWestern Longitude = " + westLon + "\n\tEastern Longitude = " + eastLon + "\n\tNorthern Latitude = " + northLat + "\n\tSouthern Latitude = " + southLat + "\n\trows = " + rows + " cols = " + cols); */ Linear2DSet domain = new LinearLatLonSet(RealTupleType.SpatialEarth2DTuple, -westLon, -eastLon, cols, // Vis5D west positive northLat, southLat, rows); // Vis5D rows upside down FunctionType ftype = new FunctionType(((SetType)domain.getType()).getDomain(), RealType.Altitude); FlatField data = new FlatField(ftype, domain); float[][] samples = new float[1][rows*cols]; for (int i = 0; i < rows*cols; i++) { short s = (short) (din.readShort()/2); samples[0][i] = new Short(s).floatValue(); } data.setSamples(samples, false); return data; } }