예제 #1
0
    def test_raster_bbox(self):
        raster_io = RasterFileIO(
            uri=os.path.join(testfile_path, 'satellite_test_data',
                             'LC81070352015218LGN00_B5.TIF'))

        bbox = raster_io.get_bbox()
        self.assertEquals(bbox, [
            307366.7298195886, 3869968.931078481, 539974.1151507461,
            4107482.3190209507
        ])
예제 #2
0
    def __init__(self, calc=None, **kwargs):
        """
        Initialize a RasterMathProcess object.

        :param calc: A text representation of the calculation to make.
        :param kwargs: Other keyword arguments
        """
        self.calc = calc
        super(RasterMathProcess, self).__init__(**kwargs)
        if not self.output:
            self.output = RasterFileIO(name='result', uri=self.get_outpath())
예제 #3
0
    def test_raster_footprint(self):
        raster_io = RasterFileIO(
            uri=os.path.join(testfile_path, 'satellite_test_data',
                             'LC81070352015218LGN00_B5.TIF'))

        footprint = raster_io.get_footprint()
        self.assertEquals(footprint, [(354404.6484867488, 4107482.3190209507),
                                      (307366.7298195886, 3915415.660631991),
                                      (492936.19648358587, 3869968.931078481),
                                      (539974.1151507461, 4062035.5894674407),
                                      (354404.6484867488, 4107482.3190209507)])
예제 #4
0
    def test_validationInputsNoMax(self):
        """
        Test the GaiaProcess.validate() function - pass on no max input types
        """

        raster_io1 = RasterFileIO(uri='/fake/path1')
        raster_io2 = RasterFileIO(uri='/fake/path2')

        try:
            geo.RasterMathProcess(inputs=[raster_io1, raster_io2], calc='A+B')
        except geo.GaiaException:
            self.fail("Multiple inputs should have passed validation")
예제 #5
0
    def __init__(self, **kwargs):
        """
        Create a process to subset a raster by a vector polygon

        :param clip_io: IO object containing vector polygon data
        :param raster_io: IO object containing raster data
        :param kwargs:
        :return: SubsetProcess object
        """
        super(SubsetProcess, self).__init__(**kwargs)
        if not self.output:
            self.output = RasterFileIO(name='result', uri=self.get_outpath())
예제 #6
0
    def test_rastermath_add(self):
        """
        Test adding two rasters together
        """
        raster1_io = RasterFileIO(name='A',
                                  uri=os.path.join(testfile_path,
                                                   'globalairtemp.tif'))
        raster2_io = RasterFileIO(name='B',
                                  uri=os.path.join(testfile_path,
                                                   'globalprecip.tif'))
        calc = 'A + B'
        bands = [1, 1]

        process = geo.RasterMathProcess(inputs=[raster1_io, raster2_io],
                                        calc=calc,
                                        bands=bands)
        try:
            process.compute()
            self.assertTrue(os.path.exists(process.output.uri))
            oraster, raster1, raster2 = [
                x.read() for x in (process.output, raster1_io, raster2_io)
            ]
            # Output raster should be same dimensions as raster 1
            self.assertEquals((oraster.RasterXSize, oraster.RasterYSize),
                              (raster1.RasterXSize, raster1.RasterYSize))
            orb, r1b, r2b = [
                x.GetRasterBand(1) for x in (oraster, raster1, raster2)
            ]
            # Min value of output should be >= the max minimum of inputs
            self.assertGreaterEqual(
                orb.GetStatistics(False, True)[0],
                max(
                    r1b.GetStatistics(False, True)[0],
                    r2b.GetStatistics(False, True)[0]))

            # Max value of output >=  max(minimum)+min(maximum) of inputs
            self.assertGreaterEqual(
                orb.GetStatistics(False, True)[1],
                max(
                    r1b.GetStatistics(False, True)[0],
                    r2b.GetStatistics(False, True)[0]) + min(
                        r1b.GetStatistics(False, True)[1],
                        r2b.GetStatistics(False, True)[1]))
        finally:
            if process:
                process.purge()
예제 #7
0
class SubsetProcess(GaiaProcess):
    """
    Generates a raster dataset representing the portion of the input raster
    dataset that is contained within a vector polygon.
    """
    #: Tuple of required inputs; name, type , max # of each; None = no max
    required_inputs = [
        {'description': 'Image to subset',
         'type': types.RASTER,
         'max': 1
         },
        {'description': 'Subset area:',
         'type': types.VECTOR,
         'max': 1
         }
    ]

    #: Default output format for the process
    default_output = formats.RASTER

    def __init__(self, **kwargs):
        """
        Create a process to subset a raster by a vector polygon

        :param clip_io: IO object containing vector polygon data
        :param raster_io: IO object containing raster data
        :param kwargs:
        :return: SubsetProcess object
        """
        super(SubsetProcess, self).__init__(**kwargs)
        if not self.output:
            self.output = RasterFileIO(name='result', uri=self.get_outpath())

    def compute(self):
        """
        Runs the subset computation, creating a raster dataset as output.
        """
        raster, clip = self.inputs[0], self.inputs[1]
        raster_img = raster.read()
        clip_df = clip.read(epsg=raster.get_epsg())
        # Merge all features in vector input
        raster_output = self.output.uri
        self.output.create_output_dir(raster_output)
        clip_json = clip_df.geometry.unary_union.__geo_interface__
        self.output.data = gdal_clip(raster_img, raster_output, clip_json)
