Example #1
0
    def getRunner(self):
        """ Factory to create a new runner thread.
        Requires three parameters to be set before execution
        can take place:

        * Hazard layer - a path to a raster (string)
        * Exposure layer - a path to a vector hazard layer (string).
        * Function - a function name that defines how the Hazard assessment
          will be computed (string).

        Args:
           None.
        Returns:
           None
        Raises:
           InsufficientParametersError if not all parameters are
           set.
        """
        self._filename = None
        self._result = None
        if self._hazardLayer is None or self._hazardLayer == '':
            myMessage = self.tr('Error: Hazard layer not set.')
            raise InsufficientParametersError(myMessage)

        if self._exposureLayer is None or self._exposureLayer == '':
            myMessage = self.tr('Error: Exposure layer not set.')
            raise InsufficientParametersError(myMessage)

        if self._function is None or self._function == '':
            myMessage = self.tr('Error: Function not set.')
            raise InsufficientParametersError(myMessage)

        # Call impact calculation engine
        try:
            myHazardLayer = readSafeLayer(self._hazardLayer)
            myExposureLayer = readSafeLayer(self._exposureLayer)
        except:
            raise

        myFunctions = getSafeImpactFunctions(self._function)
        myFunction = myFunctions[0][self._function]
        return ImpactCalculatorThread(myHazardLayer,
                                      myExposureLayer,
                                      myFunction)
Example #2
0
    def getRunner(self):
        """ Factory to create a new runner thread.
        Requires three parameters to be set before execution
        can take place:

        * Hazard layer - a path to a raster (string)
        * Exposure layer - a path to a vector hazard layer (string).
        * Function - a function name that defines how the Hazard assessment
          will be computed (string).

        Args:
           None.
        Returns:
           None
        Raises:
           InsufficientParametersError if not all parameters are
           set.
        """
        self._filename = None
        self._result = None
        if self._hazardLayer is None or self._hazardLayer == '':
            myMessage = self.tr('Error: Hazard layer not set.')
            raise InsufficientParametersError(myMessage)

        if self._exposureLayer is None or self._exposureLayer == '':
            myMessage = self.tr('Error: Exposure layer not set.')
            raise InsufficientParametersError(myMessage)

        if self._function is None or self._function == '':
            myMessage = self.tr('Error: Function not set.')
            raise InsufficientParametersError(myMessage)

        # Call impact calculation engine
        try:
            myHazardLayer = readSafeLayer(self._hazardLayer)
            myExposureLayer = readSafeLayer(self._exposureLayer)
        except:
            raise

        myFunctions = getSafeImpactFunctions(self._function)
        myFunction = myFunctions[0][self._function]
        return ImpactCalculatorThread(myHazardLayer,
                                      myExposureLayer,
                                      myFunction)
    def setUp(self):
        """Create shared resources that all tests can use"""
        self.calculator = ImpactCalculator()
        self.vector_path = os.path.join(TESTDATA, 'Padang_WGS84.shp')
        self.vector_layer = readSafeLayer(self.vector_path)
        self.raster_shake_path = os.path.join(
            HAZDATA, 'Shakemap_Padang_2009.asc')
        self.raster_shake = readSafeLayer(self.raster_shake_path)
        # UTM projected layer

        fn = 'tsunami_max_inundation_depth_BB_utm.asc'
        self.raster_tsunami_path = os.path.join(TESTDATA, fn)
        self.raster_exposure_path = os.path.join(
            TESTDATA, 'tsunami_building_exposure.shp')

        self.raster_population_path = os.path.join(EXPDATA, 'glp10ag.asc')
        self.calculator.set_hazard_layer(self.raster_shake)
        self.calculator.set_exposure_layer(self.vector_layer)
        self.calculator.set_function('Earthquake Building Impact Function')
