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