diff options
-rw-r--r-- | read_layers.py | 65 |
1 files changed, 52 insertions, 13 deletions
diff --git a/read_layers.py b/read_layers.py index 3a26b5d..3d10445 100644 --- a/read_layers.py +++ b/read_layers.py @@ -8,8 +8,10 @@ # import cairo +import json import math import os +import shutil import stat import yaml @@ -52,6 +54,9 @@ class Layer(object): def _load_file(self, path): raise NotImplementedError + def __cmp__(self, other): + return cmp(self.name, other.name) + class PdfLayer(Layer): def _load_file(self, path): @@ -93,7 +98,7 @@ class PngLayer(Layer): class LayerLoader(object): def load(self, layer_path): layers = [] - for layer_file in sorted(os.listdir(layer_path)): + for layer_file in os.listdir(layer_path): if layer_file.endswith('.txt'): continue layer_file = os.path.join(layer_path, layer_file) @@ -124,6 +129,7 @@ class TileGenerator(object): self.tile_size = 256 if tile_size is None else tile_size self.zoom_step = 2.0 if zoom_step is None else float(zoom_step) self.scale = scale + self.draw_per_plane = True def create_tiles(self, path): # calculate how many zoom levels we need by getting the largest number with @@ -143,40 +149,71 @@ class TileGenerator(object): else: prescale = 1.0 + self.layer.max_zoom_level = max_zoom_level scaled_size = (self.size[0] * prescale, self.size[1] * prescale) # Actual tile rendering starts here tile_surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, self.tile_size, self.tile_size) tile_context = cairo.Context(tile_surface) - - layer_transform = cairo.Matrix(xx=prescale, yy=prescale) # Scale by Prescale - for zoom_level in range(max_zoom_level + 1): zoom_factor = self.zoom_step ** -zoom_level tiles_x = int_ceil(zoom_factor * scaled_size[0] / self.tile_size) tiles_y = int_ceil(zoom_factor * scaled_size[1] / self.tile_size) - zoom_level_transform = layer_transform * cairo.Matrix(xx=zoom_factor, yy=zoom_factor) + zoom_level_transform = cairo.Matrix(xx=prescale * zoom_factor, yy=prescale * zoom_factor) + + if self.draw_per_plane: + plane_surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, + self.tile_size * tiles_x, + self.tile_size * tiles_y) + plane_context = cairo.Context(plane_surface) + plane_context.set_matrix(zoom_level_transform) + plane_context.set_source_rgba(1.0, 1.0, 1.0, 1.0) + plane_context.paint() + layer.draw(plane_context) for x in range(tiles_x): makedirs(os.path.join(path, str(max_zoom_level - zoom_level), str(x))) - column_transform = zoom_level_transform * cairo.Matrix(x0=-self.tile_size * x) # Shift image to left for x tiles + column_transform = cairo.Matrix(x0=-self.tile_size * x) # Shift image to left for x tiles for y in range(tiles_y): tile_path = os.path.join(path, str(max_zoom_level - zoom_level), str(x), '{0}.png'.format(y)) - tile_transform = column_transform * cairo.Matrix(y0=-self.tile_size * y) - tile_context.set_matrix(tile_transform) - - tile_context.set_source_rgba(1.0, 1.0, 1.0, 1.0) - tile_context.paint() - layer.draw(tile_context) + tile_transform = column_transform * cairo.Matrix(y0=-self.tile_size * y) # Shift image up for y tiles + + if self.draw_per_plane: + tile_context.set_matrix(tile_transform) + tile_context.set_source_surface(plane_surface) + tile_context.paint() + else: + tile_context.set_matrix(zoom_level_transform * tile_transform) + tile_context.set_source_rgba(1.0, 1.0, 1.0, 1.0) + tile_context.paint() + layer.draw(tile_context) tile_surface.write_to_png(tile_path) +class LayerInfoStore(object): + def __init__(self, layers): + self.layers = layers + + def store(self, path): + document = [] + for layer in sorted(self.layers): + document.append({ + 'name': layer.name, + 'max_zoom': layer.max_zoom_level + }) + with open(path, "w") as f: + json.dump(document, f) if __name__ == '__main__': layer_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'layers') - tiles_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'tiles') + web_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'web') + tiles_path = os.path.join(web_path, 'images', 'tiles') + layer_info_path = os.path.join(web_path, 'js', 'layers.json') + + if os.path.exists(tiles_path): + shutil.rmtree(tiles_path) layers = LayerLoader().load(layer_path) layer_width = max([layer.width for layer in layers]) @@ -185,3 +222,5 @@ if __name__ == '__main__': for layer in layers: tile_generator = TileGenerator(layer, layer_width, layer_height) tile_generator.create_tiles(os.path.join(tiles_path, layer.name)) + + LayerInfoStore(layers).store(layer_info_path) |