/**
   * _more_
   *
   * @param stationLat _more_
   * @param stationLon _more_
   * @throws RemoteException _more_
   * @throws VisADException _more_
   */
  protected void initLinePosition(float stationLat, float stationLon)
      throws VisADException, RemoteException {
    if (getVerticalAxisRange() == null) {
      setVerticalAxisRange(new Range(0, 20000));
    }
    //   get station location from the data coordinate transform

    LatLonPointImpl lp1 = Bearing.findPoint(stationLat, stationLon, 0, 150.0f, null);

    LatLonPointImpl lp2 = Bearing.findPoint(stationLat, stationLon, 180, 150.0f, null);

    startLocation = new EarthLocationTuple(lp2.getLatitude(), lp2.getLongitude(), 0.0);
    endLocation = new EarthLocationTuple(lp1.getLatitude(), lp1.getLongitude(), 0.0);
  }
예제 #2
0
  /**
   * @param refPt The geodetic position of the reference point.
   * @param neiPt The holder for the geodetic position of the neighboring grid point.
   * @param lat The latitude of the neighboring grid point.
   * @param lon The longitude of the neighboring grid point.
   * @param azTerm An amount in degrees to be added to the computed azimuth.
   * @param bearing The holder for the computed range and bearing from the reference point to the
   *     neighboring grid point.
   * @param hat 2-element output array for computed (x,y) components of unit vector.
   */
  private static void compute(
      LatLonPointImpl refPt,
      LatLonPointImpl neiPt,
      float lat,
      float lon,
      float azTerm,
      Bearing bearing,
      float[] hat) {

    neiPt.set(lat, lon);
    Bearing.calculateBearing(refPt, neiPt, bearing);

    float az = (float) Math.toRadians(bearing.getAngle() + azTerm);
    // System.out.println("bearing.Angle = " + bearing.getAngle() + "; azTerm = " + azTerm+ ";
    // result= " + Math.toDegrees(az));

    hat[0] = (float) Math.sin(az);
    hat[1] = (float) Math.cos(az);
  }
예제 #3
0
  /**
   * @param refPt The geodetic position of the reference point.
   * @param neiPt The holder for the geodetic position of the neighboring grid point.
   * @param lat The latitude of the neighboring grid point.
   * @param lon The longitude of the neighboring grid point.
   * @param azTerm An amount in degrees to be added to the computed azimuth.
   * @param wind Magnitude of grid-relative wind component.
   * @param bearing The holder for the computed range and bearing from the reference point to the
   *     neighboring grid point.
   * @param uv 2-element output array for computed (U,V) wind components.
   */
  private static void compute(
      LatLonPointImpl refPt,
      LatLonPointImpl neiPt,
      float lat,
      float lon,
      float azTerm,
      float wind,
      Bearing bearing,
      float[] uv) {

    neiPt.set(lat, lon);
    Bearing.calculateBearing(refPt, neiPt, bearing);

    float az = (float) Math.toRadians(bearing.getAngle() + azTerm);
    float xhat = (float) Math.sin(az);
    float yhat = (float) Math.cos(az);

    uv[0] = xhat * wind;
    uv[1] = yhat * wind;
  }
예제 #4
0
 /**
  * Test the calculations - forward and back
  *
  * @param args non used
  */
 public static void main(String[] args) {
   // Bearing         workBearing = new Bearing();
   LatLonPointImpl pt1 = new LatLonPointImpl(40, -105);
   LatLonPointImpl pt2 = new LatLonPointImpl(37.4, -118.4);
   Bearing b = calculateBearing(pt1, pt2, null);
   System.out.println("Bearing from " + pt1 + " to " + pt2 + " = \n\t" + b);
   LatLonPointImpl pt3 = new LatLonPointImpl();
   pt3 = findPoint(pt1, b.getAngle(), b.getDistance(), pt3);
   System.out.println("using first point, angle and distance, found second point at " + pt3);
   pt3 = findPoint(pt2, b.getBackAzimuth(), b.getDistance(), pt3);
   System.out.println("using second point, backazimuth and distance, found first point at " + pt3);
   /*  uncomment for timing tests
   for(int j=0;j<10;j++) {
       long t1 = System.currentTimeMillis();
       for(int i=0;i<30000;i++) {
           workBearing = Bearing.calculateBearing(42.5,-93.0,
                                                  48.9,-117.09,workBearing);
       }
       long t2 = System.currentTimeMillis();
       System.err.println ("time:" + (t2-t1));
   }
   */
 }
