On Thu, Mar 27, 2008 at 1:18 AM, Martijn van Oosterhout
<[EMAIL PROTECTED]> wrote:
>
> On Wed, Mar 26, 2008 at 5:34 PM, Xin <[EMAIL PROTECTED]> wrote:
> > I need to update the styling soon, so have to go through this whole process
> > again. Is there anything I can do to speed up this process and reduce the
> > footprint? Perhaps by generate only 1 tile for the million of empty tiles.
>
> Sure, use TileCache to only render tiles when someone actually wants
> to look at them. On the NL tileserver we have half a dozen layers all
> generated on the fly. For layers which are used a lot it uses a lot of
> space, for layers not used much there's less diskspace...
>


I was in the same boat and was having some troubles with TileCache on
my system and didn't quite have the time to figure out why, so I threw
something similar together. TileCache is undoubtedly better, but if
that isn't going to fly for whatever reason here's an alternative.
Requests are made to the url:
http://your.domain.name/path/to/get_tile.py/handler?layer=layer1&z=[z]&x=[x]&y=[y]
With z x y as the z x y according to Google's tile scheme (you might
need to amend that as need be). Projection is in the Google / Virtual
Earth projection.
This was running on an apache system using mod_python.



-----------------------------------------------------------------
import os, pg, datetime, sys
from mapnik import *
from mod_python import apache

##  Renders tiles on request.. URL should be something along the lines of:
##     
http://your.domain.name/path/to/get_tile.py/handler?layer=layer1&z=[z]&x=[x]&y=[y]

def render_tile(req, tile_root, layer, zoom_level, x_i, y_i, write_over=False):

   m = Map(256,256,"+proj=latlong +ellps=WGS84")
   # Actually in the '900913' projection, but this works.. may have
something to do with
   # proj.4 not being supported on FreeBSD?

   if layer == 'layer1':
       layer1_lyr = Layer('layer1')
       layer1_lyr.datasource = Shapefile(file='/usr/path/to/shp')
       layer1_lyr_style = Style()
       layer1_lyr_rule = Rule()
       layer1_lyr_rule.symbols.append(LineSymbolizer(Color('black'), .02))
       layer1_lyr_style.rules.append(layer1_lyr_rule)
       m.append_style('layer1', layer1_lyr_style)
       layer1_lyr.styles.append('layer1')
       m.layers.append(layer1_lyr)
       m.background = Color('transparent')
       m.zoom_to_box(layer1_lyr.envelope())


   elif layer == 'layer2':
       #symbology rules for layer2 rules for layer two...

   else:
       sys.exit(2)

   tile_size = 256

   # figure out how many tiles per row/column we'll have
   tiles_per_row = pow(2, zoom_level);

   tile_coord_size = 40075016.6855784 / tiles_per_row   #size in
coordinates of each tile

   # For the bounding boxes.. based on the google tile scheme
   tile_x_min = int(x_i) * tile_coord_size
   tile_y_min = (tiles_per_row - 1 - int(y_i)) * tile_coord_size
   tile_x_max = tile_x_min + tile_coord_size
   tile_y_max = tile_y_min + tile_coord_size

   render_tile_to_file(req, m, tile_root, zoom_level, int(x_i), int(y_i), \
                           tile_x_min, tile_y_min, tile_x_max, tile_y_max, \
                           True)


##  This function renders individual tiles to the tile directory
def render_tile_to_file(req, render_map, tile_root, z, x, y, LL_x,
LL_y, UR_x, UR_y, write_over):
   if not tile_root.endswith('/'):
       tile_root += '/'

   if not os.path.exists(tile_root[0:len(tile_root)-1]):
       raise RenderError, "'" + tile_root + "' path does not exist or
you do not have proper missions."
       exit

   if not os.path.exists(tile_root + 'z' + str(z) + '/'):
       os.mkdir(tile_root + 'z' + str(z) + '/')

   if not os.path.exists(tile_root+ 'z' + str(z) + '/' + 'x' + str(x) + '/'):
       os.mkdir(tile_root + 'z' + str(z) + '/' + 'x' + str(x) + '/')

   if os.path.isfile(tile_root + 'z' + str(z) + '/x' + str(x) + '/y'
+ str(y) + '.png') \
      and not write_over:
       raise RenderError, tile_root + 'z' + str(z) + '/x' + str(x) +
'/y' + str(y) + '.png' + ' exists' + \
             ' already, file not written over.'
       exit

   render_map.zoom_to_box(Envelope(LL_x, LL_y, UR_x, UR_y))

   img_path =  tile_root + 'z' + str(z) + '/x' + str(x) + '/y' +
str(y) + '.png'

   render_to_file(render_map,img_path, 'png')



def handler(req, layer, z, x, y):
   req.content_type = "image/png"

   # translate URL to system path
   filepath = '/usr/local/www/apache22/data/tiles/' + str(layer) +
'/z' + str(z) + '/x' + str(x) + '/y' + str(y) + '.png'

   # if tile doesn't already exist, render it..
   if not os.path.isfile(filepath):
       render_tile(req, '/usr/local/www/apache22/data/tiles/' +
str(layer) + '/', layer, z, x, y)

   req.sendfile(filepath)

   return apache.OK

-----------------------------------------------------------------


Cheers,
Andy
_______________________________________________
Mapnik-users mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/mapnik-users

Reply via email to