def test_getKeywordFromFile(self): """Get keyword from a filesystem file's .keyword file.""" keyword = read_file_keywords(self.rasterShakePath, "category") expected_keyword = "hazard" message = "Got: %s\n\nExpected %s\n\nDB: %s" % (keyword, expected_keyword, self.rasterShakePath) assert keyword == "hazard", message # Test we get an exception if keyword is not found try: _ = read_file_keywords(self.rasterShakePath, "boguskeyword") except KeywordNotFoundError: pass # this is good except Exception, e: message = ("Request for bogus keyword raised incorrect " "exception type: \n %s") % str(e) assert (), message
def test_getKeywordFromFile(self): """Get keyword from a filesystem file's .keyword file.""" myKeyword = read_file_keywords(self.rasterShakePath, 'category') myExpectedKeyword = 'hazard' myMessage = 'Got: %s\n\nExpected %s\n\nDB: %s' % ( myKeyword, myExpectedKeyword, self.rasterShakePath) assert myKeyword == 'hazard', myMessage # Test we get an exception if keyword is not found try: _ = read_file_keywords(self.rasterShakePath, 'boguskeyword') except KeywordNotFoundError: pass # this is good except Exception, e: myMessage = ('Request for bogus keyword raised incorrect ' 'exception type: \n %s') % str(e) assert (), myMessage
def test_copy_keywords(self): """Test we can copy the keywords.""" out_path = unique_filename( prefix='test_copy_keywords', suffix='.keywords') self.keyword_io.copy_keywords(self.raster_layer, out_path) copied_keywords = read_file_keywords(out_path) expected_keywords = self.expected_raster_keywords message = 'Got:\n%s\nExpected:\n%s\nSource:\n%s' % ( copied_keywords, expected_keywords, out_path) self.assertEquals(copied_keywords, expected_keywords, message)
def test_copy_keywords(self): """Test we can copy the keywords.""" out_path = unique_filename( prefix='test_copy_keywords', suffix='.keywords') self.keyword_io.copy_keywords(self.raster_layer, out_path) copied_keywords = read_file_keywords(out_path) expected_keywords = self.expected_raster_keywords message = 'Got:\n%s\nExpected:\n%s\nSource:\n%s' % ( copied_keywords, expected_keywords, out_path) self.assertEquals(copied_keywords, expected_keywords, message)
def test_get_keyword_from_file(self): """Get keyword from a filesystem file's .keyword file.""" keyword = read_file_keywords(self.rasterShakePath, 'category') expected_keyword = 'hazard' message = 'Got: %s\n\nExpected %s\n\nDB: %s' % ( keyword, expected_keyword, self.rasterShakePath) self.assertEqual(keyword, 'hazard', message) # Test we get an exception if keyword is not found try: _ = read_file_keywords(self.rasterShakePath, 'boguskeyword') except KeywordNotFoundError: pass # this is good except Exception, e: message = ('Request for bogus keyword raised incorrect ' 'exception type: \n %s') % str(e) assert(), message
def test_availableFunctions(self): """Check we can get the available functions from the impact calculator. """ myList = availableFunctions() message = "No functions available (len=%ss)" % len(myList) assert len(myList) > 0, message # Also test if it works when we give it two layers # to see if we can determine which functions will # work for them. keywords1 = read_file_keywords(self.rasterShakePath) keywords2 = read_file_keywords(self.vectorPath) # We need to explicitly add the layer type to each keyword list keywords1["layertype"] = "raster" keywords2["layertype"] = "vector" myList = [keywords1, keywords2] myList = availableFunctions(myList) message = "No functions available (len=%ss)" % len(myList) assert len(myList) > 0, message
def test_available_functions(self): """Check we can get the available functions from the impact calculator. """ functions = available_functions() message = 'No functions available (len=%ss)' % len(functions) self.assertTrue(len(functions) > 0, message) # Also test if it works when we give it two layers # to see if we can determine which functions will # work for them. keywords1 = read_file_keywords(self.rasterShakePath) keywords2 = read_file_keywords(self.vectorPath) # We need to explicitly add the layer type to each keyword list keywords1['layertype'] = 'raster' keywords2['layertype'] = 'vector' functions = [keywords1, keywords2] functions = available_functions(functions) message = 'No functions available (len=%ss)' % len(functions) self.assertTrue(len(functions) > 0, message)
def test_availableFunctions(self): """Check we can get the available functions from the impact calculator. """ myList = availableFunctions() myMessage = 'No functions available (len=%ss)' % len(myList) assert len(myList) > 0, myMessage # Also test if it works when we give it two layers # to see if we can determine which functions will # work for them. myKeywords1 = read_file_keywords(self.rasterShakePath) myKeywords2 = read_file_keywords(self.vectorPath) # We need to explicitly add the layer type to each keyword list myKeywords1['layertype'] = 'raster' myKeywords2['layertype'] = 'vector' myList = [myKeywords1, myKeywords2] myList = availableFunctions(myList) myMessage = 'No functions available (len=%ss)' % len(myList) assert len(myList) > 0, myMessage
def test_available_functions(self): """Check we can get the available functions from the impact calculator. """ functions = available_functions() message = 'No functions available (len=%ss)' % len(functions) self.assertTrue(len(functions) > 0, message) # Also test if it works when we give it two layers # to see if we can determine which functions will # work for them. keywords1 = read_file_keywords(self.rasterShakePath) keywords2 = read_file_keywords(self.vectorPath) # We need to explicitly add the layer type to each keyword list keywords1['layertype'] = 'raster' keywords2['layertype'] = 'vector' functions = [keywords1, keywords2] functions = available_functions(functions) message = 'No functions available (len=%ss)' % len(functions) self.assertTrue(len(functions) > 0, message)
def makePointLayer(): """Helper function that returns a single predefined layer""" myFile = 'test_buildings.shp' myPath = os.path.join(TESTDATA, myFile) try: myTitle = read_file_keywords(myPath, 'title') except KeywordNotFoundError: myTitle = 'kabupaten_jakarta_singlepart_3_good_attr' myLayer = QgsVectorLayer(myPath, myTitle, 'ogr') # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayer(myLayer) return myLayer
def make_point_layer(): """Helper function that returns a single predefined layer.""" path = 'test_buildings.shp' full_path = os.path.join(TESTDATA, path) try: title = read_file_keywords(full_path, 'title') except KeywordNotFoundError: title = 'kabupaten_jakarta_singlepart_3_good_attr' layer = QgsVectorLayer(full_path, title, 'ogr') # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayers([layer]) return layer
def make_point_layer(): """Helper function that returns a single predefined layer.""" path = 'test_buildings.shp' full_path = os.path.join(TESTDATA, path) try: title = read_file_keywords(full_path, 'title') except KeywordNotFoundError: title = 'kabupaten_jakarta_singlepart_3_good_attr' layer = QgsVectorLayer(full_path, title, 'ogr') # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayer(layer) return layer
def makePointLayer(): """Helper function that returns a single predefined layer""" myFile = 'test_buildings.shp' myPath = os.path.join(TESTDATA, myFile) try: myTitle = read_file_keywords(myPath, 'title') except KeywordNotFoundError: myTitle = 'kabupaten_jakarta_singlepart_3_good_attr' myLayer = QgsVectorLayer(myPath, myTitle, 'ogr') # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayer(myLayer) return myLayer
def makePadangLayer(): """Helper function that returns a single predefined layer""" myFile = 'Shakemap_Padang_2009.asc' myPath = os.path.join(HAZDATA, myFile) myTitle = read_file_keywords(myPath, 'title') # myTitle = 'An earthquake in Padang like in 2009' myLayer = QgsRasterLayer(myPath, myTitle) if qgis_version() >= 10800: # 1.8 or newer # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayers([myLayer]) else: # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayer(myLayer) return myLayer
def make_padang_layer(): """Helper function that returns a single predefined layer.""" path = 'Shakemap_Padang_2009.asc' full_path = os.path.join(HAZDATA, path) title = read_file_keywords(full_path, 'title') # title = 'An earthquake in Padang like in 2009' layer = QgsRasterLayer(full_path, title) if qgis_version() >= 10800: # 1.8 or newer # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayers([layer]) else: # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayer(layer) return layer
def makePadangLayer(): """Helper function that returns a single predefined layer""" myFile = 'Shakemap_Padang_2009.asc' myPath = os.path.join(HAZDATA, myFile) myTitle = read_file_keywords(myPath, 'title') # myTitle = 'An earthquake in Padang like in 2009' myLayer = QgsRasterLayer(myPath, myTitle) if qgis_version() >= 10800: # 1.8 or newer # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayers([myLayer]) else: # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayer(myLayer) return myLayer
def make_padang_layer(): """Helper function that returns a single predefined layer.""" path = 'Shakemap_Padang_2009.asc' full_path = os.path.join(HAZDATA, path) title = read_file_keywords(full_path, 'title') # title = 'An earthquake in Padang like in 2009' layer = QgsRasterLayer(full_path, title) if qgis_version() >= 10800: # 1.8 or newer # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayers([layer]) else: # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayer(layer) return layer
def read_keywords(self, layer, keyword=None): """Read keywords for a datasource and return them as a dictionary. This is a wrapper method that will 'do the right thing' to fetch keywords for the given datasource. In particular, if the datasource is remote (e.g. a database connection) it will fetch the keywords from the keywords store. :param layer: A QGIS QgsMapLayer instance that you want to obtain the keywords for. :type layer: QgsMapLayer, QgsRasterLayer, QgsVectorLayer, QgsPluginLayer :param keyword: If set, will extract only the specified keyword from the keywords dict. :type keyword: str :returns: A dict if keyword is omitted, otherwise the value for the given key if it is present. :rtype: dict, str TODO: Don't raise generic exceptions. :raises: HashNotFoundError, Exception, OperationalError, NoKeywordsFoundError, KeywordNotFoundError, InvalidParameterError, UnsupportedProviderError """ source = str(layer.source()) try: flag = self.are_keywords_file_based(layer) except UnsupportedProviderError: raise try: if flag: keywords = read_file_keywords(source, keyword) else: keywords = self.read_keyword_from_uri(source, keyword) return keywords except (HashNotFoundError, Exception, OperationalError, NoKeywordsFoundError, KeywordNotFoundError, InvalidParameterError, UnsupportedProviderError): raise
def load_layer(layer_file, directory=TESTDATA): """Helper to load and return a single QGIS layer :param layer_file: Path name to raster or vector file. :type layer_file: str :param directory: Optional parent dir. If None, path name is assumed to be absolute. :type directory: str, None :returns: tuple containing layer and its category. :rtype: (QgsMapLayer, str) """ # Extract basename and absolute path file_path = os.path.split(layer_file)[-1] # In case path was absolute base_name, extension = os.path.splitext(file_path) if directory is None: path = layer_file else: path = os.path.join(directory, layer_file) keyword_path = path[:-4] + '.keywords' # Determine if layer is hazard or exposure keywords = read_file_keywords(keyword_path) category = 'undefined' if 'category' in keywords: category = keywords['category'] message = 'Could not read %s' % keyword_path assert keywords is not None, message # Create QGis Layer Instance if extension in ['.asc', '.tif']: layer = QgsRasterLayer(path, base_name) elif extension in ['.shp']: layer = QgsVectorLayer(path, base_name, 'ogr') else: message = 'File %s had illegal extension' % path raise Exception(message) # noinspection PyUnresolvedReferences message = 'Layer "%s" is not valid' % str(layer.source()) # noinspection PyUnresolvedReferences if not layer.isValid(): print message # noinspection PyUnresolvedReferences assert layer.isValid(), message return layer, category
def load_layer(layer_file, directory=TESTDATA): """Helper to load and return a single QGIS layer :param layer_file: Path name to raster or vector file. :type layer_file: str :param directory: Optional parent dir. If None, path name is assumed to be absolute. :type directory: str, None :returns: tuple containing layer and its category. :rtype: (QgsMapLayer, str) """ # Extract basename and absolute path file_path = os.path.split(layer_file)[-1] # In case path was absolute base_name, extension = os.path.splitext(file_path) if directory is None: path = layer_file else: path = os.path.join(directory, layer_file) keyword_path = path[:-4] + '.keywords' # Determine if layer is hazard or exposure keywords = read_file_keywords(keyword_path) category = 'undefined' if 'category' in keywords: category = keywords['category'] message = 'Could not read %s' % keyword_path assert keywords is not None, message # Create QGis Layer Instance if extension in ['.asc', '.tif']: layer = QgsRasterLayer(path, base_name) elif extension in ['.shp']: layer = QgsVectorLayer(path, base_name, 'ogr') else: message = 'File %s had illegal extension' % path raise Exception(message) # noinspection PyUnresolvedReferences message = 'Layer "%s" is not valid' % str(layer.source()) # noinspection PyUnresolvedReferences if not layer.isValid(): print message # noinspection PyUnresolvedReferences assert layer.isValid(), message return layer, category
def makePolygonLayer(): """Helper function that returns a single predefined layer""" myFile = 'kabupaten_jakarta_singlepart_3_good_attr.shp' myPath = os.path.join(TESTDATA, myFile) try: myTitle = read_file_keywords(myPath, 'title') except KeywordNotFoundError: myTitle = 'kabupaten_jakarta_singlepart_3_good_attr' myLayer = QgsVectorLayer(myPath, myTitle, 'ogr') if qgis_version() >= 10800: # 1.8 or newer # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayers([myLayer]) else: # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayer(myLayer) return myLayer
def makePolygonLayer(): """Helper function that returns a single predefined layer""" myFile = 'kabupaten_jakarta_singlepart_3_good_attr.shp' myPath = os.path.join(TESTDATA, myFile) try: myTitle = read_file_keywords(myPath, 'title') except KeywordNotFoundError: myTitle = 'kabupaten_jakarta_singlepart_3_good_attr' myLayer = QgsVectorLayer(myPath, myTitle, 'ogr') if qgis_version() >= 10800: # 1.8 or newer # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayers([myLayer]) else: # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayer(myLayer) return myLayer
def make_polygon_layer(): """Helper function that returns a single predefined layer.""" path = 'kabupaten_jakarta_singlepart_3_good_attr.shp' full_path = os.path.join(TESTDATA, path) try: title = read_file_keywords(full_path, 'title') except KeywordNotFoundError: title = 'kabupaten_jakarta_singlepart_3_good_attr' layer = QgsVectorLayer(full_path, title, 'ogr') if qgis_version() >= 10800: # 1.8 or newer # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayers([layer]) else: # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayer(layer) return layer
def make_polygon_layer(): """Helper function that returns a single predefined layer.""" path = 'kabupaten_jakarta_singlepart_3_good_attr.shp' full_path = os.path.join(TESTDATA, path) try: title = read_file_keywords(full_path, 'title') except KeywordNotFoundError: title = 'kabupaten_jakarta_singlepart_3_good_attr' layer = QgsVectorLayer(full_path, title, 'ogr') if qgis_version() >= 10800: # 1.8 or newer # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayers([layer]) else: # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayer(layer) return layer
def read_keywords(self, layer, keyword=None): """Read keywords for a datasource and return them as a dictionary. This is a wrapper method that will 'do the right thing' to fetch keywords for the given datasource. In particular, if the datasource is remote (e.g. a database connection) it will fetch the keywords from the keywords store. :param layer: A QGIS QgsMapLayer instance that you want to obtain the keywords for. :type layer: QgsMapLayer, QgsRasterLayer, QgsVectorLayer, QgsPluginLayer :param keyword: If set, will extract only the specified keyword from the keywords dict. :type keyword: str :returns: A dict if keyword is omitted, otherwise the value for the given key if it is present. :rtype: dict, str TODO: Don't raise generic exceptions. :raises: HashNotFoundError, Exception, OperationalError, NoKeywordsFoundError, KeywordNotFoundError, InvalidParameterError, UnsupportedProviderError """ source = str(layer.source()) try: flag = self.are_keywords_file_based(layer) except UnsupportedProviderError: raise try: if flag: keywords = read_file_keywords(source, keyword) else: keywords = self.read_keyword_from_uri(source, keyword) return keywords except (HashNotFoundError, Exception, OperationalError, NoKeywordsFoundError, KeywordNotFoundError, InvalidParameterError, UnsupportedProviderError): raise
def load_layer(layer_file, directory=TESTDATA): """Helper to load and return a single QGIS layer :param layer_file: Path name to raster or vector file. :type layer_file: str :param directory: Optional parent dir. If None, path name is assumed to be absolute. :type directory: str, None :returns: tuple containing layer and its category. :rtype: (QgsMapLayer, str) """ # Extract basename and absolute path file_path = os.path.split(layer_file)[-1] # In case path was absolute base_name, extension = os.path.splitext(file_path) if directory is None: path = layer_file else: path = os.path.join(directory, layer_file) keyword_path = path[:-4] + ".keywords" # Determine if layer is hazard or exposure keywords = read_file_keywords(keyword_path) category = "undefined" if "category" in keywords: category = keywords["category"] message = "Could not read %s" % keyword_path assert keywords is not None, message # Create QGis Layer Instance if extension in [".asc", ".tif"]: layer = QgsRasterLayer(path, base_name) elif extension in [".shp"]: layer = QgsVectorLayer(path, base_name, "ogr") else: message = "File %s had illegal extension" % path raise Exception(message) message = 'Layer "%s" is not valid' % str(layer.source()) assert layer.isValid(), message return layer, category
def load_layer(layer_file, directory=TESTDATA): """Helper to load and return a single QGIS layer :param layer_file: Path name to raster or vector file. :type layer_file: str :param directory: Optional parent dir. If None, path name is assumed to be absolute. :type directory: str, None :returns: tuple containing layer and its category. :rtype: (QgsMapLayer, str) """ # Extract basename and absolute path myFilename = os.path.split(layer_file)[-1] # In case path was absolute myBaseName, myExt = os.path.splitext(myFilename) if directory is None: myPath = layer_file else: myPath = os.path.join(directory, layer_file) myKeywordPath = myPath[:-4] + '.keywords' # Determine if layer is hazard or exposure myKeywords = read_file_keywords(myKeywordPath) myCategory = 'undefined' if 'category' in myKeywords: myCategory = myKeywords['category'] myMessage = 'Could not read %s' % myKeywordPath assert myKeywords is not None, myMessage # Create QGis Layer Instance if myExt in ['.asc', '.tif']: myLayer = QgsRasterLayer(myPath, myBaseName) elif myExt in ['.shp']: myLayer = QgsVectorLayer(myPath, myBaseName, 'ogr') else: myMessage = 'File %s had illegal extension' % myPath raise Exception(myMessage) myMessage = 'Layer "%s" is not valid' % str(myLayer.source()) assert myLayer.isValid(), myMessage return myLayer, myCategory
def clone_padang_layer(): """Helper function that copies padang keyword for testing and return it.""" path = 'Shakemap_Padang_2009' extensions = [ '.asc', '.asc.aux.xml', '.keywords', '.lic', '.prj', '.qml', '.sld'] temp_path = unique_filename() # copy to temp file for ext in extensions: source_path = os.path.join(HAZDATA, path + ext) dest_path = os.path.join(HAZDATA, temp_path + ext) shutil.copy2(source_path, dest_path) # return a single predefined layer path = temp_path + '.asc' full_path = os.path.join(HAZDATA, path) title = read_file_keywords(full_path, 'title') layer = QgsRasterLayer(full_path, title) if qgis_version() >= 10800: # 1.8 or newer # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayers([layer]) else: # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayers([layer]) return layer, temp_path
def makePadangLayerClone(): """Helper function that copies padang keyword for testing and return it.""" mySourceFileName = 'Shakemap_Padang_2009' myExts = ['.asc', '.asc.aux.xml', '.keywords', '.lic', '.prj', '.qml', '.sld'] myFileName = unique_filename() # copy to temp file for ext in myExts: mySourcePath = os.path.join(HAZDATA, mySourceFileName + ext) myDestPath = os.path.join(HAZDATA, myFileName + ext) shutil.copy2(mySourcePath, myDestPath) # return a single predefined layer myFile = myFileName + '.asc' myPath = os.path.join(HAZDATA, myFile) myTitle = read_file_keywords(myPath, 'title') myLayer = QgsRasterLayer(myPath, myTitle) if qgis_version() >= 10800: # 1.8 or newer # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayers([myLayer]) else: # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayer(myLayer) return myLayer, myFileName
def makePadangLayerClone(): """Helper function that copies padang keyword for testing and return it.""" mySourceFileName = 'Shakemap_Padang_2009' myExts = [ '.asc', '.asc.aux.xml', '.keywords', '.lic', '.prj', '.qml', '.sld' ] myFileName = unique_filename() # copy to temp file for ext in myExts: mySourcePath = os.path.join(HAZDATA, mySourceFileName + ext) myDestPath = os.path.join(HAZDATA, myFileName + ext) shutil.copy2(mySourcePath, myDestPath) # return a single predefined layer myFile = myFileName + '.asc' myPath = os.path.join(HAZDATA, myFile) myTitle = read_file_keywords(myPath, 'title') myLayer = QgsRasterLayer(myPath, myTitle) if qgis_version() >= 10800: # 1.8 or newer # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayers([myLayer]) else: # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayer(myLayer) return myLayer, myFileName
def clone_padang_layer(): """Helper function that copies padang keyword for testing and return it.""" path = 'Shakemap_Padang_2009' extensions = [ '.asc', '.asc.aux.xml', '.keywords', '.lic', '.prj', '.qml', '.sld' ] temp_path = unique_filename() # copy to temp file for ext in extensions: source_path = os.path.join(HAZDATA, path + ext) dest_path = os.path.join(HAZDATA, temp_path + ext) shutil.copy2(source_path, dest_path) # return a single predefined layer path = temp_path + '.asc' full_path = os.path.join(HAZDATA, path) title = read_file_keywords(full_path, 'title') layer = QgsRasterLayer(full_path, title) if qgis_version() >= 10800: # 1.8 or newer # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayers([layer]) else: # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayer(layer) return layer, temp_path
def _clip_raster_layer( layer, extent, cell_size=None, extra_keywords=None): """Clip a Hazard or Exposure raster layer to the extents provided. The layer must be a raster layer or an exception will be thrown. .. note:: The extent *must* be in EPSG:4326. The output layer will always be in WGS84/Geographic. :param layer: A valid QGIS raster layer in EPSG:4326 :type layer: QgsRasterLayer :param extent: An array representing the exposure layer extents in the form [xmin, ymin, xmax, ymax]. It is assumed that the coordinates are in EPSG:4326 although currently no checks are made to enforce this. or: A QgsGeometry of type polygon. **Polygon clipping currently only supported for vector datasets.** :type extent: list(float), QgsGeometry :param cell_size: Cell size (in GeoCRS) which the layer should be resampled to. If not provided for a raster layer (i.e. theCellSize=None), the native raster cell size will be used. :type cell_size: float :returns: Output clipped layer (placed in the system temp dir). :rtype: QgsRasterLayer :raises: InvalidProjectionError - if input layer is a density layer in projected coordinates. See issue #123. """ if not layer or not extent: message = tr('Layer or Extent passed to clip is None.') raise InvalidParameterError(message) if layer.type() != QgsMapLayer.RasterLayer: message = tr( 'Expected a raster layer but received a %s.' % str(layer.type())) raise InvalidParameterError(message) working_layer = str(layer.source()) # Check for existence of keywords file base, _ = os.path.splitext(working_layer) keywords_path = base + '.keywords' message = tr( 'Input file to be clipped "%s" does not have the ' 'expected keywords file %s' % ( working_layer, keywords_path )) verify(os.path.isfile(keywords_path), message) # Raise exception if layer is projected and refers to density (issue #123) # FIXME (Ole): Need to deal with it - e.g. by automatically reprojecting # the layer at this point and setting the native resolution accordingly # in its keywords. keywords = read_file_keywords(keywords_path) if 'datatype' in keywords and keywords['datatype'] == 'density': if str(layer.crs().authid()) != 'EPSG:4326': # This layer is not WGS84 geographic message = ( 'Layer %s represents density but has spatial reference "%s". ' 'Density layers must be given in WGS84 geographic coordinates, ' 'so please reproject and try again. For more information, ' 'see issue https://github.com/AIFDR/inasafe/issues/123' % ( working_layer, layer.crs().toProj4() )) raise InvalidProjectionError(message) # We need to provide gdalwarp with a dataset for the clip # because unline gdal_translate, it does not take projwin. clip_kml = extent_to_kml(extent) # Create a filename for the clipped, resampled and reprojected layer handle, filename = tempfile.mkstemp('.tif', 'clip_', temp_dir()) os.close(handle) os.remove(filename) # If no cell size is specified, we need to run gdalwarp without # specifying the output pixel size to ensure the raster dims # remain consistent. binary_list = which('gdalwarp') LOGGER.debug('Path for gdalwarp: %s' % binary_list) if len(binary_list) < 1: raise CallGDALError( tr('gdalwarp could not be found on your computer')) # Use the first matching gdalwarp found binary = binary_list[0] if cell_size is None: command = ( '"%s" -q -t_srs EPSG:4326 -r near -cutline %s -crop_to_cutline ' '-of GTiff "%s" "%s"' % ( binary, clip_kml, working_layer, filename)) else: command = ( '"%s" -q -t_srs EPSG:4326 -r near -tr %f %f -cutline %s ' '-crop_to_cutline -of GTiff "%s" "%s"' % ( binary, cell_size, cell_size, clip_kml, working_layer, filename)) LOGGER.debug(command) result = QProcess().execute(command) # For QProcess exit codes see # http://qt-project.org/doc/qt-4.8/qprocess.html#execute if result == -2: # cannot be started message_detail = tr('Process could not be started.') message = tr( '<p>Error while executing the following shell command:' '</p><pre>%s</pre><p>Error message: %s' % (command, message_detail)) raise CallGDALError(message) elif result == -1: # process crashed message_detail = tr('Process crashed.') message = tr('<p>Error while executing the following shell command:</p>' '<pre>%s</pre><p>Error message: %s' % (command, message_detail)) raise CallGDALError(message) # .. todo:: Check the result of the shell call is ok keyword_io = KeywordIO() keyword_io.copy_keywords(layer, filename, extra_keywords=extra_keywords) base_name = '%s clipped' % layer.name() layer = QgsRasterLayer(filename, base_name) return layer
message = 'Got: %s\n\nExpected %s\n\nDB: %s' % ( keyword, expected_keyword, self.rasterShakePath) self.assertEqual(keyword, 'hazard', message) # Test we get an exception if keyword is not found try: _ = read_file_keywords(self.rasterShakePath, 'boguskeyword') except KeywordNotFoundError: pass # this is good except Exception, e: message = ('Request for bogus keyword raised incorrect ' 'exception type: \n %s') % str(e) assert(), message keywords = read_file_keywords(self.rasterShakePath) expected_keywords = { 'category': 'hazard', 'subcategory': 'earthquake', 'source': 'USGS', 'unit': 'MMI', 'title': 'An earthquake in Padang like in 2009'} message = 'Expected:\n%s\nGot:\n%s\n' % (expected_keywords, keywords) self.assertEqual(keywords, expected_keywords, message) keywords = read_file_keywords(self.rasterPopulationPath) expected_keywords = { 'category': 'exposure', 'source': ('Center for International Earth Science Information ' 'Network (CIESIN)'),
myExpectedKeyword = 'hazard' myMessage = 'Got: %s\n\nExpected %s\n\nDB: %s' % ( myKeyword, myExpectedKeyword, self.rasterShakePath) assert myKeyword == 'hazard', myMessage # Test we get an exception if keyword is not found try: _ = read_file_keywords(self.rasterShakePath, 'boguskeyword') except KeywordNotFoundError: pass # this is good except Exception, e: myMessage = ('Request for bogus keyword raised incorrect ' 'exception type: \n %s') % str(e) assert (), myMessage myKeywords = read_file_keywords(self.rasterShakePath) myExpectedKeywords = { 'category': 'hazard', 'subcategory': 'earthquake', 'source': 'USGS', 'unit': 'MMI', 'title': 'An earthquake in Padang like in 2009' } myMessage = 'Expected:\n%s\nGot:\n%s\n' % (myExpectedKeywords, myKeywords) assert myKeywords == myExpectedKeywords, myMessage myKeywords = read_file_keywords(self.rasterPopulationPath) myExpectedKeywords = { 'category':
def _clip_raster_layer(layer, extent, cell_size=None, extra_keywords=None): """Clip a Hazard or Exposure raster layer to the extents provided. The layer must be a raster layer or an exception will be thrown. .. note:: The extent *must* be in EPSG:4326. The output layer will always be in WGS84/Geographic. :param layer: A valid QGIS raster layer in EPSG:4326 :type layer: QgsRasterLayer :param extent: An array representing the exposure layer extents in the form [xmin, ymin, xmax, ymax]. It is assumed that the coordinates are in EPSG:4326 although currently no checks are made to enforce this. or: A QgsGeometry of type polygon. **Polygon clipping currently only supported for vector datasets.** :type extent: list(float), QgsGeometry :param cell_size: Cell size (in GeoCRS) which the layer should be resampled to. If not provided for a raster layer (i.e. theCellSize=None), the native raster cell size will be used. :type cell_size: float :returns: Output clipped layer (placed in the system temp dir). :rtype: QgsRasterLayer :raises: InvalidProjectionError - if input layer is a density layer in projected coordinates. See issue #123. """ if not layer or not extent: message = tr('Layer or Extent passed to clip is None.') raise InvalidParameterError(message) if layer.type() != QgsMapLayer.RasterLayer: message = tr('Expected a raster layer but received a %s.' % str(layer.type())) raise InvalidParameterError(message) working_layer = str(layer.source()) # Check for existence of keywords file base, _ = os.path.splitext(working_layer) keywords_path = base + '.keywords' message = tr('Input file to be clipped "%s" does not have the ' 'expected keywords file %s' % (working_layer, keywords_path)) verify(os.path.isfile(keywords_path), message) # Raise exception if layer is projected and refers to density (issue #123) # FIXME (Ole): Need to deal with it - e.g. by automatically reprojecting # the layer at this point and setting the native resolution accordingly # in its keywords. keywords = read_file_keywords(keywords_path) if 'datatype' in keywords and keywords['datatype'] == 'density': if str(layer.crs().authid()) != 'EPSG:4326': # This layer is not WGS84 geographic message = ( 'Layer %s represents density but has spatial reference "%s". ' 'Density layers must be given in WGS84 geographic ' 'coordinates, so please reproject and try again. For more ' 'information, see issue ' 'https://github.com/AIFDR/inasafe/issues/123' % (working_layer, layer.crs().toProj4())) raise InvalidProjectionError(message) # We need to provide gdalwarp with a dataset for the clip # because unline gdal_translate, it does not take projwin. clip_kml = extent_to_kml(extent) # Create a filename for the clipped, resampled and reprojected layer handle, filename = tempfile.mkstemp('.tif', 'clip_', temp_dir()) os.close(handle) os.remove(filename) # If no cell size is specified, we need to run gdalwarp without # specifying the output pixel size to ensure the raster dims # remain consistent. binary_list = which('gdalwarp') LOGGER.debug('Path for gdalwarp: %s' % binary_list) if len(binary_list) < 1: raise CallGDALError(tr('gdalwarp could not be found on your computer')) # Use the first matching gdalwarp found binary = binary_list[0] if cell_size is None: command = ( '"%s" -q -t_srs EPSG:4326 -r near -cutline %s -crop_to_cutline ' '-ot Float64 -of GTiff "%s" "%s"' % (binary, clip_kml, working_layer, filename)) else: command = ( '"%s" -q -t_srs EPSG:4326 -r near -tr %f %f -cutline %s ' '-crop_to_cutline -ot Float64 -of GTiff "%s" "%s"' % (binary, cell_size, cell_size, clip_kml, working_layer, filename)) LOGGER.debug(command) result = QProcess().execute(command) # For QProcess exit codes see # http://qt-project.org/doc/qt-4.8/qprocess.html#execute if result == -2: # cannot be started message_detail = tr('Process could not be started.') message = tr('<p>Error while executing the following shell command:' '</p><pre>%s</pre><p>Error message: %s' % (command, message_detail)) raise CallGDALError(message) elif result == -1: # process crashed message_detail = tr('Process crashed.') message = tr( '<p>Error while executing the following shell command:</p>' '<pre>%s</pre><p>Error message: %s' % (command, message_detail)) raise CallGDALError(message) # .. todo:: Check the result of the shell call is ok keyword_io = KeywordIO() keyword_io.copy_keywords(layer, filename, extra_keywords=extra_keywords) base_name = '%s clipped' % layer.name() layer = QgsRasterLayer(filename, base_name) return layer