/** * @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; } } }
/* * Determine if shape belong to a screen based on Screen longitude and latitude * and shape max/min longitude latitude */ public static boolean isOnScreen(Origin origin, double lat, double lon) { double maxLatScreen = origin.getLatScreenTop(); double minLatScreen = origin.getLatScreenBot(); double minLonScreen = origin.getLonScreenLeft(); double maxLonScreen = origin.getLonScreenRight(); boolean isInLat = lat < maxLatScreen && lat > minLatScreen; boolean isInLon = lon < maxLonScreen && lon > minLonScreen; return isInLat && isInLon; }
/** * * 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()); } } }
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); }
/** @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; }
/* (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); }
private void updateCoordinates() { mOrigin.update(mGpsTile, getWidth(), getHeight(), mGpsParams, mPan, mScale); }