Пример #1
0
 /** Simple GPS destination. No db query required */
 public Destination(StorageService service, double lon, double lat) {
   GpsParams params = service.getGpsParams();
   mPref = new Preferences(service.getApplicationContext());
   if (null != params) {
     mLonInit = params.getLongitude();
     mLatInit = params.getLatitude();
   } else {
     mLonInit = lon;
     mLatInit = lat;
   }
   mInited = true;
   mService = service;
   mDbType = GPS;
   mFound = true;
   mLooking = false;
   mRunways = new LinkedList<Runway>();
   mTrackShape = new TrackShape();
   mEte = new String("--:--");
   mEta = new String("--:--");
   mFuel = new String("-.-");
   mLond = lon;
   mLatd = lat;
   mParams = new LinkedHashMap<String, String>();
   mFreq = new LinkedHashMap<String, String>();
   mAwos = new LinkedList<Awos>();
   mParams.put(DataBaseHelper.LONGITUDE, "" + mLond);
   mParams.put(DataBaseHelper.LATITUDE, "" + mLatd);
   mParams.put(DataBaseHelper.FACILITY_NAME, GPS);
   addTime();
   mTrackShape.updateShape(new GpsParams(getLocationInit()), Destination.this);
   mAfdFound = null;
   mName = Helper.truncGeo(lat) + "&" + Helper.truncGeo(lon);
   mDestType = GPS;
 }
Пример #2
0
  /**
   * Find if a GPS dst is valid
   *
   * @return
   */
  public static boolean isGPSValid(String dst) {
    if (dst.contains("&")) {
      String tokens[] = dst.split("&");

      try {
        double lon = Double.parseDouble(tokens[1]);
        double lat = Double.parseDouble(tokens[0]);
        if ((Helper.isLatitudeSane(lat)) && (Helper.isLongitudeSane(lon))) {
          return true;
        }
      } catch (Exception e) {
      }
    }
    return false;
  }
Пример #3
0
  private void startClosestAirportTask(double x, double y) {
    // We won't be doing the airport long press under certain circumstances
    if (mDraw) {

      return;
    }

    if (null != mClosestTask) {
      mClosestTask.cancel(true);
    }
    mLongTouchDestination = null;
    mClosestTask = new ClosestAirportTask();

    double lon2, lat2;
    if (mPref.isTrackUp()) {
      double c_x = mOrigin.getOffsetX(mGpsParams.getLongitude());
      double c_y = mOrigin.getOffsetY(mGpsParams.getLatitude());
      double thetab = mGpsParams.getBearing();

      double p[];
      p = Helper.rotateCoord(c_x, c_y, thetab, x, y);
      lon2 = mOrigin.getLongitudeOf(p[0]);
      lat2 = mOrigin.getLatitudeOf(p[1]);
    } else {
      lon2 = mOrigin.getLongitudeOf(x);
      lat2 = mOrigin.getLatitudeOf(y);
    }
    mClosestTask.execute(lon2, lat2);
  }
Пример #4
0
  /**
   * @param name
   * @param type
   */
  private void parseGps(String name, String type) {
    /*
     * GPS
     * GPS coordinates are either x&y (user), or addr@x&y (google maps)
     * get the x&y part, then parse them to lon=y lat=x
     */
    if (name.contains("&")) {
      String token[] = new String[2];
      token[1] = token[0] = name;
      if (name.contains("@")) {
        /*
         * This could be the geo point from maps
         */
        token = name.split("@");
      }
      /*
       * This is lon/lat destination
       */
      String tokens[] = token[1].split("&");

      try {
        mLond = Double.parseDouble(tokens[1]);
        mLatd = Double.parseDouble(tokens[0]);
      } catch (Exception e) {
        /*
         * Bad input from user on GPS
         */
        mName = "";
        mDestType = "";
        return;
      }

      /*
       * Sane input
       */
      if ((!Helper.isLatitudeSane(mLatd)) || (!Helper.isLongitudeSane(mLond))) {
        mName = "";
        mDestType = "";
        return;
      }
      mName = token[0];
      mDestType = type;
    }
  }
