gt:             double resAlt = this.results.get(i).getPoint().getAltitude();
context: package ch.hgdev.toposuite.calculation;
  
  import com.google.common.math.DoubleMath;
  
  import org.json.JSONArray;
  import org.json.JSONException;
  import org.json.JSONObject;
  
  import java.io.Serializable;
  import java.util.ArrayList;
  import java.util.Date;
  import java.util.List;
  
  import ch.hgdev.toposuite.App;
  import ch.hgdev.toposuite.R;
  import ch.hgdev.toposuite.SharedResources;
  import ch.hgdev.toposuite.calculation.activities.freestation.FreeStationActivity;
  import ch.hgdev.toposuite.points.Point;
  import ch.hgdev.toposuite.utils.MathUtils;
  
  public class FreeStation extends Calculation {
      private static final String STATION_NUMBER = "station_number";
      private static final String MEASURES = "measures";
      private static final String INSTRUMENT = "instrument";
  
      private String stationNumber;
      private ArrayList<Measure> measures;
      /**
       * Height of the instrument (I).
       */
      private double i;
  
      private Point stationResult;
      private final ArrayList<Result> results;
      private double unknownOrientation;
      private double scaleFactor;
  
      /**
       * Mean east error.
       */
      private double sE;
  
      /**
       * Mean north error.
       */
      private double sN;
  
      /**
       * Mean altitude error.
       */
      private double sA;
  
      /**
       * Mean FS.
       */
      private double meanFS;
  
      public FreeStation(String _stationNumber, double _i, boolean hasDAO) {
          super(CalculationType.FREESTATION, App.getContext().getString(
                  R.string.title_activity_free_station), hasDAO);
  
          this.stationNumber = _stationNumber;
          this.i = _i;
          this.measures = new ArrayList<>();
          this.results = new ArrayList<>();
          this.scaleFactor = MathUtils.IGNORE_DOUBLE;
      }
  
      public FreeStation(String _stationNumber, boolean hasDAO) {
          this(_stationNumber, MathUtils.IGNORE_DOUBLE, hasDAO);
      }
  
      public FreeStation(boolean hasDAO) {
          this("", hasDAO);
      }
  
      public FreeStation(long id, Date lastModification) {
          super(id, CalculationType.FREESTATION, App.getContext().getString(
                  R.string.title_activity_free_station),
                  lastModification, true);
  
          this.measures = new ArrayList<>();
          this.results = new ArrayList<>();
          this.scaleFactor = MathUtils.IGNORE_DOUBLE;
      }
  
      @Override
      public void compute() throws CalculationException {
          if (this.measures.size() < 3) {
              throw new CalculationException("not enough measures provided");
          }
  
          // since we need to adjust some measures for the computation, use a copy
          // this prevents future calls to compute() to modify the measures (see #731)
          ArrayList<Measure> measuresCopy = new ArrayList<>(this.measures.size());
          for (Measure m : this.measures) {
              // zenithal angle value is optional, needs to be 100.0 by default
              if (MathUtils.isIgnorable(m.getZenAngle())) {
                  m.setZenAngle(100.0); // default value for zenithal angle
              }
              measuresCopy.add(new Measure(m));
          }
  
          if (!this.hasDeactivatedMeasure(measuresCopy)) {
              this.results.clear();
          }
  
          this.sE = 0.0;
          this.sN = 0.0;
          this.sA = 0.0;
          this.meanFS = 0.0;
  
          // fictive coordinates centroid
          double centroidYFict = 0.0;
          double centroidXFict = 0.0;
          Point centroidFict;
  
          // cadastral coordinates centroid
          double centroidYCadast = 0.0;
          double centroidXCadast = 0.0;
          Point centroidCadast;
  
          // altitude related stuff
          double totalWeights = 0.0;
          double meanAltitude = 0.0;
          int nbAltitudes = 0;
  
          int numberOfDeactivatedOrientations = 0;
          int index = -1;
  
          for (Measure m : measuresCopy) {
              index++;
  
              if (m.isDeactivated()) {
                  numberOfDeactivatedOrientations++;
                  continue;
              }
              Point res = new Point(m.getPoint().getNumber(), m.getPoint().getEast(),
                      m.getPoint().getNorth(), m.getPoint().getAltitude(),
                      false, false);
  
              double hz = MathUtils.modulo400(m.getHorizDir());
              double zenAngle = MathUtils.gradToRad(MathUtils.modulo400(m.getZenAngle()));
              double horizDist = m.getDistance() * Math.sin(zenAngle);
              if (!MathUtils.isIgnorable(m.getLonDepl())) {
                  horizDist += m.getLonDepl();
              }
              if (!MathUtils.isIgnorable(m.getLatDepl())) {
                  hz += MathUtils.radToGrad(Math.atan(m.getLatDepl() / horizDist));
                  horizDist = MathUtils.pythagoras(horizDist, m.getLatDepl());
              }
              // the distance, here horizontal distance, is used later on
              m.setDistance(horizDist);
              m.setHorizDir(hz);
  
              res.setEast(MathUtils.pointLanceEast(0, hz, horizDist));
              res.setNorth(MathUtils.pointLanceNorth(0, hz, horizDist));
  
              double weight = 0.0;
              if (!MathUtils.isIgnorable(m.getPoint().getAltitude())
                      && MathUtils.isPositive(m.getPoint().getAltitude())
                      && MathUtils.isIgnorable(m.getLatDepl())
                      && MathUtils.isIgnorable(m.getLonDepl())
                      && !MathUtils.isIgnorable(this.i)
                      && MathUtils.isPositive(this.i)) {
                  res.setAltitude(res.getAltitude() - MathUtils.nivellTrigo(
                          horizDist, m.getZenAngle(), this.i, m.getS(), res.getAltitude()));
                  weight = 1 / Math.pow((horizDist / 1000), 2);
  
                  totalWeights += weight;
                  meanAltitude += weight * res.getAltitude();
                  nbAltitudes++;
              } else {
                  res.setAltitude(MathUtils.IGNORE_DOUBLE);
              }
  
              if (!this.hasDeactivatedMeasure(measuresCopy)) {
                  this.results.add(new Result(res, weight));
              } else {
                  // just used as tmp variable for modifying the pointed value of
                  // the current result
                  Result oldResult = this.results.get(index);
                  oldResult = new Result(res, weight);
              }
  
              // centroid calculation
              centroidYFict += res.getEast();
              centroidXFict += res.getNorth();
  
              centroidYCadast += m.getPoint().getEast();
              centroidXCadast += m.getPoint().getNorth();
          }
  
          int n = this.results.size() - numberOfDeactivatedOrientations;
          centroidFict = new Point("", centroidYFict / n, centroidXFict / n,
                  MathUtils.IGNORE_DOUBLE, false, false);
          centroidCadast = new Point("", centroidYCadast / n, centroidXCadast / n,
                  MathUtils.IGNORE_DOUBLE, false, false);
  
          List<IntermediateResults> intermRes = new ArrayList<>();
          double meanRotation = 0.0;
          this.scaleFactor = 0.0;
  
          for (int i = 0; i < this.results.size(); i++) {
              if (measuresCopy.get(i).isDeactivated()) {
                  // dummy intermediate results in order to avoid index problems
                  intermRes.add(new IntermediateResults(
                          MathUtils.IGNORE_DOUBLE,
                          MathUtils.IGNORE_DOUBLE,
                          MathUtils.IGNORE_DOUBLE,
                          MathUtils.IGNORE_DOUBLE));
                  continue;
              }
              Gisement g1 = new Gisement(centroidFict, this.results.get(i).getPoint(), false);
              Gisement g2 = new Gisement(centroidCadast, measuresCopy.get(i).getPoint(), false);
              intermRes.add(
                      new IntermediateResults(
                              g1.getGisement(), g1.getHorizDist(),
                              g2.getGisement(), g2.getHorizDist()));
  
              // calculation of the rotation between fictive and cadastral
              // coordinates according to the following formula:
              // mod400(gis_cadastral - gis_fictive)
              intermRes.get(i).rotation = MathUtils.modulo400(g2.getGisement() - g1.getGisement());
  
              // calculation of the multiplication constants between fictive and
              // cadastral coordinates according to the following formula:
              // dist_cadastral / dist_fictive
              double constant = g2.getHorizDist() / g1.getHorizDist();
              intermRes.get(i).constant = constant;
              this.scaleFactor += constant;
          }
          double minRotation = this.getMinRotation(intermRes);
          for (IntermediateResults res : intermRes) {
              double rotation = res.rotation;
              // skip values to ignore (deactivated measures)
              if (MathUtils.isIgnorable(rotation)) {
                  continue;
              }
              if (DoubleMath.fuzzyCompare(rotation - minRotation, -15.0, App.getAngleTolerance()) < 0) {
                  rotation += 400.0;
              } else if (DoubleMath.fuzzyCompare(rotation - minRotation, 15.0,
                      App.getAngleTolerance()) > 0) {
                  rotation -= 400.0;
              }
              meanRotation += rotation;
          }
  
          meanRotation = MathUtils.modulo400(meanRotation / n);
          this.scaleFactor /= n;
  
          // calculation of the gisement/distance between the fictive centroid and
          // the station (which is actually at the coordinates 0;0).
          this.stationResult = new Point(this.stationNumber, MathUtils.IGNORE_DOUBLE, MathUtils.IGNORE_DOUBLE, MathUtils.IGNORE_DOUBLE, false, false);
          Gisement g = new Gisement(centroidFict, this.stationResult, false);
          double gisFictiveGToSt = g.getGisement(); // gisement g-St
          double distFictiveGToSt = g.getHorizDist(); // distance g-St
  
          // calculation of the station coordinates
          double tmp1 = MathUtils.gradToRad(gisFictiveGToSt + meanRotation);
          double tmp2 = distFictiveGToSt * this.scaleFactor;
          this.stationResult.setEast((Math.sin(tmp1) * tmp2) + centroidCadast.getEast());
          this.stationResult.setNorth((Math.cos(tmp1) * tmp2) + centroidCadast.getNorth());
          double altitude = MathUtils.IGNORE_DOUBLE;
          if (!MathUtils.isIgnorable(meanAltitude) && (nbAltitudes > 0)) {
              altitude = meanAltitude / totalWeights;
          }
          this.stationResult.setAltitude(altitude);
  
          double diffAlt = 0.0;
  
          double u = 0.0;
          double v = 0.0;
  
          for (int i = 0; i < this.results.size(); i++) {
              if (measuresCopy.get(i).isDeactivated()) {
                  continue;
              }
  
              double newGis = MathUtils.modulo400(meanRotation + measuresCopy.get(i).getHorizDir());
              double newDist = this.scaleFactor * measuresCopy.get(i).getDistance();
  
              // vE [cm]
              double newE = MathUtils.pointLanceEast(this.stationResult.getEast(), newGis, newDist);
              double vE = (newE - measuresCopy.get(i).getPoint().getEast()) * 100;
              this.results.get(i).setvE(vE);
  
              // vN [cm]
              double newN = MathUtils.pointLanceNorth(this.stationResult.getNorth(), newGis, newDist);
              double vN = (newN - measuresCopy.get(i).getPoint().getNorth()) * 100;
              this.results.get(i).setvN(vN);
  
              // vA [cm]
  