/** * @param name * @param type * @param pref * @param service */ public Destination(String name, String type, Preferences pref, StorageService service) { GpsParams params = service.getGpsParams(); mInited = false; if (null != params) { mLonInit = params.getLongitude(); mLatInit = params.getLatitude(); mInited = true; } mDbType = ""; mFound = mLooking = false; mRunways = new LinkedList<Runway>(); mService = service; mDataSource = mService.getDBResource(); mTrackShape = new TrackShape(); mPref = pref; mEte = new String("--:--"); mEta = new String("--:--"); mEteSec = Long.MAX_VALUE; mFuel = "-.-"; mFuelGallons = Float.MAX_VALUE; mParams = new LinkedHashMap<String, String>(); mFreq = new LinkedHashMap<String, String>(); mAwos = new LinkedList<Awos>(); mAfdFound = null; mName = name.toUpperCase(Locale.getDefault()); mDestType = type; mLond = mLatd = 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; }
/** @param params */ public void updateParams(GpsParams params) { /* * Comes from location manager */ mGpsParams = params; updateCoordinates(); /* * Database query for new location / pan location. */ if (mGpsTile != null) { double offsets[] = new double[2]; /* * No need to load tiles when we are on current tile */ if (mGpsTile.within(mGpsParams.getLongitude(), mGpsParams.getLatitude())) { /* * We are within same tile no need for query. */ offsets[0] = mGpsTile.getOffsetX(mGpsParams.getLongitude()); offsets[1] = mGpsTile.getOffsetY(mGpsParams.getLatitude()); mMovement = new Movement(offsets); postInvalidate(); return; } } loadTiles(); }
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); }
/** @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; }
/** Function that loads new tiles in background */ private void loadTiles() { if (mService == null) { return; } if (mImageDataSource == null) { return; } TileMap map = mService.getTiles(); map.loadTiles( mGpsParams.getLongitude(), mGpsParams.getLatitude(), mPan, mMacro, mScale, mGpsParams.getBearing(), new GenericCallback() { @Override public Object callback(Object map, Object tu) { TileMap.TileUpdate t = (TileMap.TileUpdate) tu; ((TileMap) map).flip(); /* * Set move with pan after new tiles are finally loaded */ mPan.setMove( (float) (mPan.getMoveX() * t.factor), (float) (mPan.getMoveY() * t.factor)); int index = Integer.parseInt(mPref.getChartType()); String type = Boundaries.getChartType(index); mGpsTile = t.gpsTile; mOnChart = type + "\n" + t.chart; /* * And pan */ mPan.setTileMove(t.movex, t.movey); mMovement = new Movement(t.offsets); mService.setMovement(mMovement); mMacro = mScale.getMacroFactor(); mScale.updateMacro(); updateCoordinates(); invalidate(); return null; } }); }
public long getVerticalSpeedToNoFmt(GpsParams gpsParams) { double altAbove = getAltitudeAboveDest(gpsParams); double time = (mDistance / gpsParams.getSpeed()) * 60; if (altAbove == 0 || time == 0) { return 0; } return -Math.round(altAbove / time); }
/** * @param canvas * @param ctx */ private void drawAircraft(Canvas canvas, DrawingContext ctx) { mPaint.setShadowLayer(0, 0, 0, 0); mPaint.setColor(Color.WHITE); if (null != mAirplaneBitmap && null == mPointProjection) { /* * Rotate and move to a panned location */ BitmapHolder.rotateBitmapIntoPlace( mAirplaneBitmap, (float) mGpsParams.getBearing(), mGpsParams.getLongitude(), mGpsParams.getLatitude(), true, mOrigin); canvas.drawBitmap(mAirplaneBitmap.getBitmap(), mAirplaneBitmap.getTransform(), mPaint); } }
/** * * Calculate the glideslope given our current position/altitude and the position/elevation of * the target airport * * @param gpsParams where we are * @param dest what our destination is */ public void calcGlideSlope(GpsParams gpsParams, Destination dest) { // Show no vertical offset by default mDspOffset = 0; mBackColor = mColorOn; // If either of these objects are null, there is nothing // we can do if (dest == null || gpsParams == null) { mShow = false; return; } // Fetch the elevation of our destination. If we can't find it // then we don't want to display any vertical information double destElev = dest.getElevation(); if (destElev == -200) { mShow = false; return; } // Calculate our relative AGL compared to destination. If we are // lower then no display info double relativeAGL = gpsParams.getAltitude() - destElev; // Convert the destination distance to feet. double destDist = dest.getDistance(); double destInFeet = mConvertToFt * destDist; // Figure out our glide slope now based on our AGL height and distance mGlideSlope = Math.toDegrees(Math.atan(relativeAGL / destInFeet)); // Set the color of the glide slope background. According to the AIM, // if (mGlideSlope < (3 - BAR_DEGREES)) { mBackColor = mColorLow; } else if (mGlideSlope > (3 + BAR_DEGREES)) { mBackColor = mColorHigh; } // Calculate the vertical display offset of the indicator // Anything greater/equal to 3.7 pegs at the top // Anything less/equal to 2.3 pegs at the bottom // all others scale in between based upon instrument height double fullDeflection = mInstHeight / 2 - mBarHeight * 1.5; if (mGlideSlope >= 3.7) { mDspOffset = -(int) fullDeflection; } else if (mGlideSlope <= 2.3) { mDspOffset = (int) fullDeflection; } else { mDspOffset = -(int) ((((mGlideSlope - 3) / BAR_DEGREES)) * (fullDeflection / ((mBarCount - 1) / 2))); } mShow = true; }
/** * * Draw the edge distance markers if configured to do so * * @param canvas what to draw them on */ private void drawEdgeMarkers(Canvas canvas) { if (mPref.isShowEdgeTape()) { if (mPointProjection == null) { int x = (int) (mOrigin.getOffsetX(mGpsParams.getLongitude())); int y = (int) (mOrigin.getOffsetY(mGpsParams.getLatitude())); float pixPerNm = mOrigin.getPixelsInNmAtLatitude(1, mGpsParams.getLatitude()); mService .getEdgeTape() .draw( canvas, mScale, pixPerNm, x, y, (int) mService.getInfoLines().getHeight(), getWidth(), getHeight()); } } }
public double getAltitudeAboveDest(GpsParams gpsParams) { double height = gpsParams.getAltitude(); if (mDestType.equals(BASE)) { try { /* * For bases, go to pattern altitude */ String pa = mParams.get("Pattern Altitude"); height -= Double.parseDouble(pa); } catch (Exception e) { } } else { /* * Only for airport */ return 0; } return height; }
/** * 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); }
/** @param canvas Does pretty much all drawing on screen */ private void drawMap(Canvas canvas) { if (mService == null) { return; } // If our track is supposed to be at the top, save the current // canvas and rotate it based upon our bearing if we have one boolean bRotated = false; if (mPref.isTrackUp() && (mGpsParams != null)) { bRotated = true; canvas.save(); /* * Rotate around current position */ float x = (float) mOrigin.getOffsetX(mGpsParams.getLongitude()); float y = (float) mOrigin.getOffsetY(mGpsParams.getLatitude()); canvas.rotate(-(int) mGpsParams.getBearing(), x, y); } DrawingContext ctx = new DrawingContext(); ctx.service = mService; ctx.canvas = canvas; ctx.context = mContext; ctx.dip2pix = mDipToPix; ctx.movement = mMovement; ctx.origin = mOrigin; ctx.paint = mPaint; ctx.textPaint = mMsgPaint; ctx.scale = mScale; ctx.pan = mPan; ctx.pref = mPref; ctx.runwayPaint = mRunwayPaint; ctx.view = this; // Call the draw routines for the items that rotate with // the chart drawTiles(canvas, ctx); drawLayers(canvas, ctx); drawDrawing(canvas, ctx); drawCapGrids(canvas, ctx); drawTraffic(canvas, ctx); drawTFR(canvas, ctx); drawGameTFRs(ctx); drawShapes(canvas, ctx); drawAirSigMet(canvas, ctx); drawTracks(canvas, ctx); drawTrack(canvas, ctx); drawRunways(canvas, ctx); drawAircraft(canvas, ctx); drawUserDefinedWaypoints(canvas, ctx); // Restore the canvas to be upright again if (true == bRotated) { canvas.restore(); } // Now draw the items that do NOT rotate with the chart drawDistanceRings(canvas); drawCDI(canvas); drawVASI(canvas); drawStatusLines(canvas); drawEdgeMarkers(canvas); // Must be after the infolines drawNavComments(canvas); }
/* (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; }