Пример #5
0
 /* (non-Javadoc)
  * @see java.lang.Object#toString()
  */
 @Override
 public String toString() {
   /*
    * For display purpose
    */
   if (!mFound) {
     return (mName + "? ");
   } else {
     return Helper.makeLine(
         mDistance, Preferences.distanceConversionUnit, mEte, mBearing, mDeclination);
   }
 }
Пример #6
0
 /** @return */
 private String getPriorityMessage() {
   if (mPointProjection != null) {
     String priorityMessage =
         Helper.makeLine2(
             mPointProjection.getDistance(),
             Preferences.distanceConversionUnit,
             mPointProjection.getGeneralDirectionFrom(mGpsParams.getDeclinition()),
             mPointProjection.getBearing(),
             mGpsParams.getDeclinition());
     return priorityMessage;
   }
   return null;
 }
Пример #7
0
  /** @param params */
  public void initParams(GpsParams params, StorageService service) {
    /*
     * Comes from storage service. This will do nothing for fresh start,
     * but it will load previous combo on re-activation
     */
    mService = service;

    mMovement = mService.getMovement();
    mImageDataSource = mService.getDBResource();
    if (null == mMovement) {
      mMovement = new Movement();
    }
    mPan = mService.getPan();
    if (null == mPan) {
      mPan = new Pan();
      mService.setPan(mPan);
    }
    if (null != params) {
      mGpsParams = params;
    } else if (null != mService.getDestination()) {
      mGpsParams = new GpsParams(mService.getDestination().getLocation());
    } else {
      mGpsParams = new GpsParams(null);
    }
    loadTiles();
    postInvalidate();

    // Tell the CDI the paint that we use for display tfr
    mService.getCDI().setSize(mPaint, Math.min(getWidth(), getHeight()));
    mService.getVNAV().setSize(mPaint, Math.min(getWidth(), getHeight()));

    // Tell the odometer how to access preferences
    mService.getOdometer().setPref(mPref);

    mService.getEdgeTape().setPaint(mPaint);

    // Resize our runway icon based upon the size of the display.
    // We want the icon no more than 1/3 the size of the screen. Since we show 2 images
    // of this icon, that means the total size is no more than 2/3 of the available space.
    // This leaves room to print the runway numbers with some real estate left over.
    Bitmap newRunway =
        Helper.getResizedBitmap(mRunwayBitmap.getBitmap(), getWidth(), getHeight(), (double) 1 / 3);

    // If a new bitmap was generated, then load it in.
    if (newRunway != mRunwayBitmap.getBitmap()) {
      mRunwayBitmap = new BitmapHolder(newRunway);
    }
  }