Example #4
0
    def setUp(self):
        """Create shared resources that all tests can use"""
        self.calculator = ImpactCalculator()
        self.vector_path = os.path.join(TESTDATA, 'Padang_WGS84.shp')
        self.vector_layer = readSafeLayer(self.vector_path)
        self.raster_shake_path = os.path.join(HAZDATA,
                                              'Shakemap_Padang_2009.asc')
        self.raster_shake = readSafeLayer(self.raster_shake_path)
        # UTM projected layer

        fn = 'tsunami_max_inundation_depth_BB_utm.asc'
        self.raster_tsunami_path = os.path.join(TESTDATA, fn)
        self.raster_exposure_path = os.path.join(
            TESTDATA, 'tsunami_building_exposure.shp')

        self.raster_population_path = os.path.join(EXPDATA, 'glp10ag.asc')
        self.calculator.set_hazard_layer(self.raster_shake)
        self.calculator.set_exposure_layer(self.vector_layer)
        self.calculator.set_function('Earthquake Building Impact Function')
 def test_issue100(self):
     """Test for issue 100: unhashable type dict"""
     exposure_path = os.path.join(
         TESTDATA, 'OSM_building_polygons_20110905.shp')
     hazard_path = os.path.join(
         HAZDATA, 'Flood_Current_Depth_Jakarta_geographic.asc')
     # Verify relevant metada is ok
     h = readSafeLayer(hazard_path)
     e = readSafeLayer(exposure_path)
     self.calculator.set_hazard_layer(h)
     self.calculator.set_exposure_layer(e)
     self.calculator.set_function('Flood Building Impact Function')
     try:
         function_runner = self.calculator.get_runner()
         # Run non threaded
         function_runner.run()
         message = function_runner.result()
         impact_layer = function_runner.impact_layer()
         file_name = impact_layer.get_filename()
         assert(file_name and not file_name == '')
         assert(message and not message == '')
     except Exception, e:  # pylint: disable=W0703
         message = 'Calculator run failed. %s' % str(e)
         assert(), message
Example #6
0
 def test_issue100(self):
     """Test for issue 100: unhashable type dict"""
     exposure_path = os.path.join(TESTDATA,
                                  'OSM_building_polygons_20110905.shp')
     hazard_path = os.path.join(
         HAZDATA, 'Flood_Current_Depth_Jakarta_geographic.asc')
     # Verify relevant metada is ok
     h = readSafeLayer(hazard_path)
     e = readSafeLayer(exposure_path)
     self.calculator.set_hazard_layer(h)
     self.calculator.set_exposure_layer(e)
     self.calculator.set_function('Flood Building Impact Function')
     try:
         function_runner = self.calculator.get_runner()
         # Run non threaded
         function_runner.run()
         message = function_runner.result()
         impact_layer = function_runner.impact_layer()
         file_name = impact_layer.get_filename()
         assert (file_name and not file_name == '')
         assert (message and not message == '')
     except Exception, e:  # pylint: disable=W0703
         message = 'Calculator run failed. %s' % str(e)
         assert (), message
Example #7
0
    def test_raster_scaling_projected(self):
        """Attempt to scale projected density raster layers raise exception.

        Automatic scaling when resampling density data
        does not currently work for projected layers. See issue #123.

        For the time being this test checks that an exception is raised
        when scaling is attempted on projected layers.
        When we resolve issue #123, this test should be rewritten.
        """

        test_filename = 'Population_Jakarta_UTM48N.tif'
        raster_path = ('%s/%s' % (TESTDATA, test_filename))

        # Get reference values
        safe_layer = readSafeLayer(raster_path)
        min_value, max_value = safe_layer.get_extrema()
        native_resolution = safe_layer.get_resolution()

        print min_value, max_value
        print native_resolution

        # Define bounding box in EPSG:4326
        bounding_box = [106.61, -6.38, 107.05, -6.07]

        resolutions = [0.02, 0.01, 0.005, 0.002, 0.001]
        # Test for a range of resolutions
        for resolution in resolutions:

            # Clip the raster to the bbox
            extra_keywords = {'resolution': native_resolution}
            raster_layer = QgsRasterLayer(raster_path, 'xxx')
            try:
                clip_layer(
                    raster_layer,
                    bounding_box,
                    resolution,
                    extra_keywords=extra_keywords
                )
            except InvalidProjectionError:
                pass
            else:
                message = 'Should have raised InvalidProjectionError'
                raise Exception(message)
Example #8
0
    def testRasterScaling_projected(self):
        """Attempt to scale projected density raster layers raise exception

        Automatic scaling when resampling density data
        does not currently work for projected layers. See issue #123.

        For the time being this test checks that an exception is raised
        when scaling is attempted on projected layers.
        When we resolve issue #123, this test should be rewritten.
        """

        myTestFilename = 'Population_Jakarta_UTM48N.tif'
        myRasterPath = ('%s/%s' % (TESTDATA, myTestFilename))

        # Get reference values
        mySafeLayer = readSafeLayer(myRasterPath)
        myMinimum, myMaximum = mySafeLayer.get_extrema()
        myNativeResolution = mySafeLayer.get_resolution()

        print
        print myMinimum, myMaximum
        print myNativeResolution

        # Define bounding box in EPSG:4326
        myBoundingBox = [106.61, -6.38, 107.05, -6.07]

        # Test for a range of resolutions
        for myResolution in [0.02, 0.01, 0.005, 0.002, 0.001]:

            # Clip the raster to the bbox
            myExtraKeywords = {'resolution': myNativeResolution}
            myRasterLayer = QgsRasterLayer(myRasterPath, 'xxx')
            try:
                clipLayer(myRasterLayer,
                          myBoundingBox,
                          myResolution,
                          theExtraKeywords=myExtraKeywords)
            except InvalidProjectionError:
                pass
            else:
                myMessage = 'Should have raised InvalidProjectionError'
                raise Exception(myMessage)
