/*
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);
    }

}

 

Ads help maintain this website.