Пример #8
0
    /* (non-Javadoc)
     * @see android.os.AsyncTask#doInBackground(Params[])
     */
    @Override
    protected Boolean doInBackground(Object... vals) {

      Thread.currentThread().setName("Destination");

      Boolean guess = (Boolean) vals[0];
      String dbType = (String) vals[1];

      /*
       * If we dont know type, find with a guess.
       */
      if (guess) {
        StringPreference s = mService.getDBResource().searchOne(mName);
        if (null == s) {
          return false;
        }
        mDestType = s.getType();
        mName = s.getId();
      }

      /*
       * If GPS/Maps, parse
       */
      if (mName.contains("&")) {
        parseGps(mName, mDestType);
      }

      mWinds = mService.getDBResource().getWindsAloft(mLond, mLatd);

      if (mDestType.equals(UDW)) {
        Waypoint p = mService.getUDWMgr().get(mName);
        if (null != p) {
          mLatd = p.getLat();
          mLond = p.getLon();
          mCmt = p.getCmt();
          mParams.put(DataBaseHelper.LONGITUDE, "" + mLond);
          mParams.put(DataBaseHelper.LATITUDE, "" + mLatd);
          mParams.put(DataBaseHelper.FACILITY_NAME, UDWMgr.UDWDESCRIPTION);
          addTime();
          mAfdFound = null;
          mFound = true;
          mLooking = false;
          mDbType = UDW;
          mTrackShape.updateShape(new GpsParams(getLocationInit()), Destination.this);
          return true;
        }
        return false;
      }

      if (mDestType.equals(GPS)) {
        /*
         * For GPS coordinates, simply put parsed lon/lat in params
         * No need to query database
         */
        mParams = new LinkedHashMap<String, String>();
        mFreq = new LinkedHashMap<String, String>();
        mAwos = new LinkedList<Awos>();
        mParams.put(DataBaseHelper.LONGITUDE, "" + mLond);
        mParams.put(DataBaseHelper.LATITUDE, "" + mLatd);
        mParams.put(DataBaseHelper.FACILITY_NAME, GPS);
        addTime();
        mAfdFound = null;
        mFound = true;
        mLooking = false;
        mDbType = GPS;
        mTrackShape.updateShape(new GpsParams(getLocationInit()), Destination.this);
        if (!isGPSValid(mName)) {
          mFound = false;
        }
        if (!mName.contains("&")) {
          /*
           * This comes from MAPS to GPS for user edited
           */
          mName += "@" + mLatd + "&" + mLond;
        }
        return true;
      }

      if (null == mDataSource) {
        return false;
      }

      /*
       * For Google maps address, if we have already geo decoded it using internet,
       * then no need to do again because internet may not be available on flight.
       * It could be coming from storage and not google maps.
       */
      if (mDestType.equals(MAPS)) {

        if (mLond == 0 && mLatd == 0) {
          /*
           * We have already decomposed it?
           * No.
           */
          String strAddress = mName;

          Geocoder coder = new Geocoder(mService);
          Address location = null;

          /*
           * Decompose
           */
          try {
            List<Address> address = coder.getFromLocationName(strAddress, 1);
            if (address != null) {
              location = address.get(0);
            }
          } catch (Exception e) {
            return false;
          }

          if (null == location) {
            return false;
          }

          /*
           * Decomposed it
           *
           */
          try {
            mLond = Helper.truncGeo(location.getLongitude());
            mLatd = Helper.truncGeo(location.getLatitude());
          } catch (Exception e) {

          }
          if ((!Helper.isLatitudeSane(mLatd)) || (!Helper.isLongitudeSane(mLond))) {
            return false;
          }
        }
        /*
         * Common stuff
         */
        mParams = new LinkedHashMap<String, String>();
        mFreq = new LinkedHashMap<String, String>();
        mAwos = new LinkedList<Awos>();
        mAfdFound = null;
        mDbType = mDestType;
        mParams.put(DataBaseHelper.TYPE, mDestType);
        mParams.put(DataBaseHelper.FACILITY_NAME, mName);
        mParams.put(DataBaseHelper.LONGITUDE, "" + mLond);
        mParams.put(DataBaseHelper.LATITUDE, "" + mLatd);
        addTime();
        mName += "@" + mLatd + "&" + mLond;
        return true;
      }

      /*
       * For all others, find in DB
       */
      mDataSource.findDestination(mName, mDestType, dbType, mParams, mRunways, mFreq, mAwos);

      if (mDestType.equals(BASE)) {

        /*
         * Find A/FD
         */
        mAfdFound = null;
        final LinkedList<String> afdName = mDataSource.findAFD(mName);
        if (afdName.size() > 0) {
          FilenameFilter filter =
              new FilenameFilter() {
                public boolean accept(File directory, String fileName) {
                  boolean match = false;
                  for (final String name : afdName) {
                    match |=
                        fileName.matches(name + Preferences.IMAGE_EXTENSION)
                            || fileName.matches(name + "-[0-9]+" + Preferences.IMAGE_EXTENSION);
                  }
                  return match;
                }
              };
          String afd[] = null;
          afd = new File(mPref.mapsFolder() + "/afd/").list(filter);
          if (null != afd) {
            java.util.Arrays.sort(afd);
            int len1 = afd.length;
            String tmp1[] = new String[len1];
            for (int count = 0; count < len1; count++) {
              /*
               * Add A/FD
               */
              String tokens[] = afd[count].split(Preferences.IMAGE_EXTENSION);
              tmp1[count] = mPref.mapsFolder() + "/afd/" + tokens[0];
            }
            if (len1 > 0) {
              mAfdFound = tmp1;
            }
          }
        }
      }

      return (!mParams.isEmpty());
    }
