/** * @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; } } }
/** * @param canvas * @param ctx */ private void drawTrack(Canvas canvas, DrawingContext ctx) { TrackShape.draw( ctx, mService.getPlan(), mService.getDestination(), mGpsParams, mLineBitmap, mLineHeadingBitmap, mPointProjection == null); }
/** * 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); }