/* 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.meteorology; import visad.*; import java.rmi.RemoteException; import visad.util.DataUtility; /** * Implementation of an ImageSequence. The images in this Field are * sorted by time. */ public class ImageSequenceImpl extends FieldImpl implements ImageSequence { //SingleBandedImage[] images; /** * Create an image sequence with the specified FunctionType. * * @param type new type for the sequence. The FunctionType of all * the images must be the same as the range of type * and the domain must be RealType.Time. * @param images array of images to be in the sequence * * @throws VisADException not the correct MathType or images have different * MathTypes. * @throws RemoteException couldn't create the remote object */ public ImageSequenceImpl(FunctionType type, SingleBandedImage[] images) throws VisADException, RemoteException { super(ensureFunctionType(type), makeDomainSet(images)); //this.images = images; FunctionType rangeType = (FunctionType) type.getRange(); for (int i = 0; i < images.length; i++) { RealTuple timeTuple = new RealTuple(new Real[] {images[i].getStartTime()}); FunctionType imageRange = (FunctionType) images[i].getType(); SingleBandedImage image = (imageRange.equals(rangeType)) ? images[i] : (SingleBandedImage) images[i].changeMathType(rangeType); setSample(timeTuple, image, false); } } /** * Create an image sequence from an array of images * * @param images array of images to be in the sequence. The FunctionType * of all the images must be the same. * * @throws VisADException images have different FunctionTypes. * @throws RemoteException couldn't create the remote object */ public ImageSequenceImpl(SingleBandedImage[] images) throws VisADException, RemoteException { this( new FunctionType(RealType.Time, (FunctionType) images[0].getType()), images); } private static SampledSet makeDomainSet(SingleBandedImage[] images) throws VisADException, RemoteException { if (images == null) throw new VisADException("images can't be null"); DateTime[] startTimes = new DateTime[images.length]; for (int i = 0; i < images.length; i++) { startTimes[i] = images[i].getStartTime(); } return (startTimes.length > 1) ? (SampledSet) DateTime.makeTimeSet(startTimes) : (SampledSet) new SingletonSet(new RealTuple(new Real[] {startTimes[0]})); } /** * Return the list of times associated with this sequence. * @return array of image start times. */ public DateTime[] getImageTimes() throws VisADException { DateTime[] times = null; if (getDomainSet().getLength() > 1) times = DateTime.timeSetToArray( (Gridded1DDoubleSet) getDomainSet()); else times = new DateTime[] {new DateTime( ((SingletonSet) getDomainSet()).getDoubles()[0][0])}; return times == null ? new DateTime[0] : times; } /** * Return the number of images in the sequence. * @return number of images */ public int getImageCount() throws VisADException { return ((SampledSet) getDomainSet()).getLength(); } /** * Get the image at the specified time * @param dt image time * @return single banded image at that time. * @throws VisADException no image in the sequence at the requested time */ public SingleBandedImage getImage(DateTime dt) throws VisADException, RemoteException { return (SingleBandedImage) evaluate(dt); } /** * Return the image at the index'th position in the sequence. * @param index in the sequence * @return single banded image at that index * @throws VisADException no image in the sequence at the requested index */ public SingleBandedImage getImage(int index) throws VisADException, RemoteException { return (SingleBandedImage) getSample(index); } private static FunctionType ensureFunctionType(FunctionType type) throws VisADException { if (type.getDomain().equals( DataUtility.ensureRealTupleType(RealType.Time)) && type.getRange() instanceof FunctionType && ((RealTupleType) ((FunctionType) type.getRange()).getFlatRange()).getDimension() == 1) return type; else throw new VisADException( "Not a valid ImageSequence type: " + type); } }