예제 #5
0
  /**
   * @param grid The grid.
   * @param gridWinds The grid-relative winds.
   * @param cs The coordinate system transformation of the grid.
   * @param index The index of the grid-relative wind component.
   * @param latI The index of latitude in the reference coordinate system.
   * @param lonI The index of longitude in the reference coordinate system.
   * @param us The array in which to add the computed U-component of the wind.
   * @param us The array in which to add the computed V-component of the wind.
   * @param vs
   * @throws IndexOutOfBoundsException if <code>gridWinds</code>, <code>us
   *                                   </code>, or <code>vs</code> is too small.
   * @throws VisADException if a VisAD failure occurs.
   */
  private static void addComponent(
      SampledSet grid,
      float[][] gridWinds,
      CoordinateSystem cs,
      int index,
      int latI,
      int lonI,
      float[] us,
      float[] vs)
      throws VisADException {

    int[][] neighbors = grid.getNeighbors(index);
    LatLonPointImpl refPt = new LatLonPointImpl();
    LatLonPointImpl neiPt = new LatLonPointImpl();
    Bearing bearing = new Bearing();
    float[] uv1 = new float[2];
    float[] uv2 = new float[2];
    boolean hasCS = cs != null;
    float[][] domainSamples = grid.getSamples(false);
    float[][] crefCoords = (hasCS) ? cs.toReference(Set.copyFloats(domainSamples)) : domainSamples;
    // If the grid is lat/lon or has an IdentityCoordinateSystem
    // don't do the rotation
    // TODO:  handle rotated lat/lon grids
    if (!hasCS
        || (crefCoords == domainSamples)
        || (Arrays.equals(crefCoords[latI], domainSamples[latI])
            && Arrays.equals(crefCoords[lonI], domainSamples[lonI]))) {
      // us = gridWinds[0];
      // vs = gridWinds[1];
      System.arraycopy(gridWinds[0], 0, us, 0, us.length);
      System.arraycopy(gridWinds[1], 0, vs, 0, vs.length);
    } else {

      for (int i = 0; i < neighbors.length; i++) {

        float[][] refCoords = grid.indexToValue(new int[] {i});
        if (hasCS) {
          refCoords = cs.toReference(refCoords);
        }

        float[][] neiCoords = grid.indexToValue(neighbors[i]);
        if (hasCS) {
          neiCoords = cs.toReference(neiCoords);
        }

        refPt.set(refCoords[latI][0], refCoords[lonI][0]);

        compute(
            refPt,
            neiPt,
            neiCoords[latI][0],
            neiCoords[lonI][0],
            -180,
            gridWinds[index][i],
            bearing,
            uv1);

        float d1 = (float) bearing.getDistance();

        compute(
            refPt,
            neiPt,
            neiCoords[latI][1],
            neiCoords[lonI][1],
            0,
            gridWinds[index][i],
            bearing,
            uv2);

        float d2 = (float) bearing.getDistance();
        boolean bad1 = Double.isNaN(d1);
        boolean bad2 = Double.isNaN(d2);

        if (bad1 && bad2) {
          us[i] = Float.NaN;
          vs[i] = Float.NaN;
        } else {
          if (bad1) {
            us[i] += uv2[0];
            vs[i] += uv2[1];
          } else if (bad2) {
            us[i] += uv1[0];
            vs[i] += uv1[1];
          } else {
            float tot = d1 + d2;
            float c1 = d2 / tot;
            float c2 = d1 / tot;

            us[i] += c1 * uv1[0] + c2 * uv2[0];
            vs[i] += c1 * uv1[1] + c2 * uv2[1];
          }
        }
      }
    }
  }