Example #9
0
    def testRasterScaling_projected(self):
        """Attempt to scale projected density raster layers raise exception

        Automatic scaling when resampling density data
        does not currently work for projected layers. See issue #123.

        For the time being this test checks that an exception is raised
        when scaling is attempted on projected layers.
        When we resolve issue #123, this test should be rewritten.
        """

        myTestFilename = 'Population_Jakarta_UTM48N.tif'
        myRasterPath = ('%s/%s' % (TESTDATA, myTestFilename))

        # Get reference values
        mySafeLayer = readSafeLayer(myRasterPath)
        myMinimum, myMaximum = mySafeLayer.get_extrema()
        myNativeResolution = mySafeLayer.get_resolution()

        print
        print myMinimum, myMaximum
        print myNativeResolution

        # Define bounding box in EPSG:4326
        myBoundingBox = [106.61, -6.38, 107.05, -6.07]

        # Test for a range of resolutions
        for myResolution in [0.02, 0.01, 0.005, 0.002, 0.001]:

            # Clip the raster to the bbox
            myExtraKeywords = {'resolution': myNativeResolution}
            myRasterLayer = QgsRasterLayer(myRasterPath, 'xxx')
            try:
                clip_layer(myRasterLayer,
                           myBoundingBox,
                           myResolution,
                           extra_keywords=myExtraKeywords)
            except InvalidProjectionError:
                pass
            else:
                myMessage = 'Should have raised InvalidProjectionError'
                raise Exception(myMessage)
