We wrote a hack to build our web based map feature into a mobile application.

Step 1) Get the initial tile for the users position using Lat/Lon/Zoom direct from the appropriate tile server, ( we call this the 256x256 master tile).

Step 2) Paint overlay dot, or pushpin on master tile.

Step 3) Build surrounding tiles, just one tile on each border of the master tile. N, NE, E, SE, S, SW, W, and NW.

Step 4) Stitch all tiles together on the server and push it to the mobile phone.


We are trying to create a map overlay to put a red dot at the exact location of the users Lat/Lon using the following Java method but the Pixel position returned is way off... Can someone point us in the right direction for adding a pushpin, or dot to represent the users exact location

We are calling this method just for the initial 256 x 256 tile that is returned (master tile) and not for the final stitched together png, and painting the overlay on just that master tile png. We are doing this from a custom Java server-side application and not using the standard javascript encountered using the html approach.


LatLongToPixelXY(LAT_double, LON_double, zoom_level);

then use the returned int[0], and int[1] to call

PixelXYToTileXY(int[0], int[1]);

use return result to paint red dot overlay.

example master tile: g=1

for lat/lon/zoom

"36.11354072045737","-115.13779163360595", "16"

Code Block

public int[] LatLongToPixelXY(double latitude, double longitude, int levelOfDetail){

int retInt[]={0,0};

latitude = Clip(latitude, MinLatitude, MaxLatitude);

longitude = Clip(longitude, MinLongitude, MaxLongitude);

double x = (longitude + 180) / 360;

double sinLatitude = Math.sin(latitude * Math.PI / 180);

double y = 0.5 - Math.log((1 + sinLatitude) / (1 - sinLatitude)) /

(4 * Math.PI);

int mapSize = MapSize(levelOfDetail);

retInt[0] = (int) Clip(x * mapSize + 0.5, 0, mapSize - 1);

retInt[1] = (int) Clip(y * mapSize + 0.5, 0, mapSize - 1);

return retInt; }

public int[] PixelXYToTileXY(int pixelX, int pixelY){

int retInt[]={0,0};

retInt[0] = pixelX / 256;

retInt[1] = pixelY / 256;

return retInt; }

private double MinLatitude = -85.05112878;

private double MaxLatitude = 85.05112878;

private double MinLongitude = -180;

private double MaxLongitude = 180;

private double Clip(double n, double minValue, double maxValue){

return Math.min(Math.max(n, minValue), maxValue); }

private int MapSize(int levelOfDetail){

return (int) 256 << levelOfDetail; }

Re: Virtual Earth mobile hack: map overlay question

Daniel Hawkins


I have this code that works well for me

Code Block

Public Shared Function GetPointFromNwSe(ByVal locationToFind As Location, ByVal height As Int32, ByVal width As Int32, ByVal northwest As Location, ByVal southeast As Location) As Point

Dim longWidth As Double = -1

Dim latHeight As Double = -1

Dim point As New Point

longWidth = (southeast.Longitude - northwest.Longitude)

latHeight = (northwest.Latitude - southeast.Latitude)

point.X = CInt((width * (locationToFind.Longitude - northwest.Longitude)) / longWidth)

Dim scale As Double

Dim mercNw As Double

Dim mercSe As Double

mercNw = Mercator(northwest.Latitude)

mercSe = Mercator(southeast.Latitude)

scale = height / (mercNw - mercSe)

point.Y = Convert.ToInt32(height - (Mercator(locationToFind.Latitude) - mercSe) * scale)

Return point

End Function

Private Shared Function Mercator(ByVal val As Double) As Double

Return 0.5 * Math.Log((1 + Math.Sin(val * Math.PI / 180)) / (1 - Math.Sin(val * Math.PI / 180)))

End Function

Hope that helps.

Re: Virtual Earth mobile hack: map overlay question


There is some great code surrounding tiles and lat/long conversions in these two articles:

I used this code to determin the pixel position of shapes for my server side clustering logic.