public void draw(
      Canvas canvas, MapCameraInterface mapCamera, MapRenderer mapRenderer, View mapOverlay) {
    if (canvas == null) {
      return;
    }

    LocationInformation ownLocation = this.application.getOwnLocationInformation();
    LocationProvider provider = this.application.getLocationProvider();

    int[] ownPositionCoords =
        mapCamera.getScreenCoordinate(
            (int) ownLocation.getMC2Position().getMc2Latitude(),
            (int) ownLocation.getMC2Position().getMc2Longitude());
    if (provider != null) {
      int origX = ownPositionCoords[0];
      int origY = ownPositionCoords[1];
      int x = origX;
      int y = origY;

      boolean isOnScreen = true;
      int arrowSize = this.arrow.getWidth() >> 1;

      int coords[] = {0, 0};
      if (mapOverlay != null) {
        mapOverlay.getLocationOnScreen(coords);
      }
      int top = coords[1];

      iOwnerMap.getLocationOnScreen(coords);
      top -= coords[1];

      int canvasHeight = canvas.getHeight();
      this.overlayHeight = (mapOverlay != null ? canvasHeight - top : 0);
      this.minX = arrowSize;
      this.maxX = canvas.getWidth() - arrowSize;
      this.minY = arrowSize;
      this.maxY = canvasHeight - this.overlayHeight - arrowSize;

      if (x < this.minX) {
        x = this.minX;
        isOnScreen = false;
      }

      if (x > this.maxX) {
        x = this.maxX;
        isOnScreen = false;
      }

      if (y < this.minY) {
        y = this.minY;
        isOnScreen = false;
      }

      if (y > this.maxY) {
        y = this.maxY;
        isOnScreen = false;
      }

      draw(canvas, mapCamera, ownLocation, provider, origX, origY, x, y, isOnScreen);
    }
  }
  private void draw(
      Canvas canvas,
      MapCameraInterface mapCamera,
      LocationInformation ownLocation,
      LocationProvider provider,
      int origX,
      int origY,
      int x,
      int y,
      boolean isOnScreen) {
    int radius = ownLocation.getAccuracy();
    if (radius <= AbstractActivity.ACCURACY_MAX) {
      if (provider.getState() == LocationProvider.PROVIDER_STATE_AVAILABLE) {
        if (this.on) {
          drawMarker(canvas, ownPositionPinEnabled1, origX, origY);
        } else {
          drawMarker(canvas, ownPositionPinEnabled2, origX, origY);
        }
      } else {
        drawMarker(canvas, ownPositionPinDisabled, origX, origY);
      }
    } else {
      float screenRadius = (float) radius / (float) this.application.getMapInterface().getScale();
      Resources resources = application.getResources();
      float minRadious = resources.getDimensionPixelSize(R.dimen.location_circle_radius);

      if (screenRadius < minRadious) {
        screenRadius = minRadious;
      }

      int radiusColor = 0x4C0099DA;
      int borderColor = 0xAA0099DA;
      if (provider.getState() != LocationProvider.PROVIDER_STATE_AVAILABLE) {
        radiusColor = 0x4C999999;
        borderColor = 0xAA999999;
      }
      this.radiusPaint.setColor(radiusColor);
      this.borderPaint.setColor(borderColor);

      canvas.drawCircle(origX, origY, screenRadius, this.radiusPaint);
      canvas.drawCircle(origX, origY, screenRadius, this.borderPaint);
    }

    if (!isOnScreen) {
      int arrowSize = this.arrow.getWidth();
      int textX = x;
      int textY = y;
      Align align = Paint.Align.LEFT;
      int angle = 0;
      if (origX >= this.minX && origX <= this.maxX) {
        if (origY <= this.minY) {
          // outside the top of screen
          angle = 0;
          align = Paint.Align.CENTER;
          textY += arrowSize;
        } else if (origY >= this.maxY) {
          // outside the bottom of screen
          angle = 180;
          align = Paint.Align.CENTER;
          textY -= arrowSize;
        } else {
          // onscreen, shouldn't happen here
        }
      } else if (origY >= this.minY && origY <= this.maxY) {
        if (origX <= this.minX) {
          // outside the left of screen
          angle = 270;
          align = Paint.Align.LEFT;
          textX += arrowSize;
        } else if (origX >= this.maxX) {
          // outside the right of screen
          angle = 90;
          align = Paint.Align.RIGHT;
          textX -= arrowSize;
        } else {
          // onscreen, shouldn't happen here
        }
      } else {
        // both x and y is outside of screen�s boundaries
        if (origX >= this.maxX && origY <= this.minY) {
          // top, right
          angle = 45;
          align = Paint.Align.RIGHT;
          textX -= arrowSize;
          textY += arrowSize;
        } else if (origX >= this.maxX && origY >= this.maxY) {
          // bottom, right
          angle = 135;
          align = Paint.Align.RIGHT;
          textX -= arrowSize;
          textY -= arrowSize;
        } else if (origX <= this.minX && origY <= this.minY) {
          // top, left
          angle = 315;
          align = Paint.Align.LEFT;
          textX += arrowSize;
          textY += arrowSize;
        } else if (origX <= this.minX && origY >= this.maxY) {
          // bottom, left
          angle = 225;
          align = Paint.Align.LEFT;
          textX += arrowSize;
          textY -= arrowSize;
        } else {
          // onscreen, shouldn't happen here
        }
      }

      long[] worldCoords = mapCamera.getWorldCoordinate(x, y);
      Position position = new Position((int) worldCoords[0], (int) worldCoords[1]);
      int d = position.distanceTo(ownLocation.getMC2Position());
      FormattingResult result = this.application.getUnitsFormatter().formatDistance(d);
      String distance = result.getRoundedValue() + " " + result.getUnitAbbr();

      this.updateRotation(angle);
      canvas.drawBitmap(
          this.rotatedArrow,
          x - (this.rotatedArrow.getWidth() >> 1),
          y - (this.rotatedArrow.getHeight() >> 1),
          this.borderPaint);

      this.borderPaint.setTextAlign(align);

      this.borderPaint.setColor(0xFFFFFFFF);
      for (int i = 0; i < 9; i++) {
        if (i != 4) {
          canvas.drawText(
              distance,
              textX - (i % 3) + 1,
              textY - ((int) this.borderPaint.ascent() >> 1) - (i / 3) + 1,
              this.borderPaint);
        }
      }
      this.borderPaint.setColor(0xFF000000);
      canvas.drawText(
          distance, textX, textY - ((int) this.borderPaint.ascent() >> 1), this.borderPaint);
    }
  }