Example #10
0
    def testRasterScaling(self):
        """Raster layers can be scaled when resampled

        This is a test for ticket #52

        Native test .asc data has

        Population_Jakarta_geographic.asc
        ncols         638
        nrows         649
        cellsize      0.00045228819716044

        Population_2010.asc
        ncols         5525
        nrows         2050
        cellsize      0.0083333333333333

        Scaling is necessary for raster data that represents density
        such as population per km^2
        """

        for myFilename in ['Population_Jakarta_geographic.asc',
                           'Population_2010.asc']:

            myRasterPath = ('%s/%s' % (TESTDATA, myFilename))

            # Get reference values
            mySafeLayer = readSafeLayer(myRasterPath)
            myMinimum, myMaximum = mySafeLayer.get_extrema()
            del myMaximum
            del myMinimum
            myNativeResolution = mySafeLayer.get_resolution()

            # Get the Hazard extents as an array in EPSG:4326
            myBoundingBox = mySafeLayer.get_bounding_box()

            # Test for a range of resolutions
            for myResolution in [0.02,
                                 0.01,
                                 0.005,
                                 0.002,
                                 0.001,
                                 0.0005,   # Coarser
                                 0.0002]:  # Finer

                # To save time only do two resolutions for the
                # large population set
                if myFilename.startswith('Population_2010'):
                    if myResolution > 0.01 or myResolution < 0.005:
                        break

                # Clip the raster to the bbox
                myExtraKeywords = {'resolution': myNativeResolution}
                myRasterLayer = QgsRasterLayer(myRasterPath, 'xxx')
                myResult = clip_layer(myRasterLayer,
                                      myBoundingBox,
                                      myResolution,
                                      extra_keywords=myExtraKeywords)

                mySafeLayer = readSafeLayer(myResult.source())
                myNativeData = mySafeLayer.get_data(scaling=False)
                myScaledData = mySafeLayer.get_data(scaling=True)

                mySigma = (mySafeLayer.get_resolution()[0] /
                           myNativeResolution[0]) ** 2

                # Compare extrema
                myExpectedScaledMax = mySigma * numpy.nanmax(myNativeData)
                myMessage = ('Resampled raster was not rescaled correctly: '
                             'max(myScaledData) was %f but expected %f'
                             % (numpy.nanmax(myScaledData),
                                myExpectedScaledMax))

                # FIXME (Ole): The rtol used to be 1.0e-8 -
                #              now it has to be 1.0e-6, otherwise we get
                #              max(myScaledData) was 12083021.000000 but
                #              expected 12083020.414316
                #              Is something being rounded to the nearest
                #              integer?
                assert numpy.allclose(myExpectedScaledMax,
                                      numpy.nanmax(myScaledData),
                                      rtol=1.0e-6, atol=1.0e-8), myMessage

                myExpectedScaledMin = mySigma * numpy.nanmin(myNativeData)
                myMessage = ('Resampled raster was not rescaled correctly: '
                             'min(myScaledData) was %f but expected %f'
                             % (numpy.nanmin(myScaledData),
                                myExpectedScaledMin))
                assert numpy.allclose(myExpectedScaledMin,
                                      numpy.nanmin(myScaledData),
                                      rtol=1.0e-8, atol=1.0e-12), myMessage

                # Compare elementwise
                myMessage = 'Resampled raster was not rescaled correctly'
                assert nan_allclose(myNativeData * mySigma, myScaledData,
                                   rtol=1.0e-8, atol=1.0e-8), myMessage

                # Check that it also works with manual scaling
                myManualData = mySafeLayer.get_data(scaling=mySigma)
                myMessage = 'Resampled raster was not rescaled correctly'
                assert nan_allclose(myManualData, myScaledData,
                                   rtol=1.0e-8, atol=1.0e-8), myMessage

                # Check that an exception is raised for bad arguments
                try:
                    mySafeLayer.get_data(scaling='bad')
                except GetDataError:
                    pass
                else:
                    myMessage = 'String argument should have raised exception'
                    raise Exception(myMessage)

                try:
                    mySafeLayer.get_data(scaling='(1, 3)')
                except GetDataError:
                    pass
                else:
                    myMessage = 'Tuple argument should have raised exception'
                    raise Exception(myMessage)

                # Check None option without keyword datatype == 'density'
                mySafeLayer.keywords['datatype'] = 'undefined'
                myUnscaledData = mySafeLayer.get_data(scaling=None)
                myMessage = 'Data should not have changed'
                assert nan_allclose(myNativeData, myUnscaledData,
                                   rtol=1.0e-12, atol=1.0e-12), myMessage

                # Try with None and density keyword
                mySafeLayer.keywords['datatype'] = 'density'
                myUnscaledData = mySafeLayer.get_data(scaling=None)
                myMessage = 'Resampled raster was not rescaled correctly'
                assert nan_allclose(myScaledData, myUnscaledData,
                                   rtol=1.0e-12, atol=1.0e-12), myMessage

                mySafeLayer.keywords['datatype'] = 'counts'
                myUnscaledData = mySafeLayer.get_data(scaling=None)
                myMessage = 'Data should not have changed'
                assert nan_allclose(myNativeData, myUnscaledData,
                                   rtol=1.0e-12, atol=1.0e-12), myMessage
Example #11
0
    def test_clipBoth(self):
        """Raster and Vector layers can be clipped
        """

        # Create a vector layer
        myName = 'padang'
        myVectorLayer = QgsVectorLayer(VECTOR_PATH, myName, 'ogr')
        myMessage = 'Did not find layer "%s" in path "%s"' % \
                    (myName, VECTOR_PATH)
        assert myVectorLayer.isValid(), myMessage

        # Create a raster layer
        myName = 'shake'
        myRasterLayer = QgsRasterLayer(RASTERPATH, myName)
        myMessage = 'Did not find layer "%s" in path "%s"' % \
                    (myName, RASTERPATH)
        assert myRasterLayer.isValid(), myMessage

        # Create a bounding box
        myViewportGeoExtent = [99.53, -1.22, 101.20, -0.36]

        # Get the Hazard extents as an array in EPSG:4326
        myHazardGeoExtent = [myRasterLayer.extent().xMinimum(),
                             myRasterLayer.extent().yMinimum(),
                             myRasterLayer.extent().xMaximum(),
                             myRasterLayer.extent().yMaximum()]

        # Get the Exposure extents as an array in EPSG:4326
        myExposureGeoExtent = [myVectorLayer.extent().xMinimum(),
                               myVectorLayer.extent().yMinimum(),
                               myVectorLayer.extent().xMaximum(),
                               myVectorLayer.extent().yMaximum()]

        # Now work out the optimal extent between the two layers and
        # the current view extent. The optimal extent is the intersection
        # between the two layers and the viewport.
        # Extent is returned as an array [xmin,ymin,xmax,ymax]
        myGeoExtent = getOptimalExtent(myHazardGeoExtent,
                                       myExposureGeoExtent,
                                       myViewportGeoExtent)

        # Clip the vector to the bbox
        myResult = clip_layer(myVectorLayer, myGeoExtent)

        # Check the output is valid
        assert os.path.exists(myResult.source())
        readSafeLayer(myResult.source())

        # Clip the raster to the bbox
        myResult = clip_layer(myRasterLayer, myGeoExtent)

        # Check the output is valid
        assert os.path.exists(myResult.source())
        readSafeLayer(myResult.source())

        # -------------------------------
        # Check the extra keywords option
        # -------------------------------
        # Clip the vector to the bbox
        myResult = clip_layer(myVectorLayer, myGeoExtent,
                              extra_keywords={'kermit': 'piggy'})

        # Check the output is valid
        assert os.path.exists(myResult.source())
        L = readSafeLayer(myResult.source())
        kwds = L.get_keywords()
        # myMessage = 'Extra keyword wasn\'t found in %s: %s' % (myResult,
        # kwds)
        assert kwds['kermit'] == 'piggy'

        # Clip the raster to the bbox
        myResult = clip_layer(myRasterLayer, myGeoExtent,
                              extra_keywords={'zoot': 'animal'})

        # Check the output is valid
        assert os.path.exists(myResult.source())
        L = readSafeLayer(myResult.source())
        kwds = L.get_keywords()

        myMessage = 'Extra keyword was not found in %s: %s' % (
            myResult.source(), kwds)
        assert kwds['zoot'] == 'animal', myMessage
