source: cows/trunk/cows/service/imps/pywms/render_imp.py @ 5052

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/cows/trunk/cows/service/imps/pywms/render_imp.py@5052
Revision 5052, 4.4 KB checked in by domlowe, 11 years ago (diff)

simple fix for render_imp trying to write to / under mod_wsgi

Line 
1# BSD Licence
2# Copyright (c) 2009, Science & Technology Facilities Council (STFC)
3# All rights reserved.
4#
5# See the LICENSE file in the source distribution of this software for
6# the full license text.
7
8"""
9Implementation of grid rendering classes.
10
11@author: Stephen Pascoe
12"""
13
14from view import GridRenderer
15import ImageColor, Image
16import numpy as N
17import logging
18from matplotlib import cm, colors
19
20logger = logging.getLogger(__name__)
21
22class RGBARenderer(GridRenderer):
23    """Creates an RGBA PNG with a selectable matplotlib colour scale.
24    """
25
26    mimeType = 'image/png'
27
28    def __init__(self, varmin, varmax):
29        self.varmin = varmin
30        self.varmax = varmax
31        self._norm = colors.normalize(varmin, varmax)
32
33    def renderColourbar(self, width, height, cmap, isVertical=True):
34        a = N.arrayrange(0, 1.0, 1.0/256)
35        if isVertical:
36            a = a[-1::-1]
37            shape = (1, 256)
38        else:
39            shape = (256, 1)
40
41        cbar = (cmap(a) * 255).astype('b').tostring()
42        img = Image.frombuffer("RGBA", shape, cbar, "raw", "RGBA", 0, 1)
43        img = img.resize((width, height))
44
45        return img
46
47    def renderGrid(self, grid, bbox, width, height, cmap):
48        cmap.set_bad('#ffffff', 0.0)
49
50        logger.debug('grid %s, %s, %s, %s, %s, %s %s, %s' %
51                    (grid.x0, grid.y0, grid.dx, grid.dy, grid.nx, grid.ny,
52                     grid.ix, grid.iy))
53        logger.debug('bbox %s' % (bbox,))
54
55        # Get a pixel = grid-box image for the grid
56        img = self._grid2Img(grid, cmap)
57
58        # Calculate the pixel-size of a grid box
59        pxPerDeg_x = float(width) / (bbox[2] - bbox[0])
60        pxPerDeg_y = float(height) / (bbox[3] - bbox[1])
61        pxPerGrid_x = grid.dx * pxPerDeg_x
62        pxPerGrid_y = grid.dy * pxPerDeg_y
63
64        # Scale Img to the right size
65        img = img.resize(((abs(pxPerGrid_x * grid.nx),
66                           abs(pxPerGrid_y * grid.ny))))
67
68        #!NO: We assume the grid points represent the centre of the grid boxes
69        #!NO: therefore we can calculate the upper-left position of the image
70        # Adapted so that the grid points represent the lower left corner of grid boxes
71
72        # Find top-left corner of grid
73        if grid.dx > 0:
74            leftX = grid.x0
75        else:
76            leftX = grid.x0 + (grid.dx * (grid.nx - 1))
77        if grid.dy > 0:
78            topY = grid.y0 + (grid.dy * (grid.ny - 1))
79        else:
80            topY = grid.y0
81
82        logger.debug('top-left = %s x, %s y' % (leftX, topY))
83
84        # Find pixel position of top left centre grid box
85        cx = width * ((leftX - bbox[0])/ (bbox[2] - bbox[0]))
86        cy = height * ((bbox[3] - topY) / (bbox[3] - bbox[1]))
87        logger.debug('top-left centre pixel = %s x, %s y' % (cx, cy))
88
89        # Apply half width of grid box
90        #ox = int(cx - pxPerGrid_x / 2)
91        #oy = int(cy - pxPerGrid_y / 2)
92        ox,oy = int(cx), int(cy-pxPerGrid_y)
93        logger.debug('Offset: %s x, %s y' % (ox, oy))
94
95
96        # Paste the grid image into the tile image
97        tileImg = Image.new('RGBA', (width, height))
98        logger.debug('Pasting image img%s into tileImg%s at (%s,%s)' % (img.size, tileImg.size, ox, oy))
99        tileImg.paste(img, (ox, oy))
100
101        return tileImg
102
103
104    def _grid2Img(self, grid, cmap):
105        """Returns the grid as an image where each pixel is one grid box.
106
107        """
108        a = self._norm(grid.value)
109        img_buf = (cmap(a) * 255).astype('b')
110
111        # This code assumes the axis ordering is either (y, x, time) or (x, y, time)
112        if min(grid.iy, grid.ix) != 0 and max(grid.iy, grid.ix) != 1:
113            raise ValueError("X and Y must be the first 2 dimensions!")
114
115        if grid.iy < grid.ix:
116            yxOrdering = True
117        else:
118            yxOrdering = False
119   
120        img = Image.frombuffer("RGBA", img_buf.shape[1::-1], img_buf.tostring(), "raw", "RGBA", 0, 1)
121        img.save('tmp/raw1.png')
122
123        # Rotate if axis order is x, y
124        if not yxOrdering:
125            img = img.transpose(Image.ROTATE_90)
126
127        # Flip if x or y are ordered the wrong way
128        if grid.dy > 0:
129            logger.debug('Flipping y')
130            img = img.transpose(Image.FLIP_TOP_BOTTOM)
131        if grid.dx < 0:
132            logger.debug('Flipping x')
133            img = img.transpose(Image.FLIP_LEFT_RIGHT)
134
135
136        return img
137
138
139#---------------------------------------------------------------------------------
140
Note: See TracBrowser for help on using the repository browser.