public int countImagesInSector(Sector sector, int levelNumber) {
    if (sector == null) {
      String msg = Logging.getMessage("nullValue.SectorIsNull");
      Logging.logger().severe(msg);
      throw new IllegalArgumentException(msg);
    }

    Level targetLevel = this.levels.getLastLevel();
    if (levelNumber >= 0) {
      for (int i = levelNumber; i < this.getLevels().getLastLevel().getLevelNumber(); i++) {
        if (this.levels.isLevelEmpty(i)) continue;

        targetLevel = this.levels.getLevel(i);
        break;
      }
    }

    // Collect all the tiles intersecting the input sector.
    LatLon delta = targetLevel.getTileDelta();
    Angle latOrigin = this.levels.getTileOrigin().getLatitude();
    Angle lonOrigin = this.levels.getTileOrigin().getLongitude();
    final int nwRow = Tile.computeRow(delta.getLatitude(), sector.getMaxLatitude(), latOrigin);
    final int nwCol = Tile.computeColumn(delta.getLongitude(), sector.getMinLongitude(), lonOrigin);
    final int seRow = Tile.computeRow(delta.getLatitude(), sector.getMinLatitude(), latOrigin);
    final int seCol = Tile.computeColumn(delta.getLongitude(), sector.getMaxLongitude(), lonOrigin);

    int numRows = nwRow - seRow + 1;
    int numCols = seCol - nwCol + 1;

    return numRows * numCols;
  }
    private void adjustDateLineCrossingPoints() {
      ArrayList<LatLon> corners = new ArrayList<LatLon>(Arrays.asList(sw, se, nw, ne));
      if (!LatLon.locationsCrossDateLine(corners)) return;

      double lonSign = 0;
      for (LatLon corner : corners) {
        if (Math.abs(corner.getLongitude().degrees) != 180)
          lonSign = Math.signum(corner.getLongitude().degrees);
      }

      if (lonSign == 0) return;

      if (Math.abs(sw.getLongitude().degrees) == 180
          && Math.signum(sw.getLongitude().degrees) != lonSign)
        sw = new Position(sw.getLatitude(), sw.getLongitude().multiply(-1), sw.getElevation());
      if (Math.abs(se.getLongitude().degrees) == 180
          && Math.signum(se.getLongitude().degrees) != lonSign)
        se = new Position(se.getLatitude(), se.getLongitude().multiply(-1), se.getElevation());
      if (Math.abs(nw.getLongitude().degrees) == 180
          && Math.signum(nw.getLongitude().degrees) != lonSign)
        nw = new Position(nw.getLatitude(), nw.getLongitude().multiply(-1), nw.getElevation());
      if (Math.abs(ne.getLongitude().degrees) == 180
          && Math.signum(ne.getLongitude().degrees) != lonSign)
        ne = new Position(ne.getLatitude(), ne.getLongitude().multiply(-1), ne.getElevation());
    }
  /**
   * Determines whether a latitude/longitude position is within the sector. The sector's angles are
   * assumed to be normalized to +/- 90 degrees latitude and +/- 180 degrees longitude. The result
   * of the operation is undefined if they are not.
   *
   * @param latLon the position to test, with angles normalized to +/- &#960 latitude and +/- 2&#960
   *     longitude.
   * @return <code>true</code> if the position is within the sector, <code>false</code> otherwise.
   * @throws IllegalArgumentException if <code>latlon</code> is null.
   */
  public final boolean contains(LatLon latLon) {
    if (latLon == null) {
      throw new IllegalArgumentException("LatLon Is Null");
    }

    return this.contains(latLon.getLatitude(), latLon.getLongitude());
  }
  /**
   * {@inheritDoc}
   *
   * @param positions Control points. This graphic uses only two control point, which determine the
   *     midpoints of two opposite sides of the quad. See Fire Support Area (2.X.4.3.2.1.2) on pg.
   *     652 of MIL-STD-2525C for an example of how these points are interpreted.
   */
  public void setPositions(Iterable<? extends Position> positions) {
    if (positions == null) {
      String message = Logging.getMessage("nullValue.PositionsListIsNull");
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }

    Iterator<? extends Position> iterator = positions.iterator();
    try {
      Position pos1 = iterator.next();
      Position pos2 = iterator.next();

      LatLon center = LatLon.interpolateGreatCircle(0.5, pos1, pos2);
      this.quad.setCenter(center);

      Angle heading = LatLon.greatCircleAzimuth(pos2, pos1);
      this.quad.setHeading(heading.subtract(Angle.POS90));

      this.positions = positions;
      this.shapeInvalid = true; // Need to recompute quad size
    } catch (NoSuchElementException e) {
      String message = Logging.getMessage("generic.InsufficientPositions");
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }
  }
  private void drawTileIDs(DrawContext dc, ArrayList<MercatorTextureTile> tiles) {
    java.awt.Rectangle viewport = dc.getView().getViewport();
    if (this.textRenderer == null) {
      this.textRenderer = new TextRenderer(java.awt.Font.decode("Arial-Plain-13"), true, true);
      this.textRenderer.setUseVertexArrays(false);
    }

    dc.getGL().glDisable(GL.GL_DEPTH_TEST);
    dc.getGL().glDisable(GL.GL_BLEND);
    dc.getGL().glDisable(GL.GL_TEXTURE_2D);

    this.textRenderer.setColor(java.awt.Color.YELLOW);
    this.textRenderer.beginRendering(viewport.width, viewport.height);
    for (MercatorTextureTile tile : tiles) {
      String tileLabel = tile.getLabel();

      if (tile.getFallbackTile() != null) tileLabel += "/" + tile.getFallbackTile().getLabel();

      LatLon ll = tile.getSector().getCentroid();
      Vec4 pt =
          dc.getGlobe()
              .computePointFromPosition(
                  ll.getLatitude(),
                  ll.getLongitude(),
                  dc.getGlobe().getElevation(ll.getLatitude(), ll.getLongitude()));
      pt = dc.getView().project(pt);
      this.textRenderer.draw(tileLabel, (int) pt.x, (int) pt.y);
    }
    this.textRenderer.endRendering();
  }
  public static Sector boundingSector(Iterable<? extends LatLon> locations) {
    if (locations == null) {
      throw new IllegalArgumentException("Positions List Is Null");
    }

    if (!locations.iterator().hasNext()) {
      return EMPTY_SECTOR; // TODO: should be returning null
    }
    double minLat = Angle.POS90.getDegrees();
    double minLon = Angle.POS180.getDegrees();
    double maxLat = Angle.NEG90.getDegrees();
    double maxLon = Angle.NEG180.getDegrees();

    for (LatLon p : locations) {
      double lat = p.getLatitude().getDegrees();
      if (lat < minLat) {
        minLat = lat;
      }
      if (lat > maxLat) {
        maxLat = lat;
      }

      double lon = p.getLongitude().getDegrees();
      if (lon < minLon) {
        minLon = lon;
      }
      if (lon > maxLon) {
        maxLon = lon;
      }
    }

    return Sector.fromDegrees(minLat, maxLat, minLon, maxLon);
  }
 protected double computeLocationDistanceDegreesSquared(Sector drawSector, LatLon location) {
   double lonOffset = computeHemisphereOffset(drawSector, location);
   double dLat = location.getLatitude().degrees - drawSector.getCentroid().getLatitude().degrees;
   double dLon =
       location.getLongitude().degrees
           - drawSector.getCentroid().getLongitude().degrees
           + lonOffset;
   return dLat * dLat + dLon * dLon;
 }
 protected Vec4 getPoint(LatLon latlon, double elevation) {
   SceneController sc = this.getApp().getWwd().getSceneController();
   Globe globe = this.getApp().getWwd().getModel().getGlobe();
   double e = globe.getElevation(latlon.getLatitude(), latlon.getLongitude());
   return globe.computePointFromPosition(
       latlon.getLatitude(),
       latlon.getLongitude(),
       (e + elevation) * sc.getVerticalExaggeration());
 }
  public static Sector[] splitBoundingSectors(Iterable<? extends LatLon> locations) {
    if (locations == null) {
      throw new IllegalArgumentException("Location In List Is Null");
    }

    if (!locations.iterator().hasNext()) {
      return null;
    }

    double minLat = Angle.POS90.getDegrees();
    double minLon = Angle.POS180.getDegrees();
    double maxLat = Angle.NEG90.getDegrees();
    double maxLon = Angle.NEG180.getDegrees();

    LatLon lastLocation = null;

    for (LatLon ll : locations) {
      double lat = ll.getLatitude().getDegrees();
      if (lat < minLat) {
        minLat = lat;
      }
      if (lat > maxLat) {
        maxLat = lat;
      }

      double lon = ll.getLongitude().getDegrees();
      if (lon >= 0 && lon < minLon) {
        minLon = lon;
      }
      if (lon <= 0 && lon > maxLon) {
        maxLon = lon;
      }

      if (lastLocation != null) {
        double lastLon = lastLocation.getLongitude().getDegrees();
        if (Math.signum(lon) != Math.signum(lastLon)) {
          if (Math.abs(lon - lastLon) < 180) {
            // Crossing the zero longitude line too
            maxLon = 0;
            minLon = 0;
          }
        }
      }
      lastLocation = ll;
    }

    if (minLat == maxLat && minLon == maxLon) {
      return null;
    }

    return new Sector[] {
      Sector.fromDegrees(minLat, maxLat, minLon, 180), // Sector on eastern hemisphere.
      Sector.fromDegrees(minLat, maxLat, -180, maxLon) // Sector on western hemisphere.
    };
  }
  public static Sector union(Iterable<? extends Sector> sectors) {
    if (sectors == null) {
      throw new IllegalArgumentException("Sector List Is Null");
    }

    Angle minLat = Angle.POS90;
    Angle maxLat = Angle.NEG90;
    Angle minLon = Angle.POS180;
    Angle maxLon = Angle.NEG180;

    for (Sector s : sectors) {
      if (s == null) {
        continue;
      }

      for (LatLon p : s) {
        if (p.getLatitude().degrees < minLat.degrees) {
          minLat = p.getLatitude();
        }
        if (p.getLatitude().degrees > maxLat.degrees) {
          maxLat = p.getLatitude();
        }
        if (p.getLongitude().degrees < minLon.degrees) {
          minLon = p.getLongitude();
        }
        if (p.getLongitude().degrees > maxLon.degrees) {
          maxLon = p.getLongitude();
        }
      }
    }

    return new Sector(minLat, maxLat, minLon, maxLon);
  }
    public void doActionOnButton3() {
      //            Sector sector = Sector.fromDegrees( 44d, 46d, -123.3d, -123.2d );

      ArrayList<LatLon> latlons = new ArrayList<LatLon>();

      latlons.add(LatLon.fromDegrees(45.50d, -123.3d));
      //            latlons.add( LatLon.fromDegrees( 45.51d, -123.3d ) );
      latlons.add(LatLon.fromDegrees(45.52d, -123.3d));
      //            latlons.add( LatLon.fromDegrees( 45.53d, -123.3d ) );
      latlons.add(LatLon.fromDegrees(45.54d, -123.3d));
      //            latlons.add( LatLon.fromDegrees( 45.55d, -123.3d ) );
      latlons.add(LatLon.fromDegrees(45.56d, -123.3d));
      //            latlons.add( LatLon.fromDegrees( 45.57d, -123.3d ) );
      latlons.add(LatLon.fromDegrees(45.58d, -123.3d));
      //            latlons.add( LatLon.fromDegrees( 45.59d, -123.3d ) );
      latlons.add(LatLon.fromDegrees(45.60d, -123.3d));

      ElevationModel model = this.wwd.getModel().getGlobe().getElevationModel();

      StringBuffer sb = new StringBuffer();
      for (LatLon ll : latlons) {
        double e = model.getElevation(ll.getLatitude(), ll.getLongitude());
        sb.append("\n").append(e);
      }

      Logging.logger().info(sb.toString());
    }
