public boolean onToolTouchEvent(MotionEvent event) {
    if (mapView == null || mapView.isClickable()) {
      return false;
    }

    Projection pj = mapView.getProjection();
    // handle drawing
    float currentX = event.getX();
    float currentY = event.getY();
    int deltaPixels = 100;

    int action = event.getAction();
    switch (action) {
      case MotionEvent.ACTION_DOWN:
      case MotionEvent.ACTION_MOVE:
        GeoPoint currentGeoPoint = pj.fromPixels(round(currentX), round(currentY));
        GeoPoint plusPoint =
            pj.fromPixels(round(currentX + deltaPixels), round(currentY + deltaPixels));

        double touchLon = currentGeoPoint.getLongitude();
        double touchLat = currentGeoPoint.getLatitude();
        double lonPlus = plusPoint.getLongitude();
        double latPlus = plusPoint.getLatitude();
        double deltaX = Math.abs(touchLon - lonPlus);
        double deltaY = Math.abs(touchLat - latPlus);
        Coordinate touchCoord = new Coordinate(touchLon, touchLat);
        Envelope queryEnvelope = new Envelope(touchCoord);
        queryEnvelope.expandBy(deltaX, deltaY);

        List<GpsLogInfo> result = gpsLogInfoTree.query(queryEnvelope);
        if (result.size() == 0) {
          return true;
        } else {
          GpsLogInfo nearest = null;
          double minDist = Double.POSITIVE_INFINITY;
          for (GpsLogInfo info : result) {
            double dist = touchCoord.distance(info.pointXYZ);
            if (dist < minDist) {
              minDist = dist;
              nearest = info;
            }
          }
          gpsLogInfo = nearest;
        }
        break;
      case MotionEvent.ACTION_UP:
        gpsLogInfo = null;
        break;
    }
    EditManager.INSTANCE.invalidateEditingView();
    return true;
  }
  @Override
  public int getLongitudeSpan() {

    int span = 0;

    Projection projection = getProjection();

    if (projection != null && getWidth() > 0) {
      GeoPoint low = projection.fromPixels(0, 0);
      GeoPoint high = projection.fromPixels(getWidth(), 0);

      if (low != null && high != null) {
        span = Math.abs(high.getLongitudeE6() - low.getLongitudeE6());
      }
    }

    return span;
  }
  public boolean onToolTouchEvent(MotionEvent event) {
    if (mapView == null || mapView.isClickable()) {
      return false;
    }
    Projection pj = editingViewProjection;

    // handle drawing
    float currentX = event.getX();
    float currentY = event.getY();

    int action = event.getAction();
    switch (action) {
      case MotionEvent.ACTION_DOWN:
        GeoPoint startGeoPoint = pj.fromPixels(round(currentX), round(currentY));
        pj.toPixels(startGeoPoint, startP);

        lastX = currentX;
        lastY = currentY;
        break;
      case MotionEvent.ACTION_MOVE:
        float dx = currentX - lastX;
        float dy = currentY - lastY;
        if (abs(dx) < 1 && abs(dy) < 1) {
          lastX = currentX;
          lastY = currentY;
          return true;
        }
        GeoPoint currentGeoPoint = pj.fromPixels(round(currentX), round(currentY));
        pj.toPixels(currentGeoPoint, tmpP);

        left = Math.min(tmpP.x, startP.x);
        right = Math.max(tmpP.x, startP.x);
        bottom = Math.max(tmpP.y, startP.y);
        top = Math.min(tmpP.y, startP.y);
        rect.set((int) left, (int) top, (int) right, (int) bottom);

        EditManager.INSTANCE.invalidateEditingView();
        break;
      case MotionEvent.ACTION_UP:
        float deltaY = abs(top - bottom);
        float deltaX = abs(right - left);
        if (deltaX > TOUCH_BOX_THRES && deltaY > TOUCH_BOX_THRES) {
          GeoPoint ul = pj.fromPixels((int) left, (int) top);
          GeoPoint lr = pj.fromPixels((int) right, (int) bottom);

          select(ul.getLatitude(), ul.getLongitude(), lr.getLatitude(), lr.getLongitude());
        }

        break;
    }

    return true;
  }
  public void onToolDraw(Canvas canvas) {
    if (startP.x == 0 && startP.y == 0) return;
    canvas.drawCircle(startP.x, startP.y, 15, drawingPaintFill);
    canvas.drawPath(drawingPath, drawingPaintStroke);
    canvas.drawCircle(endP.x, endP.y, 15, drawingPaintFill);

    if (previewGeometry != null) {
      Projection projection = editingViewProjection;

      byte zoomLevelBeforeDraw;
      synchronized (mapView) {
        zoomLevelBeforeDraw = mapView.getMapPosition().getZoomLevel();
        positionBeforeDraw =
            projection.toPoint(
                mapView.getMapPosition().getMapCenter(), positionBeforeDraw, zoomLevelBeforeDraw);
      }

      // calculate the top-left point of the visible rectangle
      point.x = positionBeforeDraw.x - (canvas.getWidth() >> 1);
      point.y = positionBeforeDraw.y - (canvas.getHeight() >> 1);

      MapViewPosition mapPosition = mapView.getMapPosition();
      byte zoomLevel = mapPosition.getZoomLevel();

      PointTransformation pointTransformer =
          new MapsforgePointTransformation(projection, point, zoomLevel);
      ShapeWriter shapeWriter = new ShapeWriter(pointTransformer);
      shapeWriter.setRemoveDuplicatePoints(true);

      FeatureUtilities.drawGeometry(
          previewGeometry,
          canvas,
          shapeWriter,
          selectedPreviewGeometryPaintFill,
          selectedPreviewGeometryPaintStroke);
    }
  }
  public boolean onToolTouchEvent(MotionEvent event) {
    if (mapView == null || mapView.isClickable()) {
      return false;
    }
    Projection pj = editingViewProjection;

    // handle drawing
    currentX = event.getX();
    currentY = event.getY();

    int action = event.getAction();
    switch (action) {
      case MotionEvent.ACTION_DOWN:
        startGeoPoint = pj.fromPixels(round(currentX), round(currentY));
        pj.toPixels(startGeoPoint, startP);
        endP.set(startP.x, startP.y);

        drawingPath.reset();
        drawingPath.moveTo(startP.x, startP.y);

        lastX = currentX;
        lastY = currentY;
        break;
      case MotionEvent.ACTION_MOVE:
        float dx = currentX - lastX;
        float dy = currentY - lastY;
        if (abs(dx) < 1 && abs(dy) < 1) {
          lastX = currentX;
          lastY = currentY;
          return true;
        }
        GeoPoint currentGeoPoint = pj.fromPixels(round(currentX), round(currentY));
        pj.toPixels(currentGeoPoint, tmpP);
        drawingPath.lineTo(tmpP.x, tmpP.y);
        endP.set(tmpP.x, tmpP.y);

        EditManager.INSTANCE.invalidateEditingView();
        break;
      case MotionEvent.ACTION_UP:
        GeoPoint endGeoPoint = pj.fromPixels(round(currentX), round(currentY));
        GeometryFactory gf = new GeometryFactory();
        Coordinate startCoord =
            new Coordinate(startGeoPoint.getLongitude(), startGeoPoint.getLatitude());
        com.vividsolutions.jts.geom.Point startPoint = gf.createPoint(startCoord);
        Coordinate endCoord = new Coordinate(endGeoPoint.getLongitude(), endGeoPoint.getLatitude());
        com.vividsolutions.jts.geom.Point endPoint = gf.createPoint(endCoord);
        Envelope env = new Envelope(startCoord, endCoord);
        select(env.getMaxY(), env.getMinX(), env.getMinY(), env.getMaxX(), startPoint, endPoint);
        //            EditManager.INSTANCE.invalidateEditingView();
        break;
    }

    return true;
  }
 @Override
 public void toPixels(GeoPointImpl leftGeo, Point left) {
   projection.toPixels((GeoPoint) leftGeo, left);
 }
  @Override
  public boolean onTouchEvent(MotionEvent event) {
    if (mapView == null || mapView.isClickable()) {
      return false;
    }

    if (doInfoMode) {

      Projection pj = sliderDrawProjection;

      // handle drawing
      currentX = event.getX();
      currentY = event.getY();

      int action = event.getAction();
      switch (action) {
        case MotionEvent.ACTION_DOWN:
          startGeoPoint = pj.fromPixels(round(currentX), round(currentY));
          pj.toPixels(startGeoPoint, startP);
          break;
        case MotionEvent.ACTION_MOVE:
          float dx = currentX - lastX;
          float dy = currentY - lastY;
          if (abs(dx) < 1 && abs(dy) < 1) {
            lastX = currentX;
            lastY = currentY;
            return true;
          }

          GeoPoint currentGeoPoint = pj.fromPixels(round(currentX), round(currentY));
          pj.toPixels(currentGeoPoint, tmpP);

          left = tmpP.x < startP.x ? tmpP.x : startP.x;
          right = tmpP.x > startP.x ? tmpP.x : startP.x;
          bottom = tmpP.y < startP.y ? tmpP.y : startP.y;
          top = tmpP.y > startP.y ? tmpP.y : startP.y;
          rect.set((int) left, (int) top, (int) right, (int) bottom);

          invalidate();
          break;
        case MotionEvent.ACTION_UP:
          GeoPoint ul = pj.fromPixels((int) left, (int) top);
          GeoPoint lr = pj.fromPixels((int) right, (int) bottom);

          infoDialog(ul.getLatitude(), ul.getLongitude(), lr.getLatitude(), lr.getLongitude());

          if (GPLog.LOG_HEAVY)
            GPLog.addLogEntry(
                this, "UNTOUCH: " + tmpP.x + "/" + tmpP.y); // $NON-NLS-1$//$NON-NLS-2$
          break;
      }
    }
    if (doMeasureMode) {

      Projection pj = mapView.getProjection();
      // handle drawing
      currentX = event.getX();
      currentY = event.getY();

      tmpP.set(round(currentX), round(currentY));

      int action = event.getAction();
      switch (action) {
        case MotionEvent.ACTION_DOWN:
          measuredDistance = 0;
          measurePath.reset();
          GeoPoint firstGeoPoint = pj.fromPixels(round(currentX), round(currentY));
          pj.toPixels(firstGeoPoint, tmpP);
          measurePath.moveTo(tmpP.x, tmpP.y);

          lastX = currentX;
          lastY = currentY;

          if (GPLog.LOG_HEAVY)
            GPLog.addLogEntry(this, "TOUCH: " + tmpP.x + "/" + tmpP.y); // $NON-NLS-1$//$NON-NLS-2$
          break;
        case MotionEvent.ACTION_MOVE:
          float dx = currentX - lastX;
          float dy = currentY - lastY;
          if (abs(dx) < 1 && abs(dy) < 1) {
            lastX = currentX;
            lastY = currentY;
            return true;
          }

          GeoPoint currentGeoPoint = pj.fromPixels(round(currentX), round(currentY));
          pj.toPixels(currentGeoPoint, tmpP);
          measurePath.lineTo(tmpP.x, tmpP.y);
          if (GPLog.LOG_HEAVY)
            GPLog.addLogEntry(this, "DRAG: " + tmpP.x + "/" + tmpP.y); // $NON-NLS-1$ //$NON-NLS-2$
          // the measurement
          GeoPoint previousGeoPoint = pj.fromPixels(round(lastX), round(lastY));

          Location l1 = new Location("gps"); // $NON-NLS-1$
          l1.setLatitude(previousGeoPoint.getLatitude());
          l1.setLongitude(previousGeoPoint.getLongitude());
          Location l2 = new Location("gps"); // $NON-NLS-1$
          l2.setLatitude(currentGeoPoint.getLatitude());
          l2.setLongitude(currentGeoPoint.getLongitude());

          float distanceTo = l1.distanceTo(l2);
          lastX = currentX;
          lastY = currentY;
          measuredDistance = measuredDistance + distanceTo;
          invalidate();
          break;
        case MotionEvent.ACTION_UP:
          if (GPLog.LOG_HEAVY)
            GPLog.addLogEntry(
                this, "UNTOUCH: " + tmpP.x + "/" + tmpP.y); // $NON-NLS-1$//$NON-NLS-2$
          break;
      }
    }
    return true;
  }