[OSM-dev] tiles cut corners
Lars Aronsson
lars at aronsson.se
Sat Feb 25 19:32:17 GMT 2006
I think that the map viewer fails to render line segments that cut
across a corner of a tile, e.g. where node_a is to the west and
node_b is to the north of the tile borders. This becomes apparent
at deep zoom levels or where line segments are very long. One
example where this happens in three places is
http://www.openstreetmap.org/index.html?lat=58.379&lon=15.419&zoom=15
But it shows also in less extreme cases, where a few pixels can be
missing from a road. I think this is what happens at the very
center of
http://www.openstreetmap.org/index.html?lat=58.3799&lon=15.4240&zoom=12
This effect is demoralizing to the careful map editor. The
resulting map looks as if she missed something. As if Wikipedia
would introduce spelling errors in the text you wrote.
I think the street tiles are generated with
svn/ruby/api/wms/streets.rbx and the function dao.getnodes() in
svn/ruby/api/osm/dao.rb where the SQL statement is:
select id, latitude, longitude, visible, tags
from (select *
from (select nodes.id, nodes.latitude, nodes.longitude,
nodes.visible, nodes.tags
from nodes, nodes as a
where a.latitude > #{lat2} and a.latitude < #{lat1}
and a.longitude > #{lon1} and a.longitude < #{lon2}
and nodes.id = a.id
order by nodes.timestamp desc) as b
group by id) as c
where visible = true
and latitude > #{lat2} and latitude < #{lat1}
and longitude > #{lon1} and longitude < #{lon2}
This code is hard to read as it is, and it doesn't get better from
the fact that lat2 < lat1 even though lon1 < lon2. The call is
dao.getnodes(trlat, bllon, bllat, trlon), whereas the argument
order in the CGI interface is bbox=bllon,bllat,trlon,trlat. I
must admit I don't fully understand what this deeply nested SQL
statement does. For example, where do "b" and "c" go? Does this
statement select any node outside of the current tile? Isn't it
in fact equivalent to the following?
select id, latitude, longitude
from nodes
where latitude > minlat
and latitude < maxlat
and longitude > minlon
and longitude < maxlon
and visible = true
In order to include line segments that cut corners, it is
necessary to include lines that begin and end outside of the
current tile. The naive way I would have implemented this is to
add a margin around the tile, equal to the maximum length of a
line segment, and simply do
select id, latitude, longitude
from nodes
where latitude > minlat - margin
and latitude < maxlat + margin
and longitude > minlon - margin
and longitude < maxlon + margin
and visible = true
On the other hand, it has the drawback that a margin would have to
be specified and no segments longer than this should be allowed.
Such a margin could perhaps be 0.005 degrees or 550 meters.
--
Lars Aronsson (lars at aronsson.se)
Aronsson Datateknik - http://aronsson.se
More information about the dev
mailing list