Hi all,
I am currently using a setup similar to
http://wiki.openstreetmap.org/wiki/Howto_real_time_tiles_rendering_with_mapnik_and_mod_python.
The problem I have is that some tiles are properly rendered, but other
are not, like in this example:
http://yvecai.olympe-network.com/divers/Capture.png
It looks like the rendering is not 'finished', and this is also the case
for a layer containing only hillshading from SRTM raster images (some
tiles are simply missing).
On the other and, the generate_tile.py script works OK to create the
tiles on disk.
Please find attached the scripts used by mod_python and the apache
config file.
Ubuntu 10.04, mapnik 0.7.1
Apache/2.2.14 (Ubuntu) mod_python/3.3.1 Python/2.6.5 configured
Yves
#!/usr/bin/env python
# Source is GPL, credit goes to Nicolas Pouillon
# comments goes to sylvain letuffe org (" " are replaced by @ and . )
# fichier execute par mod_python. handle() est le point d'entree.
import os, os.path
from gen_tile import MapMaker
def get_renderers(path, zmax = 20):
r = {}
for filename in os.listdir(path):
print filename
if filename.startswith("."):
continue
if not filename.endswith(".xml"):
continue
rname = filename[:-4]
print 'rname:', rname
print path
try:
r[rname] = MapMaker(os.path.join(path, filename), zmax)
print 'full path', os.path.join(path, filename)
except:
pass
return r
zmax=20
renderers = get_renderers("/home/yves/sites/www.moi.org/mapnik-styles/", zmax)
print 'renderers', renderers
def handle(req):
from mod_python import apache, util
path = os.path.basename(req.filename)+req.path_info
# strip .png
script, right = path.split(".", 1)
new_path, ext = right.split(".", 1)
rien, style, z, x, y = new_path.split('/', 4)
if style in renderers:
req.status = 200
req.content_type = 'image/png'
z = int(z)
x = int(x)
y = int(y)
#req.content_type = 'text/plain'
#req.write(renderers[style])
#return apache.OK
if z<13:
cache=True
else:
cache=False
req.write(renderers[style].genTile(x, y, z, ext, cache))
else:
req.status = 404
req.content_type = 'text/plain'
req.write("No such style")
return apache.OK
#!/usr/bin/env python
import os
import mapnik
import math
def minmax (a,b,c):
a = max(a,b)
a = min(a,c)
return a
class GoogleProjection:
def __init__(self,levels=18):
self.Bc = []
self.Cc = []
self.zc = []
self.Ac = []
c = 256
for d in range(0,levels):
e = c/2;
self.Bc.append(c/360.0)
self.Cc.append(c/(2 * math.pi))
self.zc.append((e,e))
self.Ac.append(c)
c *= 2
def fromLLtoPixel(self,ll,zoom):
d = self.zc[zoom]
e = round(d[0] + ll[0] * self.Bc[zoom])
f = minmax(math.sin(math.radians(ll[1])),-0.9999,0.9999)
g = round(d[1] + 0.5*math.log((1+f)/(1-f))*-self.Cc[zoom])
return (e,g)
def fromPixelToLL(self,px,zoom):
e = self.zc[zoom]
f = (px[0] - e[0])/self.Bc[zoom]
g = (px[1] - e[1])/-self.Cc[zoom]
h = math.degrees( 2 * math.atan(math.exp(g)) - 0.5 * math.pi)
return (f,h)
class MapMaker:
sx = 256
sy = 256
prj = mapnik.Projection("+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgri...@null +no_defs +over")
def __init__(self, mapfile, max_zoom):
# print mapfile
self.m = mapnik.Map(2*self.sx, 2*self.sy)
self.max_zoom = max_zoom
self.gprj = GoogleProjection(max_zoom)
try:
mapnik.load_map(self.m,mapfile)
except RuntimeError:
print 'Bad File'
raise ValueError("Bad file", mapfile)
self.name = hex(hash(mapfile))
def tileno2bbox(self, x, y, z):
p0 = self.gprj.fromPixelToLL((self.sx*x, self.sy*(y+1)), z)
p1 = self.gprj.fromPixelToLL((self.sx*(x+1), self.sy*y), z)
c0 = self.prj.forward(mapnik.Coord(p0[0],p0[1]))
c1 = self.prj.forward(mapnik.Coord(p1[0],p1[1]))
return mapnik.Envelope(c0.x,c0.y,c1.x,c1.y)
def genTile(self, x, y, z, ext="png", cache=False):
if cache:
outname = '/home/yves/sites/www.moi.org/tiles/cache/%d/%d/%d.%s'%( z, x, y, ext)
if os.path.exists(outname):
fd = open(outname, 'r')
return fd.read()
try:
os.makedirs(os.path.dirname(outname))
except:
pass
else:
outname = os.tmpnam()
bbox = self.tileno2bbox(x, y, z)
bbox.width(bbox.width() * 2)
bbox.height(bbox.height() * 2)
self.m.zoom_to_box(bbox)
im = mapnik.Image(self.sx*2, self.sy*2)
mapnik.render(self.m, im)
view = im.view(self.sx/2, self.sy/2, self.sx, self.sy)
view.save(outname, ext)
fd = open(outname)
out = fd.read()
fd.close()
if not cache:
os.unlink(outname)
return out
# Fonction de test, qui n'est appelee que si on execute le fichier
# directement.
def test():
renderer = MapMaker('/home/yves/sites/www.moi.org/mapnik-styles/template.xml', 18)
for filename, x, y, z in (
('test.png', 2074, 1409, 12),
):
fd = open(filename, 'w')
fd.write(renderer.genTile(x, y, z))
fd.close()
if __name__ == '__main__':
test()
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of version 3 of the GNU General Public License as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
<VirtualHost _default_:80>
ServerName moi.org
DocumentRoot /home/yves/sites/www.moi.org
CustomLog /home/yves/sites/www.moi.org/custom combined
ErrorLog /home/yves/sites/www.moi.org/error
loglevel debug
<Directory "/home/yves/sites">
AllowOverride All
Options +ExecCGI MultiViews FollowSymLinks
AddHandler python-program .py
PythonDebug On
PythonHandler test
AcceptPathInfo On
AddOutputFilterByType DEFLATE text/html text/plain text/xml
text/css text/javascript application/x-javascript
ExpiresActive On
ExpiresDefault A2592000
</Directory>
<IfModule mod_userdir.c>
UserDir disable
</IfModule>
</VirtualHost>
_______________________________________________
dev mailing list
dev@openstreetmap.org
http://lists.openstreetmap.org/listinfo/dev