예제 #1
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);
  }
예제 #2
0
 @Test
 public void testAntipodalPointsB() {
   LatLon begin = LatLon.fromDegrees(-12.0, 87.0);
   double azimuthRadians = Math.toRadians(-90.0);
   double distanceRadians = Math.toRadians(180.0);
   LatLon end = LatLon.greatCircleEndPosition(begin, azimuthRadians, distanceRadians);
   assertEquals("Antipodal points B (lat)", 12.0, end.getLatitude().degrees, THRESHOLD);
   assertEquals("Antipodal points B (lon)", -93.0, end.getLongitude().degrees, THRESHOLD);
 }
예제 #3
0
 @Test
 public void testAntipodalPointsA() {
   LatLon begin = LatLon.fromDegrees(53.0902505, 112.8935442);
   double azimuthRadians = Math.toRadians(-90.0);
   double distanceRadians = Math.toRadians(180.0);
   LatLon end = LatLon.greatCircleEndPosition(begin, azimuthRadians, distanceRadians);
   assertEquals("Antipodal points A (lat)", -53.0902505, end.getLatitude().degrees, THRESHOLD);
   assertEquals("Antipodal points A (lon)", -67.1064558, end.getLongitude().degrees, THRESHOLD);
 }
예제 #4
0
 @Test
 public void testTrivialAzimuthB() {
   LatLon begin = LatLon.fromDegrees(0.0, 0.0);
   double azimuthRadians = Math.toRadians(90.0);
   double distanceRadians = Math.toRadians(360.0);
   LatLon end = LatLon.greatCircleEndPosition(begin, azimuthRadians, distanceRadians);
   assertEquals("Trivial Azimuth B (lat)", 0.0, end.getLatitude().degrees, THRESHOLD);
   assertEquals("Trivial Azimuth B (lon)", 0.0, end.getLongitude().degrees, THRESHOLD);
 }
예제 #5
0
 @Test
 public void testKnownPointsB() {
   LatLon begin = LatLon.fromDegrees(53.0902505, 112.8935442);
   double azimuthRadians = Math.toRadians(-68.4055227);
   double distanceRadians = Math.toRadians(10.53630354);
   LatLon end = LatLon.greatCircleEndPosition(begin, azimuthRadians, distanceRadians);
   assertEquals("Known points B (lat)", 55.7426290038835, end.getLatitude().degrees, THRESHOLD);
   assertEquals(
       "Known points B (lon)", 95.313127193979270, end.getLongitude().degrees, THRESHOLD);
 }
  protected void doMoveTo(Position oldReferencePosition, Position newReferencePosition) {
    java.util.ArrayList<LatLon> newLocations = new java.util.ArrayList<LatLon>();

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

    this.setLocations(newLocations);
  }
예제 #7
0
 @Test
 public void testKnownPointsA() {
   LatLon begin = LatLon.fromDegrees(-53.0902505, -67.1064558);
   double azimuthRadians = Math.toRadians(15.2204311);
   double distanceRadians = Math.toRadians(-88.7560694);
   LatLon end = LatLon.greatCircleEndPosition(begin, azimuthRadians, distanceRadians);
   assertEquals(
       "Known points A (lat)", -36.63477988750917, end.getLatitude().degrees, THRESHOLD);
   assertEquals(
       "Known points A (lon)", 131.98550742812412, end.getLongitude().degrees, THRESHOLD);
 }