Example #12
0
    def test_raster_scaling(self):
        """Raster layers can be scaled when resampled.

        This is a test for ticket #52

        Native test .asc data has

        Population_Jakarta_geographic.asc
        ncols         638
        nrows         649
        cellsize      0.00045228819716044

        Population_2010.asc
        ncols         5525
        nrows         2050
        cellsize      0.0083333333333333

        Scaling is necessary for raster data that represents density
        such as population per km^2
        """

        filenames = [
            'Population_Jakarta_geographic.asc',
            'Population_2010.asc'
        ]
        for filename in filenames:
            raster_path = ('%s/%s' % (TESTDATA, filename))

            # Get reference values
            safe_layer = readSafeLayer(raster_path)
            min_value, max_value = safe_layer.get_extrema()
            del max_value
            del min_value
            native_resolution = safe_layer.get_resolution()

            # Get the Hazard extents as an array in EPSG:4326
            bounding_box = safe_layer.get_bounding_box()

            resolutions = [
                0.02,
                0.01,
                0.005,
                0.002,
                0.001,
                0.0005,  # Coarser
                0.0002  # Finer
            ]
            # Test for a range of resolutions
            for resolution in resolutions:  # Finer
                # To save time only do two resolutions for the
                # large population set
                if filename.startswith('Population_2010'):
                    if resolution > 0.01 or resolution < 0.005:
                        break

                # Clip the raster to the bbox
                extra_keywords = {'resolution': native_resolution}
                raster_layer = QgsRasterLayer(raster_path, 'xxx')
                result = clip_layer(
                    raster_layer,
                    bounding_box,
                    resolution,
                    extra_keywords=extra_keywords
                )

                safe_layer = readSafeLayer(result.source())
                native_data = safe_layer.get_data(scaling=False)
                scaled_data = safe_layer.get_data(scaling=True)

                sigma_value = (safe_layer.get_resolution()[0] /
                               native_resolution[0]) ** 2

                # Compare extrema
                expected_scaled_max = sigma_value * numpy.nanmax(native_data)
                message = (
                    'Resampled raster was not rescaled correctly: '
                    'max(scaled_data) was %f but expected %f' %
                    (numpy.nanmax(scaled_data), expected_scaled_max))

                # FIXME (Ole): The rtol used to be 1.0e-8 -
                #              now it has to be 1.0e-6, otherwise we get
                #              max(scaled_data) was 12083021.000000 but
                #              expected 12083020.414316
                #              Is something being rounded to the nearest
                #              integer?
                assert numpy.allclose(expected_scaled_max,
                                      numpy.nanmax(scaled_data),
                                      rtol=1.0e-6, atol=1.0e-8), message

                expected_scaled_min = sigma_value * numpy.nanmin(native_data)
                message = (
                    'Resampled raster was not rescaled correctly: '
                    'min(scaled_data) was %f but expected %f' %
                    (numpy.nanmin(scaled_data), expected_scaled_min))
                assert numpy.allclose(expected_scaled_min,
                                      numpy.nanmin(scaled_data),
                                      rtol=1.0e-8, atol=1.0e-12), message

                # Compare element-wise
                message = 'Resampled raster was not rescaled correctly'
                assert nan_allclose(native_data * sigma_value, scaled_data,
                                    rtol=1.0e-8, atol=1.0e-8), message

                # Check that it also works with manual scaling
                manual_data = safe_layer.get_data(scaling=sigma_value)
                message = 'Resampled raster was not rescaled correctly'
                assert nan_allclose(manual_data, scaled_data,
                                    rtol=1.0e-8, atol=1.0e-8), message

                # Check that an exception is raised for bad arguments
                try:
                    safe_layer.get_data(scaling='bad')
                except GetDataError:
                    pass
                else:
                    message = 'String argument should have raised exception'
                    raise Exception(message)

                try:
                    safe_layer.get_data(scaling='(1, 3)')
                except GetDataError:
                    pass
                else:
                    message = 'Tuple argument should have raised exception'
                    raise Exception(message)

                # Check None option without keyword datatype == 'density'
                safe_layer.keywords['datatype'] = 'undefined'
                unscaled_data = safe_layer.get_data(scaling=None)
                message = 'Data should not have changed'
                assert nan_allclose(native_data, unscaled_data,
                                    rtol=1.0e-12, atol=1.0e-12), message

                # Try with None and density keyword
                safe_layer.keywords['datatype'] = 'density'
                unscaled_data = safe_layer.get_data(scaling=None)
                message = 'Resampled raster was not rescaled correctly'
                assert nan_allclose(scaled_data, unscaled_data,
                                    rtol=1.0e-12, atol=1.0e-12), message

                safe_layer.keywords['datatype'] = 'counts'
                unscaled_data = safe_layer.get_data(scaling=None)
                message = 'Data should not have changed'
                assert nan_allclose(native_data, unscaled_data,
                                    rtol=1.0e-12, atol=1.0e-12), message
