@Override
  public boolean onTouchEvent(MotionEvent event) {
    float x = event.getX() - CENTER_X;
    float y = event.getY() - CENTER_Y;
    boolean inCenter = java.lang.Math.sqrt(x * x + y * y) <= CENTER_RADIUS;

    switch (event.getAction()) {
      case MotionEvent.ACTION_DOWN:
      case MotionEvent.ACTION_MOVE:
        if (!inCenter) {
          float angle = (float) java.lang.Math.atan2(y, x);
          // need to turn angle [-PI ... PI] into unit [0....1]
          float unit = angle / (2 * PI);
          if (unit < 0) {
            unit += 1;
          }
          int color = interpColor(mColors, unit);
          mCenterPaint.setColor(color);
          this.setColor(color);
          invalidate();
        }
        break;
    }
    return true;
  }
    @SuppressLint("FloatMath")
    @Override
    public boolean onTouchEvent(MotionEvent event) {
      float x = event.getX() - CENTER_X;
      float y = event.getY() - CENTER_Y;
      boolean inCenter = java.lang.Math.sqrt(x * x + y * y) <= CENTER_RADIUS;

      switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
          mTrackingCenter = inCenter;
          if (inCenter) {
            mHighlightCenter = true;
            invalidate();
            break;
          }
        case MotionEvent.ACTION_MOVE:
          if (mTrackingCenter) {
            if (mHighlightCenter != inCenter) {
              mHighlightCenter = inCenter;
              invalidate();
            }
          } else {
            float angle = (float) java.lang.Math.atan2(y, x);
            // need to turn angle [-PI ... PI] into unit [0....1]
            float unit = angle / (2 * PI);
            if (unit < 0) {
              unit += 1;
            }
            mCenterPaint.setColor(interpColor(mColors, unit));
            invalidate();
          }
          break;
        case MotionEvent.ACTION_UP:
          if (mTrackingCenter) {
            if (inCenter) {
              mListener.colorChanged(mCenterPaint.getColor());
            }
            mTrackingCenter = false; // so we draw w/o halo
            invalidate();
          }
          break;
      }
      return true;
    }
 private int floatToByte(float x) {
   int n = java.lang.Math.round(x);
   return n;
 }
 private int ave(int s, int d, float p) {
   return s + java.lang.Math.round(p * (d - s));
 }
  public boolean onTouchEvent(MotionEvent ev) {
    if (mapThreadRunning) return false; // no updates when download is running
    if (gestureDetector.onTouchEvent(ev)) return true;

    final int action = ev.getAction();
    switch (action & MotionEvent.ACTION_MASK) {
      case MotionEvent.ACTION_DOWN:
        {
          mLastTouchX = ev.getX();
          mLastTouchY = ev.getY();
          mActivePointerId = ev.getPointerId(0);
          break;
        }
      case MotionEvent.ACTION_POINTER_DOWN:
        {
          mLastTouchX2 = ev.getX();
          mLastTouchY2 = ev.getY();
          if (ev.getPointerCount() > 1) mActivePointerId2 = ev.getPointerId(1);
          break;
        }
      case MotionEvent.ACTION_MOVE:
        {
          int pointerIndex;
          float x = 0.0f, y = 0.0f;

          try {
            if ((mActivePointerId != INVALID_POINTER_ID)
                || (mActivePointerId2 != INVALID_POINTER_ID)) {
              pointerIndex = ev.findPointerIndex(mActivePointerId);
              x = ev.getX(pointerIndex);
              y = ev.getY(pointerIndex);
            }
            if ((mActivePointerId != INVALID_POINTER_ID)
                && (mActivePointerId2 != INVALID_POINTER_ID)) {
              double d1, d2;

              pointerIndex = ev.findPointerIndex(mActivePointerId2);
              if (pointerIndex < 0) return false;
              float x2 = ev.getX(pointerIndex);
              float y2 = ev.getY(pointerIndex);

              d1 = java.lang.Math.sqrt((x - x2) * (x - x2) + (y - y2) * (y - y2));
              d2 =
                  java.lang.Math.sqrt(
                      (mLastTouchX - mLastTouchX2) * (mLastTouchX - mLastTouchX2)
                          + (mLastTouchY - mLastTouchY2) * (mLastTouchY - mLastTouchY2));

              /*                  if ((Math.abs(d1)>300) || (Math.abs(d2)>300))
              {
                 int i=0;
                 i=i;
              }*/

              if ((d1 > 0) && (d2 > 0)) {
                float w, h, s;

                s = (float) (d1 / d2);
                mScaleFactor *= s;
                matrix.postScale(s, s);
                w = scrWidth / 2.0f;
                h = scrHeight / 2.0f;

                matrix.postTranslate(w, h);
                imgOffsetX += w;
                imgOffsetY += h;
              }

              mLastTouchX2 = x2;
              mLastTouchY2 = y2;
            } else if (mScaleFactor == 1.0) {
              mScaleFactor = 1.0f;
              imgOffsetX += (x - mLastTouchX);
              imgOffsetY += (y - mLastTouchY);
              matrix.setTranslate(imgOffsetX, imgOffsetY);
            }

            if ((mActivePointerId != INVALID_POINTER_ID)
                || (mActivePointerId2 != INVALID_POINTER_ID)) {
              mLastTouchX = x;
              mLastTouchY = y;
            }
          } catch (Exception e) {
            // can be caused by
            // pointerIndex= ev.findPointerIndex(mActivePointerId);
            // x= ev.getX(pointerIndex);
            // above which seems to be a Android bug
          }
          invalidate();
          break;
        }
      case MotionEvent.ACTION_UP:
      case MotionEvent.ACTION_POINTER_UP:
        {
          breakMapThread = true;
          mActivePointerId = INVALID_POINTER_ID;
          mActivePointerId2 = INVALID_POINTER_ID;
          restartMap();
          break;
        }
    }
    return true;
  }