예제 #6
0
  /**
   * I have no idea what this does.
   *
   * @param grid sampling grid
   * @param index some sort of index
   * @return a new flat field with something different
   * @throws RemoteException Java RMI error
   * @throws VisADException VisAD error
   */
  private static FlatField hatFieldOld(Set grid, int index) throws VisADException, RemoteException {

    CoordinateSystem cs = grid.getCoordinateSystem();
    boolean hasCS = (cs != null);

    RealTupleType rtt = (hasCS) ? cs.getReference() : ((SetType) grid.getType()).getDomain();

    int latI = rtt.getIndex(RealType.Latitude);

    if (latI == -1) {
      throw new IllegalArgumentException(grid.toString());
    }

    int lonI = rtt.getIndex(RealType.Longitude);

    if (lonI == -1) {
      throw new IllegalArgumentException(grid.toString());
    }

    if (grid.getManifoldDimension() < 2) {
      throw new IllegalArgumentException(grid.toString());
    }

    int[][] neighbors = grid.getNeighbors(index);
    LatLonPointImpl refPt = new LatLonPointImpl();
    LatLonPointImpl neiPt = new LatLonPointImpl();
    Bearing bearing = new Bearing();
    float[] hat1 = new float[2];
    float[] hat2 = new float[2];
    float[][] hat = new float[2][grid.getLength()];

    for (int i = 0; i < neighbors.length; i++) {
      float[][] refCoords = grid.indexToValue(new int[] {i});
      if (hasCS) {
        refCoords = cs.toReference(refCoords);
      }

      float[][] neiCoords = grid.indexToValue(neighbors[i]);
      if (hasCS) {
        neiCoords = cs.toReference(neiCoords);
      }

      refPt.set(refCoords[latI][0], refCoords[lonI][0]);
      compute(refPt, neiPt, neiCoords[latI][0], neiCoords[lonI][0], -180, bearing, hat1);

      float d1 = (float) bearing.getDistance();

      compute(refPt, neiPt, neiCoords[latI][1], neiCoords[lonI][1], 0, bearing, hat2);

      float d2 = (float) bearing.getDistance();
      boolean bad1 = Double.isNaN(d1);
      boolean bad2 = Double.isNaN(d2);

      if (bad1 && bad2) {
        hat[0][i] = Float.NaN;
        hat[1][i] = Float.NaN;
      } else {
        if (bad1) {
          hat[0][i] = hat2[0];
          hat[1][i] = hat2[1];
        } else if (bad2) {
          hat[0][i] = hat1[0];
          hat[1][i] = hat1[1];
        } else {
          float tot = d1 + d2;
          float c1 = d2 / tot;
          float c2 = d1 / tot;
          float xhat = c1 * hat1[0] + c2 * hat2[0];
          float yhat = c1 * hat1[1] + c2 * hat2[1];
          float mag = (float) Math.sqrt(xhat * xhat + yhat * yhat);

          hat[0][i] = xhat / mag;
          hat[1][i] = yhat / mag;
        }
      }
    }

    FlatField hatField =
        new FlatField(
            new FunctionType(
                ((SetType) grid.getType()).getDomain(),
                new RealTupleType(
                    RealType.getRealType("xHat", CommonUnit.dimensionless),
                    RealType.getRealType("yHat", CommonUnit.dimensionless))),
            grid);

    hatField.setSamples(hat, false);

    return hatField;
  }