예제 #8
0
    def test_validationInputsOrder(self):
        """
        Test the GaiaProcess.validate() function - fail on incorrect order
        """
        raster_iO = RasterFileIO(uri='/fake/path1')
        vector_io = VectorFileIO(uri='/fake/path2')

        with self.assertRaises(geo.GaiaException) as ge:
            geo.ZonalStatsProcess(inputs=[vector_io, raster_iO])
        self.assertIn('Input #1 is of incorrect type.', str(ge.exception))
예제 #9
0
 def test_validationInputsPass(self):
     """
     Test the GaiaProcess.validate() function - pass on valid input
     """
     raster_io = RasterFileIO(uri='/fake/path')
     vector_io = VectorFileIO(uri='/fake/path')
     try:
         geo.ZonalStatsProcess(inputs=[raster_io, vector_io])
     except geo.GaiaException:
         self.fail("ZonalProcess should have passed validation but did not")
예제 #10
0
    def __init__(self, **kwargs):
        """
        Create a process to merge rasters.

        :param inputs: Images to merge.
        :param kwargs: Other keyword arguments.
        :return: MergeProcess object
        """
        super(MergeProcess, self).__init__(**kwargs)
        if not self.output:
            self.output = RasterFileIO(name='result', uri=self.get_outpath())
예제 #11
0
 def test_zonalstats(self):
     vector_io = FeatureIO(features=[{
         "type": "Feature",
         "geometry": {
             "type":
             "Polygon",
             "coordinates": [[[100.0, 0.0], [120.0, 0.0], [120.0, 30.0],
                              [100.0, 30.0], [100.0, 0.0]]]
         },
         "properties": {
             "prop0": "value1",
             "prop1": {
                 "this": "that"
             }
         }
     }, {
         "type": "Feature",
         "geometry": {
             "type":
             "Polygon",
             "coordinates": [[[-100.0, 0.0], [-120.0, 0.0], [-120.0, -30.0],
                              [100.0, -30.0], [100.0, 0.0]]]
         },
         "properties": {
             "prop0": "value0",
             "prop1": {
                 "this": "other thing"
             }
         }
     }])
     raster_io = RasterFileIO(name='temp',
                              uri=os.path.join(testfile_path,
                                               'globalairtemp.tif'))
     process = geo.ZonalStatsProcess(inputs=[raster_io, vector_io])
     try:
         process.compute()
         with open(
                 os.path.join(testfile_path,
                              'zonalstats_process_results.json')) as exp:
             expected_json = json.load(exp)
         actual_json = json.loads(
             process.output.read(format=geo.formats.JSON))
         self.assertEquals(len(expected_json['features']),
                           len(actual_json['features']))
     finally:
         pass
         if process:
             process.purge()
예제 #12
0
    def test_rastermath_multiply_by_value(self):
        """
        Test multiplying a raster by a value,
        and specifying output type (Float32)
        """
        raster1_io = RasterFileIO(name='A',
                                  uri=os.path.join(testfile_path,
                                                   'globalprecip.tif'))
        calc = 'A * 2'
        output_type = 'Float32'

        process = geo.RasterMathProcess(inputs=[
            raster1_io,
        ],
                                        calc=calc,
                                        output_type=output_type)
        try:
            process.compute()
            self.assertTrue(os.path.exists(process.output.uri))
            oraster, raster1 = [x.read() for x in (process.output, raster1_io)]
            # Output raster should be same dimensions as raster 1
            self.assertEquals((oraster.RasterXSize, oraster.RasterYSize),
                              (raster1.RasterXSize, raster1.RasterYSize))
            orb, r1b = [x.GetRasterBand(1) for x in (oraster, raster1)]
            # Maximum value of output should be 2x the max of input raster
            self.assertEqual(
                orb.GetStatistics(False, True)[1],
                r1b.GetStatistics(False, True)[1] * 2)
            # Datatype of band should be Float32 (== gdal.GDT_Float32 == 6)
            self.assertEquals(6, orb.DataType)
            self.assertEquals(1.175494351E-38, orb.GetNoDataValue())

            # Each pixel of output raster should equal 2x input raster
            # unless it is a nodata value
            ora, r1a = [x.ReadAsArray() for x in (orb, r1b)]
            for x in range(raster1.RasterXSize):
                for y in range(raster1.RasterYSize):
                    if r1a[y, x] != r1b.GetNoDataValue():
                        self.assertEquals(ora[y, x], r1a[y, x] * 2)
        finally:
            if process:
                process.purge()
