def test_read_and_write_of_rasters(self): """Test that rasters can be read and written correctly """ for coveragename in ['Earthquake_Ground_Shaking_clip.tif', 'Population_2010_clip.tif', 'shakemap_padang_20090930.asc', 'population_padang_1.asc']: filename = 'data/%s' % coveragename for R1 in [Raster(filename), read_coverage(filename)]: # Check consistency of raster A1 = R1.get_data() M, N = A1.shape msg = 'Dimensions of raster array do not match those of raster file %s' % R1.filename assert M == R1.rows, msg assert N == R1.columns, msg # Write back to new file outfilename = '/tmp/%s' % coveragename try: os.remove(outfilename) except: pass write_coverage_to_geotiff(A1, outfilename, R1.get_projection(), R1.get_geotransform()) # Read again and check consistency R2 = Raster(outfilename) msg = 'Dimensions of written raster array do not match those of input raster file\n' msg += ' Dimensions of input file %s: (%s, %s)\n' % (R1.filename, R1.rows, R1.columns) msg += ' Dimensions of output file %s: (%s, %s)' % (R2.filename, R2.rows, R2.columns) assert R1.rows == R2.rows, msg assert R1.columns == R2.columns, msg A2 = R2.get_data() assert numpy.allclose(numpy.min(A1), numpy.min(A2)) assert numpy.allclose(numpy.max(A1), numpy.max(A2)) msg = 'Array values of written raster array were not as expected' assert numpy.allclose(A1, A2), msg # NOTE: This does not always hold as projection text might differ slightly. E.g. #assert R1.get_projection() == R2.get_projection(), msg #E.g. These two refer to the same projection #GEOGCS["GCS_WGS_1984",DATUM["WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]] #GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.2572235630016,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433],AUTHORITY["EPSG","4326"]] msg = 'Geotransforms were different' assert R1.get_geotransform() == R2.get_geotransform(), msg
def calculate(self, hazards, exposures, impact_function_id, impact, bounding_box, comment): """Calculate the Impact Geo as a function of Hazards and Exposures Arguments impact_function_id=Id of the impact function to be run (fully qualified path (from base path)) hazards = A list of hazard levels .. [H1,H2..HN] each H is a geoserver layer path where each layer follows the format username:userpass@geoserver_url:layer_name (Look at REST for inspiration) exposure = A list of exposure levels ..[E1,E2...EN] each E is a geoserver layer path impact = Handle to output impact level layer bounding_box = ... comment = String with comment for output metadata Returns string: 'SUCCESS' if complete, otherwise Exception is raised Note hazards and exposure may be lists of handles or just a single handle each. """ # Make sure hazards and exposures are lists if type(hazards) != type([]): hazards = [hazards] if type(exposures) != type([]): exposures = [exposures] # Download data - FIXME(Ole): Currently only raster. FIXME (Ole): Not even sure they should be lists projection = None geotransform = None hazard_layers = [] for hazard in hazards: raster = self.get_raster_data(hazard, bounding_box) H = raster.get_data() hazard_layers.append(H) # FIXME (Ole): These two could be combined into one thing. if projection is None: projection = raster.get_projection() else: msg = 'Projections in hazard levels are different: %s %s' % (projection, raster.get_projection()) assert projection == raster.get_projection(), msg if geotransform is None: geotransform = raster.get_geotransform() else: msg = 'Geotransforms in hazard levels are different: %s %s' % (geotransform, raster.get_geotransform()) geotransform == raster.get_geotransform(), msg exposure_layers = [] for exposure in exposures: raster = self.get_raster_data(exposure, bounding_box) E = raster.get_data() exposure_layers.append(E) msg = 'Projections in exposure levels are different: %s %s' % (projection, raster.get_projection()) assert projection == raster.get_projection(), msg msg = 'Geotransforms in exposure levels are different: %s %s' % (geotransform, raster.get_geotransform()) geotransform == raster.get_geotransform(), msg # Pass hazard and exposure arrays on to plugin # FIXME, for the time being we just calculate the fatality function assuming only one of each layer. H = hazard_layers[0] E = exposure_layers[0] # Calculate impact # FIXME (Ole): This is where an impact plugin should be called a = 0.97429 b = 11.037 F = 10**(a*H-b)*E # Upload result username, userpass, geoserver_url, layer_name, workspace = self.split_geoserver_layer_handle(impact) output_file = 'data/%s.tif' % layer_name write_coverage_to_geotiff(F, output_file, projection=projection, geotransform=geotransform) #(FIXME(Ole): still super hacky and not at all general) # FIXME(Ole): Get everything from gdalinfo #output_file = 'data/%s.asc' % layer_name #write_coverage_to_ascii(F, output_file, # xllcorner = bounding_box[0], # yllcorner = bounding_box[1], # cellsize=0.030741064, # #cellsize=0.008333333333000, # nodata_value=-9999, # # FIXME(Ole): Need to get projection for haz and exp from GeoServer. For now use example. # projection=open('data/test_grid.prj').read()) # And upload it again lh = self.create_geoserver_layer_handle(username, userpass, geoserver_url, '', workspace) self.upload_geoserver_layer(output_file, lh) return 'SUCCES'