Пример #9
0
  /**
   * Update the current speed, lat, lon, that will update ETA, distance and bearing to the
   * destination
   *
   * @param params
   */
  public void updateTo(GpsParams params) {

    /*
     */
    double mLon = params.getLongitude();
    double mLat = params.getLatitude();
    double speed = params.getSpeed();
    mDeclination = params.getDeclinition();

    if (!mFound) {
      return;
    }

    if (!mInited) {
      mLonInit = mLon;
      mLatInit = mLat;
      mInited = true;
    }

    /*
     * Project and find distance
     */
    Projection p = new Projection(mLon, mLat, mLond, mLatd);

    mDistance = p.getDistance();

    mBearing = p.getBearing();

    // in flying mode, calculate time based on ground speed from GPS
    mGroundSpeed = speed;
    mWca = 0;
    mCrs = mBearing;
    if (mPref.isSimulationMode()) {
      double ws = 0;
      double wd = 0;
      if (mWinds != null) {
        double winds[] = mWinds.getWindAtAltitude(params.getAltitude());
        ws = winds[0];
        wd = winds[1];
      }

      // in sim mode, do planning with winds
      speed = mPref.getAircraftTAS(); // in sim mode, use preferred TAS
      // from aviation formulary
      double hd = mBearing;
      mGroundSpeed =
          Math.sqrt(
              ws * ws + speed * speed - 2 * ws * speed * Math.cos((hd - wd) * Math.PI / 180.0));
      mWca =
          -Math.toDegrees(
              Math.atan2(
                  ws * Math.sin((hd - wd) * Math.PI / 180.0),
                  speed - ws * Math.cos((hd - wd) * Math.PI / 180.0)));
      mCrs = (hd + mWca + 360) % 360;
    } else if (mPref.useBearingForETEA() && (!mService.getPlan().isActive())) {
      // This is just when we have a destination set and no plan is active
      // We can't assume that we are heading DIRECTLY for the destination, so
      // we need to figure out the multiply factor by taking the COS of the difference
      // between the bearing and the heading.
      double angDif = Helper.angularDifference(params.getBearing(), mBearing);
      double xFactor = 1;

      // If the difference is 90 or greater, then ETE means nothing as we are not
      // closing on the target
      if (angDif < 90) {
        // Calculate the actual relative speed closing on the target
        xFactor = Math.cos(angDif * Math.PI / 180);
      }
      mGroundSpeed *= xFactor;
    }

    /*
     * ETA when speed != 0
     */
    mEte = Helper.calculateEte(mDistance, mGroundSpeed, 0, true);
    if (mGroundSpeed == 0) {
      mEteSec = Long.MAX_VALUE;
      mFuelGallons = Float.MAX_VALUE;
      mFuel = "-.-";
    } else {
      mEteSec = (long) (mDistance / mGroundSpeed * 3600);
      mFuelGallons = (float) mEteSec / 3600 * mPref.getFuelBurn();
      mFuel = String.valueOf((float) Math.round(mFuelGallons * 10.f) / 10.f);
    }

    // Calculate the time of arrival at our destination. We SHOULD be taking in to account
    // the timezone at that location
    mEta = Helper.calculateEta(Calendar.getInstance().getTimeZone(), mDistance, mGroundSpeed);
  }
