pngtile/tile.py
author Tero Marttila <terom@paivola.fi>
Sun, 14 Sep 2014 18:04:11 +0300
changeset 138 59d61da2b64f
parent 135 e99dd75afa15
child 140 a3bbecbd31e7
permissions -rw-r--r--
pngtile.tile: split off BaseAppliation
135
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     1
"""
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     2
    Raw tile handling.
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     3
"""
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     4
138
59d61da2b64f pngtile.tile: split off BaseAppliation
Tero Marttila <terom@paivola.fi>
parents: 135
diff changeset
     5
from pngtile.application import BaseApplication
135
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     6
from werkzeug import Request, Response, exceptions
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     7
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     8
import pypngtile
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     9
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    10
## Coordinates
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    11
# width of a tile
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    12
TILE_WIDTH = 256
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    13
TILE_HEIGHT = 256
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    14
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    15
# max. output resolution to allow
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    16
MAX_PIXELS = 1920 * 1200
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    17
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    18
def scale (val, zoom):
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    19
    """
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    20
        Scale dimension by zoom factor
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    21
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    22
        zl > 0 -> bigger
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    23
        zl < 0 -> smaller
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    24
    """
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    25
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    26
    if zoom > 0:
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    27
        return val << zoom
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    28
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    29
    elif zoom < 0:
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    30
        return val >> -zoom
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    31
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    32
    else:
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    33
        return val
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    34
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    35
def scale_center (val, dim, zoom):
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    36
    """
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    37
        Scale value about center by zoom.
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    38
    """
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    39
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    40
    return scale(val - dim / 2, zoom)
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    41
138
59d61da2b64f pngtile.tile: split off BaseAppliation
Tero Marttila <terom@paivola.fi>
parents: 135
diff changeset
    42
class TileApplication (BaseApplication):
59d61da2b64f pngtile.tile: split off BaseAppliation
Tero Marttila <terom@paivola.fi>
parents: 135
diff changeset
    43
    def __init__ (self, **opts):
59d61da2b64f pngtile.tile: split off BaseAppliation
Tero Marttila <terom@paivola.fi>
parents: 135
diff changeset
    44
        BaseApplication.__init__(self, **opts)
135
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    45
        
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    46
    def render_region (self, request, image):
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    47
        """
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    48
            Handle request for an image region
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    49
        """
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    50
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    51
        width = int(request.args['w'])
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    52
        height = int(request.args['h'])
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    53
        x = int(request.args['x'])
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    54
        y = int(request.args['y'])
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    55
        zoom = int(request.args.get('zoom', "0"))
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    56
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    57
        # safely limit
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    58
        if width * height > MAX_PIXELS:
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    59
            raise exceptions.BadRequest("Image size: %d * %d > %d" % (width, height, MAX_PIXELS))
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    60
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    61
        x = scale(x, zoom)
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    62
        y = scale(y, zoom)
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    63
        
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    64
        try:
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    65
            return image.tile_mem(width, height, x, y, zoom)
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    66
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    67
        except pypngtile.Error as error:
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    68
            raise exceptions.BadRequest(str(error))
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    69
        
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    70
    def render_tile (self, request, image):
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    71
        """
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    72
            Handle request for image tile
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    73
        """
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    74
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    75
        width = TILE_WIDTH
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    76
        height = TILE_HEIGHT
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    77
        row = int(request.args['row'])
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    78
        col = int(request.args['col'])
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    79
        zoom = int(request.args.get('zoom', "0"))
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    80
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    81
        x = scale(row * width, zoom)
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    82
        y = scale(col * height, zoom)
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    83
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    84
        try:
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    85
            return image.tile_mem(width, height, x, y, zoom)
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    86
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    87
        except pypngtile.Error as error:
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    88
            raise exceptions.BadRequest(str(error))
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    89
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    90
    def handle (self, request):
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    91
        """
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    92
            Handle request for an image
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    93
        """
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    94
        
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    95
        try:
138
59d61da2b64f pngtile.tile: split off BaseAppliation
Tero Marttila <terom@paivola.fi>
parents: 135
diff changeset
    96
            image, name = self.get_image(request.path)
135
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    97
        except pypngtile.Error as error:
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    98
            raise exceptions.BadRequest(str(error))
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    99
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   100
        if 'w' in request.args and 'h' in request.args and 'x' in request.args and 'y' in request.args:
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   101
            png = self.render_region(request, image)
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   102
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   103
        elif 'row' in request.args and 'col' in request.args:
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   104
            png = self.render_tile(request, image)
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   105
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   106
        else:
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   107
            raise exceptions.BadRequest("Unknown args")
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   108
e99dd75afa15 pngtile.tile: separate Application dedicated to PNG serving
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   109
        return Response(png, content_type='image/png')