예제 #7
0
  /**
   * The returned {@link visad.FlatField} will have NaN-s for those unit vector components that
   * could not be computed.
   *
   * @param grid The spatial grid.
   * @param index The index of the manifold dimension along which to compute the unit vector.
   * @return A field of components of the unit vector for the given manifold dimension.
   * @throws NullPointerException if the grid is <code>null</code>.
   * @throws IllegalArgumentException if the manifold dimension of the grid is less than 2 or if the
   *     grid doesn't contain {@link visad.RealType#Latitude} and {@link visad.RealType#Longitude}.
   * @throws VisADException if a VisAD failure occurs.
   * @throws RemoteException if a Java RMI failure occurs.
   */
  private static FlatField hatFieldNew(Set grid, int index) throws VisADException, RemoteException {

    CoordinateSystem cs = grid.getCoordinateSystem();
    boolean hasCS = cs != null;

    RealTupleType rtt = (hasCS) ? cs.getReference() : ((SetType) grid.getType()).getDomain();

    int latI = rtt.getIndex(RealType.Latitude);

    if (latI == -1) {
      throw new IllegalArgumentException(rtt.toString());
    }

    int lonI = rtt.getIndex(RealType.Longitude);
    if (lonI == -1) {
      throw new IllegalArgumentException(rtt.toString());
    }

    if (grid.getManifoldDimension() < 2) {
      throw new IllegalArgumentException(grid.toString());
    }

    int[][] neighbors = grid.getNeighbors(index);
    LatLonPointImpl refPt = new LatLonPointImpl();
    LatLonPointImpl neiPt = new LatLonPointImpl();
    Bearing bearing = new Bearing();
    float[] hat1 = new float[2];
    float[] hat2 = new float[2];
    float[][] hat = new float[2][grid.getLength()];

    float[][] refCoords = null;
    float[][] neiCoords = null;
    float[][] domainSamples = grid.getSamples(false);

    refCoords = (hasCS) ? cs.toReference(Set.copyFloats(domainSamples)) : domainSamples;
    // If the grid is lat/lon or has an IdentityCoordinateSystem
    // don't do the rotation
    // TODO:  handle rotated lat/lon grids
    if (!hasCS
        || (refCoords == domainSamples)
        || (Arrays.equals(refCoords[latI], domainSamples[latI])
            && Arrays.equals(refCoords[lonI], domainSamples[lonI]))) {
      if (index == 0) {
        Arrays.fill(hat[0], 1);
        Arrays.fill(hat[1], 0);
      } else {
        Arrays.fill(hat[0], 0);
        Arrays.fill(hat[1], 1);
      }
    } else {

      float latBefore, lonBefore, latAfter, lonAfter;
      // int backOffset = (index==0) ? -180 : 0;
      // int foreOffset = (index==0) ? 0 : -180;
      int backOffset = -180;
      int foreOffset = 0;
      for (int i = 0; i < neighbors.length; i++) {
        refPt.set(refCoords[latI][i], refCoords[lonI][i]);
        if ((neighbors[i][0] < 0) || (neighbors[i][0] >= neighbors.length)) {
          latBefore = Float.NaN;
          lonBefore = Float.NaN;
        } else {
          latBefore = refCoords[latI][neighbors[i][0]];
          lonBefore = refCoords[lonI][neighbors[i][0]];
        }
        if ((neighbors[i][1] < 0) || (neighbors[i][1] >= neighbors.length)) {
          latAfter = Float.NaN;
          lonAfter = Float.NaN;
        } else {
          latAfter = refCoords[latI][neighbors[i][1]];
          lonAfter = refCoords[lonI][neighbors[i][1]];
        }

        compute(refPt, neiPt, latBefore, lonBefore, backOffset, bearing, hat1);

        float d1 = (float) bearing.getDistance();

        compute(refPt, neiPt, latAfter, lonAfter, foreOffset, bearing, hat2);

        float d2 = (float) bearing.getDistance();
        boolean bad1 = Double.isNaN(d1);
        boolean bad2 = Double.isNaN(d2);

        if (bad1 && bad2) {
          hat[0][i] = Float.NaN;
          hat[1][i] = Float.NaN;
        } else {
          if (bad1) {
            hat[0][i] = hat2[0];
            hat[1][i] = hat2[1];
          } else if (bad2) {
            hat[0][i] = hat1[0];
            hat[1][i] = hat1[1];
          } else {
            float tot = d1 + d2;
            float c1 = d2 / tot;
            float c2 = d1 / tot;
            float xhat = c1 * hat1[0] + c2 * hat2[0];
            float yhat = c1 * hat1[1] + c2 * hat2[1];
            float mag = (float) Math.sqrt(xhat * xhat + yhat * yhat);

            hat[0][i] = xhat / mag;
            hat[1][i] = yhat / mag;
          }
        }
      }
    }

    FlatField hatField =
        new FlatField(
            new FunctionType(
                ((SetType) grid.getType()).getDomain(),
                new RealTupleType(
                    RealType.getRealType("xHat", CommonUnit.dimensionless),
                    RealType.getRealType("yHat", CommonUnit.dimensionless))),
            grid);

    hatField.setSamples(hat, false);
    return hatField;
  }