Пример #10
0
  /* (non-Javadoc)
   * @see com.ds.avare.MultiTouchController.MultiTouchObjectCanvas#setPositionAndScale(java.lang.Object, com.ds.avare.MultiTouchController.PositionAndScale, com.ds.avare.MultiTouchController.PointInfo)
   */
  public boolean setPositionAndScale(
      Object obj, PositionAndScale newObjPosAndScale, PointInfo touchPoint) {
    touchPointChanged(touchPoint);
    if (false == mCurrTouchPoint.isMultiTouch()) {

      /*
       * Do not move on drag
       */
      if (mDragPlanPoint >= 0) {
        return true;
      }

      /*
       * Do not move on multitouch
       */
      if (mDraw && mService != null) {
        float x = mCurrTouchPoint.getX() * mScale.getScaleFactor();
        float y = mCurrTouchPoint.getY() * mScale.getScaleFactor();
        /*
         * Threshold the drawing so we do not generate too many points
         */
        if (mPref.isTrackUp()) {
          double thetab = mGpsParams.getBearing();
          double p[] = new double[2];
          double c_x = mOrigin.getOffsetX(mGpsParams.getLongitude());
          double c_y = mOrigin.getOffsetY(mGpsParams.getLatitude());
          p = Helper.rotateCoord(c_x, c_y, thetab, x, y);
          mService.getDraw().addPoint((float) p[0], (float) p[1], mOrigin);
        } else {
          mService.getDraw().addPoint(x, y, mOrigin);
        }
        return true;
      }

      // Pan
      if (mPan.setMove(newObjPosAndScale.getXOff(), newObjPosAndScale.getYOff())) {
        /*
         * Query when we have moved one tile. This will happen in background.
         */
        loadTiles();
      }
    } else {

      // Zooming does not change drag
      mDragPlanPoint = -1;

      /*
       * on double touch find distance and bearing between two points.
       */

      if (mPointProjection == null) {
        double x0 = mCurrTouchPoint.getXs()[0];
        double y0 = mCurrTouchPoint.getYs()[0];
        double x1 = mCurrTouchPoint.getXs()[1];
        double y1 = mCurrTouchPoint.getYs()[1];

        double lon0, lat0, lon1, lat1;
        // convert to origin coord if Trackup
        if (mPref.isTrackUp()) {
          double c_x = mOrigin.getOffsetX(mGpsParams.getLongitude());
          double c_y = mOrigin.getOffsetY(mGpsParams.getLatitude());
          double thetab = mGpsParams.getBearing();
          double p0[], p1[];
          p0 = Helper.rotateCoord(c_x, c_y, thetab, x0, y0);
          p1 = Helper.rotateCoord(c_x, c_y, thetab, x1, y1);
          lon0 = mOrigin.getLongitudeOf(p0[0]);
          lat0 = mOrigin.getLatitudeOf(p0[1]);
          lon1 = mOrigin.getLongitudeOf(p1[0]);
          lat1 = mOrigin.getLatitudeOf(p1[1]);
        } else {
          lon0 = mOrigin.getLongitudeOf(x0);
          lat0 = mOrigin.getLatitudeOf(y0);
          lon1 = mOrigin.getLongitudeOf(x1);
          lat1 = mOrigin.getLatitudeOf(y1);
        }
        mPointProjection = new Projection(lon0, lat0, lon1, lat1);
      }

      /*
       * Clamp scaling.
       */

      mScale.setScaleFactor(newObjPosAndScale.getScale());
    }
    updateCoordinates();
    invalidate();
    return true;
  }
Пример #11
0
  /** @param context */
  private void setup(Context context) {

    /*
     * Set up all graphics.
     */
    mContext = context;
    mPan = new Pan();
    mScale = new Scale(MAX_SCALE);
    mOrigin = new Origin();
    mMovement = new Movement();
    mErrorStatus = null;
    mMacro = 1;
    mDragPlanPoint = -1;
    mImageDataSource = null;
    mGpsParams = new GpsParams(null);
    mPaint = new Paint();
    mPaint.setAntiAlias(true);
    mPointProjection = null;
    mDraw = false;

    mPref = new Preferences(context);

    mFace = Typeface.createFromAsset(mContext.getAssets(), "LiberationMono-Bold.ttf");
    mPaint.setTypeface(mFace);
    mPaint.setTextSize(getResources().getDimension(R.dimen.TextSize));

    mTextPaint = new TextPaint();
    mTextPaint.setAntiAlias(true);
    mTextPaint.setColor(Color.WHITE);
    mTextPaint.setTypeface(mFace);
    mTextPaint.setTextSize(R.dimen.TextSize);

    /*
     * Set up the paint for misc messages to display
     */
    mMsgPaint = new Paint();
    mMsgPaint.setAntiAlias(true);
    mMsgPaint.setTextSize(getResources().getDimension(R.dimen.distanceRingNumberTextSize));

    /*
     * Set up the paint for the runways as much as possible here
     */
    mRunwayPaint = new Paint(mPaint);
    mRunwayPaint.setTextSize(getResources().getDimension(R.dimen.runwayNumberTextSize));

    setOnTouchListener(this);
    mAirplaneBitmap = DisplayIcon.getDisplayIcon(context, mPref);
    mLineBitmap = new BitmapHolder(context, R.drawable.line);
    mLineHeadingBitmap = new BitmapHolder(context, R.drawable.line_heading);
    mRunwayBitmap = new BitmapHolder(context, R.drawable.runway_extension);
    mMultiTouchC = new MultiTouchController<Object>(this);
    mCurrTouchPoint = new PointInfo();

    mGestureDetector = new GestureDetector(context, new GestureListener());

    // We're going to give the user twice the slop as normal
    final ViewConfiguration configuration = ViewConfiguration.get(context);
    int touchSlop = configuration.getScaledTouchSlop() * 2;
    mTouchSlopSquare = touchSlop * touchSlop;
    mDoCallbackWhenDone = false;

    mDipToPix = Helper.getDpiToPix(context);
  }
