コード例 #1
0
 @Test
 public void testTrivialEquivalentPointsC() {
   LatLon begin = LatLon.fromDegrees(90.0, 0.0);
   LatLon end = LatLon.fromDegrees(90.0, 0.0);
   double azimuth = LatLon.greatCircleAzimuth(begin, end).degrees;
   assertEquals("Trivial equivalent points C", 0.0, azimuth, THRESHOLD);
 }
コード例 #2
0
 @Test
 public void testKnownAzimuthE() {
   LatLon begin = LatLon.fromDegrees(-12.0, 87.0);
   LatLon end = LatLon.fromDegrees(53.0902505, -67.1064558);
   double azimuth = LatLon.greatCircleAzimuth(begin, end).degrees;
   assertEquals("Known Azimuth E", -21.38356223882703, azimuth, THRESHOLD);
 }
コード例 #3
0
 @Test
 public void testKnownAzimuthC() {
   LatLon begin = LatLon.fromDegrees(-12.0, 87.0);
   LatLon end = LatLon.fromDegrees(-12.0000001, 86.9999999);
   double azimuth = LatLon.greatCircleAzimuth(begin, end).degrees;
   assertEquals("Known Azimuth C", -135.6329170237546, azimuth, THRESHOLD);
 }
コード例 #4
0
 @Test
 public void testKnownAzimuthD() {
   LatLon begin = LatLon.fromDegrees(-12.0, 87.0);
   LatLon end = LatLon.fromDegrees(11.9999999, -93.0000001);
   double azimuth = LatLon.greatCircleAzimuth(begin, end).degrees;
   assertEquals("Known Azimuth D", 135.6329170162944, azimuth, THRESHOLD);
 }
コード例 #5
0
 @Test
 public void testKnownAzimuthB() {
   LatLon begin = LatLon.fromDegrees(53.0902505, 112.8935442);
   LatLon end = LatLon.fromDegrees(-53.0902505, -67.1064558);
   double azimuth = LatLon.greatCircleAzimuth(begin, end).degrees;
   assertEquals("Known Azimuth B", -90.0, azimuth, THRESHOLD);
 }
コード例 #6
0
 @Test
 public void testKnownAzimuthA() {
   LatLon begin = LatLon.fromDegrees(-90.0, -180.0);
   LatLon end = LatLon.fromDegrees(90.0, 180.0);
   double azimuth = LatLon.greatCircleAzimuth(begin, end).degrees;
   assertEquals("Known Azimuth A", 0.0, azimuth, THRESHOLD);
 }
コード例 #7
0
 @Test
 public void testEquivalentPoints() {
   LatLon begin = LatLon.fromDegrees(53.0902505, 112.8935442);
   LatLon end = LatLon.fromDegrees(53.0902505, 112.8935442);
   double azimuth = LatLon.greatCircleAzimuth(begin, end).degrees;
   assertEquals("Equivalent points", 0.0, azimuth, THRESHOLD);
 }
コード例 #8
0
  /**
   * {@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);
    }
  }
コード例 #9
0
 @Test
 public void testTrivialWest() {
   LatLon begin = LatLon.fromDegrees(0.0, 0.0);
   LatLon end = LatLon.fromDegrees(0.0, -90.0);
   double azimuth = LatLon.greatCircleAzimuth(begin, end).degrees;
   assertEquals("Trivial West greatCircleAzimuth", -90.0, azimuth, THRESHOLD);
 }
コード例 #10
0
  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);
  }
コード例 #11
0
ファイル: SearchArea.java プロジェクト: metsci/worldwind
  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);
  }
コード例 #12
0
ファイル: SearchArea.java プロジェクト: metsci/worldwind
  /**
   * 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);
  }
コード例 #13
0
  @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();
  }
コード例 #14
0
 protected void setCursor(MeasureTool.ControlPoint controlPoint) {
   // TODO: handle 'rotating' mode cursor is this.isRotating() - when using Alt key on regular
   // shapes
   if (controlPoint == null) {
     setComponentCursor(null);
   } else {
     if (this.measureTool.isRegularShape()) {
       if (this.measureTool.isCornerControl(controlPoint)) {
         Angle azimuth =
             LatLon.greatCircleAzimuth(
                 controlPoint.getPosition(), this.measureTool.getCenterPosition());
         // Account for view heading in cursor selection
         azimuth = azimuth.subtract(this.measureTool.getWwd().getView().getHeading());
         setComponentCursor(selectResizeCursor(azimuth));
       } else if (this.measureTool.isCenterControl(controlPoint)) {
         setComponentCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
       }
     } else {
       // Line, path and polygon
       setComponentCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
     }
   }
 }
コード例 #15
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));
  }
コード例 #16
0
 /**
  * Move the shape to the specified new position
  *
  * @param oldPosition Previous position of shape
  * @param newPosition New position for shape
  */
 protected void moveToPosition(Position oldPosition, Position newPosition) {
   Angle distanceAngle = LatLon.greatCircleDistance(oldPosition, newPosition);
   Angle azimuthAngle = LatLon.greatCircleAzimuth(oldPosition, newPosition);
   measureTool.moveMeasureShape(azimuthAngle, distanceAngle);
   measureTool.firePropertyChange(MeasureTool.EVENT_POSITION_REPLACE, oldPosition, newPosition);
 }
コード例 #17
0
 protected Angle computeHeading(Position pa, Position pb) {
   return LatLon.greatCircleAzimuth(pa, pb);
 }
コード例 #18
0
ファイル: LengthMeasurer.java プロジェクト: kedzie/WWA
  /**
   * 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;
  }