title: Tile Projection Google Maps: Convert Distance to Screen Dimensions
body: <p>I am using the CanvasTileProvider in Google Maps Android v2. </p>
  
  <p>I can convert lat long points to screen pixels. </p>
  
  <p>However I would like to create a method to convert a distance to screen pixels. This will allow me to draw a circle of x radius.  Can anyone help with this?</p>
  
  <p>The code below I have butchered and modified from somewhere else so credit to the original author.</p>
  
  <pre><code>/**
   * Converts between LatLng coordinates and the pixels inside a tile.
   */
  public class TileProjection {
  
      public int x;
      public int y;
      private int zoom;
      private int TILE_SIZE;
  
      private DoublePoint pixelOrigin_;
      private double pixelsPerLonDegree_;
      private double pixelsPerLonRadian_;
  
      TileProjection(int tileSize, int x, int y, int zoom) {
          this.TILE_SIZE = tileSize;
          this.x = x;
          this.y = y;
          this.zoom = zoom;
          pixelOrigin_ = new DoublePoint(TILE_SIZE / 2, TILE_SIZE / 2);
          pixelsPerLonDegree_ = TILE_SIZE / 360d;
          pixelsPerLonRadian_ = TILE_SIZE / (2 * Math.PI);
      }
  
      /**
       * Get the dimensions of the Tile in LatLng coordinates
       */
      public LatLngBounds getTileBounds() {
          DoublePoint tileSW = new DoublePoint(x * TILE_SIZE, (y + 1) * TILE_SIZE);
          DoublePoint worldSW = pixelToWorldCoordinates(tileSW);
          LatLng SW = worldCoordToLatLng(worldSW);
          DoublePoint tileNE = new DoublePoint((x + 1) * TILE_SIZE, y * TILE_SIZE);
          DoublePoint worldNE = pixelToWorldCoordinates(tileNE);
          LatLng NE = worldCoordToLatLng(worldNE);
          return new LatLngBounds(SW, NE);
      }
  
      /**
       * Calculate the pixel coordinates inside a tile, relative to the left upper
       * corner (origin) of the tile.
       */
      public PointF latLngToPoint(LatLng latLng) {
          DoublePoint result = new DoublePoint(1, 1);
          //  Log.d("Aero","x " + String.valueOf(x));
          // Log.d("Aero","y " + String.valueOf(y));
  
          latLngToWorldCoordinates(latLng, result);
          worldToPixelCoordinates(result, result);
          result.x -= x * TILE_SIZE;
  
          int numTiles = 1 &lt;&lt; zoom;
          if (latLng.longitude &lt; 0) {
              result.x = result.x + (numTiles * TILE_SIZE);
          }
  
          result.y -= y * TILE_SIZE;
          return new PointF((float) result.x, (float) result.y);
      }    
  
      private DoublePoint pixelToWorldCoordinates(DoublePoint pixelCoord) {
          int numTiles = 1 &lt;&lt; zoom;
          DoublePoint worldCoordinate = new DoublePoint(pixelCoord.x / numTiles,
                  pixelCoord.y / numTiles);
          return worldCoordinate;
      }
  
      /**
       * Transform the world coordinates into pixel-coordinates relative to the
       * whole tile-area. (i.e. the coordinate system that spans all tiles.)
       * &lt;p/&gt;
       * &lt;p/&gt;
       * Takes the resulting point as parameter, to avoid creation of new objects.
       */
      private void worldToPixelCoordinates(DoublePoint worldCoord, DoublePoint result) {
          int numTiles = 1 &lt;&lt; zoom;
          result.x = worldCoord.x * numTiles;
          result.y = worldCoord.y * numTiles;
      }
  
      private LatLng worldCoordToLatLng(DoublePoint worldCoordinate) {
          DoublePoint origin = pixelOrigin_;
          double lng = (worldCoordinate.x - origin.x) / pixelsPerLonDegree_;
          double latRadians = (worldCoordinate.y - origin.y)
                  / -pixelsPerLonRadian_;
          double lat = Math.toDegrees(2 * Math.atan(Math.exp(latRadians))
                  - Math.PI / 2);
          return new LatLng(lat, lng);
      }
  
      /**
       * Get the coordinates in a system describing the whole globe in a
       * coordinate range from 0 to TILE_SIZE (type double).
       * &lt;p/&gt;
       * Takes the resulting point as parameter, to avoid creation of new objects.
       */
      private void latLngToWorldCoordinates(LatLng latLng, DoublePoint result) {
          DoublePoint origin = pixelOrigin_;
  
          result.x = origin.x + latLng.longitude * pixelsPerLonDegree_;
  
  
          // Truncating to 0.9999 effectively limits latitude to 89.189. This is
          // about a third of a tile past the edge of the world tile.
          double siny = bound(Math.sin(Math.toRadians(latLng.latitude)), -0.9999,
                  0.9999);
          result.y = origin.y + 0.5 * Math.log((1 + siny) / (1 - siny))
                  * -pixelsPerLonRadian_;
      }
  
      ;
  
      /**
       * Return value reduced to min and max if outside one of these bounds.
       */
      private double bound(double value, double min, double max) {
          value = Math.max(value, min);
          value = Math.min(value, max);
          return value;
      }
  
      /**
       * A Point in an x/y coordinate system with coordinates of type double
       */
      public static class DoublePoint {
          double x;
          double y;
  
          public DoublePoint(double x, double y) {
              this.x = x;
              this.y = y;
          }
      }
  
  }
  </code></pre>
  
  <p>This is what I am proposing to use:</p>
  
  <pre><code>public Double MetersToPixels(LatLng latLng, Double distance){
      double tileScale = TILE_SIZE / 256;
      double pixelsPerMeter =1 / (156543.03392 * Math.cos(latLng.latitude * Math.PI / 180) / Math.pow(2, zoom)) * tileScale;
      return  pixelsPerMeter * distance;
  }
  </code></pre>