class AlgebraView(RasterView): """ A view to calculate map algebra on raster layers. """ def __init__(self, *args, **kwargs): super(AlgebraView, self).__init__(*args, **kwargs) self.parser = RasterAlgebraParser() def get(self, request, masked=False, *args, **kwargs): # Get layer ids ids = request.GET.get('layers').split(',') # Parse layer ids into dictionary with variable names ids = {idx.split('=')[0]: idx.split('=')[1] for idx in ids} # Get raster data as 1D arrays and store in dict that can be used # for formula evaluation. data = {} for name, layerid in ids.items(): tile = self.get_tile(layerid) if tile: data[name] = tile else: # Create empty image if any layer misses the required tile img = Image.new("RGBA", (WEB_MERCATOR_TILESIZE, WEB_MERCATOR_TILESIZE), (0, 0, 0, 0)) return self.write_img_to_response(img, {}) # Get formula from request formula = request.GET.get('formula') # Evaluate raster algebra expression, return 404 if not successfull try: # Evaluate raster algebra expression result = self.parser.evaluate_raster_algebra(data, formula) except: raise Http404('Failed to evaluate raster algebra.') # Get array from algebra result result = result.bands[0].data() # Render tile colormap = self.get_colormap() if colormap: # Render tile using the legend data img, stats = band_data_to_image(result, colormap) else: # Scale to grayscale rgb (can be colorscheme later on) result = result.astype('float').ravel() result = 255 * (result - numpy.min(result)) / (numpy.max(result) - numpy.min(result)) # Create rgba matrix from grayscale array result = numpy.array((result, result, result, numpy.repeat(255, len(result)))).T rgba = result.reshape(WEB_MERCATOR_TILESIZE, WEB_MERCATOR_TILESIZE, 4).astype('uint8') # Create image from array img = Image.fromarray(rgba) stats = {} # Return rendered image return self.write_img_to_response(img, stats)
def __init__(self, *args, **kwargs): super(AlgebraView, self).__init__(*args, **kwargs) self.parser = RasterAlgebraParser()
def test_algebra_parser(self): parser = RasterAlgebraParser() result = parser.evaluate_raster_algebra(self.data, "x*(x>11) + 2*y + 3*z*(z==30)", check_aligned=True) self.assertEqual(result.bands[0].data().ravel().tolist(), [92, 2, 14, 15])