@Override
  public Point toPoint(GeoPoint in, Point out, byte zoom) {
    if (out == null) {
      // create a new point and return it
      return new Point(
          (int) MercatorProjection.longitudeToPixelX(in.getLongitude(), zoom),
          (int) MercatorProjection.latitudeToPixelY(in.getLatitude(), zoom));
    }

    // reuse the existing point
    out.x = (int) MercatorProjection.longitudeToPixelX(in.getLongitude(), zoom);
    out.y = (int) MercatorProjection.latitudeToPixelY(in.getLatitude(), zoom);
    return out;
  }
  @Override
  public Point toPixels(GeoPoint in, Point out) {
    if (this.mapView.getWidth() <= 0 || this.mapView.getHeight() <= 0) {
      return null;
    }

    MapPosition mapPosition = this.mapView.getMapPosition().getMapPosition();

    // calculate the pixel coordinates of the top left corner
    GeoPoint geoPoint = mapPosition.geoPoint;
    double pixelX =
        MercatorProjection.longitudeToPixelX(geoPoint.getLongitude(), mapPosition.zoomLevel);
    double pixelY =
        MercatorProjection.latitudeToPixelY(geoPoint.getLatitude(), mapPosition.zoomLevel);
    pixelX -= this.mapView.getWidth() >> 1;
    pixelY -= this.mapView.getHeight() >> 1;

    if (out == null) {
      // create a new point and return it
      return new Point(
          (int)
              (MercatorProjection.longitudeToPixelX(in.getLongitude(), mapPosition.zoomLevel)
                  - pixelX),
          (int)
              (MercatorProjection.latitudeToPixelY(in.getLatitude(), mapPosition.zoomLevel)
                  - pixelY));
    }

    // reuse the existing point
    out.x =
        (int)
            (MercatorProjection.longitudeToPixelX(in.getLongitude(), mapPosition.zoomLevel)
                - pixelX);
    out.y =
        (int)
            (MercatorProjection.latitudeToPixelY(in.getLatitude(), mapPosition.zoomLevel) - pixelY);
    return out;
  }
  @Override
  public GeoPoint fromPixels(int x, int y) {
    if (this.mapView.getWidth() <= 0 || this.mapView.getHeight() <= 0) {
      return null;
    }

    MapPosition mapPosition = this.mapView.getMapPosition().getMapPosition();

    // calculate the pixel coordinates of the top left corner
    GeoPoint geoPoint = mapPosition.geoPoint;
    double pixelX =
        MercatorProjection.longitudeToPixelX(geoPoint.getLongitude(), mapPosition.zoomLevel);
    double pixelY =
        MercatorProjection.latitudeToPixelY(geoPoint.getLatitude(), mapPosition.zoomLevel);
    pixelX -= this.mapView.getWidth() >> 1;
    pixelY -= this.mapView.getHeight() >> 1;

    // convert the pixel coordinates to a GeoPoint and return it
    return new GeoPoint(
        MercatorProjection.pixelYToLatitude(pixelY + y, mapPosition.zoomLevel),
        MercatorProjection.pixelXToLongitude(pixelX + x, mapPosition.zoomLevel));
  }