[OSM-dev] Projection Issues

Christopher Schmidt crschmidt at crschmidt.net
Wed May 31 05:11:18 BST 2006


After hours and hours of staring at dao.rb, I think that with pair
code-reading, we may have found the reason that using OpenStreetMap WMS
is not working in situations other than using OpenStreetMap's specific
version of Tile.js:

Lines 19 and 20:

19        @dlon = width / 2 * degrees_per_pixel
20        @dlat = height / 2 * degrees_per_pixel  * cos(@clat * PI / 180)

dlon and dlat in this case are half-tile distances in degrees. However,
this math appears to be backwards from what pretty much everything else 
thinks. The reason for this is clear (though not obvious) if you think 
about the way that latitude and longitude works.

Latitudes are equidistant. One degree of latitude is always 111.1km. As
you head towards the poles, this is still the case. However, longitude
changes: at the poles, obviously, the distance between longitudes is 0.

It appears as if the code should probably be:

     @dlon = width / 2 * degrees_per_pixel * cos(@clat * PI / 180)
     @dlat = height / 2 * degrees_per_pixel 

My next step was to try and work out *why* this works at all in
OpenStreetMap. Looking back to the original version of tile.js, checked
into the repository 10/09/05 14:32:02, r624, and diffed it against the
original civicmaps Tile engine source (maps.civicactions.net), and found
this: 
-  + "&BBOX=" + lt + "," + tp + "," + rt + "," + bt;
+  + "&BBOX=" + lt + "," + 180 / 3.141592 * (2 * Math.atan(Math.exp(tp *
3.141592 / 180)) - 3.141592 /2)  + "," + rt + "," + 180 / 3.141592 * (2
* Math.atan(Math.exp(bt * 3.141592 / 180 )) - 3.141592 /2)  ;

In other words: modify our latitude to be in a 'mercator' projection.

Mapserver modifies the Landsat according to the requested bounding box,
so the landsat is stretched to fit the request. This is why the streets
and landsat layers match up.

The result when viewing the data in some viewer that doesn't suffer the
same confusion with regard to Mercator, is that the streets are
vertically much taller than they otherwise would be.

You can see two resulting tiles from different algorithms:
http://tile.openstreetmap.org/cgi-bin/steve/mapserv?map=/usr/lib/cgi-bin/steve/wms.map&service=WMS&WMTVER=1.0.0&REQUEST=map&STYLES=&TRANSPARENT=TRUE&bbox=-0.046875,51.5078125,-0.03125,51.515625&width=256&height=128&layers=landsat,streets&service=WMS&version=1.1.1&request=GetMap
http://tile.openstreetmap.org/cgi-bin/steve/mapserv?map=/usr/lib/cgi-bin/steve/wms.map&service=WMS&WMTVER=1.0.0&REQUEST=map&STYLES=&TRANSPARENT=TRUE&LAYERS=landsat,streets&WIDTH=256&HEIGHT=128&BBOX=-0.043946,51.507621666833884,-0.021973,51.51445895579278

Note that despite having the same height and width, and almost exactly
the same latitude delta, but the longitude is significantly different...

There are still some issues with this: specifically,
http://trac.openstreetmap.org/browser/www.openstreetmap.org/ruby/api/wms/wms.map
states that the streets are in Lat/Lon WGS-84, when really, they may be
something different.

So, what we have is a combination of two things 'broken' or not written
correctly in the exact same way, which seems to have the end result of
the code working inside OpenStreetMap and not anywhere else. 

Note that I could well be wrong. This is the closest approximation to
a concise description of the problem, and it may be that I'm utterly
wrong, but at least the dlon/dlat above seem like they should be
backwards from the way they are. And there's a lot of other code that
seems to be changing to match that.

I'm not sure if this helps at all, but it seems like this might be a
first step towards getting closer to getting OSM into OpenLayers.

-- 
Christopher Schmidt
Web Developer




More information about the dev mailing list