Example #13
0
    def testRasterScaling(self):
        """Raster layers can be scaled when resampled

        This is a test for ticket #52

        Native test .asc data has

        Population_Jakarta_geographic.asc
        ncols         638
        nrows         649
        cellsize      0.00045228819716044

        Population_2010.asc
        ncols         5525
        nrows         2050
        cellsize      0.0083333333333333

        Scaling is necessary for raster data that represents density
        such as population per km^2
        """

        for myFilename in [
                'Population_Jakarta_geographic.asc', 'Population_2010.asc'
        ]:

            myRasterPath = ('%s/%s' % (TESTDATA, myFilename))

            # Get reference values
            mySafeLayer = readSafeLayer(myRasterPath)
            myMinimum, myMaximum = mySafeLayer.get_extrema()
            del myMaximum
            del myMinimum
            myNativeResolution = mySafeLayer.get_resolution()

            # Get the Hazard extents as an array in EPSG:4326
            myBoundingBox = mySafeLayer.get_bounding_box()

            # Test for a range of resolutions
            for myResolution in [
                    0.02,
                    0.01,
                    0.005,
                    0.002,
                    0.001,
                    0.0005,  # Coarser
                    0.0002
            ]:  # Finer

                # To save time only do two resolutions for the
                # large population set
                if myFilename.startswith('Population_2010'):
                    if myResolution > 0.01 or myResolution < 0.005:
                        break

                # Clip the raster to the bbox
                myExtraKeywords = {'resolution': myNativeResolution}
                myRasterLayer = QgsRasterLayer(myRasterPath, 'xxx')
                myResult = clipLayer(myRasterLayer,
                                     myBoundingBox,
                                     myResolution,
                                     theExtraKeywords=myExtraKeywords)

                mySafeLayer = readSafeLayer(myResult)
                myNativeData = mySafeLayer.get_data(scaling=False)
                myScaledData = mySafeLayer.get_data(scaling=True)

                mySigma = (mySafeLayer.get_resolution()[0] /
                           myNativeResolution[0])**2

                # Compare extrema
                myExpectedScaledMax = mySigma * numpy.nanmax(myNativeData)
                myMessage = ('Resampled raster was not rescaled correctly: '
                             'max(myScaledData) was %f but expected %f' %
                             (numpy.nanmax(myScaledData), myExpectedScaledMax))

                # FIXME (Ole): The rtol used to be 1.0e-8 -
                #              now it has to be 1.0e-6, otherwise we get
                #              max(myScaledData) was 12083021.000000 but
                #              expected 12083020.414316
                #              Is something being rounded to the nearest
                #              integer?
                assert numpy.allclose(myExpectedScaledMax,
                                      numpy.nanmax(myScaledData),
                                      rtol=1.0e-6,
                                      atol=1.0e-8), myMessage

                myExpectedScaledMin = mySigma * numpy.nanmin(myNativeData)
                myMessage = ('Resampled raster was not rescaled correctly: '
                             'min(myScaledData) was %f but expected %f' %
                             (numpy.nanmin(myScaledData), myExpectedScaledMin))
                assert numpy.allclose(myExpectedScaledMin,
                                      numpy.nanmin(myScaledData),
                                      rtol=1.0e-8,
                                      atol=1.0e-12), myMessage

                # Compare elementwise
                myMessage = 'Resampled raster was not rescaled correctly'
                assert nanallclose(myNativeData * mySigma,
                                   myScaledData,
                                   rtol=1.0e-8,
                                   atol=1.0e-8), myMessage

                # Check that it also works with manual scaling
                myManualData = mySafeLayer.get_data(scaling=mySigma)
                myMessage = 'Resampled raster was not rescaled correctly'
                assert nanallclose(myManualData,
                                   myScaledData,
                                   rtol=1.0e-8,
                                   atol=1.0e-8), myMessage

                # Check that an exception is raised for bad arguments
                try:
                    mySafeLayer.get_data(scaling='bad')
                except GetDataError:
                    pass
                else:
                    myMessage = 'String argument should have raised exception'
                    raise Exception(myMessage)

                try:
                    mySafeLayer.get_data(scaling='(1, 3)')
                except GetDataError:
                    pass
                else:
                    myMessage = 'Tuple argument should have raised exception'
                    raise Exception(myMessage)

                # Check None option without keyword datatype == 'density'
                mySafeLayer.keywords['datatype'] = 'undefined'
                myUnscaledData = mySafeLayer.get_data(scaling=None)
                myMessage = 'Data should not have changed'
                assert nanallclose(myNativeData,
                                   myUnscaledData,
                                   rtol=1.0e-12,
                                   atol=1.0e-12), myMessage

                # Try with None and density keyword
                mySafeLayer.keywords['datatype'] = 'density'
                myUnscaledData = mySafeLayer.get_data(scaling=None)
                myMessage = 'Resampled raster was not rescaled correctly'
                assert nanallclose(myScaledData,
                                   myUnscaledData,
                                   rtol=1.0e-12,
                                   atol=1.0e-12), myMessage

                mySafeLayer.keywords['datatype'] = 'counts'
                myUnscaledData = mySafeLayer.get_data(scaling=None)
                myMessage = 'Data should not have changed'
                assert nanallclose(myNativeData,
                                   myUnscaledData,
                                   rtol=1.0e-12,
                                   atol=1.0e-12), myMessage
