def GetMap(self, r, kwargs): parms = GetMapMixin.Parameters.create(kwargs).cleaned_data kwargs = {i: j for i, j in kwargs.items() if i not in parms} item = self.adapter.get_cache_record(**parms) if item and not parms['fresh']: return HttpResponse(item, content_type='image/' + parms['format']) if self.adapter.requires_time and 'time' not in parms: raise common.MissingParameterValue.at('time') if self.adapter.requires_elevation and 'elevation' not in parms: raise common.MissingParameterValue.at('elevation') if parms['format'].startswith('image/'): fmt = parms['format'][len('image/'):] else: fmt = parms['format'] if self.task: ret = self.task.delay(parms).get() else: fltr = None if parms['filter']: fltr = json.loads(parms['filter']) ds = self.adapter.get_2d_dataset(layers=parms['layers'], srs=parms['srs'], bbox=parms['bbox'], width=parms['width'], height=parms['height'], styles=parms['styles'], bgcolor=parms['bgcolor'], transparent=parms['transparent'], time=parms['time'], elevation=parms['elevation'], v=parms['v'], filter=fltr, format=fmt.encode('ascii'), **kwargs) tmp = None ret = None # this codepath is officially confusing. Here's the deal. We have several different ways of returning # datasets that ga_wms can handle. # We can A: return a GDAL dataset. This will be written to a tempfile and passed to the requestor. # # B: return a filename. This is assumed to already be in the proper format. If it's not, you're going to # confuse a bunch of people # # C: return a numpy array in which case scipy is asked to handle it through "imsave" # # D: return a file or StringIO instance. This is also already assumed to be in the proper format # # All these cases are handled properly by the below code, HOWEVER, as it stands right now if you return # filenames, files, or StringIO isntances, we assume that you're caching them yourself. Otherwise why would # you have handed us a real file? if not isinstance( ds, gdal.Dataset ): # then it == a Cairo imagesurface or numpy array, or at least... it'd BETTER be if HAVE_CAIRO and isinstance(ds, cairo.Surface): tmp = tempfile.NamedTemporaryFile(suffix='.png') ds.write_to_png(tmp.name) ds = gdal.Open(tmp.name) # TODO add all the appropriate metadata from the request into the dataset if this == being returned as a GeoTIFF elif isinstance(ds, tuple): ret = ds[1] elif isinstance(ds, basestring): try: ret = open(ds) except IOError: if HAVE_SCIPY: tmp = tempfile.NamedTemporaryFile(suffix='.tif') scipy.misc.imsave(tmp.name, ds) ds = gdal.Open(tmp.name) # TODO add all the appropriate metadata from the request into the dataset if this == being returned as a GeoTIFF elif HAVE_SCIPY: tmp = tempfile.NamedTemporaryFile(suffix='.tif') scipy.misc.imsave(tmp.name, ds) ds = gdal.Open(tmp.name) # TODO add all the appropriate metadata from the request into the dataset if this == being returned as a GeoTIFF if not ret: if fmt == 'tiff' or fmt == 'geotiff': driver = gdal.GetDriverByName('GTiff') elif fmt == 'jpg' or fmt == 'jpeg': driver = gdal.GetDriverByName('jpeg') elif fmt == 'jp2k' or fmt == 'jpeg2000': tmp = tempfile.NamedTemporaryFile(suffix='.jp2') driver = gdal.GetDriverByName('jpeg2000') else: driver = gdal.GetDriverByName(fmt.encode('ascii')) try: tmp = tempfile.NamedTemporaryFile(suffix='.' + fmt) ds2 = driver.CreateCopy(tmp.name, ds) del ds2 tmp.seek(0) ret = tmp.read() self.adapter.cache_result(ret, **parms) except Exception as ex: del tmp raise common.NoApplicableCode(str(ex)) resp = HttpResponse(ret, content_type=fmt if '/' in fmt else 'image/' + fmt) return resp
def run(self, parms, callback=None, cache_only=False): """ :param parms: A dict containing the parameters in :class:ga_ows.views.wms.WMSAdapterBase :param callback: A Celery subtask, optional, that takes the place of simply returning the rendered data. :param cache_only: If true, return no result and only use this task to cache the data calculated. Useful for pre-calculating tiles. :return: A binary stream containing data formatted in a particular file format, such as JPEG, GeoTIFF... anything GDAL can write. """ if parms['format'].startswith('image/'): format = parms['format'][len('image/'):] else: format = parms['format'] filter = None if parms['filter']: filter = json.loads(parms['filter']) ds = self.adapter.get_2d_dataset(layers=parms['layers'], srs=parms['srs'], bbox=parms['bbox'], width=parms['width'], height=parms['height'], styles=parms['styles'], bgcolor=parms['bgcolor'], transparent=parms['transparent'], time=parms['time'], elevation=parms['elevation'], v=parms['v'], filter=filter) tmp = None ret = None if not isinstance( ds, gdal.Dataset ): # then it == a Cairo imagesurface or numpy array, or at least... it'd BETTER be if have_cairo and isinstance(ds, cairo.Surface): tmp = tempfile.NamedTemporaryFile(suffix='.png') ds.write_to_png(tmp.name) ds = gdal.Open(tmp.name) # TODO add all the appropriate metadata from the request into the dataset if this == being returned as a GeoTIFF elif isinstance(ds, file): ret = ds elif isinstance(ds, StringIO): ret = ds elif have_scipy: tmp = tempfile.NamedTemporaryFile(suffix='.tif') scipy.misc.imsave(tmp.name, ds) ds = gdal.Open(tmp.name) # TODO add all the appropriate metadata from the request into the dataset if this == being returned as a GeoTIFF if ret: return ret if format == 'tiff' or format == 'geotiff': driver = gdal.GetDriverByName('GTiff') elif format == 'jpg' or format == 'jpeg': driver = gdal.GetDriverByName('jpeg') elif format == 'jp2k' or format == 'jpeg2000': tmp = tempfile.NamedTemporaryFile(suffix='.jp2') driver = gdal.GetDriverByName('jpeg2000') else: driver = gdal.GetDriverByName(format.encode('ascii')) try: tmp = tempfile.NamedTemporaryFile(suffix='.' + format) ds2 = driver.CreateCopy(tmp.name, ds) del ds2 tmp.seek(0) ret = tmp.read() if callback: subtask(callback).delay(ret, parms) return None elif cache_only: self.adapter.cache_result(ret, **parms) return None else: self.adapter.cache_result(ret, **parms) return ret except Exception as ex: del tmp raise common.NoApplicableCode(str(ex))
def GetMap(self, r, kwargs): parms = GetMapMixin.Parameters.create(kwargs).cleaned_data item = self.adapter.get_cache_record(**parms) if item and not parms['fresh']: return HttpResponse(item, mimetype='image/'+parms['format']) if self.adapter.requires_time and 'time' not in parms: raise common.MissingParameterValue.at('time') if self.adapter.requires_elevation and 'elevation' not in parms: raise common.MissingParameterValue.at('elevation') if parms['format'].startswith('image/'): format = parms['format'][len('image/'):] else: format = parms['format'] if self.task: ret = self.task.delay(parms).get() else: filter = None if parms['filter']: filter = json.loads(parms['filter']) ds = self.adapter.get_2d_dataset( layers=parms['layers'], srs=parms['srs'], bbox=parms['bbox'], width=parms['width'], height=parms['height'], styles=parms['styles'], bgcolor=parms['bgcolor'], transparent=parms['transparent'], time=parms['time'], elevation=parms['elevation'], v=parms['v'], filter = filter ) tmp = None if not isinstance(ds, gdal.Dataset): # then it == a Cairo imagesurface or numpy array, or at least... it'd BETTER be if isinstance(ds,cairo.Surface): tmp = tempfile.NamedTemporaryFile(suffix='.png') ds.write_to_png(tmp.name) ds = gdal.Open(tmp.name) # TODO add all the appropriate metadata from the request into the dataset if this == being returned as a GeoTIFF else: tmp = tempfile.NamedTemporaryFile(suffix='.tif') scipy.misc.imsave(tmp.name, ds) ds = gdal.Open(tmp.name) # TODO add all the appropriate metadata from the request into the dataset if this == being returned as a GeoTIFF if format == 'tiff' or format == 'geotiff': driver = gdal.GetDriverByName('GTiff') elif format == 'jpg' or format == 'jpeg': driver = gdal.GetDriverByName('jpeg') elif format == 'jp2k' or format == 'jpeg2000': tmp = tempfile.NamedTemporaryFile(suffix='.jp2') driver = gdal.GetDriverByName('jpeg2000') else: driver = gdal.GetDriverByName(format.encode('ascii')) try: tmp = tempfile.NamedTemporaryFile(suffix='.' + format) ds2 = driver.CreateCopy(tmp.name, ds) del ds2 tmp.seek(0) ret = tmp.read() self.adapter.cache_result(ret, **parms) except Exception as ex: del tmp raise common.NoApplicableCode(str(ex)) return HttpResponse(ret, mimetype=format)