Beispiel #12
0
  protected List<Position> computePathPositions(
      Position startPosition, Position endPosition, Angle delta) {
    Angle dist = LatLon.greatCircleDistance(startPosition, endPosition);
    dist = dist.multiply(0.6);

    Angle azimuth = LatLon.greatCircleAzimuth(startPosition, endPosition);

    LatLon locA = LatLon.greatCircleEndPosition(startPosition, azimuth.add(delta), dist);

    dist = dist.multiply(0.9);
    LatLon locB = LatLon.greatCircleEndPosition(startPosition, azimuth.subtract(delta), dist);

    return Arrays.asList(startPosition, new Position(locA, 0), new Position(locB, 0), endPosition);
  }
  private MercatorTextureTile[][] getTilesInSector(Sector sector, int levelNumber) {
    if (sector == null) {
      String msg = Logging.getMessage("nullValue.SectorIsNull");
      Logging.logger().severe(msg);
      throw new IllegalArgumentException(msg);
    }

    Level targetLevel = this.levels.getLastLevel();
    if (levelNumber >= 0) {
      for (int i = levelNumber; i < this.getLevels().getLastLevel().getLevelNumber(); i++) {
        if (this.levels.isLevelEmpty(i)) continue;

        targetLevel = this.levels.getLevel(i);
        break;
      }
    }

    // Collect all the tiles intersecting the input sector.
    LatLon delta = targetLevel.getTileDelta();
    Angle latOrigin = this.levels.getTileOrigin().getLatitude();
    Angle lonOrigin = this.levels.getTileOrigin().getLongitude();
    final int nwRow = Tile.computeRow(delta.getLatitude(), sector.getMaxLatitude(), latOrigin);
    final int nwCol = Tile.computeColumn(delta.getLongitude(), sector.getMinLongitude(), lonOrigin);
    final int seRow = Tile.computeRow(delta.getLatitude(), sector.getMinLatitude(), latOrigin);
    final int seCol = Tile.computeColumn(delta.getLongitude(), sector.getMaxLongitude(), lonOrigin);

    int numRows = nwRow - seRow + 1;
    int numCols = seCol - nwCol + 1;
    MercatorTextureTile[][] sectorTiles = new MercatorTextureTile[numRows][numCols];

    for (int row = nwRow; row >= seRow; row--) {
      for (int col = nwCol; col <= seCol; col++) {
        TileKey key =
            new TileKey(targetLevel.getLevelNumber(), row, col, targetLevel.getCacheName());
        Sector tileSector = this.levels.computeSectorForKey(key);
        MercatorSector mSector = MercatorSector.fromSector(tileSector); // TODO: check
        sectorTiles[nwRow - row][col - nwCol] =
            new MercatorTextureTile(mSector, targetLevel, row, col);
      }
    }

    return sectorTiles;
  }
  @Override
  protected void doMoveTo(Position oldReferencePosition, Position newReferencePosition) {
    if (this.boundaries.getContourCount() == 0) return;

    for (int i = 0; i < this.boundaries.getContourCount(); i++) {
      ArrayList<LatLon> newLocations = new ArrayList<LatLon>();

      for (LatLon ll : this.boundaries.getContour(i)) {
        Angle heading = LatLon.greatCircleAzimuth(oldReferencePosition, ll);
        Angle pathLength = LatLon.greatCircleDistance(oldReferencePosition, ll);
        newLocations.add(LatLon.greatCircleEndPosition(newReferencePosition, heading, pathLength));
      }

      this.boundaries.setContour(i, newLocations);
    }

    // We've changed the multi-polygon's list of boundaries; flag the shape as changed.
    this.onShapeChanged();
  }
    protected Vec4 getSurfacePoint(LatLon latlon, double elevation) {
      Vec4 point = null;

      SceneController sc = this.getApp().getWwd().getSceneController();
      Globe globe = this.getApp().getWwd().getModel().getGlobe();

      if (sc.getTerrain() != null) {
        point =
            sc.getTerrain()
                .getSurfacePoint(
                    latlon.getLatitude(),
                    latlon.getLongitude(),
                    elevation * sc.getVerticalExaggeration());
      }

      if (point == null) {
        double e = globe.getElevation(latlon.getLatitude(), latlon.getLongitude());
        point =
            globe.computePointFromPosition(
                latlon.getLatitude(),
                latlon.getLongitude(),
                (e + elevation) * sc.getVerticalExaggeration());
      }

      return point;
    }
  protected void computeQuadSize(DrawContext dc) {
    if (this.positions == null) return;

    Iterator<? extends Position> iterator = this.positions.iterator();

    Position pos1 = iterator.next();
    Position pos2 = iterator.next();

    Angle angularDistance = LatLon.greatCircleDistance(pos1, pos2);
    double length = angularDistance.radians * dc.getGlobe().getRadius();

    this.quad.setWidth(length);
  }
    protected void initializePolygon(WorldWindow wwd, Polygon polygon, boolean fitShapeToViewport) {
      // Creates a rectangle in the center of the viewport. Attempts to guess at a reasonable size
      // and height.

      Position position = ShapeUtils.getNewShapePosition(wwd);
      Angle heading = ShapeUtils.getNewShapeHeading(wwd, true);
      double sizeInMeters =
          fitShapeToViewport ? ShapeUtils.getViewportScaleFactor(wwd) : DEFAULT_SHAPE_SIZE_METERS;

      java.util.List<LatLon> locations =
          ShapeUtils.createSquareInViewport(wwd, position, heading, sizeInMeters);

      double maxElevation = -Double.MAX_VALUE;
      Globe globe = wwd.getModel().getGlobe();

      for (LatLon ll : locations) {
        double e = globe.getElevation(ll.getLatitude(), ll.getLongitude());
        if (e > maxElevation) maxElevation = e;
      }

      polygon.setAltitudes(0.0, maxElevation + sizeInMeters);
      polygon.setTerrainConforming(true, false);
      polygon.setLocations(locations);
    }
  public static Sector boundingSector(LatLon pA, LatLon pB) {
    if (pA == null || pB == null) {
      throw new IllegalArgumentException("Positions List Is Null");
    }

    double minLat = pA.getLatitude().degrees;
    double minLon = pA.getLongitude().degrees;
    double maxLat = pA.getLatitude().degrees;
    double maxLon = pA.getLongitude().degrees;

    if (pB.getLatitude().degrees < minLat) {
      minLat = pB.getLatitude().degrees;
    } else if (pB.getLatitude().degrees > maxLat) {
      maxLat = pB.getLatitude().degrees;
    }

    if (pB.getLongitude().degrees < minLon) {
      minLon = pB.getLongitude().degrees;
    } else if (pB.getLongitude().degrees > maxLon) {
      maxLon = pB.getLongitude().degrees;
    }

    return Sector.fromDegrees(minLat, maxLat, minLon, maxLon);
  }