Example #14
0
    def test_clipBoth(self):
        """Raster and Vector layers can be clipped
        """

        # Create a vector layer
        myName = 'padang'
        myVectorLayer = QgsVectorLayer(VECTOR_PATH, myName, 'ogr')
        myMessage = 'Did not find layer "%s" in path "%s"' % \
                    (myName, VECTOR_PATH)
        assert myVectorLayer.isValid(), myMessage

        # Create a raster layer
        myName = 'shake'
        myRasterLayer = QgsRasterLayer(RASTERPATH, myName)
        myMessage = 'Did not find layer "%s" in path "%s"' % \
                    (myName, RASTERPATH)
        assert myRasterLayer.isValid(), myMessage

        # Create a bounding box
        myViewportGeoExtent = [99.53, -1.22, 101.20, -0.36]

        # Get the Hazard extents as an array in EPSG:4326
        myHazardGeoExtent = [
            myRasterLayer.extent().xMinimum(),
            myRasterLayer.extent().yMinimum(),
            myRasterLayer.extent().xMaximum(),
            myRasterLayer.extent().yMaximum()
        ]

        # Get the Exposure extents as an array in EPSG:4326
        myExposureGeoExtent = [
            myVectorLayer.extent().xMinimum(),
            myVectorLayer.extent().yMinimum(),
            myVectorLayer.extent().xMaximum(),
            myVectorLayer.extent().yMaximum()
        ]

        # Now work out the optimal extent between the two layers and
        # the current view extent. The optimal extent is the intersection
        # between the two layers and the viewport.
        # Extent is returned as an array [xmin,ymin,xmax,ymax]
        myGeoExtent = getOptimalExtent(myHazardGeoExtent, myExposureGeoExtent,
                                       myViewportGeoExtent)

        # Clip the vector to the bbox
        myResult = clipLayer(myVectorLayer, myGeoExtent)

        # Check the output is valid
        assert os.path.exists(myResult)
        readSafeLayer(myResult)

        # Clip the raster to the bbox
        myResult = clipLayer(myRasterLayer, myGeoExtent)

        # Check the output is valid
        assert os.path.exists(myResult)
        readSafeLayer(myResult)

        # -------------------------------
        # Check the extra keywords option
        # -------------------------------
        # Clip the vector to the bbox
        myResult = clipLayer(myVectorLayer,
                             myGeoExtent,
                             theExtraKeywords={'kermit': 'piggy'})

        # Check the output is valid
        assert os.path.exists(myResult)
        L = readSafeLayer(myResult)
        kwds = L.get_keywords()
        myMessage = 'Extra keyword was not found in %s: %s' % (myResult, kwds)
        assert kwds['kermit'] == 'piggy'

        # Clip the raster to the bbox
        myResult = clipLayer(myRasterLayer,
                             myGeoExtent,
                             theExtraKeywords={'zoot': 'animal'})

        # Check the output is valid
        assert os.path.exists(myResult)
        L = readSafeLayer(myResult)
        kwds = L.get_keywords()

        myMessage = 'Extra keyword was not found in %s: %s' % (myResult, kwds)
        assert kwds['zoot'] == 'animal', myMessage
