/** * @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 x * @param y * @param finish */ private void rubberBand(float x, float y, boolean finish) { // Rubberbanding if (mDragPlanPoint >= 0 && mService.getPlan() != null) { // Threshold for movement float movementx = Math.abs(x - mDragStartedX); float movementy = Math.abs(y - mDragStartedY); if ((movementx > MOVEMENT_THRESHOLD * mDipToPix) || (movementy > MOVEMENT_THRESHOLD * mDipToPix)) { /* * Do something to plan * This is the new location */ double lon = mOrigin.getLongitudeOf(x); double lat = mOrigin.getLatitudeOf(y); mService.getPlan().replaceDestination(mPref, mDragPlanPoint, lon, lat, finish); // This will not snap again mDragStartedX = -1000; mDragStartedY = -1000; } } }
/** * * Draw the vertical approach slope indicator if we have a destination set * * @param canvas what to draw the data upon */ private void drawVASI(Canvas canvas) { if (mPointProjection == null && mErrorStatus == null) { if (mPref.getShowCDI()) { Destination dest = mService.getDestination(); if (dest != null) { mService.getVNAV().drawVNAV(canvas, getWidth(), getHeight(), dest); } } } }
/** * @param canvas * @param ctx */ private void drawTrack(Canvas canvas, DrawingContext ctx) { TrackShape.draw( ctx, mService.getPlan(), mService.getDestination(), mGpsParams, mLineBitmap, mLineHeadingBitmap, mPointProjection == null); }
public void setLayerType(String type) { mLayerType = type; if (mService == null) { } else if (mLayerType.equals("NEXRAD")) { mService.getRadarLayer().parse(); } else if (mLayerType.equals("METAR")) { mService.getMetarLayer().parse(); } invalidate(); }
/** Center to the location */ public void center() { /* * On double tap, move to center */ mPan = new Pan(); if (mService != null) { mPan.setMove(0, (float) ((getHeight() * .25) / mScale.getScaleFactor())); mService.setPan(mPan); mService.getTiles().forceReload(); } loadTiles(); updateCoordinates(); postInvalidate(); }
/** @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); } }
/** * @param canvas * @param ctx */ private void drawDrawing(Canvas canvas, DrawingContext ctx) { /* * Get draw points. */ // Blue inside, black outside Paint.Cap oldCaps = mPaint.getStrokeCap(); mPaint.setStrokeCap( Paint.Cap.ROUND); // We use a wide line. Without ROUND the line looks broken. mPaint.setColor(Color.BLACK); mPaint.setStrokeWidth(6 * mDipToPix); mService.getDraw().drawShape(canvas, mPaint, mOrigin); mPaint.setColor(Color.BLUE); mPaint.setStrokeWidth(2 * mDipToPix); mService.getDraw().drawShape(canvas, mPaint, mOrigin); mPaint.setStrokeCap(oldCaps); // Restore the Cap we had before drawing }
/** * @param canvas * @param ctx */ private void drawTraffic(Canvas canvas, DrawingContext ctx) { Traffic.draw( ctx, mService.getTrafficCache().getTraffic(), mService.getTrafficCache().getOwnAltitude(), mGpsParams, mPref.getAircraftICAOCode(), null == mPointProjection); }
public void updateDestination() { /* * Comes from database */ if (null == mService) { return; } if (null != mService.getDestination()) { if (mService.getDestination().isFound()) { /* * Set pan to zero since we entered new destination * and we want to show it without pan. */ mPan = new Pan(); mService.setPan(mPan); updateCoordinates(); } } }
/** * * 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()); } } }
/** * @param canvas * @param ctx */ private void drawLayers(Canvas canvas, DrawingContext ctx) { if (mLayerType == null || null != mPointProjection || 0 == mPref.showLayer()) { return; } if (ctx.pref.useAdsbWeather()) { if (mLayerType.equals("NEXRAD")) { NexradBitmap.draw( ctx, mService.getAdsbWeather().getNexrad(), mService.getAdsbWeather().getNexradConus(), null == mPointProjection); } else if (mLayerType.equals("METAR")) { AdsbWeatherCache.drawMetars( ctx, mService.getAdsbWeather().getAllMetars(), null == mPointProjection); } } else { if (mLayerType.equals("NEXRAD")) { // draw nexrad mLayer = mService.getRadarLayer(); } else if (mLayerType.equals("METAR")) { // draw metar flight catergory mLayer = ctx.service.getMetarLayer(); } else { mLayer = null; return; } /* * layer is way too old. */ if (mLayer.isOld(ctx.pref.getExpiryTime())) { return; } mPaint.setAlpha(mPref.showLayer()); mLayer.draw(canvas, mPaint, mOrigin); mPaint.setAlpha(255); } }
/** * Draws concentric circles around the current aircraft position showing distance. author: rwalker * * @param canvas upon which to draw the circles */ private void drawDistanceRings(Canvas canvas) { /* * Some pre-conditions that would prevent us from drawing anything */ if (null != mPointProjection) { return; } // Tell the rings to draw themselves mService .getDistanceRings() .draw(canvas, mOrigin, mScale, mMovement, mPref.isTrackUp(), mGpsParams); }
// Draw the top status lines private void drawStatusLines(Canvas canvas) { mService .getInfoLines() .drawCornerTextsDynamic( canvas, mPaint, TEXT_COLOR, TEXT_COLOR_OPPOSITE, 4, getWidth(), getHeight(), mErrorStatus, getPriorityMessage()); }
/** 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; } }); }
/** * Draw the tracks to show our previous positions. If tracking is enabled, there is a linked list * of gps coordinates attached to this view with the most recent one at the end of that list. * Start at the end value to begin the drawing and as soon as we find one that is not in the range * of this display, we can assume that we're done. * * @param canvas * @param ctx */ private void drawTracks(Canvas canvas, DrawingContext ctx) { /* * Some pre-conditions that would prevent us from drawing anything */ if (mPref.isDrawTracks() && (null == mPointProjection)) { /* * Set the brush color and width */ mPaint.setColor(Color.CYAN); mPaint.setStrokeWidth(6 * mDipToPix); mPaint.setStyle(Paint.Style.FILL); mService .getKMLRecorder() .getShape() .drawShape(canvas, mOrigin, mScale, mMovement, mPaint, mPref.isNightMode(), true); } }
/** @return */ public BitmapHolder getBitmap() { return (mService.getDiagram()); }
/** * 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); }
/* (non-Javadoc) * @see android.view.View.OnTouchListener#onTouch(android.view.View, android.view.MotionEvent) */ @Override public boolean onTouch(View view, MotionEvent e) { boolean bPassToGestureDetector = true; if (e.getAction() == MotionEvent.ACTION_UP) { /** Rubberbanding */ rubberBand(e.getX(), e.getY(), true); /* * Drag stops for rubber band */ mDragPlanPoint = -1; /* * Do not draw point. Only when long press and down. */ mPointProjection = null; /* * Now that we have moved passed the macro level, re-query for new tiles. * Do not query repeatedly hence check for mFactor = 1 */ if (mMacro != mScale.getMacroFactor()) { loadTiles(); } } else if (e.getAction() == MotionEvent.ACTION_DOWN) { if (mService != null) { /* * Find if this is close to a plan point. Do rubber banding if true * This is where rubberbanding starts */ if (mService.getPlan() != null && mDragPlanPoint < 0 && mPref.allowRubberBanding()) { double lon = mOrigin.getLongitudeOf(e.getX()); double lat = mOrigin.getLatitudeOf(e.getY()); mDragPlanPoint = mService.getPlan().findClosePointId(lon, lat, mScale.getScaleFactor()); mDragStartedX = e.getX(); mDragStartedY = e.getY(); } } mGestureCallBack.gestureCallBack(GestureInterface.TOUCH, (LongTouchDestination) null); // Remember this point so we can make sure we move far enough before losing the long press mDoCallbackWhenDone = false; mDownFocusPoint = getFocusPoint(e); startClosestAirportTask(e.getX(), e.getY()); } else if (e.getAction() == MotionEvent.ACTION_MOVE) { if (mDownFocusPoint != null) { Point fp = getFocusPoint(e); final int deltaX = fp.x - mDownFocusPoint.x; final int deltaY = fp.y - mDownFocusPoint.y; int distanceSquare = (deltaX * deltaX) + (deltaY * deltaY); bPassToGestureDetector = distanceSquare > mTouchSlopSquare; } // Rubberbanding, intermediate rubberBand(e.getX(), e.getY(), false); } if (bPassToGestureDetector) { // Once we break out of the square or stop the long press, keep sending if (e.getAction() == MotionEvent.ACTION_MOVE || e.getAction() == MotionEvent.ACTION_UP) { mDownFocusPoint = null; mPointProjection = null; if (mClosestTask != null) { mClosestTask.cancel(true); } } mGestureDetector.onTouchEvent(e); } return mMultiTouchC.onTouchEvent(e, mScale.getMaxScale(), mScale.getMinScale(), mMacro); }
/* (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; }
/** * @param canvas * @param ctx */ private void drawTiles(Canvas canvas, DrawingContext ctx) { Tile.draw(ctx, mOnChart, mService.getTiles()); }
/** * @param canvas * @param ctx */ private void drawTFR(Canvas canvas, DrawingContext ctx) { TFRShape.draw(ctx, mService.getTFRShapes(), null == mPointProjection); }
// Display the nav comments private void drawNavComments(Canvas canvas) { NavComments navComments = mService.getNavComments(); if (null != navComments) { navComments.draw(this, canvas, mMsgPaint, mService.getShadowedText()); } }
/** * @param canvas * @param ctx */ private void drawShapes(Canvas canvas, DrawingContext ctx) { ShapeFileShape.draw(ctx, mService.getShapeShapes(), null == mPointProjection); }
// Display cap grids private void drawCapGrids(Canvas canvas, DrawingContext ctx) { if (mPointProjection == null && mPref.showCAPGrids()) { mService.getCap().draw(canvas, mOrigin, mScale); } }
// Display all of the user defined waypoints if configured to do so private void drawUserDefinedWaypoints(Canvas canvas, DrawingContext ctx) { if (mPointProjection == null) { mService.getUDWMgr().draw(canvas, mPref.isTrackUp(), mGpsParams, mFace, mOrigin); } }
/** * @param canvas * @param ctx */ private void drawAirSigMet(Canvas canvas, DrawingContext ctx) { MetShape.draw(ctx, mService.getInternetWeatherCache().getAirSigMet(), null == mPointProjection); }
/** * */ private void drawGameTFRs(DrawingContext ctx) { if (mPointProjection == null) { mService.getmGameTFRs().draw(ctx); } }
/** * @param canvas * @param ctx */ private void drawRunways(Canvas canvas, DrawingContext ctx) { Runway.draw( ctx, mRunwayBitmap, mService.getDestination(), mGpsParams, mPointProjection == null); }