Source code for safe_qgis.test_safe_interface

"""
InaSAFE Disaster risk assessment tool developed by AusAid -
**SAFE Interface test suite.**

Contact : ole.moller.nielsen@gmail.com

.. note:: This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation; either version 2 of the License, or
     (at your option) any later version.

"""

__author__ = 'tim@linfiniti.com'
__date__ = '04/04/2012'
__copyright__ = ('Copyright 2012, Australia Indonesia Facility for '
                 'Disaster Reduction')

import os
import numpy
import unittest
from safe_qgis.safe_interface import (getOptimalExtent,
                                      availableFunctions,
                                      readKeywordsFromFile,
                                      readSafeLayer)
from safe_qgis.exceptions import (KeywordNotFoundException,
                                  InsufficientOverlapException)
from safe.common.exceptions import BoundingBoxError
from safe.common.testing import TESTDATA, HAZDATA, EXPDATA


[docs]class SafeInterfaceTest(unittest.TestCase): """Test the SAFE API Wrapper"""
[docs] def setUp(self): """Setup test before each unit""" self.vectorPath = os.path.join(TESTDATA, 'Padang_WGS84.shp') self.rasterShakePath = os.path.join(HAZDATA, 'Shakemap_Padang_2009.asc') self.rasterTsunamiPath = os.path.join(TESTDATA, 'tsunami_max_inundation_depth_utm56s.tif') self.rasterExposurePath = os.path.join(TESTDATA, 'tsunami_building_exposure.shp') self.rasterPopulationPath = os.path.join(EXPDATA, 'glp10ag.asc')
[docs] def test_getOptimalExtent(self): """Optimal extent is calculated correctly """ exposure_path = os.path.join(TESTDATA, 'Population_2010.asc') hazard_path = os.path.join(HAZDATA, 'Lembang_Earthquake_Scenario.asc') # Expected data haz_metadata = {'bounding_box': (105.3000035, -8.3749994999999995, 110.2914705, -5.5667784999999999), 'resolution': (0.0083330000000000001, 0.0083330000000000001)} exp_metadata = {'bounding_box': (94.972335000000001, -11.009721000000001, 141.0140016666665, 6.0736123333332639), 'resolution': (0.0083333333333333003, 0.0083333333333333003)} # Verify relevant metada is ok H = readSafeLayer(hazard_path) E = readSafeLayer(exposure_path) hazard_bbox = H.get_bounding_box() assert numpy.allclose(hazard_bbox, haz_metadata['bounding_box'], rtol=1.0e-12, atol=1.0e-12) exposure_bbox = E.get_bounding_box() assert numpy.allclose(exposure_bbox, exp_metadata['bounding_box'], rtol=1.0e-12, atol=1.0e-12) hazard_res = H.get_resolution() assert numpy.allclose(hazard_res, haz_metadata['resolution'], rtol=1.0e-12, atol=1.0e-12) exposure_res = E.get_resolution() assert numpy.allclose(exposure_res, exp_metadata['resolution'], rtol=1.0e-12, atol=1.0e-12) # First, do some examples that produce valid results ref_box = [105.3000035, -8.3749995, 110.2914705, -5.5667785] view_port = [94.972335, -11.009721, 141.014002, 6.073612] bbox = getOptimalExtent(hazard_bbox, exposure_bbox, view_port) assert numpy.allclose(bbox, ref_box, rtol=1.0e-12, atol=1.0e-12) #testing with viewport clipping disabled bbox = getOptimalExtent(hazard_bbox, exposure_bbox, None) assert numpy.allclose(bbox, ref_box, rtol=1.0e-12, atol=1.0e-12) view_port = [105.3000035, -8.3749994999999995, 110.2914705, -5.5667784999999999] bbox = getOptimalExtent(hazard_bbox, exposure_bbox, view_port) assert numpy.allclose(bbox, ref_box, rtol=1.0e-12, atol=1.0e-12) # Very small viewport fully inside other layers view_port = [106.0, -6.0, 108.0, -5.8] bbox = getOptimalExtent(hazard_bbox, exposure_bbox, view_port) assert numpy.allclose(bbox, view_port, rtol=1.0e-12, atol=1.0e-12) # viewport that intersects hazard layer view_port = [107.0, -6.0, 112.0, -3.0] ref_box = [107, -6, 110.2914705, -5.5667785] bbox = getOptimalExtent(hazard_bbox, exposure_bbox, view_port) assert numpy.allclose(bbox, ref_box, rtol=1.0e-12, atol=1.0e-12) # Then one where boxes don't overlap view_port = [105.3, -4.3, 110.29, -2.5] try: getOptimalExtent(hazard_bbox, exposure_bbox, view_port) except InsufficientOverlapException, e: myMessage = 'Did not find expected error message in %s' % str(e) assert 'did not overlap' in str(e), myMessage else: myMessage = ('Non ovelapping bounding boxes should have raised ' 'an exception') raise Exception(myMessage) # Try with wrong input data try: getOptimalExtent(haz_metadata, exp_metadata, view_port) except BoundingBoxError: #good this was expected pass except InsufficientOverlapException, e: myMessage = 'Did not find expected error message in %s' % str(e) assert 'Invalid' in str(e), myMessage else: myMessage = ('Wrong input data should have raised an exception') raise Exception(myMessage) try: getOptimalExtent(None, None, view_port) except BoundingBoxError, e: myMessage = 'Did not find expected error message in %s' % str(e) assert 'cannot be None' in str(e), myMessage else: myMessage = ('Wrong input data should have raised an exception') raise Exception(myMessage) try: getOptimalExtent('aoeush', 'oeuuoe', view_port) except BoundingBoxError, e: myMessage = 'Did not find expected error message in %s' % str(e) assert 'Instead i got "aoeush"' in str(e), myMessage else: myMessage = ('Wrong input data should have raised an exception') raise Exception(myMessage)
[docs] 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 = readKeywordsFromFile(self.rasterShakePath) myKeywords2 = readKeywordsFromFile(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
[docs] def test_getKeywordFromFile(self): """Get keyword from a filesystem file's .keyword file.""" myKeyword = readKeywordsFromFile( 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: myKeyword = readKeywordsFromFile( self.rasterShakePath, 'boguskeyword') except KeywordNotFoundException: pass # this is good except Exception, e: myMessage = ('Request for bogus keyword raised incorrect ' 'exception type: \n %s') % str(e) assert(), myMessage myKeywords = readKeywordsFromFile(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 = readKeywordsFromFile(self.rasterPopulationPath) myExpectedKeywords = {'category': 'exposure', 'source': ('Center for International Earth ' 'Science Information Network (CIESIN)'), 'subcategory': 'population', 'datatype': 'density', 'title': 'People'} myMessage = 'Expected:\n%s\nGot:\n%s\n' % (myExpectedKeywords, myKeywords) assert myKeywords == myExpectedKeywords, myMessage myKeywords = readKeywordsFromFile(self.vectorPath) myExpectedKeywords = {'category': 'exposure', 'datatype': 'itb', 'subcategory': 'structure'} myMessage = 'Expected:\n%s\nGot:\n%s\n' % (myExpectedKeywords, myKeywords) assert myKeywords == myExpectedKeywords, myMessage # tsunami example (one layer is UTM) myKeywords = readKeywordsFromFile(self.rasterTsunamiPath) myExpectedKeywords = {'title': 'Tsunami Max Inundation', 'category': 'hazard', 'subcategory': 'tsunami', 'unit': 'm'} myMessage = 'Expected:\n%s\nGot:\n%s\n' % (myExpectedKeywords, myKeywords) assert myKeywords == myExpectedKeywords, myMessage myKeywords = readKeywordsFromFile(self.rasterExposurePath) myExpectedKeywords = {'category': 'exposure', 'subcategory': 'structure', 'title': 'Tsunami Building Exposure'} myMessage = 'Expected:\n%s\nGot:\n%s\n' % (myExpectedKeywords, myKeywords) assert myKeywords == myExpectedKeywords, myMessage
if __name__ == '__main__': suite = unittest.makeSuite(SafeInterfaceTest, 'test') runner = unittest.TextTestRunner(verbosity=2) runner.run(suite)