예제 #8
0
  /**
   * Computes distance (in km), azimuth (degrees clockwise positive from North, 0 to 360), and back
   * azimuth (degrees clockwise positive from North, 0 to 360), from latitude-longituide point pt1
   * to latitude-longituide pt2.
   *
   * <p>Algorithm from U.S. National Geodetic Survey, FORTRAN program "inverse," subroutine
   * "INVER1," by L. PFEIFER and JOHN G. GERGEN. See
   * http://www.ngs.noaa.gov/TOOLS/Inv_Fwd/Inv_Fwd.html
   *
   * <p>Original documentation: <br>
   * SOLUTION OF THE GEODETIC INVERSE PROBLEM AFTER T.VINCENTY <br>
   * MODIFIED RAINSFORD'S METHOD WITH HELMERT'S ELLIPTICAL TERMS <br>
   * EFFECTIVE IN ANY AZIMUTH AND AT ANY DISTANCE SHORT OF ANTIPODAL <br>
   * STANDPOINT/FOREPOINT MUST NOT BE THE GEOGRAPHIC POLE Reference ellipsoid is the WGS-84
   * ellipsoid. <br>
   * See http://www.colorado.edu/geography/gcraft/notes/datum/elist.html
   *
   * <p>Requires close to 1.4 E-5 seconds wall clock time per call on a 550 MHz Pentium with Linux
   * 7.2.
   *
   * @param e Earth object (defines radius and flattening)
   * @param lat1 Lat of point 1
   * @param lon1 Lon of point 1
   * @param lat2 Lat of point 2
   * @param lon2 Lon of point 2
   * @param result put result here, or null to allocate
   * @return a Bearing object with distance (in km), azimuth from pt1 to pt2 (degrees, 0 = north,
   *     clockwise positive)
   */
  public static Bearing calculateBearing(
      Earth e, double lat1, double lon1, double lat2, double lon2, Bearing result) {

    if (result == null) {
      result = new Bearing();
    }

    if ((lat1 == lat2) && (lon1 == lon2)) {
      result.distance = 0;
      result.azimuth = 0;
      result.backazimuth = 0;
      return result;
    }

    A = e.getMajor();
    F = e.getFlattening();
    R = 1.0 - F;

    // Algorithm from National Geodetic Survey, FORTRAN program "inverse,"
    // subroutine "INVER1," by L. PFEIFER and JOHN G. GERGEN.
    // http://www.ngs.noaa.gov/TOOLS/Inv_Fwd/Inv_Fwd.html
    // Conversion to JAVA from FORTRAN was made with as few changes as possible
    // to avoid errors made while recasting form, and to facilitate any future
    // comparisons between the original code and the altered version in Java.
    // Original documentation:
    // SOLUTION OF THE GEODETIC INVERSE PROBLEM AFTER T.VINCENTY
    // MODIFIED RAINSFORD'S METHOD WITH HELMERT'S ELLIPTICAL TERMS
    // EFFECTIVE IN ANY AZIMUTH AND AT ANY DISTANCE SHORT OF ANTIPODAL
    // STANDPOINT/FOREPOINT MUST NOT BE THE GEOGRAPHIC POLE
    // A IS THE SEMI-MAJOR AXIS OF THE REFERENCE ELLIPSOID
    // F IS THE FLATTENING (NOT RECIPROCAL) OF THE REFERNECE ELLIPSOID
    // LATITUDES GLAT1 AND GLAT2
    // AND LONGITUDES GLON1 AND GLON2 ARE IN RADIANS POSITIVE NORTH AND EAST
    // FORWARD AZIMUTHS AT BOTH POINTS RETURNED IN RADIANS FROM NORTH
    //
    // Reference ellipsoid is the WGS-84 ellipsoid.
    // See http://www.colorado.edu/geography/gcraft/notes/datum/elist.html
    // FAZ is forward azimuth in radians from pt1 to pt2;
    // BAZ is backward azimuth from point 2 to 1;
    // S is distance in meters.
    //
    // Conversion to JAVA from FORTRAN was made with as few changes as possible
    // to avoid errors made while recasting form, and to facilitate any future
    // comparisons between the original code and the altered version in Java.
    //
    // IMPLICIT REAL*8 (A-H,O-Z)
    //  COMMON/CONST/PI,RAD
    //  COMMON/ELIPSOID/A,F
    double GLAT1 = rad * lat1;
    double GLAT2 = rad * lat2;
    double TU1 = R * Math.sin(GLAT1) / Math.cos(GLAT1);
    double TU2 = R * Math.sin(GLAT2) / Math.cos(GLAT2);
    double CU1 = 1. / Math.sqrt(TU1 * TU1 + 1.);
    double SU1 = CU1 * TU1;
    double CU2 = 1. / Math.sqrt(TU2 * TU2 + 1.);
    double S = CU1 * CU2;
    double BAZ = S * TU2;
    double FAZ = BAZ * TU1;
    double GLON1 = rad * lon1;
    double GLON2 = rad * lon2;
    double X = GLON2 - GLON1;
    double D, SX, CX, SY, CY, Y, SA, C2A, CZ, E, C;
    int loopCnt = 0;
    do {
      loopCnt++;
      // Check for an infinite loop
      if (loopCnt > 1000) {
        throw new IllegalArgumentException(
            "Too many iterations calculating bearing:"
                + lat1
                + " "
                + lon1
                + " "
                + lat2
                + " "
                + lon2);
      }
      SX = Math.sin(X);
      CX = Math.cos(X);
      TU1 = CU2 * SX;
      TU2 = BAZ - SU1 * CU2 * CX;
      SY = Math.sqrt(TU1 * TU1 + TU2 * TU2);
      CY = S * CX + FAZ;
      Y = Math.atan2(SY, CY);
      SA = S * SX / SY;
      C2A = -SA * SA + 1.;
      CZ = FAZ + FAZ;
      if (C2A > 0.) {
        CZ = -CZ / C2A + CY;
      }
      E = CZ * CZ * 2. - 1.;
      C = ((-3. * C2A + 4.) * F + 4.) * C2A * F / 16.;
      D = X;
      X = ((E * CY * C + CZ) * SY * C + Y) * SA;
      X = (1. - C) * X * F + GLON2 - GLON1;
      // IF(DABS(D-X).GT.EPS) GO TO 100
    } while (Math.abs(D - X) > EPS);

    if (loopCnt > maxLoopCnt) {
      maxLoopCnt = loopCnt;
      //        System.err.println("loopCnt:" + loopCnt);
    }

    FAZ = Math.atan2(TU1, TU2);
    BAZ = Math.atan2(CU1 * SX, BAZ * CX - SU1 * CU2) + Math.PI;
    X = Math.sqrt((1. / R / R - 1.) * C2A + 1.) + 1.;
    X = (X - 2.) / X;
    C = 1. - X;
    C = (X * X / 4. + 1.) / C;
    D = (0.375 * X * X - 1.) * X;
    X = E * CY;
    S = 1. - E - E;
    S = ((((SY * SY * 4. - 3.) * S * CZ * D / 6. - X) * D / 4. + CZ) * SY * D + Y) * C * A * R;

    result.distance = S / 1000.0; // meters to km
    result.azimuth = FAZ * deg; // radians to degrees

    if (result.azimuth < 0.0) {
      result.azimuth += 360.0; // reset azs from -180 to 180 to 0 to 360
    }

    result.backazimuth = BAZ * deg; // radians to degrees; already in 0 to 360 range

    return result;
  }