Example #15
0
    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 InsufficientOverlapError, e:
            myMessage = 'Did not find expected error message in %s' % str(e)
            assert 'did not overlap' in str(e), myMessage
Example #16
0
    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 InsufficientOverlapError, e:
            myMessage = 'Did not find expected error message in %s' % str(e)
            assert 'did not overlap' in str(e), myMessage
Example #17
0
    def test_clip_both(self):
        """Raster and Vector layers can be clipped."""

        # Create a vector layer
        layer_name = 'padang'
        vector_layer = QgsVectorLayer(VECTOR_PATH, layer_name, 'ogr')
        message = (
            'Did not find layer "%s" in path "%s"' % (layer_name, VECTOR_PATH))
        assert vector_layer.isValid(), message

        # Create a raster layer
        layer_name = 'shake'
        raster_layer = QgsRasterLayer(RASTERPATH, layer_name)
        message = (
            'Did not find layer "%s" in path "%s"' % (layer_name, RASTERPATH))
        assert raster_layer.isValid(), message

        # Create a bounding box
        view_port_geo_extent = [99.53, -1.22, 101.20, -0.36]

        # Get the Hazard extents as an array in EPSG:4326
        hazard_geo_extent = [
            raster_layer.extent().xMinimum(),
            raster_layer.extent().yMinimum(),
            raster_layer.extent().xMaximum(),
            raster_layer.extent().yMaximum()
        ]

        # Get the Exposure extents as an array in EPSG:4326
        exposure_geo_extent = [
            vector_layer.extent().xMinimum(),
            vector_layer.extent().yMinimum(),
            vector_layer.extent().xMaximum(),
            vector_layer.extent().yMaximum()
        ]

        # Now work out the optimal extent between the two layers and
        # the current view extent. The optimal extent is the intersection
        # between the two layers and the viewport.
        # Extent is returned as an array [xmin,ymin,xmax,ymax]
        geo_extent = getOptimalExtent(
            hazard_geo_extent, exposure_geo_extent, view_port_geo_extent)

        # Clip the vector to the bbox
        result = clip_layer(vector_layer, geo_extent)

        # Check the output is valid
        assert os.path.exists(result.source())
        readSafeLayer(result.source())

        # Clip the raster to the bbox
        result = clip_layer(raster_layer, geo_extent)

        # Check the output is valid
        assert os.path.exists(result.source())
        readSafeLayer(result.source())

        # -------------------------------
        # Check the extra keywords option
        # -------------------------------
        # Clip the vector to the bbox
        result = clip_layer(
            vector_layer, geo_extent, extra_keywords={'kermit': 'piggy'})

        # Check the output is valid
        assert os.path.exists(result.source())
        safe_layer = readSafeLayer(result.source())
        keywords = safe_layer.get_keywords()
        # message = 'Extra keyword was not found in %s: %s' % (myResult,
        # keywords)
        assert keywords['kermit'] == 'piggy'

        # Clip the raster to the bbox
        result = clip_layer(
            raster_layer, geo_extent, extra_keywords={'zoot': 'animal'})

        # Check the output is valid
        assert os.path.exists(result.source())
        safe_layer = readSafeLayer(result.source())
        keywords = safe_layer.get_keywords()

        message = ('Extra keyword was not found in %s: %s' %
                   (result.source(), keywords))
        assert keywords['zoot'] == 'animal', message