예제 #8
0
 /**
  * Compute the view range footprint on the globe.
  *
  * @param dc the current <code>DrawContext</code>
  * @param steps the number of steps.
  * @return an array list of <code>LatLon</code> forming a closed shape.
  */
 protected ArrayList<LatLon> computeViewFootPrint(DrawContext dc, int steps) {
   ArrayList<LatLon> positions = new ArrayList<LatLon>();
   Position eyePos = dc.getView().getEyePosition();
   Angle distance =
       Angle.fromRadians(
           Math.asin(
               dc.getView().getFarClipDistance()
                   / (dc.getGlobe().getRadius() + eyePos.getElevation())));
   if (distance.degrees > 10) {
     double headStep = 360d / steps;
     Angle heading = Angle.ZERO;
     for (int i = 0; i <= steps; i++) {
       LatLon p = LatLon.greatCircleEndPosition(eyePos, heading, distance);
       positions.add(p);
       heading = heading.addDegrees(headStep);
     }
     return positions;
   } else return null;
 }
  @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();
  }
  /** {@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;
    }
  }
예제 #11
0
  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));
  }
예제 #12
0
  /**
   * Subdivide a list of positions so that no segment is longer then the provided maxLength. Only
   * the positions between start and start + count - 1 will be processed.
   *
   * <p>If needed, new intermediate positions will be created along lines that follow the given
   * pathType - one of Polyline.LINEAR, Polyline.RHUMB_LINE or Polyline.GREAT_CIRCLE. All position
   * elevations will be either at the terrain surface if followTerrain is true, or interpolated
   * according to the original elevations.
   *
   * @param globe the globe to draw elevations and points from.
   * @param positions the original position list
   * @param maxLength the maximum length for one segment.
   * @param followTerrain true if the positions should be on the terrain surface.
   * @param pathType the type of path to use in between two positions.
   * @param start the first position indice in the original list.
   * @param count how many positions from the original list have to be processed and returned.
   * @return a list of positions with no segment longer then maxLength and elevations following
   *     terrain or not.
   */
  protected static ArrayList<? extends Position> subdividePositions(
      Globe globe,
      ArrayList<? extends Position> positions,
      double maxLength,
      boolean followTerrain,
      String pathType,
      int start,
      int count) {
    if (positions == null || positions.size() < start + count) return positions;

    ArrayList<Position> newPositions = new ArrayList<Position>();
    // Add first position
    Position pos1 = positions.get(start);
    if (followTerrain)
      newPositions.add(
          new Position(pos1, globe.getElevation(pos1.getLatitude(), pos1.getLongitude())));
    else newPositions.add(pos1);
    for (int i = 1; i < count; i++) {
      Position pos2 = positions.get(start + i);
      double arcLengthRadians = LatLon.greatCircleDistance(pos1, pos2).radians;
      double arcLength = arcLengthRadians * globe.getRadiusAt(LatLon.interpolate(.5, pos1, pos2));
      if (arcLength > maxLength) {
        // if necessary subdivide segment at regular intervals smaller then maxLength
        Angle segmentAzimuth = null;
        Angle segmentDistance = null;
        int steps = (int) Math.ceil(arcLength / maxLength); // number of intervals - at least two
        for (int j = 1; j < steps; j++) {
          float s = (float) j / steps;
          LatLon destLatLon;
          if (pathType.equals(AVKey.LINEAR)) {
            destLatLon = LatLon.interpolate(s, pos1, pos2);
          } else if (pathType.equals(AVKey.RHUMB_LINE)) {
            if (segmentAzimuth == null) {
              segmentAzimuth = LatLon.rhumbAzimuth(pos1, pos2);
              segmentDistance = LatLon.rhumbDistance(pos1, pos2);
            }
            destLatLon =
                LatLon.rhumbEndPosition(pos1, segmentAzimuth.radians, s * segmentDistance.radians);
          } else // GREAT_CIRCLE
          {
            if (segmentAzimuth == null) {
              segmentAzimuth = LatLon.greatCircleAzimuth(pos1, pos2);
              segmentDistance = LatLon.greatCircleDistance(pos1, pos2);
            }
            destLatLon =
                LatLon.greatCircleEndPosition(
                    pos1, segmentAzimuth.radians, s * segmentDistance.radians);
          }
          // Set elevation
          double elevation;
          if (followTerrain)
            elevation = globe.getElevation(destLatLon.getLatitude(), destLatLon.getLongitude());
          else elevation = pos1.elevation * (1 - s) + pos2.elevation * s;
          // Add new position
          newPositions.add(new Position(destLatLon, elevation));
        }
      }
      // Finally add the segment end position
      if (followTerrain)
        newPositions.add(
            new Position(pos2, globe.getElevation(pos2.getLatitude(), pos2.getLongitude())));
      else newPositions.add(pos2);
      // Prepare for next segment
      pos1 = pos2;
    }
    return newPositions;
  }