001/*
002 * $Id: CoverageAnalyzer.java,v 1.4 2011/03/24 16:06:33 davep Exp $
003 *
004 * This file is part of McIDAS-V
005 *
006 * Copyright 2007-2011
007 * Space Science and Engineering Center (SSEC)
008 * University of Wisconsin - Madison
009 * 1225 W. Dayton Street, Madison, WI 53706, USA
010 * https://www.ssec.wisc.edu/mcidas
011 * 
012 * All Rights Reserved
013 * 
014 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and
015 * some McIDAS-V source code is based on IDV and VisAD source code.  
016 * 
017 * McIDAS-V is free software; you can redistribute it and/or modify
018 * it under the terms of the GNU Lesser Public License as published by
019 * the Free Software Foundation; either version 3 of the License, or
020 * (at your option) any later version.
021 * 
022 * McIDAS-V is distributed in the hope that it will be useful,
023 * but WITHOUT ANY WARRANTY; without even the implied warranty of
024 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
025 * GNU Lesser Public License for more details.
026 * 
027 * You should have received a copy of the GNU Lesser Public License
028 * along with this program.  If not, see http://www.gnu.org/licenses.
029 */
030
031//package jsattrak.coverage;
032package edu.wisc.ssec.mcidasv.data.adde.sgp4;
033
034import edu.wisc.ssec.mcidasv.data.GroundStations;
035
036import java.awt.Color;
037import java.awt.Graphics2D;
038import java.text.DecimalFormat;
039import java.text.NumberFormat;
040import java.util.Hashtable;
041import java.util.Vector;
042/*
043import jsattrak.gui.J2dEarthLabel2;
044import jsattrak.objects.AbstractSatellite;
045import jsattrak.objects.GroundStation;
046import name.gano.astro.GeoFunctions;
047import name.gano.astro.time.Time;
048*/
049
050/**
051 *
052 * @author Shawn
053 */
054//public class CoverageAnalyzer implements JSatTrakRenderable,JSatTrakTimeDependent
055public class CoverageAnalyzer
056{
057    // data arrays
058    private  double[][] coverageCumTime;  // cumulative coverage time array [latPanels x longPanels] in days
059     // in degrees
060    private double[] latPanelMidPoints; // middle point latitude of each division/panel
061    private double[] lonPanelMidPoints; // middle point longitude of each division/panel
062    private double[] latGridPoints; // grid end points for latitude
063    private double[] lonGridPoints; // grid end points for longitude
064   
065    private double minNotZeroVal = 1;  // current maximum and minimum (NOT ZERO) values 
066    private double maxVal = 100;
067    
068    private Time startTime = new Time(); // keep track of start time
069    
070    // color map for data
071    //ColorMap colorMap = new ColorMap();
072    
073    private double lastMJD = -1; // last MJD update time
074    
075    Vector<String> satsUsedInCoverage = new Vector<String>(); // vector of satellites used in Coverage anaylsis
076    
077    // settings ===========
078    // grid sizing >=1
079    private int latPanels = 36; //72;//36; //18// number of divisons along lines of latitude (grid points -1)
080    private int longPanels = 72;  //144;//72; //36 // number of divisions along lines of longitude (grid points -1)
081    
082    // in degrees
083    private double[] latBounds = {-90.0, 90.0}; // minimum,maxium latitude to use in coverage anaylsis
084    private double[] longBounds = {-180.0, 180.0}; // minimum,maxium longitude to use in coverage anaylsis
085    
086    private int alpha = 150; //151; // tranparency of colored panels, 0=can't see it, 255=solid
087    
088    private boolean dynamicUpdating = true; // if dynamic updating from GUI time stepping is enabled
089    private boolean plotCoverageGrid = false; // plot panel grid and center points of panels
090    private double elevationLimit = 15; //15; // elevation limit for ground coverage [degrees] (must be higher for this to count as coverage
091    private NumberFormat colorBarNumberFormat = new DecimalFormat("0.00E0");
092    private boolean showColorBar = true; // Color bar settings
093    private int pixelsFromBottom = 20;
094    private int pixelsFromLeft = 20;
095    private int colorBarLen = 100;
096    private int colorBarHeight = 10;
097    private int colorBarTextSpacing = 5;
098    private // pixels below bar where text is displayed
099    Color colorbarBGcolor = new Color(255, 255, 255, 180);
100    private Color colorBarTextcolor = Color.BLACK;
101    
102    // default constructor
103    public CoverageAnalyzer()
104    {
105        iniParamters();
106    } // constructor
107    
108    /**
109     * Constructor with current time - this will allow coverage to start on next time step
110     * @param currentJulianDate current Julian Date
111     */
112    public CoverageAnalyzer(final Time currentJulianDate)
113    {
114        iniParamters();
115        lastMJD = currentJulianDate.getMJD();
116        startTime.set(currentJulianDate.getCurrentGregorianCalendar().getTimeInMillis());        
117    }
118    
119//    /**
120//     * NEEDS TO INCLUDE - SATS INTO VECTOR BEFORE THIS WILL WORK PROPERLY
121//     * Constructor with current time and current time step - this will allow coverage anaylsis to immediately start
122//     * @param currentJulianDate current Julian Date
123//     * @param timeStepDays time step to be used in days
124//     * @param satHash Hashtable of current satellites
125//     */
126//    public CoverageAnalyzer(final Time currentJulianDate, double timeStepDays, final Hashtable<String,AbstractSatellite> satHash)
127//    {
128//        iniParamters();
129//        lastMJD = currentJulianDate.getMJD()-timeStepDays;
130//        
131//        performCoverageAnalysis(currentJulianDate, satHash);
132//    }
133    
134    /**
135     * Clear coverage data and initalizie update time for next simulation step
136     * @param currentJulianDate
137     */
138    public void clearCoverageData(final Time currentJulianDate)
139    {
140        iniParamters();
141        lastMJD = currentJulianDate.getMJD();
142        startTime.set(currentJulianDate.getCurrentGregorianCalendar().getTimeInMillis());
143    }
144    
145    /**
146     * Clears the coverage data and resets last update date
147     */
148    public void clearCoverageData()
149    {
150        iniParamters();
151    }
152    
153    // initalized all parameters (used at class construction to create all arrays, etc)
154    private void iniParamters()
155    {
156        // cumulative time create new array (default 0)
157        coverageCumTime = new double[latPanels][longPanels];
158        // mid points
159        latPanelMidPoints = new double[latPanels];
160        lonPanelMidPoints = new double[longPanels];
161        // grid points
162        latGridPoints = new double[latPanels+1];
163        lonGridPoints = new double[longPanels+1];
164        
165        // calulate grid points, mid points
166        for(int i=0;i<latPanels+1;i++)
167        {
168            latGridPoints[i] = i*(latBounds[1]-latBounds[0])/(latPanels)+latBounds[0];
169            if(i>0)
170            {
171                latPanelMidPoints[i-1] = (getLatGridPoints()[i]+getLatGridPoints()[i-1])/2.0;
172            }
173        }
174        for(int i=0;i<longPanels+1;i++)
175        {
176            lonGridPoints[i] = i*(longBounds[1]-longBounds[0])/(longPanels)+longBounds[0];
177            if(i>0)
178            {
179                lonPanelMidPoints[i-1] = (getLonGridPoints()[i]+getLonGridPoints()[i-1])/2.0;
180            }
181        }
182        
183        // clear last mjd update
184        lastMJD = -1;
185        
186    }// iniParamters
187    
188    // test main function
189    public static void main(String[] args)
190    {
191        CoverageAnalyzer ca = new CoverageAnalyzer();
192    } // main
193    
194    
195    /**
196     *  Performa an update of time and data of Coverage Metrics
197     * @param currentJulianDate
198     * @param satHash
199     * @param gsHash
200     */
201/*
202    @Override
203    public void updateTime(final Time currentJulianDate, final Hashtable<String,AbstractSatellite> satHash, final Hashtable<String,GroundStation> gsHash)
204    {
205        if(!dynamicUpdating)
206        {
207            return; // don't update converage anlysis from JSatTrack GUI
208        }
209        
210        performCoverageAnalysis(currentJulianDate,satHash); // do the analysis
211        
212    } // updateTime
213*/ 
214    // internal function to actually perform the anaylsis - so it can be used by GUI update calls or coverage tool
215    /**
216     * Performs coverage anaylsis with given time and satellite array, this fuction should be called only when directly performing coverage analysis, otherwise call updateTime
217     * @param currentJulianDate
218     * @param satHash
219     */
220    public void performCoverageAnalysis(final Time currentJulianDate, final Hashtable<String,AbstractSatellite> satHash)
221    {
222        // if first time update, save time and quit (only start calc after first time step)
223        if(lastMJD == -1)
224        {
225            lastMJD = currentJulianDate.getMJD();
226            startTime.set(currentJulianDate.getCurrentGregorianCalendar().getTimeInMillis());
227            return;
228        }
229        
230        // check time make sure this time is past when the last time update was 
231        if(currentJulianDate.getMJD() <= lastMJD)
232        {
233            return; // do nothing as this time is later
234        }
235        // calc time diff, and save time
236        double timeDiffDays = currentJulianDate.getMJD() - lastMJD;
237        lastMJD = currentJulianDate.getMJD();
238        
239        // create temp array for time cumlation (so we don't double count sat coverage)
240        // each panel either has access or it doesn't for the current time step -- boolean 
241        boolean[][] tempAcessArray = new boolean[latPanels][longPanels];
242        
243        // === do coverage anaylsis, for each satellite ===
244        for(String satName : satsUsedInCoverage)
245        {
246            // get sat Object
247            AbstractSatellite currentSat = satHash.get(satName);
248            
249            // check to see if satellite is in lat/long AOI coverage box
250            if(currentSat.getLatitude()*180/Math.PI  >= latBounds[0]  && 
251               currentSat.getLatitude()*180/Math.PI  <= latBounds[1]  &&
252               currentSat.getLongitude()*180/Math.PI >= longBounds[0] &&
253               currentSat.getLongitude()*180/Math.PI <= longBounds[1]    )
254            {
255                
256                // find closest panel under satellite and the index of that panel
257                double latPercentile = (currentSat.getLatitude()*180/Math.PI-latBounds[0]) / (latBounds[1]-latBounds[0]);
258                int latIndex = (int)Math.floor(latPercentile*latPanels);
259                double longPercentile = (currentSat.getLongitude()*180/Math.PI-longBounds[0]) / (longBounds[1]-longBounds[0]);
260                int longIndex = (int)Math.floor(longPercentile*longPanels);
261                
262                // Coverage assumes sat doesn't have a shaped sensor and it can look straight down (nadir)
263                // debug for now mark point as access added
264                double[] aer = new double[3];
265//                aer = GeoFunctions.calculate_AER(currentJulianDate.getJulianDate(), 
266//                        new double[]{latPanelMidPoints[latIndex],lonPanelMidPoints[longIndex],0},  // sea level
267//                        currentSat.getPosMOD());
268//                
269//                // see if sat sub-point panel has access (otherwise nothing does)
270//                if(aer[1] >= elevationLimit)
271//                {
272//                    tempAcessArray[latIndex][longIndex] = true; // can't assume access here!
273//                }
274                
275                // Search up=====================================================
276                // search upwards until no access (careful of lat >90)
277                int i = latIndex; // includes satellite sub point
278                double tempElevation2=0; // used in searching to the left and right
279                do
280                {
281                    // take care of when i >= latPanels (reflection for longitude index and make lat go down instead of up (and stay at top one iter)
282                    
283                    aer = GeoFunctions.calculate_AER(currentJulianDate.getJulianDate(), 
284                        new double[]{getLatPanelMidPoints()[i],getLonPanelMidPoints()[longIndex],0},  // sea level
285                        currentSat.getTEMEPos());
286                    
287                    if(aer[1] >= elevationLimit)
288                    {
289                        tempAcessArray[i][longIndex] = true;
290                        // search to the left =============================
291                        int j=longIndex-1;
292                        int longSearchCount = 0;
293                        int jWrappedIndex = j; // updated so seach can wrap around map
294                        do
295                        {
296                            // take car of i and j with wrap arounds
297                            if(j < 0)
298                            {
299                                jWrappedIndex = longPanels + j;
300                            }
301                            else if(j >= longPanels)
302                            {
303                                jWrappedIndex = j - longPanels;
304                            }
305                            else
306                            {
307                                jWrappedIndex = j;
308                            }
309                            
310                            tempElevation2 = GeoFunctions.calculate_AER(currentJulianDate.getJulianDate(), 
311                                new double[]{getLatPanelMidPoints()[i],getLonPanelMidPoints()[jWrappedIndex],0},  // sea level
312                                currentSat.getTEMEPos())[1];
313                            if(tempElevation2 >= elevationLimit)
314                            {
315                                tempAcessArray[i][jWrappedIndex] = true;
316                            }
317                            
318                            j--;
319                            longSearchCount++; // make sure we don't get stuck on seaching a row over and over
320                        }while(tempElevation2 >= elevationLimit && longSearchCount < longPanels); 
321                        // search to the left =============================
322                        // search to the Right =============================
323                        j=longIndex+1;
324                        longSearchCount = 0;
325                        jWrappedIndex = j; // updated so seach can wrap around map
326                        do
327                        {
328                            // take car of i and j with wrap arounds
329                            if(j < 0)
330                            {
331                                jWrappedIndex = longPanels + j;
332                            }
333                            else if(j >= longPanels)
334                            {
335                                jWrappedIndex = j - longPanels;
336                            }
337                            else
338                            {
339                                jWrappedIndex = j;
340                            }
341                            
342                            tempElevation2 = GeoFunctions.calculate_AER(currentJulianDate.getJulianDate(), 
343                                new double[]{getLatPanelMidPoints()[i],getLonPanelMidPoints()[jWrappedIndex],0},  // sea level
344                                currentSat.getTEMEPos())[1];
345                            if(tempElevation2 >= elevationLimit)
346                            {
347                                tempAcessArray[i][jWrappedIndex] = true;
348                            }
349                            
350                            j++;
351                            longSearchCount++; // make sure we don't get stuck on seaching a row over and over
352                        }while(tempElevation2 >= elevationLimit && longSearchCount < longPanels); 
353                        // search to the Right =============================
354                        
355                    }
356                    
357                    i++;
358                }while(aer[1] >= elevationLimit && i < latPanels); // do while - only search up to top of panel
359                // Search up=====================================================
360                // Search down=====================================================
361                // search down until no access (careful of lat >90)
362                i = latIndex - 1; // includes satellite sub point
363                tempElevation2 = 0; // used in searching to the left and right
364                if (i >= 0) // avoid searching down if i is already 0
365                {
366                    do
367                    {
368                        // take care of when i >= latPanels (reflection for longitude index and make lat go down instead of up (and stay at top one iter)
369                        aer = GeoFunctions.calculate_AER(currentJulianDate.getJulianDate(),
370                                new double[]
371                                {
372                                    getLatPanelMidPoints()[i], getLonPanelMidPoints()[longIndex], 0
373                                
374                                }, // sea level
375                                currentSat.getTEMEPos());
376
377                        if (aer[1] >= elevationLimit)
378                        {
379                            tempAcessArray[i][longIndex] = true;
380                            // search to the left =============================
381                            int j = longIndex - 1;
382                            int longSearchCount = 0;
383                            int jWrappedIndex = j; // updated so seach can wrap around map
384
385                            do
386                            {
387                                // take car of i and j with wrap arounds
388                                if (j < 0)
389                                {
390                                    jWrappedIndex = longPanels + j;
391                                }
392                                else if (j >= longPanels)
393                                {
394                                    jWrappedIndex = j - longPanels;
395                                }
396                                else
397                                {
398                                    jWrappedIndex = j;
399                                }
400
401                                tempElevation2 = GeoFunctions.calculate_AER(currentJulianDate.getJulianDate(),
402                                        new double[] {getLatPanelMidPoints()[i], getLonPanelMidPoints()[jWrappedIndex], 0}, // sea level
403                                        currentSat.getTEMEPos())[1];
404                                if (tempElevation2 >= elevationLimit)
405                                {
406                                    tempAcessArray[i][jWrappedIndex] = true;
407                                }
408
409                                j--;
410                                longSearchCount++; // make sure we don't get stuck on seaching a row over and over
411                            }while (tempElevation2 >= elevationLimit && longSearchCount < longPanels);
412                            // search to the left =============================
413                            // search to the Right =============================
414                            j = longIndex + 1;
415                            longSearchCount = 0;
416                            jWrappedIndex = j; // updated so seach can wrap around map
417                            do
418                            {
419                                // take car of i and j with wrap arounds
420                                if (j < 0)
421                                {
422                                    jWrappedIndex = longPanels + j;
423                                }
424                                else if (j >= longPanels)
425                                {
426                                    jWrappedIndex = j - longPanels;
427                                }
428                                else
429                                {
430                                    jWrappedIndex = j;
431                                }
432                                
433                                tempElevation2 = GeoFunctions.calculate_AER(currentJulianDate.getJulianDate(),
434                                        new double[]{getLatPanelMidPoints()[i], getLonPanelMidPoints()[jWrappedIndex], 0}, // sea level
435                                        currentSat.getTEMEPos())[1];
436                                if (tempElevation2 >= elevationLimit)
437                                {
438                                    tempAcessArray[i][jWrappedIndex] = true;
439                                }
440
441                                j++;
442                                longSearchCount++; // make sure we don't get stuck on seaching a row over and over
443                            }
444                            while (tempElevation2 >= elevationLimit && longSearchCount < longPanels);
445                        // search to the Right =============================
446
447                        } // if in elecation limit
448
449                        i--;
450                    }while (aer[1] >= elevationLimit && i >= 0); // do while
451                } // if already at 0 no need to search down
452                // Search down=====================================================
453                
454                
455            }// sat is in coverage AOI           
456        } // for each satellite - Coverage anaylsis
457        
458        // merge temp and timecumarray // and update max and min values
459        minNotZeroVal = Double.MAX_VALUE; // really high to start
460        maxVal = -1; // really low to start
461        for(int i=0;i<latPanels;i++) 
462        {
463            for(int j=0;j<longPanels;j++)
464            {
465                // DEBUG CLEAR VALUE SO ONLY POINTS CURRENTLY IN VIEW SHOW UP
466                //coverageCumTime[i][j] = 0;
467                
468                if(tempAcessArray[i][j])
469                {
470                    coverageCumTime[i][j] += timeDiffDays;
471                } // if access at this point
472                
473                // update max and min
474                if(getCoverageCumTime()[i][j] > maxVal)
475                {
476                    maxVal = getCoverageCumTime()[i][j];
477                }
478                if(getCoverageCumTime()[i][j] < minNotZeroVal && getCoverageCumTime()[i][j] > 0)
479                {
480                   minNotZeroVal =  getCoverageCumTime()[i][j];
481                }
482                
483            } // long panels (j)
484        } // lat panels (i) (merge data)
485        
486
487        
488    } // performCoverageAnalysis
489/*
490    // draw 2d
491    public void draw2d(Graphics2D g2, J2dEarthLabel2 earthLabel, int totWidth, int totHeight, int imgWidth, int imgHeight, double zoomFac, double cLat, double cLong)
492    {
493        int[] xy = new int[2];
494        int[] xy_old = new int[2];
495        
496        // draw in grid lines for lat and long of coverage area
497        if (plotCoverageGrid)
498        {
499            g2.setColor(new Color(0.0f, 1.0f, 0.0f, 0.2f));
500            for (double lat : getLatGridPoints())
501            {
502                xy = earthLabel.findXYfromLL(lat, longBounds[0], totWidth, totHeight, imgWidth, imgHeight, zoomFac, cLat, cLong);
503                xy_old = earthLabel.findXYfromLL(lat, longBounds[1], totWidth, totHeight, imgWidth, imgHeight, zoomFac, cLat, cLong);
504
505                g2.drawLine(xy_old[0], xy_old[1], xy[0], xy[1]); // draw a line across the map
506
507            }
508            g2.setColor(new Color(0.0f, 1.0f, 0.0f, 0.2f));
509            for (double lon : getLonGridPoints())
510            {
511                xy = earthLabel.findXYfromLL(latBounds[0], lon, totWidth, totHeight, imgWidth, imgHeight, zoomFac, cLat, cLong);
512                xy_old = earthLabel.findXYfromLL(latBounds[1], lon, totWidth, totHeight, imgWidth, imgHeight, zoomFac, cLat, cLong);
513
514                g2.drawLine(xy_old[0], xy_old[1], xy[0], xy[1]); // draw a line across the map
515
516            }
517            // draw center points
518            g2.setColor(new Color(0.0f, 1.0f, 0.0f, 0.2f));
519            int dotSize = 1;
520            for (double lat : getLatPanelMidPoints())
521            {
522                for (double lon : getLonPanelMidPoints())
523                {
524                    xy = earthLabel.findXYfromLL(lat, lon, totWidth, totHeight, imgWidth, imgHeight, zoomFac, cLat, cLong);
525
526                    g2.drawRect(xy[0] - dotSize / 2, xy[1] - dotSize / 2, dotSize, dotSize);
527                }
528            }
529        } // graw grid and center points
530        // fill in color scaled panels based on cumulative Coverage time
531        // should combine with above... just use alpha =0.0 when panel is blank
532        int xmax, xmin, ymax, ymin;
533        for(int i=0;i<getLatPanelMidPoints().length;i++)
534        {
535            for(int j=0;j<getLonPanelMidPoints().length;j++)
536            {
537                xy = earthLabel.findXYfromLL(getLatGridPoints()[i], getLonGridPoints()[j],totWidth,totHeight,imgWidth,imgHeight,zoomFac,cLat,cLong);
538                xy_old = earthLabel.findXYfromLL(getLatGridPoints()[i+1], getLonGridPoints()[j+1],totWidth,totHeight,imgWidth,imgHeight,zoomFac,cLat,cLong);
539                
540                xmax = Math.max(xy[0], xy_old[0]);
541                xmin = Math.min(xy[0], xy_old[0]);
542                ymax = Math.max(xy[1], xy_old[1]);
543                ymin = Math.min(xy[1], xy_old[1]);
544                
545                // color based on: coverageCumTime[i][j]
546                // dummy way for now black or white
547                if(getCoverageCumTime()[i][j]>0)
548                {
549                    g2.setColor( colorMap.getColor(getCoverageCumTime()[i][j], minNotZeroVal, maxVal, alpha)  );
550                    g2.fillRect(xmin, ymin, xmax-xmin,ymax-ymin);//xy_old[0]-xy[0], xy_old[1]-xy[1]);
551                }
552                else
553                {
554                    // don't draw anything
555                }
556                
557            } // for lon panels
558        } // for lat panels
559        
560        // Draw color bar if wanted!!
561        if(showColorBar)
562        {
563            // colorbar background
564            g2.setColor( colorbarBGcolor );
565            g2.fillRect(pixelsFromLeft-5, totHeight-pixelsFromBottom-colorBarHeight-3, colorBarLen+12+30, colorBarHeight+colorBarTextSpacing+15);
566            
567            // color bar specturm
568            for(int i=0;i<colorBarLen;i++)
569            {
570                g2.setColor( colorMap.getColor(i, 0, colorBarLen, 255) );
571                g2.drawLine(pixelsFromLeft+i, totHeight-pixelsFromBottom, pixelsFromLeft+i, totHeight-pixelsFromBottom-colorBarHeight);
572            }
573            
574            // color bar labeling
575            // 0 %
576            int textHeight = 10;
577            g2.setColor( colorBarTextcolor );
578            g2.drawLine(pixelsFromLeft-1, totHeight-pixelsFromBottom+colorBarTextSpacing, pixelsFromLeft-1,totHeight-pixelsFromBottom-colorBarHeight);
579            g2.drawString(colorBarNumberFormat.format(minNotZeroVal*24*60*60) + " sec", pixelsFromLeft-1, totHeight-pixelsFromBottom+colorBarTextSpacing+textHeight);
580            
581            // at 100%
582            g2.setColor( Color.BLACK );
583            g2.drawLine(pixelsFromLeft+colorBarLen, totHeight-pixelsFromBottom+colorBarTextSpacing, pixelsFromLeft+colorBarLen,totHeight-pixelsFromBottom-colorBarHeight);
584            g2.drawString(colorBarNumberFormat.format(maxVal*24*60*60), pixelsFromLeft+colorBarLen, totHeight-pixelsFromBottom+colorBarTextSpacing+textHeight);
585            
586        } // showColorBar
587        
588    } // draw 2d
589    
590    // draw 3d
591    public void draw3d()
592    {
593        
594    } // draw 3d
595*/ 
596    // Settings ==================================
597    
598    public void addSatToCoverageAnaylsis(String satName)
599    {
600        // first check to make sure sat isn't already in list
601        for(String name : satsUsedInCoverage)
602        {
603            if(satName.equalsIgnoreCase(name))
604            {
605                return; // already in the list
606            }
607        }
608        
609        satsUsedInCoverage.add(satName);
610    } // addSatToCoverageAnaylsis
611    
612    public void clearSatCoverageVector()
613    {
614        satsUsedInCoverage.clear();
615    }
616    
617    public void removeSatFromCoverageAnaylsis(String satName)
618    {
619        // make sure name is in the Vector
620        int i=0; // counter
621        for(String name : satsUsedInCoverage)
622        {
623            if(satName.equalsIgnoreCase(name))
624            {
625                satsUsedInCoverage.remove(i);
626                return; // already in the list
627            }
628            i++;
629        }
630    } // removeSatFromCoverageAnaylsis
631    
632    public Vector<String> getSatVector()
633    {
634        return satsUsedInCoverage;
635    }
636    
637    // ======================================================
638/*
639    public void setColorMap(ColorMap colorMap)
640    {
641        this.colorMap = colorMap;
642    }
643    
644    public ColorMap getColorMap()
645    {
646        return colorMap;
647    }
648*/
649    public int getLatPanels()
650    {
651        return latPanels;
652    }
653
654    public void setLatPanels(int latPanels)
655    {
656        this.latPanels = latPanels;
657    }
658
659    public int getLongPanels()
660    {
661        return longPanels;
662    }
663
664    public void setLongPanels(int longPanels)
665    {
666        this.longPanels = longPanels;
667    }
668
669    public double[] getLatBounds()
670    {
671        return latBounds;
672    }
673
674    public void setLatBounds(double[] latBounds)
675    {
676        this.latBounds = latBounds;
677    }
678
679    public double[] getLongBounds()
680    {
681        return longBounds;
682    }
683
684    public void setLongBounds(double[] longBounds)
685    {
686        this.longBounds = longBounds;
687    }
688
689    public int getAlpha()
690    {
691        return alpha;
692    }
693
694    public void setAlpha(int alpha)
695    {
696        this.alpha = alpha;
697    }
698
699    public boolean isDynamicUpdating()
700    {
701        return dynamicUpdating;
702    }
703
704    public void setDynamicUpdating(boolean dynamicUpdating)
705    {
706        this.dynamicUpdating = dynamicUpdating;
707    }
708
709    public boolean isPlotCoverageGrid()
710    {
711        return plotCoverageGrid;
712    }
713
714    public void setPlotCoverageGrid(boolean plotCoverageGrid)
715    {
716        this.plotCoverageGrid = plotCoverageGrid;
717    }
718
719    public double getElevationLimit()
720    {
721        return elevationLimit;
722    }
723
724    public void setElevationLimit(double elevationLimit)
725    {
726        this.elevationLimit = elevationLimit;
727    }
728
729    public NumberFormat getColorBarNumberFormat()
730    {
731        return colorBarNumberFormat;
732    }
733
734    public void setColorBarNumberFormat(NumberFormat colorBarNumberFormat)
735    {
736        this.colorBarNumberFormat = colorBarNumberFormat;
737    }
738
739    public boolean isShowColorBar()
740    {
741        return showColorBar;
742    }
743
744    public void setShowColorBar(boolean showColorBar)
745    {
746        this.showColorBar = showColorBar;
747    }
748
749    public int getPixelsFromBottom()
750    {
751        return pixelsFromBottom;
752    }
753
754    public void setPixelsFromBottom(int pixelsFromBottom)
755    {
756        this.pixelsFromBottom = pixelsFromBottom;
757    }
758
759    public int getPixelsFromLeft()
760    {
761        return pixelsFromLeft;
762    }
763
764    public void setPixelsFromLeft(int pixelsFromLeft)
765    {
766        this.pixelsFromLeft = pixelsFromLeft;
767    }
768
769    public int getColorBarLen()
770    {
771        return colorBarLen;
772    }
773
774    public void setColorBarLen(int colorBarLen)
775    {
776        this.colorBarLen = colorBarLen;
777    }
778
779    public int getColorBarHeight()
780    {
781        return colorBarHeight;
782    }
783
784    public void setColorBarHeight(int colorBarHeight)
785    {
786        this.colorBarHeight = colorBarHeight;
787    }
788
789    public int getColorBarTextSpacing()
790    {
791        return colorBarTextSpacing;
792    }
793
794    public void setColorBarTextSpacing(int colorBarTextSpacing)
795    {
796        this.colorBarTextSpacing = colorBarTextSpacing;
797    }
798
799    public Color getColorbarBGcolor()
800    {
801        return colorbarBGcolor;
802    }
803
804    public void setColorbarBGcolor(Color colorbarBGcolor)
805    {
806        this.colorbarBGcolor = colorbarBGcolor;
807    }
808
809    public Color getColorBarTextcolor()
810    {
811        return colorBarTextcolor;
812    }
813
814    public void setColorBarTextcolor(Color colorBarTextcolor)
815    {
816        this.colorBarTextcolor = colorBarTextcolor;
817    }
818
819    public double[][] getCoverageCumTime()
820    {
821        return coverageCumTime;
822    }
823
824    public double[] getLatPanelMidPoints()
825    {
826        return latPanelMidPoints;
827    }
828
829    public double[] getLonPanelMidPoints()
830    {
831        return lonPanelMidPoints;
832    }
833
834    public double[] getLatGridPoints()
835    {
836        return latGridPoints;
837    }
838
839    public double[] getLonGridPoints()
840    {
841        return lonGridPoints;
842    }
843/*
844    public Color getColorForIndex(int i, int j)
845    {
846        return colorMap.getColor(getCoverageCumTime()[i][j], minNotZeroVal, maxVal);
847    }
848*/
849    public double getMinNotZeroVal()
850    {
851        return minNotZeroVal;
852    }
853
854    public double getMaxVal()
855    {
856        return maxVal;
857    }
858    
859    public String getLowerBoundLabel()
860    {
861        return colorBarNumberFormat.format(minNotZeroVal*24*60*60) + " sec";
862    }
863    
864    public String getUpperBoundLabel()
865    {
866        return colorBarNumberFormat.format(maxVal*24*60*60);
867    }
868
869    public Time getStartTime() {
870        return startTime;
871    }
872
873    public double getLastMJD() {
874        return lastMJD;
875    }
876    
877} // CoverageAnalyzer