Beispiel #19
0
  /**
   * Create the list of positions that describe the arrow.
   *
   * @param dc Current draw context.
   */
  protected void createShapes(DrawContext dc) {
    this.paths = new Path[2];

    int i = 0;

    Angle azimuth1 = LatLon.greatCircleAzimuth(this.position1, this.position2);
    Angle azimuth2 = LatLon.greatCircleAzimuth(this.position1, this.position3);

    Angle delta = azimuth2.subtract(azimuth1);
    int sign = delta.degrees > 0 ? 1 : -1;

    delta = Angle.fromDegrees(sign * 5.0);

    // Create a path for the line part of the arrow
    List<Position> positions = this.computePathPositions(this.position1, this.position2, delta);
    this.paths[i++] = this.createPath(positions);

    // Create a polygon to draw the arrow head.
    double arrowLength = this.getArrowLength();
    Angle arrowAngle = this.getArrowAngle();
    positions =
        this.computeArrowheadPositions(
            dc, positions.get(2), positions.get(3), arrowLength, arrowAngle);
    this.arrowHead1 = this.createPolygon(positions);
    this.arrowHead1.setLocations(positions);

    delta = delta.multiply(-1.0);
    positions = this.computePathPositions(this.position1, this.position3, delta);
    this.paths[i] = this.createPath(positions);

    positions =
        this.computeArrowheadPositions(
            dc, positions.get(2), positions.get(3), arrowLength, arrowAngle);
    this.arrowHead2 = this.createPolygon(positions);
    this.arrowHead2.setLocations(positions);
  }
  protected void doMoveTo(Position oldRef, Position newRef) {
    if (oldRef == null) {
      String message = "nullValue.OldRefIsNull";
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }
    if (newRef == null) {
      String message = "nullValue.NewRefIsNull";
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }

    super.doMoveTo(oldRef, newRef);

    int count = this.locations.size();
    LatLon[] newLocations = new LatLon[count];
    for (int i = 0; i < count; i++) {
      LatLon ll = this.locations.get(i);
      double distance = LatLon.greatCircleDistance(oldRef, ll).radians;
      double azimuth = LatLon.greatCircleAzimuth(oldRef, ll).radians;
      newLocations[i] = LatLon.greatCircleEndPosition(newRef, azimuth, distance);
    }
    this.setLocations(Arrays.asList(newLocations));
  }
  @Override
  protected void doMoveTo(
      Globe globe, Position oldReferencePosition, Position newReferencePosition) {
    if (this.boundaries.getContourCount() == 0) return;

    for (int i = 0; i < this.boundaries.getContourCount(); i++) {
      List<LatLon> newLocations =
          LatLon.computeShiftedLocations(
              globe, oldReferencePosition, newReferencePosition, this.boundaries.getContour(i));

      this.boundaries.setContour(i, newLocations);
    }

    // We've changed the multi-polygon's list of boundaries; flag the shape as changed.
    this.onShapeChanged();
  }
    public void doActionOnButton1() {
      Logging.logger().info("Zooming to Matterhorn");

      View view = this.wwd.getView();

      Position matterhorn =
          new Position(LatLon.fromDegrees(45.9763888888889d, 7.65833333333333d), 0d);

      //            Position eyePos = new Position( LatLon.fromDegrees( 46.01066860997058d,
      // 7.633097536001656d ), 3363d );
      //
      //            view.setEyePosition( eyePos );
      //            view.setHeading( Angle.fromDegrees( 156d ));
      //            view.setPitch( Angle.fromDegrees( 89.9d ));

      view.goTo(matterhorn, 5000d);
    }
  /** {@inheritDoc} */
  @Override
  protected void determineLabelPositions(DrawContext dc) {
    Position center = this.getReferencePosition();
    if (center == null) return;

    // Position the labels along a line radiating out from the center of the circle. The angle (60
    // degrees) is
    // chosen to match the graphic template defined by MIL-STD-2525C, pg. 613.
    double globeRadius = dc.getGlobe().getRadius();

    Angle labelAngle = this.getLabelAngle();

    int i = 0;
    for (SurfaceCircle ring : this.rings) {
      double radius = ring.getRadius();

      LatLon ll = LatLon.greatCircleEndPosition(center, labelAngle.radians, radius / globeRadius);

      this.labels.get(i).setPosition(new Position(ll, 0));
      i += 1;
    }
  }
    public void actionPerformed(ActionEvent e) {
      if (!this.isEnabled()) {
        return;
      }

      if (NEW_AIRSPACE.equals(e.getActionCommand())) {
        this.createNewEntry(this.getView().getSelectedFactory());
      } else if (CLEAR_SELECTION.equals(e.getActionCommand())) {
        this.selectEntry(null, true);
      } else if (SIZE_NEW_SHAPES_TO_VIEWPORT.equals(e.getActionCommand())) {
        if (e.getSource() instanceof AbstractButton) {
          boolean selected = ((AbstractButton) e.getSource()).isSelected();
          this.setResizeNewShapesToViewport(selected);
        }
      } else if (ENABLE_EDIT.equals(e.getActionCommand())) {
        if (e.getSource() instanceof AbstractButton) {
          boolean selected = ((AbstractButton) e.getSource()).isSelected();
          this.setEnableEdit(selected);
        }
      } else if (OPEN.equals(e.getActionCommand())) {
        this.openFromFile();
      } else if (OPEN_URL.equals(e.getActionCommand())) {
        this.openFromURL();
      } else if (OPEN_DEMO_AIRSPACES.equals(e.getActionCommand())) {
        this.openFromPath(DEMO_AIRSPACES_PATH);
        this.zoomTo(
            LatLon.fromDegrees(47.6584074779224, -122.3059199579634),
            Angle.fromDegrees(-152),
            Angle.fromDegrees(75),
            750);
      } else if (REMOVE_SELECTED.equals(e.getActionCommand())) {
        this.removeEntries(Arrays.asList(this.getSelectedEntries()));
      } else if (SAVE.equals(e.getActionCommand())) {
        this.saveToFile();
      } else if (SELECTION_CHANGED.equals(e.getActionCommand())) {
        this.viewSelectionChanged();
      }
    }
  /**
   * Create the circles used to draw this graphic.
   *
   * @param dc Current draw context.
   */
  protected void createShapes(DrawContext dc) {
    if (this.positions == null) return;

    this.rings = new ArrayList<SurfaceCircle>();

    Iterator<? extends Position> iterator = this.positions.iterator();

    Position center = iterator.next();
    double globeRadius = dc.getGlobe().getRadius();

    while (iterator.hasNext()) {
      SurfaceCircle ring = this.createCircle();
      ring.setCenter(center);

      Position pos = iterator.next();
      Angle radius = LatLon.greatCircleDistance(center, pos);

      double radiusMeters = radius.radians * globeRadius;
      ring.setRadius(radiusMeters);

      this.rings.add(ring);
    }
  }
  /**
   * Determines whether this sector intersects the specified geographic line segment. The line
   * segment is specified by a begin location and an end location. The locations are are assumed to
   * be connected by a linear path in geographic space. This returns true if any location along that
   * linear path intersects this sector, including the begin and end locations.
   *
   * @param begin the line segment begin location.
   * @param end the line segment end location.
   * @return true <code>true</code> if this sector intersects the line segment, otherwise <code>
   *     false</code>.
   * @throws IllegalArgumentException if either the begin location or the end location is null.
   */
  public boolean intersectsSegment(LatLon begin, LatLon end) {
    if (begin == null) {
      throw new IllegalArgumentException("Begin Is Null");
    }

    if (end == null) {
      throw new IllegalArgumentException("End Is Null");
    }

    Vec4 segmentBegin = new Vec4(begin.getLongitude().degrees, begin.getLatitude().degrees, 0);
    Vec4 segmentEnd = new Vec4(end.getLongitude().degrees, end.getLatitude().degrees, 0);
    Vec4 tmp = segmentEnd.subtract3(segmentBegin);
    Vec4 segmentCenter = segmentBegin.add3(segmentEnd).divide3(2);
    Vec4 segmentDirection = tmp.normalize3();
    double segmentExtent = tmp.getLength3() / 2.0;

    LatLon centroid = this.getCentroid();
    Vec4 boxCenter = new Vec4(centroid.getLongitude().degrees, centroid.getLatitude().degrees, 0);
    double boxExtentX = this.getDeltaLonDegrees() / 2.0;
    double boxExtentY = this.getDeltaLatDegrees() / 2.0;

    Vec4 diff = segmentCenter.subtract3(boxCenter);

    if (Math.abs(diff.x) > (boxExtentX + segmentExtent * Math.abs(segmentDirection.x))) {
      return false;
    }

    if (Math.abs(diff.y) > (boxExtentY + segmentExtent * Math.abs(segmentDirection.y))) {
      return false;
    }

    //noinspection SuspiciousNameCombination
    Vec4 segmentPerp = new Vec4(segmentDirection.y, -segmentDirection.x, 0);

    return Math.abs(segmentPerp.dot3(diff))
        <= (boxExtentX * Math.abs(segmentPerp.x) + boxExtentY * Math.abs(segmentPerp.y));
  }
    public void doActionOnButton2() {
      ArrayList<LatLon> latlons = new ArrayList<LatLon>();

      latlons.add(LatLon.fromDegrees(45.50d, -123.3d));
      //            latlons.add( LatLon.fromDegrees( 45.51d, -123.3d ) );
      latlons.add(LatLon.fromDegrees(45.52d, -123.3d));
      //            latlons.add( LatLon.fromDegrees( 45.53d, -123.3d ) );
      latlons.add(LatLon.fromDegrees(45.54d, -123.3d));
      //            latlons.add( LatLon.fromDegrees( 45.55d, -123.3d ) );
      latlons.add(LatLon.fromDegrees(45.56d, -123.3d));
      //            latlons.add( LatLon.fromDegrees( 45.57d, -123.3d ) );
      latlons.add(LatLon.fromDegrees(45.58d, -123.3d));
      //            latlons.add( LatLon.fromDegrees( 45.59d, -123.3d ) );
      latlons.add(LatLon.fromDegrees(45.60d, -123.3d));

      Sector sector = Sector.fromDegrees(44d, 46d, -123d, -121d);
      //            Sector sector = Sector.boundingSector( latlons );

      double[] elevations = new double[latlons.size()];

      // request resolution of DTED2 (1degree / 3600 )
      double targetResolution = Angle.fromDegrees(1d).radians / 3600;

      double resolutionAchieved =
          this.wwd
              .getModel()
              .getGlobe()
              .getElevationModel()
              .getElevations(sector, latlons, targetResolution, elevations);

      StringBuffer sb = new StringBuffer();
      for (double e : elevations) {
        sb.append("\n").append(e);
      }
      sb.append("\nresolutionAchieved = ").append(resolutionAchieved);
      sb.append(", requested resolution = ").append(targetResolution);

      Logging.logger().info(sb.toString());
    }
  protected int computeCartesianPolygon(
      Globe globe,
      List<? extends LatLon> locations,
      List<Boolean> edgeFlags,
      Vec4[] points,
      Boolean[] edgeFlagArray,
      Matrix[] transform) {
    if (globe == null) {
      String message = Logging.getMessage("nullValue.GlobeIsNull");
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }
    if (locations == null) {
      String message = "nullValue.LocationsIsNull";
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }
    if (points == null) {
      String message = "nullValue.LocationsIsNull";
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }
    if (points.length < (1 + locations.size())) {
      String message =
          Logging.getMessage(
              "generic.ArrayInvalidLength", "points.length < " + (1 + locations.size()));
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }
    if (transform == null) {
      String message = "nullValue.TransformIsNull";
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }
    if (transform.length < 1) {
      String message = Logging.getMessage("generic.ArrayInvalidLength", "transform.length < 1");
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }

    // Allocate space to hold the list of locations and location vertices.
    int locationCount = locations.size();

    // Compute the cartesian points for each location.
    for (int i = 0; i < locationCount; i++) {
      LatLon ll = locations.get(i);
      points[i] = globe.computePointFromPosition(ll.getLatitude(), ll.getLongitude(), 0.0);

      if (edgeFlagArray != null) edgeFlagArray[i] = (edgeFlags != null) ? edgeFlags.get(i) : true;
    }

    // Compute the average of the cartesian points.
    Vec4 centerPoint = Vec4.computeAveragePoint(Arrays.asList(points));

    // Test whether the polygon is closed. If it is not closed, repeat the first vertex.
    if (!points[0].equals(points[locationCount - 1])) {
      points[locationCount] = points[0];
      if (edgeFlagArray != null) edgeFlagArray[locationCount] = edgeFlagArray[0];

      locationCount++;
    }

    // Compute a transform that will map the cartesian points to a local coordinate system centered
    // at the average
    // of the points and oriented with the globe surface.
    Position centerPos = globe.computePositionFromPoint(centerPoint);
    Matrix tx = globe.computeSurfaceOrientationAtPosition(centerPos);
    Matrix txInv = tx.getInverse();
    // Map the cartesian points to a local coordinate space.
    for (int i = 0; i < locationCount; i++) {
      points[i] = points[i].transformBy4(txInv);
    }

    transform[0] = tx;

    return locationCount;
  }
  public BarycentricQuadrilateral(LatLon p00, LatLon p10, LatLon p11, LatLon p01) {
    super(p00, p10, p01);

    this.p11 = new Vec4(p11.getLongitude().getRadians(), p11.getLatitude().getRadians(), 0);
    this.w11 = this.getBarycentricCoords(this.p11);
  }
    public void doActionOnButton4() {
      ArrayList<LatLon> locations = new ArrayList<LatLon>();

      locations.add(LatLon.fromDegrees(45.50d, -123.3d));
      locations.add(LatLon.fromDegrees(45.52d, -123.3d));
      locations.add(LatLon.fromDegrees(45.54d, -123.3d));
      locations.add(LatLon.fromDegrees(45.56d, -123.3d));
      locations.add(LatLon.fromDegrees(45.58d, -123.3d));
      locations.add(LatLon.fromDegrees(45.60d, -123.3d));

      locations.add(LatLon.fromDegrees(40.50d, -120.1d));
      locations.add(LatLon.fromDegrees(40.52d, -120.2d));
      locations.add(LatLon.fromDegrees(40.54d, -120.3d));
      locations.add(LatLon.fromDegrees(40.56d, -120.4d));
      locations.add(LatLon.fromDegrees(40.58d, -120.5d));
      locations.add(LatLon.fromDegrees(40.60d, -120.6d));

      // Now, let's find WMSBasicElevationModel
      WMSBasicElevationModel wmsbem = null;

      ElevationModel model = this.wwd.getModel().getGlobe().getElevationModel();
      if (model instanceof CompoundElevationModel) {
        CompoundElevationModel cbem = (CompoundElevationModel) model;
        for (ElevationModel em : cbem.getElevationModels()) {
          // you can have additional checks if you know specific model name, etc.
          if (em instanceof WMSBasicElevationModel) {
            wmsbem = (WMSBasicElevationModel) em;
            break;
          }
        }
      } else if (model instanceof WMSBasicElevationModel) {
        wmsbem = (WMSBasicElevationModel) model;
      }

      if (null != wmsbem) {
        ElevationsRetriever retriever =
            new ElevationsRetriever(wmsbem, locations, 10000, 30000, new NotifyWhenReady());
        retriever.start();
      } else {
        String message =
            Logging.getMessage(
                "ElevationModel.ExceptionRequestingElevations",
                "No instance of WMSBasicElevationModel was found");
        Logging.logger().severe(message);
      }
    }