예제 #9
0
  /**
   * Handle glyph moved
   *
   * @throws RemoteException On badness
   * @throws VisADException On badness
   */
  public void updateLocation() throws VisADException, RemoteException {
    super.updateLocation();
    if (points.size() < 2) {
      return;
    }
    if (showText) {
      setText(startTextDisplayable, 0, startText, startTextType);
      setText(endTextDisplayable, 1, endText, endTextType);
    }

    checkBoxVisibility();
    if ((maxDataDistance == null) || (maxDistanceBox == null)) {
      return;
    }
    double km = maxDataDistance.getValue(CommonUnit.meter) / 1000.0;
    if (km > 2000) {
      return;
    }

    EarthLocation p1 = (EarthLocation) points.get(0);
    EarthLocation p2 = (EarthLocation) points.get(1);

    MathType mathType = RealTupleType.LatitudeLongitudeAltitude;

    Bearing baseBearing =
        Bearing.calculateBearing(
            p1.getLatitude().getValue(),
            p1.getLongitude().getValue(),
            p2.getLatitude().getValue(),
            p2.getLongitude().getValue(),
            null);

    double baseAngle = baseBearing.getAngle();

    LatLonPointImpl[] llps =
        new LatLonPointImpl[] {
          Bearing.findPoint(
              p1.getLatitude().getValue(),
              p1.getLongitude().getValue(),
              baseAngle + 90.0,
              km,
              null),
          Bearing.findPoint(
              p2.getLatitude().getValue(),
              p2.getLongitude().getValue(),
              baseAngle + 90.0,
              km,
              null),
          Bearing.findPoint(
              p2.getLatitude().getValue(), p2.getLongitude().getValue(), baseAngle - 90, km, null),
          Bearing.findPoint(
              p1.getLatitude().getValue(), p1.getLongitude().getValue(), baseAngle - 90, km, null),
          Bearing.findPoint(
              p1.getLatitude().getValue(), p1.getLongitude().getValue(), baseAngle + 90.0, km, null)
        };

    float[][] lineVals = getPointValues();
    float alt = lineVals[2][0];
    lineVals = new float[3][llps.length];
    for (int i = 0; i < lineVals[0].length; i++) {
      lineVals[0][i] = (float) llps[i].getLatitude();
      lineVals[1][i] = (float) llps[i].getLongitude();
    }

    float[][] tmp = new float[3][];

    for (int i = 0; i < lineVals[0].length - 1; i++) {
      tmp[0] =
          Misc.merge(
              tmp[0],
              Misc.interpolate(
                  2 + getNumInterpolationPoints(), lineVals[0][i], lineVals[0][i + 1]));
      tmp[1] =
          Misc.merge(
              tmp[1],
              Misc.interpolate(
                  2 + getNumInterpolationPoints(), lineVals[1][i], lineVals[1][i + 1]));
    }

    tmp[2] = new float[tmp[0].length];
    lineVals = tmp;

    for (int i = 0; i < lineVals[0].length; i++) {
      lineVals[2][i] = alt;
    }

    Data theData = new Gridded3DSet(mathType, lineVals, lineVals[0].length);
    maxDistanceBox.setData(theData);
  }