Changeset 2586


Ignore:
Timestamp:
14/06/07 13:57:39 (12 years ago)
Author:
spascoe
Message:

First WMS GetMap? request working.

Location:
TI05-delivery/ows_framework/trunk/ows_server/ows_server
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • TI05-delivery/ows_framework/trunk/ows_server/ows_server/controllers/csml_wms.py

    r2578 r2586  
    77 
    88@author: Stephen Pascoe 
     9 
    910""" 
    1011from ows_server.lib.base import * 
    1112from ows_server.controllers.csml_api import get_csml_doc 
    1213from ows_server.lib.decorators import * 
     14from ows_server.lib import grid_util, render 
     15from ows_server.lib.csml_util import get_csml_doc 
    1316import ows_server.lib.validators as V 
    1417 
     
    2023from ows_common.domain import ValuesUnit, PossibleValues 
    2124 
    22 from ows_server.lib.csml_util import get_csml_doc 
    23 import ows_server.lib.validators as V 
    24  
     25import cdms 
     26import tempfile, os 
     27from cStringIO import StringIO 
     28import MA 
    2529 
    2630class CsmlWmsController(OwsController): 
     
    3842 
    3943 
     44    def _iterDimensions(self, feature): 
     45        """ 
     46        Retrieve the non-geospatial dimensions of a feature. 
     47 
     48        @return: generator of dimension names 
     49 
     50        """ 
     51        # Waiting for this feature to be implemented 
     52        #lat = feature.getLatitude() 
     53        #lon = feature.getLongitude() 
     54        lat = 'latitude'; lon = 'longitude' 
     55         
     56        for axis_name in feature.getDomain(): 
     57            if axis_name not in [lat, lon]: 
     58                yield axis_name 
     59 
    4060    def _loadFeatureDimensions(self, feature): 
    4161        dims = {} 
    42         #!WARNING 
    43         # This bit is a hack until the CSML API implements a mechanism 
    44         # to determine which elements of a domain are longitude and latitude. 
    45         for axis_name, axis in feature.getDomain().iteritems(): 
    46             if axis_name in ['longitude', 'latitude']: 
    47                 continue 
     62        domain = feature.getDomain() 
     63        for axis_name in self._iterDimensions(feature): 
     64            axis = domain[axis_name] 
    4865            dims[axis_name] = Dimension(possibleValues=PossibleValues.fromAllowedValues(axis), 
    49                                         #!TODO: this is a fudge until we can deduce UOM. 
     66                                        #!TODO: see ticket:770 for how to populate this 
    5067                                        valuesUnit=ValuesUnit(uoms=[''], 
    5168                                                              referenceSystems=[''])) 
     
    115132               transparent=False, bgcolor=None, exceptions=None): 
    116133 
     134        # Retrieve dataset and selected feature 
    117135        dataset = get_csml_doc(file) 
     136        feature = dataset.getFeature(layers) 
     137        if feature is None: 
     138            raise OWS_E.InvalidParameterValue('Layer not found', 'layers') 
    118139 
    119         return Response('Operation done') 
     140        # Define the extraction selector 
     141        sel = dict(latitude=(bbox[1], bbox[3]), longitude=(bbox[0], bbox[2])) 
     142 
     143        # Parse dimensions. 
     144        for dim in self._iterDimensions(feature): 
     145            # For the moment hard-code time in.  We don't support any other dimension yet. 
     146            if dim.lower() != 'time': 
     147                raise ValueError('Only lat, lon and time are supported domain axes') 
     148             
     149            try: 
     150                sel[dim] = request.params[dim] 
     151            except KeyError: 
     152                raise OWS_E.MissingParameterValue('%s dimension not specified' % dim, dim) 
     153             
     154        # Subset the feature 
     155        (fd, filename) = tempfile.mkstemp('.nc', 'csml_wms_'); os.close(fd) 
     156        feature.subsetToGridSeries(ncname=os.path.basename(filename), 
     157                                   outputdir=os.path.dirname(filename), 
     158                                   time=sel['time'] # workarround for CSML bug 
     159                                   #**sel 
     160                                   ) 
     161        d = cdms.open(filename) 
     162        #var = d(feature.name.CONTENT, squeeze=1) 
     163        var = d(feature.name.CONTENT, longitude=sel['longitude'], latitude=sel['latitude'], 
     164                squeeze=1) 
    120165         
     166        # Deduce min and max 
     167        varmin = MA.minimum(var, None) 
     168        varmax = MA.maximum(var, None) 
     169 
     170        # Render variable to a PIL image 
     171        img = render.render_variable(var, bbox, width, height, varmin, varmax) 
     172 
     173        # Serialise it to PNG 
     174        buf = StringIO() 
     175        img.save(buf, 'PNG') 
     176 
     177        return Response(content=buf.getvalue(), mimetype='image/png') 
  • TI05-delivery/ows_framework/trunk/ows_server/ows_server/lib/render.py

    r2582 r2586  
    9494 
    9595 
    96 def render_variable(var, bbox, width, height, cmap, varmin, varmax): 
     96def render_variable(var, bbox, width, height, varmin, varmax, cmap=None, ): 
    9797    """ 
    9898    Creates RGBA PIL images with a selectable matplotlib colour scale. 
    9999 
     100    @todo: This should be class really, but it came out of my brain as a function. 
     101    @todo: Transparent missing_value mask not working. 
     102 
    100103    """ 
     104 
     105    if cmap is None: 
     106        cmap = cm.get_cmap() 
    101107 
    102108 
     
    118124        norm = colors.normalize(varmin, varmax) 
    119125        a = norm(var.getValue()) 
    120  
     126        order = var.getOrder() 
     127         
    121128        # Render the normalised variable by converting it into a byte array then to a PIL image 
    122129        img_buf = (cmap(a) * 255).astype('b') 
    123130        (y, x, c) = img_buf.shape 
    124         img = Image.frombuffer("RGBA", (x, y), img_buf.tostring(), "raw", "RGBA", 0. 1) 
     131 
     132        img = Image.frombuffer("RGBA", (x, y), img_buf.tostring(), "raw", "RGBA", 0, 1) 
    125133 
    126134        # Ensure lat & lon increase from the bottom left 
     
    140148    # It is assumed that grid can wrap around in the longitude and therefore only 
    141149    # needs adjusting in the latitude. 
    142     if bbox != bboxObj.crs84: 
     150    if bbox != bbox_obj.crs84: 
    143151        img = Image.new('RGBA', (width, height)) 
    144         (ox, oy) = bboxObj.getCrs84OffsetInImage(width, height) 
    145         nwidth, nheight = bboxObj.getCrs84ImageSize(width, height) 
     152        (ox, oy) = bbox_obj.getCrs84OffsetInImage(width, height) 
     153        nwidth, nheight = bbox_obj.getCrs84ImageSize(width, height) 
    146154        # If the image is too small just send a blank image 
    147         if bboxObj.crs84Width > abs(dlon) and bboxObj.crs84Height > abs(dlat): 
     155        if bbox_obj.crs84Width > abs(dlon) and bbox_obj.crs84Height > abs(dlat): 
    148156            img1 = render(var, width, nheight) 
    149157            img.paste(img1, (0, oy)) 
Note: See TracChangeset for help on using the changeset viewer.