예제 #13
0
    def test_rastermath_logical_operators(self):
        """
        Test creation of a masked raster based on logical operators
        """
        raster1_io = RasterFileIO(name='A',
                                  uri=os.path.join(testfile_path,
                                                   'globalairtemp.tif'))
        calc = 'logical_or(logical_and(A >= 27000, A <= 28000), ' \
               'logical_and(A >= 30000, A <= 31000))'

        process = geo.RasterMathProcess(inputs=[
            raster1_io,
        ], calc=calc)
        try:
            process.compute()
            self.assertTrue(os.path.exists(process.output.uri))
            oraster, raster1 = [x.read() for x in (process.output, raster1_io)]
            # Output raster should be same dimensions as raster 1
            self.assertEquals((oraster.RasterXSize, oraster.RasterYSize),
                              (raster1.RasterXSize, raster1.RasterYSize))
            orb, r1b = [x.GetRasterBand(1) for x in (oraster, raster1)]
            # Maximum value of output should be 1
            self.assertEqual(orb.GetStatistics(False, True)[1], 1)
            # Minimum value of output should be 0
            self.assertEqual(orb.GetStatistics(False, True)[0], 0)
            # Pixels should be 1 where source is between 27K-28K or 30-31K
            ora, r1a = [x.ReadAsArray() for x in (orb, r1b)]
            self.assertTrue(ora[90, 10] == 1 and r1a[90, 10] == 30083)
            self.assertTrue(ora[160, 10] == 1 and r1a[160, 10] == 27074)
            # Pixels should be 0 where source is not between 27K-28K or 30-31K
            ora, r1a = [x.ReadAsArray() for x in (orb, r1b)]
            self.assertTrue(ora[120, 10] == 0 and r1a[120, 10] == 29623)
            self.assertTrue(ora[175, 10] == 0 and r1a[175, 10] == 23928)
        finally:
            if process:
                process.purge()
예제 #14
0
    def test_subset_raster(self):
        """
        Test SubsetProcess for vector & raster inputs
        """
        zipfile = ZipFile(os.path.join(testfile_path, '2states.zip'), 'r')
        zipfile.extract('2states.geojson', testfile_path)

        vector_io = VectorFileIO(
            uri=os.path.join(testfile_path, '2states.geojson'))
        raster_io = RasterFileIO(
            uri=os.path.join(testfile_path, 'globalairtemp.tif'))
        process = geo.SubsetProcess(inputs=[raster_io, vector_io])
        try:
            process.compute()
            self.assertEquals(type(process.output.data).__name__, 'Dataset')
            self.assertTrue(os.path.exists(process.output.uri))
            self.assertIsNotNone(process.id)
            self.assertIn(process.id, process.output.uri)
        finally:
            testfile = os.path.join(testfile_path, '2states.geojson')
            if os.path.exists(testfile):
                os.remove(testfile)
            if process:
                process.purge()
예제 #15
0
class RasterMathProcess(GaiaProcess):
    """
    Performs raster math/algebra based on supplied arguments.
    Inputs should consist of at least one raster IO object.
    Required arg is 'calc', an equation for the input rasters.
    Example: "A + B / (C * 2.4)".  The letters in the equation
    should correspond to the names of the inputs.
    """
    #: Tuple of required inputs; name, type , max # of each; None = no max
    required_inputs = [{
        'description': 'Image',
        'type': types.RASTER,
        'max': None
    }]
    #: Required arguments for the process
    required_args = [{
        'name': 'calc',
        'title': 'Calculation',
        'description': 'Equation to apply to rasters (ex: "(A+B)/2"',
        'type': str
    }]
    #: Default output format for the process
    default_output = formats.RASTER

    #: Default input raster bands to process
    bands = None
    #: Default NODATA value for raster input
    nodata = None
    #: Use all bands in raster input (default: False)
    all_bands = False
    #: Default data type for raster (UInt32, Float, etc)
    output_type = None
    #: Image output format (default='GTiff')
    output_format = 'GTiff'

    def __init__(self, calc=None, **kwargs):
        """
        Initialize a RasterMathProcess object.

        :param calc: A text representation of the calculation to make.
        :param kwargs: Other keyword arguments
        """
        self.calc = calc
        super(RasterMathProcess, self).__init__(**kwargs)
        if not self.output:
            self.output = RasterFileIO(name='result', uri=self.get_outpath())

    def compute(self):
        """
        Run the RasterMath process, generating a raster output dataset.
        """
        first = self.inputs[0]
        epsg = first.get_epsg()
        rasters = [x.read(epsg=epsg) for x in self.inputs]
        bands = self.bands
        nodata = self.nodata
        all_bands = self.all_bands
        otype = self.output_type
        self.output.create_output_dir(self.output.uri)
        self.output.data = gdal_calc(self.calc,
                                     self.output.uri,
                                     rasters,
                                     bands=bands,
                                     nodata=nodata,
                                     allBands=all_bands,
                                     output_type=otype,
                                     format=self.output_format)