001/* 002 * $Id: PolarOrbitTrackControl.java,v 1.25 2011/03/24 16:06:32 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 031package edu.wisc.ssec.mcidasv.control; 032 033import edu.wisc.ssec.mcidasv.data.GroundStations; 034import edu.wisc.ssec.mcidasv.data.PolarOrbitTrackDataSource; 035import edu.wisc.ssec.mcidasv.data.adde.sgp4.AstroConst; 036import edu.wisc.ssec.mcidasv.data.hydra.CurveDrawer; 037import edu.wisc.ssec.mcidasv.util.McVGuiUtils; 038import edu.wisc.ssec.mcidasv.util.McVGuiUtils.Position; 039 040import java.awt.Color; 041import java.awt.Component; 042import java.awt.Container; 043import java.awt.Dimension; 044import java.awt.Insets; 045import java.awt.event.ActionEvent; 046import java.awt.event.ActionListener; 047import java.awt.event.FocusEvent; 048import java.awt.event.FocusListener; 049import java.awt.event.KeyEvent; 050import java.awt.event.KeyListener; 051import java.lang.Math; 052import java.rmi.RemoteException; 053import java.util.ArrayList; 054import java.util.List; 055 056import javax.swing.JComboBox; 057import javax.swing.JComponent; 058import javax.swing.JLabel; 059import javax.swing.JPanel; 060import javax.swing.JSlider; 061import javax.swing.JTextField; 062import javax.swing.event.ChangeEvent; 063import javax.swing.event.ChangeListener; 064 065import org.slf4j.Logger; 066import org.slf4j.LoggerFactory; 067 068import ucar.unidata.data.DataChoice; 069import ucar.unidata.data.DataInstance; 070import ucar.unidata.data.DataSourceImpl; 071import ucar.unidata.idv.control.DisplayControlImpl; 072//import ucar.unidata.idv.control.ZSlider; 073import ucar.unidata.ui.LatLonWidget; 074import ucar.unidata.util.GuiUtils; 075import ucar.unidata.util.GuiUtils.ColorSwatch; 076import ucar.unidata.util.PreferenceList; 077import ucar.unidata.view.geoloc.NavigatedDisplay; 078import ucar.visad.display.CompositeDisplayable; 079import ucar.visad.display.Displayable; 080import ucar.visad.display.TextDisplayable; 081 082import visad.Data; 083import visad.DisplayRealType; 084import visad.Gridded2DSet; 085import visad.MathType; 086import visad.RealTuple; 087import visad.RealTupleType; 088import visad.SampledSet; 089import visad.Text; 090import visad.TextControl; 091import visad.TextControl.Justification; 092import visad.TextType; 093import visad.Tuple; 094import visad.TupleType; 095import visad.UnionSet; 096import visad.VisADException; 097import visad.georef.EarthLocation; 098import visad.georef.EarthLocationTuple; 099import visad.georef.LatLonPoint; 100import visad.georef.LatLonTuple; 101 102/** 103 * {@link ucar.unidata.idv.control.PolarOrbitTrackControl} with some McIDAS-V 104 * specific extensions. Namely parameter sets and support for inverted 105 * parameter defaults. 106 */ 107public class PolarOrbitTrackControl extends DisplayControlImpl { 108 109 private static final Logger logger = LoggerFactory.getLogger(PolarOrbitTrackControl.class); 110 111 /** The spacing used in the grid layout */ 112 protected static final int GRID_SPACING = 3; 113 114 /** Used by derived classes when they do a GuiUtils.doLayout */ 115 protected static final Insets GRID_INSETS = new Insets(GRID_SPACING, 116 GRID_SPACING, 117 GRID_SPACING, 118 GRID_SPACING); 119 /** 120 * position slider 121 */ 122// private ZSlider levelSlider = null; 123 private double latitude; 124 private double longitude; 125 private double altitude; 126 private JPanel fontSizePanel; 127 private JPanel colorPanel; 128 private JPanel antColorPanel; 129 private JPanel locationPanel; 130 private JPanel latLonAltPanel; 131 132 private int locationIndex = -1; 133 private List stations; 134 private List lats; 135 private List lons; 136 private List alts; 137 138 /** Property name to get the list or urls */ 139 public final String PREF_GROUNDSTATIONS = "mcv.groundstations"; 140 141 /** Manages the pull down list of urls */ 142 private static PreferenceList prefList; 143 144 private JComboBox locationComboBox; 145 private JTextField locationEditor; 146 147 private String station = ""; 148 private TextDisplayable groundStationDsp; 149 150 private static final int defaultAntAngle = 5; 151 private int angle = defaultAntAngle; 152 153 /** Input for lat/lon center point */ 154 protected LatLonWidget latLonWidget = new LatLonWidget(); 155 156 private JTextField latFld; 157 private JTextField lonFld; 158 private JTextField altitudeFld = new JTextField(" ", 5); 159 private JTextField antennaAngle = new JTextField(" 5", 5); 160 161// private ChangeListener sizeListener; 162 private ActionListener fontSizeChange; 163 private FocusListener fontSizeFocusChange; 164 165 /** Font size control */ 166 private static final int SLIDER_MAX = 10; 167 private static final int SLIDER_MIN = 1; 168 private static final int SLIDER_WIDTH = 150; 169 private static final int SLIDER_HEIGHT = 16; 170 171 private JSlider fontSizeSlider; 172 private JTextField fontSizeFld = new JTextField(); 173 174 private CompositeDisplayable trackDsp; 175 private CompositeDisplayable circleDsp; 176 private static final TupleType TUPTYPE = makeTupleType(); 177 178 private int fontSize; 179 private int defaultSize = 3; 180 private ColorSwatch colorSwatch; 181 private Color color; 182 private Color defaultColor = Color.GREEN; 183 private ColorSwatch antColorSwatch; 184 private Color antColor; 185 private Color defaultAntColor = Color.WHITE; 186 private PolarOrbitTrackDataSource dataSource; 187 188 private CurveDrawer coverageCircle; 189 private double satelliteAltitude = 0.0; 190 191 private double centerAlt = 0.0; 192 private double centerLat = 0.0; 193 private double centerLon = 0.0; 194 private double satZ = 0.0; 195 private NavigatedDisplay navDsp = null; 196 197 198 public PolarOrbitTrackControl() { 199 super(); 200 logger.trace("created new tlecontrol={}", Integer.toHexString(hashCode())); 201 } 202 203 @Override public boolean init(DataChoice dataChoice) 204 throws VisADException, RemoteException 205 { 206 try { 207 trackDsp = new CompositeDisplayable(); 208 circleDsp = new CompositeDisplayable(); 209 } catch (Exception e) { 210 System.out.println("problem creating composite displayable e=" + e); 211 return false; 212 } 213 boolean result = super.init((DataChoice)this.getDataChoices().get(0)); 214 215 String dispName = getDisplayName(); 216 setDisplayName(getLongParamName() + " " + dispName); 217 218 Data data = getData(getDataInstance()); 219 createTrackDisplay(data); 220 this.dataSource = getDataSource(); 221 try { 222 navDsp = getNavigatedDisplay(); 223 EarthLocation earthLoc = navDsp.getCenterPoint(); 224 LatLonPoint llp = earthLoc.getLatLonPoint(); 225 centerLat = llp.getLatitude().getValue(); 226 centerLon = llp.getLongitude().getValue(); 227 centerAlt = dataSource.getNearestAltToGroundStation(centerLat, centerLon)/1000.0; 228 EarthLocationTuple elt = new EarthLocationTuple(centerLat, centerLon, centerAlt); 229 double[] xyz = navDsp.getSpatialCoordinates((EarthLocation)elt).getValues(); 230 satZ = xyz[2]/5.0; 231 applyTrackPosition(); 232 } catch (Exception e) { 233 System.out.println("get display center e=" + e); 234 } 235 return result; 236 } 237 238 private void createTrackDisplay(Data data) { 239 try { 240 this.fontSize = getFontSize(); 241 this.color = getColor(); 242 List<String> dts = new ArrayList(); 243 if (data instanceof Tuple) { 244 Data[] dataArr = ((Tuple)data).getComponents(); 245 int npts = dataArr.length; 246 float[][] latlon = new float[2][npts]; 247 float fSize = this.fontSize/10.f; 248 for (int i=0; i<npts; i++) { 249 Tuple t = (Tuple)dataArr[i]; 250 Data[] tupleComps = t.getComponents(); 251 String str = ((Text)tupleComps[0]).getValue(); 252 dts.add(str); 253 int indx = str.indexOf(" ") + 1; 254 String subStr = "- " + str.substring(indx, indx+5); 255 256 TextDisplayable time = new TextDisplayable(TextType.Generic); 257 time.setJustification(TextControl.Justification.LEFT); 258 time.setVerticalJustification(TextControl.Justification.CENTER); 259 time.setColor(this.color); 260 261 addDisplayable(time, FLAG_COLORTABLE); 262 LatLonTuple llt = (LatLonTuple)tupleComps[1]; 263 double dlat = llt.getLatitude().getValue(); 264 double dlon = llt.getLongitude().getValue(); 265 RealTuple lonLat = 266 new RealTuple(RealTupleType.SpatialEarth2DTuple, 267 new double[] { dlon, dlat }); 268 Tuple tup = new Tuple(TUPTYPE, 269 new Data[] { lonLat, new Text(subStr)}); 270 time.setData(tup); 271 this.trackDsp.addDisplayable(time); 272 float lat = (float)dlat; 273 float lon = (float)dlon; 274 //System.out.println(" Time=" + subStr + " Lat=" + lat + " Lon=" + lon); 275 latlon[0][i] = lat; 276 latlon[1][i] = lon; 277 } 278 setDisplayableTextSize(this.fontSize); 279 Gridded2DSet track = new Gridded2DSet(RealTupleType.LatitudeLongitudeTuple, 280 latlon, npts); 281 SampledSet[] set = new SampledSet[1]; 282 set[0] = track; 283 UnionSet uset = new UnionSet(set); 284 CurveDrawer trackLines = new CurveDrawer(uset); 285 trackLines.setData(uset); 286 this.trackDsp.addDisplayable(trackLines); 287 this.trackDsp.setColor(this.color); 288 this.trackDsp.setLineWidth(2.0f); 289 addDisplayable(this.trackDsp, FLAG_COLORTABLE); 290 trackLines.setDrawingEnabled(false); 291 } 292 } catch (Exception e) { 293 System.out.println("getData e=" + e); 294 } 295 return; 296 } 297 298 private static TupleType makeTupleType() { 299 TupleType t = null; 300 try { 301 t = new TupleType(new MathType[] {RealTupleType.SpatialEarth2DTuple, 302 TextType.Generic}); 303 } catch (Exception e) { 304 System.out.println("\nPolarOrbitTrackControl.makeTupleType e=" + e); 305 } 306 return t; 307 } 308 309 public JComponent makeColorBox(Color swatchColor) { 310 GuiUtils.ColorSwatch swatch = new GuiUtils.ColorSwatch(swatchColor, 311 "Color") { 312 public void userSelectedNewColor(Color c) { 313 try { 314 getIdv().showWaitCursor(); 315 setColor(c); 316 setBackground(c); 317 getIdv().showNormalCursor(); 318 } catch (Exception e) { 319 System.out.println("\nsetColor e=" + e); 320 setColor(defaultColor); 321 } 322 } 323 }; 324 return swatch; 325 } 326 327 public JComponent makeAntColorBox(Color swatchAntColor) { 328 GuiUtils.ColorSwatch swatch = new GuiUtils.ColorSwatch(swatchAntColor, 329 "Color") { 330 public void userSelectedNewColor(Color c) { 331 try { 332 getIdv().showWaitCursor(); 333 setAntColor(c); 334 setBackground(c); 335 getIdv().showNormalCursor(); 336 } catch (Exception e) { 337 System.out.println("\nsetAntColor e=" + e); 338 setAntColor(defaultAntColor); 339 } 340 } 341 }; 342 return swatch; 343 } 344 345 /** 346 * Called by doMakeWindow in DisplayControlImpl, which then calls its 347 * doMakeMainButtonPanel(), which makes more buttons. 348 * 349 * @return container of contents 350 */ 351 public Container doMakeContents() { 352/* 353 JPanel topPanel = GuiUtils.leftCenter( 354 new JLabel("Track Z-Position: "), 355 makePositionSlider()); 356*/ 357 this.fontSizeChange =new ActionListener() { 358 public void actionPerformed(ActionEvent ae) { 359 String str = fontSizeFld.getText(); 360 int size = new Integer(str).intValue(); 361 moveFontSizeSlider(size); 362 setDisplayableTextSize(size); 363 } 364 }; 365 this.fontSizeFocusChange = new FocusListener() { 366 public void focusGained(FocusEvent fe) { 367 } 368 public void focusLost(FocusEvent fe) { 369 String str = fontSizeFld.getText(); 370 int size = new Integer(str).intValue(); 371 moveFontSizeSlider(size); 372 setDisplayableTextSize(size); 373 } 374 }; 375 376 this.fontSizeSlider = GuiUtils.makeSlider(SLIDER_MIN, SLIDER_MAX, defaultSize, 377 this, "sliderChanged", true); 378 this.fontSizeSlider.setPreferredSize(new Dimension(SLIDER_WIDTH,SLIDER_HEIGHT)); 379 this.fontSizeSlider.setMajorTickSpacing(1); 380 this.fontSizeSlider.setSnapToTicks(true); 381 int size = getSizeValue(this.fontSizeSlider); 382 setFontSize(size); 383 this.fontSizeFld = new JTextField(Integer.toString(size),3); 384 this.fontSizeFld.addFocusListener(this.fontSizeFocusChange); 385 this.fontSizeFld.addActionListener(this.fontSizeChange); 386 this.fontSizePanel = GuiUtils.doLayout( new Component[] { 387 new JLabel("FontSize: "), 388 this.fontSizeFld, 389 new JLabel(" "), 390 this.fontSizeSlider }, 4, 391 GuiUtils.WT_N, GuiUtils.WT_N); 392 393 Color swatchColor = getColor(); 394 colorSwatch = (GuiUtils.ColorSwatch)makeColorBox(swatchColor); 395 colorPanel = GuiUtils.doLayout(new Component[] { 396 new JLabel("Set Color: "), 397 colorSwatch }, 2, 398 GuiUtils.WT_N, GuiUtils.WT_N); 399 JPanel groundStationPanel = makeGroundStationPanel(); 400 401 Insets dfltGridSpacing = new Insets(4, 0, 4, 0); 402 String dfltLblSpacing = " "; 403 List allComps = new ArrayList(); 404 405// allComps.add(topPanel); 406// allComps.add(new JLabel(" ")); 407// allComps.add(new JLabel(" ")); 408 allComps.add(fontSizePanel); 409 allComps.add(colorPanel); 410 allComps.add(new JLabel(" ")); 411 allComps.add(new JLabel(" ")); 412 allComps.add(locationPanel); 413 allComps.add(groundStationPanel); 414 GuiUtils.tmpInsets = GRID_INSETS; 415 JPanel dateTimePanel = GuiUtils.doLayout(allComps, 1, GuiUtils.WT_NY, 416 GuiUtils.WT_N); 417 return GuiUtils.top(dateTimePanel); 418 } 419 420 private JPanel makeGroundStationPanel() { 421 locationComboBox = new JComboBox(); 422 locationComboBox.setEditable(true); 423 locationEditor = (JTextField)locationComboBox.getEditor().getEditorComponent(); 424 locationEditor.addKeyListener(new KeyListener() { 425 public void keyPressed(KeyEvent e) {} 426 public void keyReleased(KeyEvent e) {} 427 public void keyTyped(KeyEvent e) { 428 locationIndex = -1; 429 } 430 }); 431 432 GroundStations gs = new GroundStations(null); 433 stations = gs.getStations(); 434 GuiUtils.setListData(locationComboBox, stations); 435 lats = gs.getLatitudes(); 436 lons = gs.getLongitudes(); 437 alts = gs.getAltitudes(); 438 439 locationComboBox.addActionListener(new ActionListener() { 440 public void actionPerformed(ActionEvent ae) { 441 setStation((String)locationComboBox.getSelectedItem()); 442 locationIndex = locationComboBox.getSelectedIndex(); 443 //System.out.println("\n locationIndex=" + locationIndex); 444 if (locationIndex < 0) { 445 //locationIndex = 0; 446 //locationComboBox.setSelectedIndex(locationIndex); 447 try { 448 Object stat = (Object)getStation(); 449 //System.out.println("\n station=" + stat); 450 if (stations.contains(stat)) { 451 locationIndex = stations.indexOf(stat); 452 //System.out.println("\nstat at location: " + locationIndex); 453 locationComboBox.setSelectedIndex(locationIndex); 454 } 455/* 456 else { 457 locationIndex = 0; 458 locationComboBox.insertItemAt(stat, locationIndex); 459 locationComboBox.setSelectedIndex(locationIndex); 460 stations.add(locationIndex, stat); 461 locationEditor.setText(getStation()); 462 String zero = ""; 463 lats.add(locationIndex, zero); 464 lons.add(locationIndex, zero); 465 alts.add(locationIndex, zero); 466 latLonWidget.setLatLon(" ", " "); 467 altitudeFld.setText(zero); 468 setAltitude(); 469 } 470*/ 471 } catch (Exception e) { 472 } 473 } else { 474 try { 475 String str = (String)(lats.get(locationIndex)); 476 Double d = new Double(str); 477 double dVal = d.doubleValue(); 478 latLonWidget.setLat(dVal); 479 setLatitude(); 480 str = (String)(lons.get(locationIndex)); 481 d = new Double(str); 482 dVal = d.doubleValue(); 483 latLonWidget.setLon(dVal); 484 setLongitude(); 485 str = (String)(alts.get(locationIndex)); 486 altitudeFld.setText(str); 487 setAltitude(); 488 int val = getAntennaAngle(); 489 setAntennaAngle(val); 490 } catch (Exception e) { 491 } 492 } 493 setSatelliteAltitude(dataSource.getNearestAltToGroundStation(latitude, longitude)/1000.0); 494 redrawCoverageCircle(); 495 } 496 }); 497 498 latFld = latLonWidget.getLatField(); 499 lonFld = latLonWidget.getLonField(); 500 String str = (String)(alts.get(0)); 501 altitudeFld = new JTextField(str, 5); 502 str = (String)(lats.get(0)); 503 Double d; 504 double dVal; 505 if (!str.equals(" ")) { 506 d = new Double(str); 507 dVal = d.doubleValue(); 508 latLonWidget.setLat(dVal); 509 } 510 if (!str.equals(" ")) { 511 str = (String)(lons.get(0)); 512 d = new Double(str); 513 dVal = d.doubleValue(); 514 latLonWidget.setLon(dVal); 515 } 516 517 ActionListener latLonListener = new ActionListener() { 518 public void actionPerformed(ActionEvent ae) { 519 setLatitude(); 520 setLongitude(); 521 setAltitude(); 522 redrawCoverageCircle(); 523 } 524 }; 525 FocusListener latLonFocusChange = new FocusListener() { 526 public void focusGained(FocusEvent fe) { 527 latFld.setCaretPosition(latFld.getText().length()); 528 lonFld.setCaretPosition(lonFld.getText().length()); 529 } 530 public void focusLost(FocusEvent fe) { 531 setLatitude(); 532 setLongitude(); 533 setAltitude(); 534 redrawCoverageCircle(); 535 } 536 }; 537 latFld.addActionListener(latLonListener); 538 lonFld.addActionListener(latLonListener); 539 latFld.addFocusListener(latLonFocusChange); 540 lonFld.addFocusListener(latLonFocusChange); 541 antennaAngle.addActionListener(new ActionListener() { 542 public void actionPerformed(ActionEvent ae) { 543 String str = antennaAngle.getText(); 544 Integer iVal = new Integer(str.trim()); 545 int val = iVal.intValue(); 546 setAntennaAngle(val); 547 redrawCoverageCircle(); 548 } 549 }); 550 antennaAngle.addFocusListener(new FocusListener() { 551 public void focusGained(FocusEvent fe) { 552 } 553 public void focusLost(FocusEvent fe) { 554 String str = antennaAngle.getText(); 555 Integer iVal = new Integer(str.trim()); 556 int val = iVal.intValue(); 557 setAntennaAngle(val); 558 redrawCoverageCircle(); 559 } 560 }); 561 locationPanel = GuiUtils.doLayout(new Component[] { 562 new JLabel("Ground Station: "), 563 locationComboBox }, 2, 564 GuiUtils.WT_N, GuiUtils.WT_N); 565 latLonAltPanel = GuiUtils.doLayout(new Component[] { 566 latLonWidget, 567 new JLabel(" Altitude: "), altitudeFld, 568 new JLabel(" Antenna Angle: "), antennaAngle }, 5, 569 GuiUtils.WT_N, GuiUtils.WT_N); 570 571 Color swatchAntColor = getAntColor(); 572 antColorSwatch = (GuiUtils.ColorSwatch)makeAntColorBox(swatchAntColor); 573 antColorPanel = GuiUtils.doLayout(new Component[] { 574 new JLabel("Set Color: "), 575 antColorSwatch }, 2, 576 GuiUtils.WT_N, GuiUtils.WT_N); 577 578 List allComps = new ArrayList(); 579 allComps.add(locationPanel); 580 allComps.add(new JLabel(" ")); 581 allComps.add(latLonAltPanel); 582 allComps.add(new JLabel(" ")); 583 allComps.add(antColorPanel); 584 JPanel retPanel = GuiUtils.doLayout(allComps, 1, GuiUtils.WT_NY, 585 GuiUtils.WT_N); 586 return GuiUtils.top(retPanel); 587 } 588 589 private void getGroundStation() { 590 } 591/* 592 private JComponent makePositionSlider() { 593 levelSlider = new ZSlider(this.satZ) { 594 public void valueHasBeenSet() { 595 applyTrackPosition(); 596 } 597 }; 598 return levelSlider.getContents(); 599 } 600*/ 601 /** 602 * Apply the map (height) position to the displays 603 */ 604 private void applyTrackPosition() { 605 try { 606 DisplayRealType dispType = navDsp.getDisplayAltitudeType(); 607 trackDsp.setConstantPosition(this.satZ, dispType); 608 } catch (Exception exc) { 609 //System.out.println("Setting track z-position exc=" + exc); 610 } 611 } 612 613 private void redrawCoverageCircle() { 614 try { 615 616 int num = circleDsp.displayableCount(); 617 for (int i=0; i<num; i++) { 618 circleDsp.removeDisplayable(0); 619 } 620 621 if (drawCoverageCircle(Math.toRadians(this.latitude), Math.toRadians(this.longitude), 622 this.satelliteAltitude, getAntColor()) != null) { 623 drawGroundStation(); 624 circleDsp.setColor(getAntColor()); 625 circleDsp.setLineWidth(1f); 626 circleDsp.addDisplayable(this.coverageCircle); 627 circleDsp.addDisplayable(this.groundStationDsp); 628 addDisplayable(circleDsp, FLAG_COLORTABLE); 629 } 630 } catch (Exception e) { 631 System.out.println("redrawCoverageCircle e=" + e); 632 } 633 } 634 635 private CurveDrawer drawCoverageCircle(double lat, double lon, double satAlt, Color color) { 636 if (!(latLonWidget.isLatLonDefined())) return null; 637 638 double earthRadius = AstroConst.R_Earth/1000.0; 639 satAlt += earthRadius; 640 double pi = Math.PI; 641 double SAC = pi/2.0 + Math.toRadians(getAntennaAngle()); 642 double sinASC = earthRadius * Math.sin(SAC) / satAlt; 643 double dist = earthRadius * (Math.PI - SAC - Math.asin(sinASC)); 644 double rat = dist/earthRadius; 645 646 int npts = 360; 647 float[][] latlon = new float[2][npts]; 648 double cosDist = Math.cos(rat); 649 double sinDist = Math.sin(rat); 650 double sinLat = Math.sin(lat); 651 double cosLat = Math.cos(lat); 652 double sinLon = -Math.sin(lon); 653 double cosLon = Math.cos(lon); 654 for (int i=0; i<npts; i++) { 655 double azimuth = Math.toRadians((double)i); 656 double cosBear = Math.cos(azimuth); 657 double sinBear = Math.sin(azimuth); 658 double z = cosDist * sinLat + 659 sinDist * cosLat * cosBear; 660 double y = cosLat * cosLon * cosDist + 661 sinDist * (sinLon*sinBear - sinLat*cosLon*cosBear); 662 double x = cosLat * sinLon * cosDist - 663 sinDist * (cosLon*sinBear + sinLat*sinLon*cosBear); 664 double r = Math.sqrt(x*x + y*y); 665 double latRad = Math.atan2(z, r); 666 double lonRad = 0.0; 667 if (r > 0.0) lonRad = -Math.atan2(x, y); 668 latlon[0][i] = (float)Math.toDegrees(latRad); 669 latlon[1][i] = (float)Math.toDegrees(lonRad); 670 } 671 try { 672 Gridded2DSet circle = new Gridded2DSet(RealTupleType.LatitudeLongitudeTuple, 673 latlon, npts); 674 SampledSet[] set = new SampledSet[1]; 675 set[0] = circle; 676 UnionSet uset = new UnionSet(set); 677 this.coverageCircle = new CurveDrawer(uset); 678 this.coverageCircle.setLineStyle(1); 679 this.coverageCircle.setColor(getAntColor()); 680 this.coverageCircle.setData(uset); 681 this.coverageCircle.setDrawingEnabled(false); 682 } catch (Exception e) { 683 System.out.println("drawCoverageCircle e=" + e); 684 return null; 685 } 686 return this.coverageCircle; 687 } 688 689 private int getSizeValue(JSlider slider) { 690 int value = slider.getValue(); 691 if (value < SLIDER_MIN) { 692 value = SLIDER_MIN; 693 } else if (value > SLIDER_MAX) { 694 value = SLIDER_MAX; 695 } 696 return value; 697 } 698 699 public int getFontSize() { 700 if (this.fontSize < 1) this.fontSize = defaultSize; 701 return this.fontSize; 702 } 703 704 public void setFontSizeTextField(int size) { 705 size = setFontSize(size); 706 try { 707 if (this.fontSizeFld != null) { 708 this.fontSizeFld.setText(new Integer(size).toString()); 709 } 710 } catch (Exception e) { 711 System.out.println("Exception in PolarOrbitTrackControl.setFontSizeTextField e=" + e); 712 } 713 } 714 715 private void moveFontSizeSlider(int size) { 716 size = setFontSize(size); 717 try { 718 if (this.fontSizeSlider != null) { 719 this.fontSizeSlider.setValue(size); 720 } 721 } catch (Exception e) { 722 System.out.println("Exception in PolarOrbitTrackControl.moveFontSizeSlider e=" + e); 723 } 724 } 725 726 private void setDisplayableTextSize(int size) { 727 size = setFontSize(size); 728 try { 729 float fSize = (float)size/10.0f; 730 int num = this.trackDsp.displayableCount()-1; 731 TextDisplayable textDsp = null; 732 for (int i=num; i>-1; i--) { 733 Displayable dsp = this.trackDsp.getDisplayable(i); 734 if (dsp instanceof TextDisplayable) { 735 textDsp = (TextDisplayable)dsp; 736 break; 737 } 738 } 739 if (textDsp != null) { 740 textDsp.setTextSize(fSize); 741 } 742 } catch (Exception e) { 743 System.out.println("Exception in PolarOrbitTrackControl.setDisplayableTextSize e=" + e); 744 } 745 } 746 747 public int setFontSize(int size) { 748 if (size < 1) size = defaultSize; 749 this.fontSize = size; 750 return this.fontSize; 751 } 752 753 public Color getColor() { 754 if (this.color == null) this.color = defaultColor; 755 return this.color; 756 } 757 758 public void setColor(Color color) { 759 if (this.color == null) this.color = defaultColor; 760 try { 761 this.trackDsp.setColor(color); 762 this.color = color; 763 } catch (Exception e) { 764 System.out.println("Exception in PolarOrbitTrackControl.setColor e=" + e); 765 } 766 } 767 768 public Color getAntColor() { 769 if (this.antColor == null) this.antColor = defaultAntColor; 770 return this.antColor; 771 } 772 773 public void setAntColor(Color color) { 774 if (color == null) color = defaultAntColor; 775 try { 776 this.antColor = color; 777 circleDsp.setColor(color); 778 } catch (Exception e) { 779 System.out.println("Exception in PolarOrbitTrackControl.setAntColor e=" + e); 780 } 781 } 782 783 public void setLatitude() { 784 this.latitude = latLonWidget.getLat(); 785 //System.out.println("setLatitude: " + this.latitude); 786 } 787 788 public double getLatitude() { 789 return this.latitude; 790 } 791 792 public void setLongitude() { 793 this.longitude = latLonWidget.getLon(); 794 //System.out.println("setLongitude: " + this.longitude); 795 } 796 797 public double getLongitude() { 798 return this.longitude; 799 } 800 801 public void setAltitude() { 802 String str = altitudeFld.getText(); 803 //System.out.println("\nsetAltitude: str=" + str); 804 try { 805 Double d = new Double(str); 806 this.altitude = d.doubleValue(); 807 } catch (Exception e) { 808 this.altitude = 0.0; 809 } 810 } 811 812 public void sliderChanged(int sliderValue) { 813 setFontSizeTextField(sliderValue); 814 setDisplayableTextSize(sliderValue); 815 } 816 817 public void setStation(String val) { 818 this.station = val.trim(); 819 //System.out.println("setStation: " + this.station); 820 } 821 822 public String getStation() { 823 return this.station; 824 } 825 826 public void setAntennaAngle(int val) { 827 //System.out.println("\nsetAntennaAngle: val=" + val); 828 String str = " " + val; 829 antennaAngle.setText(str); 830 this.angle = val; 831 } 832 833 public int getAntennaAngle() { 834 //System.out.println("\ngetAntennaAngle:"); 835 String str = antennaAngle.getText(); 836 this.angle = new Integer(str.trim()).intValue(); 837 if (this.angle < defaultAntAngle) this.angle = defaultAntAngle; 838 return this.angle; 839 } 840 841 private void setSatelliteAltitude(double val) { 842 //System.out.println("\nsetSatelliteAltitude: val=" + val); 843 this.satelliteAltitude = val; 844 } 845 846 private void drawGroundStation() { 847 try { 848 String str = "+" + getStation(); 849 this.groundStationDsp = new TextDisplayable(TextType.Generic); 850 this.groundStationDsp.setJustification(TextControl.Justification.LEFT); 851 this.groundStationDsp.setVerticalJustification(TextControl.Justification.CENTER); 852 this.groundStationDsp.setTextSize(0.3f); 853 this.groundStationDsp.setColor(getAntColor()); 854 855 //addDisplayable(this.groundStationDsp, FLAG_COLORTABLE); 856 //circleDsp.addDisplayable(this.groundStationDsp); 857 double dlat = getLatitude(); 858 double dlon = getLongitude(); 859 RealTuple lonLat = 860 new RealTuple(RealTupleType.SpatialEarth2DTuple, 861 new double[] { dlon, dlat }); 862 Tuple tup = new Tuple(TUPTYPE, 863 new Data[] { lonLat, new Text(str)}); 864 this.groundStationDsp.setData(tup); 865 } catch (Exception e) { 866 System.out.println("drawGroundStation e=" + e); 867 } 868 } 869 870 public PolarOrbitTrackDataSource getDataSource() { 871 DataSourceImpl ds = null; 872 List dataSources = getDataSources(); 873 boolean gotit = false; 874 if (!dataSources.isEmpty()) { 875 int nsrc = dataSources.size(); 876 for (int i=0; i<nsrc; i++) { 877 ds = (DataSourceImpl)dataSources.get(nsrc-i-1); 878 if (ds instanceof PolarOrbitTrackDataSource) { 879 gotit = true; 880 break; 881 } 882 } 883 } 884 if (!gotit) return null; 885 return (PolarOrbitTrackDataSource)ds; 886 } 887}