Пример #12
0
    /* (non-Javadoc)
     * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
     */
    @Override
    protected void onPostExecute(String airport) {
      if (null != mGestureCallBack && null != mPointProjection && null != airport) {
        mLongTouchDestination = new LongTouchDestination();
        mLongTouchDestination.airport = airport;
        mLongTouchDestination.info =
            Math.round(mPointProjection.getDistance())
                + Preferences.distanceConversionUnit
                + "("
                + mPointProjection.getGeneralDirectionFrom(mGpsParams.getDeclinition())
                + ") "
                + Helper.correctConvertHeading(
                    Math.round(
                        Helper.getMagneticHeading(
                            mPointProjection.getBearing(), mGpsParams.getDeclinition())))
                + '\u00B0';

        /*
         * Clear old weather
         */
        mService.getAdsbWeather().sweep();

        /*
         * Do not background ADSB weather as its a RAM opertation and quick,
         * also avoids concurrent mod exception.
         */

        if (mPref.useAdsbWeather()) {
          taf = mService.getAdsbWeather().getTaf(airport);
          metar = mService.getAdsbWeather().getMETAR(airport);
          aireps = mService.getAdsbWeather().getAireps(lon, lat);
          wa = mService.getAdsbWeather().getWindsAloft(lon, lat);
          layer = mService.getAdsbWeather().getNexrad().getDate();
        } else {
          boolean inWeatherOld = mService.getInternetWeatherCache().isOld(mPref.getExpiryTime());
          if (inWeatherOld) { // expired weather and TFR text do not show
            taf = null;
            metar = null;
            aireps = null;
            textMets = null;
            tfr = null;
            wa = null;
          }
        }
        if (null != aireps) {
          for (Airep a : aireps) {
            a.updateTextWithLocation(lon, lat, mGpsParams.getDeclinition());
          }
        }
        if (null != wa) {
          wa.updateStationWithLocation(lon, lat, mGpsParams.getDeclinition());
        }
        mLongTouchDestination.tfr = tfr;
        mLongTouchDestination.taf = taf;
        mLongTouchDestination.metar = metar;
        mLongTouchDestination.airep = aireps;
        mLongTouchDestination.mets = textMets;
        mLongTouchDestination.wa = wa;
        mLongTouchDestination.freq = freq;
        mLongTouchDestination.sua = sua;
        mLongTouchDestination.layer = layer;
        mLongTouchDestination.fuel = fuel;
        mLongTouchDestination.ratings = ratings;
        if (metar != null) {
          mLongTouchDestination.performance =
              WeatherHelper.getMetarTime(metar.rawText)
                  + "\n"
                  + mContext.getString(R.string.DensityAltitude)
                  + " "
                  + WeatherHelper.getDensityAltitude(metar.rawText, elev)
                  + "\n"
                  + mContext.getString(R.string.BestRunway)
                  + " "
                  + WeatherHelper.getBestRunway(metar.rawText, runways);
        }

        // If the long press event has already occurred, we need to do the gesture callback here
        if (mDoCallbackWhenDone) {
          mGestureCallBack.gestureCallBack(GestureInterface.LONG_PRESS, mLongTouchDestination);
        }
      }
      invalidate();
    }
