1
1

I have what I think should be a fairly straight forward question.

I have a map that is 1000x700 and has a user specified Zoom and Center Coordinates. I want to be able to find the pixel location of a certain coordinate showing on the map.

For example, if I have the following map: http://pafciu17.dev.openstreetmap.org/?module=map&lon=-89.08805000000001&lat=30.6393&zoom=6.5156731549786215&width=1000.0&height=700.0&type=mapnik&imgType=gif

I would like to be able to locate Fort Worth, Texas on the image (pixel location).

I assume there is some sort of formula for determining the pixel location of a coordinate based on the image size, center coordinate, and zoom factor. Can anyone help me out? Any help is greatly appreciated.

asked 02 Feb '11, 16:58

aussiemcgr's gravatar image

aussiemcgr
30223
accept rate: 0%


4 Answers:
4

The (very) short answer is: Have a look at at the wiki and the question that was asked earlier.

As this does not resolve the submitters question, I'll edit my answer and expand it. For the original example URL we can extract the following parameters: longitude 89.08805 west, latitude 30.6393 north and zoomlevel 6.5156731549786215. (Note that this is a non integer zoomlevel and might break lots of code that only expects integer zoomlevels.) However looking at the output resulting gif it looks like the website truncates the zoomlevel and really uses zoomlevel 6.

Using this really simple java code which would support fractional zoomlevels if needed in the future we can convert lat and long to tile coordinates.

double lon = -89.08805;
double lat = 30.6393;
double zoom = 6; // 6.5156731549786215 would be possible too

double lon_rad = Math.toRadians(lon);
double lat_rad = Math.toRadians(lat);
double n = Math.pow(2.0, zoom);

double tileX = ((lon + 180) / 360) * n;
double tileY = (1 - (Math.log(Math.tan(lat_rad) + 1.0/Math.cos(lat_rad)) / Math.PI)) * n / 2.0;

System.out.println("tileX = "+tileX+" tileY = "+tileY);

It computes the location of the map center in tile coordinates as:

tileX = 16.162124444444444
tileY = 26.273150713795616

For Forth Worth I'll use longitude 97.3327459 east and latitude 32.753177 north which translates into:

tileX = 14.696400728888888
tileY = 25.831427880285347

So Fort Worth is 1.465723715555556 tiles left and 0.441722833510269 tiles above the map center. To get to pixels all you would have to do is to multiply by 256 pixels per tile. Thus we get the information that Fort Worth is 375 pixels left and 113 pixels above the map center.

Given that the map is 1000 pixels wide and 700 pixels wide this means that Fort Worth is 125 pixels from the left boundary and 237 pixels down from the top.

permanent link

answered 02 Feb '11, 17:06

petschge's gravatar image

petschge
8.0k207197
accept rate: 21%

edited 02 Feb '11, 20:28

Ok, I'm still having trouble. So when I calculate the tiles Fort Worth Airport (Long: -97.0411, Lat: 32.8964) with a zoom of 6, I get tileX = 21 and tileY = 37, which is around Santa Fe, Brazil. I copied and pasted the code you provided above. Why would I get this?

I should be getting a tileX of 14 and a tileY of 25 (based on the url: http://tile.openstreetmap.org/6/14/25.png)

Interestingly enough, if I multiply by 175 instead of 256 for Zoom 6 or 160 for a Zoom of 7, it seems to be completely correct. Is that coincidence or does zoom effect the pixels in the image?

(07 Feb '11, 15:31) aussiemcgr

I don't know what you do but my code outputs "tileX = 14.748248888888888 tileY = 25.801128101180893" for long: -97.0411, Lat: 32.8964, zoom: 6.

And not zoom level does not change the pixels per tile. But it does change the conversion to tile numbers.

(08 Feb '11, 14:29) petschge
2

I figured it out. When I powered with the zoom, I was using a double instead of an int. So the powering was adding additional value to the result of the power, thus resulting in the incorrect tiles. If I cast zoom before using it in the power, it works perfectly. Thank you for your help and your patience with me.

(09 Feb '11, 18:36) aussiemcgr

Using a double there would be right if the image creation site honored fractional zoomlevels. However it doesn't so you have to truncate the zoomlevel to match the result from that website. I'm glad we finally figured that one out.

(09 Feb '11, 18:52) petschge
0

hey, i wanted to ask how do you calculate that for Fort Worth is 1.465723715555556 tiles left and 0.441722833510269 tiles above the map center when you have tileX and tileY, what kind of calculations follow

permanent link

answered 15 Apr '11, 09:44

anichka's gravatar image

anichka
1
accept rate: 0%

1

I really hope that you are kidding, but here is the explanation: take the tileX of Forth Worth (14.696400728888888) and substract the tileX of the map center (16.162124444444444). You then get deltaX = 14.696400728888888 - 16.162124444444444 = -1.465723715555556. The X value is increasing left to right so a negative value for the difference means "left of the center". The same method applies to the Y direction.

(15 Apr '11, 10:42) petschge
0

hey plz how did you found that : Fort Worth is 125 pixels from the left boundary and 237 pixels down from the top.

permanent link

answered 23 Jul '12, 10:30

vaddinDev's gravatar image

vaddinDev
1
accept rate: 0%

0

I know this is old. But just as vaddinDev, I struggle to understand the conversion to the 100x700 map pixel location. What I think is used for calculation is that the tile is 256 images wide and tall.

So,

for width: 375 x 3 = 1125 => 1125-1000 = 125 pixels from left of image)

for height: 113 x 4 = 452 => 452-700 = -247 pixels down from top of image (I think the 237 in the original answer is a typo).

PLEASE correct me if I am stretching the math here!!!

permanent link

answered 13 Jul '18, 20:24

Omi3's gravatar image

Omi3
1
accept rate: 0%

edited 13 Jul '18, 20:26

Markdown Basics

  • *italic* or _italic_
  • **bold** or __bold__
  • link:[text](http://url.com/ "title")
  • image?![alt text](/path/img.jpg "title")
  • numbered list: 1. Foo 2. Bar
  • to add a line break simply add two spaces to where you would like the new line to be.
  • basic HTML tags are also supported

Question tags:

×89
×1

question asked: 02 Feb '11, 16:58

question was seen: 18,975 times

last updated: 13 Jul '18, 20:26

powered by OSQA