Пример #13
0
    /* (non-Javadoc)
     * @see android.os.AsyncTask#doInBackground(Params[])
     */
    @Override
    protected String doInBackground(Object... vals) {
      Thread.currentThread().setName("Closest");
      if (null == mService) {
        return null;
      }

      String airport = null;
      lon = (Double) vals[0];
      lat = (Double) vals[1];

      // if the user is moving instead of doing a long press, give them a chance
      // to cancel us before we start doing anything
      try {
        Thread.sleep(200);
      } catch (Exception e) {
      }

      if (isCancelled()) return "";

      /*
       * Get TFR tfr if touched on its top
       */
      LinkedList<TFRShape> shapes = null;
      List<AirSigMet> mets = null;
      if (null != mService) {
        shapes = mService.getTFRShapes();
        if (!mPref.useAdsbWeather()) {
          mets = mService.getInternetWeatherCache().getAirSigMet();
        }
      }
      if (null != shapes) {
        for (int shape = 0; shape < shapes.size(); shape++) {
          TFRShape cshape = shapes.get(shape);
          /*
           * Set TFR tfr
           */
          String txt = cshape.getTextIfTouched(lon, lat);
          if (null != txt) {
            tfr += txt + "\n--\n";
          }
        }
      }
      /*
       * Air/sigmets
       */
      if (null != mets) {
        for (int i = 0; i < mets.size(); i++) {
          MetShape cshape = mets.get(i).shape;
          if (null != cshape) {
            /*
             * Set MET tfr
             */
            String txt = cshape.getTextIfTouched(lon, lat);
            if (null != txt) {
              textMets += txt + "\n--\n";
            }
          }
        }
      }

      airport = mService.getDBResource().findClosestAirportID(lon, lat);
      if (isCancelled()) {
        return "";
      }

      if (null == airport) {
        airport = "" + Helper.truncGeo(lat) + "&" + Helper.truncGeo(lon);
      } else {
        freq = mService.getDBResource().findFrequencies(airport);
        if (isCancelled()) {
          return "";
        }

        taf = mService.getDBResource().getTAF(airport);
        if (isCancelled()) {
          return "";
        }

        metar = mService.getDBResource().getMETAR(airport);
        if (isCancelled()) {
          return "";
        }

        runways = mService.getDBResource().findRunways(airport);
        if (isCancelled()) {
          return "";
        }

        elev = mService.getDBResource().findElev(airport);
        if (isCancelled()) {
          return "";
        }

        LinkedList<String> fl = mService.getDBResource().findFuelCost(airport);
        if (fl.size() == 0) {
          // If fuel not available, show its not
          fuel = mContext.getString(R.string.NotAvailable);
        } else {
          fuel = "";
        }
        // Concat all fuel reports
        for (String s : fl) {
          fuel += s + "\n\n";
        }
        if (isCancelled()) return "";

        LinkedList<String> cm = mService.getDBResource().findRatings(airport);
        if (cm.size() == 0) {
          // If ratings not available, show its not
          ratings = mContext.getString(R.string.NotAvailable);
        } else {
          ratings = "";
        }
        // Concat all fuel reports
        for (String s : cm) {
          ratings += s + "\n\n";
        }
        if (isCancelled()) return "";
      }

      /*
       * ADSB gets this info from weather cache
       */
      if (!mPref.useAdsbWeather()) {
        aireps = mService.getDBResource().getAireps(lon, lat);
        if (isCancelled()) {
          return "";
        }

        wa = mService.getDBResource().getWindsAloft(lon, lat);
        if (isCancelled()) {
          return "";
        }

        sua = mService.getDBResource().getSua(lon, lat);
        if (isCancelled()) {
          return "";
        }

        if (mLayer != null) {
          layer = mLayer.getDate();
        }
        if (isCancelled()) {
          return "";
        }
      }

      mPointProjection =
          new Projection(mGpsParams.getLongitude(), mGpsParams.getLatitude(), lon, lat);
      return airport;
    }