def populate(self): """ Compute value count using the objects value count parameters. """ # Update status self.status = self.COMPUTING self.save() try: # Compute aggregate result agg = Aggregator( layer_dict=self.layer_names, formula=self.formula, zoom=self.zoom, geom=self.aggregationarea.geom, acres=self.units.lower() == 'acres', grouping=self.grouping, ) aggregation_result = agg.value_count() self.stats_min, self.stats_max, self.stats_avg, self.stats_std = agg.statistics() # Track cumulative data to be able to generalize stats over # multiple aggregation areas. self.stats_cumsum_t0 = agg._stats_t0 self.stats_cumsum_t1 = agg._stats_t1 self.stats_cumsum_t2 = agg._stats_t2 # Convert values to string for storage in hstore self.value = {k: str(v) for k, v in aggregation_result.items()} self.status = self.FINISHED except: self.status = self.FAILED self.save()
def test_layer_with_no_tiles(self): agg = Aggregator(layer_dict={ 'a': self.rasterlayer.id, 'b': self.empty_rasterlayer.id }, formula='a*b') self.assertDictEqual(agg.value_count(), {})
def test_memory_efficient(self): agg = Aggregator( layer_dict={'a': self.rasterlayer.id}, formula='a', grouping='discrete', memory_efficient=True, ) self.assertDictEqual( agg.value_count(), {str(k): v for k, v in self.expected_totals.items()} ) agg = Aggregator( layer_dict={'a': self.rasterlayer.id}, formula='a', grouping='continuous', memory_efficient=True, hist_range=(0, 100), ) self.assertDictEqual( agg.value_count(), { '(10.0, 20.0)': 0, '(60.0, 70.0)': 0, '(40.0, 50.0)': 0, '(90.0, 100.0)': 0, '(70.0, 80.0)': 0, '(50.0, 60.0)': 0, '(30.0, 40.0)': 0, '(20.0, 30.0)': 0, '(0.0, 10.0)': 62440, '(80.0, 90.0)': 0 }, )
def value_count(self, geom=None, area=False, zoom=None): """ Compute value counts or histograms for rasterlayers within a geometry. """ from raster.valuecount import Aggregator agg = Aggregator(layer_dict={'a': self.id}, formula='a', zoom=zoom, geom=geom, acres=area) return agg.value_count()
def test_layer_discrete_grouping(self): agg = Aggregator(layer_dict={'a': self.rasterlayer.id}, formula='a', grouping='discrete') self.assertDictEqual( agg.value_count(), {str(k): v for k, v in self.expected_totals.items()})
def test_layer_with_json_grouping(self): # Use a legend with simple int expression agg = Aggregator(layer_dict={'a': self.rasterlayer.id}, formula='a', grouping=self.legend.json) self.assertDictEqual(agg.value_count(), { '2': self.expected_totals[2], '10': 0 })
def test_layer_continuous_grouping(self): agg = Aggregator( layer_dict={'a': self.rasterlayer.id}, formula='a', grouping='continuous' ) self.assertDictEqual( agg.value_count(), self.continuous_expected_histogram )
def test_memory_efficient_error(self): msg = 'Secify a histogram range for memory efficient continuous aggregation.' with self.assertRaisesMessage(RasterAggregationException, msg): agg = Aggregator( layer_dict={'a': self.rasterlayer.id}, formula='a', grouping='continuous', memory_efficient=True, ) agg.value_count()
def test_layer_discrete_grouping(self): agg = Aggregator( layer_dict={'a': self.rasterlayer.id}, formula='a', grouping='discrete' ) self.assertDictEqual( agg.value_count(), {str(k): v for k, v in self.expected_totals.items()} )
def test_layer_with_json_grouping(self): # Use a legend with simple int expression agg = Aggregator( layer_dict={'a': self.rasterlayer.id}, formula='a', grouping=self.legend.json ) self.assertDictEqual( agg.value_count(), {'2': self.expected_totals[2]} )
def test_layer_stats(self): # Use a legend with simple int expression agg = Aggregator( layer_dict={'a': self.rasterlayer.id}, formula='a', ) # Get original band metadata meta = self.rasterlayer.rasterlayerbandmetadata_set.first() # The comparison here is loose, as one is computed on tiles and the other # other value are the original band values. So there are differences from # rescaling. for dat in zip(agg.statistics(), meta.statistics()): self.assertAlmostEqual(dat[0], dat[1], 1)
def test_full_mask_data(self): # Override all tiles to be fully masked. for tile in self.rasterlayer.rastertile_set.all(): tile.rast.bands[0].data([0], shape=(1, 1)) tile.rast.bands[0].nodata_value = 0 tile.save() # Use a legend with simple int expression agg = Aggregator( layer_dict={'a': self.rasterlayer.id}, formula='a', ) self.assertEqual((None, None, None, None), agg.statistics())
def test_histogram_range(self): agg = Aggregator( layer_dict={'a': self.rasterlayer.id}, formula='a', grouping='continuous', hist_range=(0, 100) ) self.assertDictEqual( agg.value_count(), { '(0.0, 10.0)': 62440, '(20.0, 30.0)': 0, '(70.0, 80.0)': 0, '(80.0, 90.0)': 0, '(30.0, 40.0)': 0, '(10.0, 20.0)': 0, '(90.0, 100.0)': 0, '(60.0, 70.0)': 0, '(50.0, 60.0)': 0, '(40.0, 50.0)': 0, } )
def test_histogram_range(self): agg = Aggregator(layer_dict={'a': self.rasterlayer.id}, formula='a', grouping='continuous', hist_range=(0, 100)) self.assertDictEqual( agg.value_count(), { '(0.0, 10.0)': 62440, '(20.0, 30.0)': 0, '(70.0, 80.0)': 0, '(80.0, 90.0)': 0, '(30.0, 40.0)': 0, '(10.0, 20.0)': 0, '(90.0, 100.0)': 0, '(60.0, 70.0)': 0, '(50.0, 60.0)': 0, '(40.0, 50.0)': 0, })
def test_valuecount_exception(self): # Invalid input type msg = 'Invalid grouping value found for valuecount.' with self.assertRaisesMessage(RasterAggregationException, msg): agg = Aggregator( layer_dict={'a': self.rasterlayer.id}, formula='a', grouping='unknown' ) agg.value_count() # Invalid legend ID msg = 'Invalid legend ID found in grouping value for valuecount.' with self.assertRaisesMessage(RasterAggregationException, msg): agg = Aggregator( layer_dict={'a': self.rasterlayer.id}, formula='a', grouping='99999' )
def test_layer_with_legend_grouping(self): # Use a legend with simple int expression agg = Aggregator( layer_dict={'a': self.rasterlayer.id}, formula='a', grouping=self.legend.id ) self.assertDictEqual( agg.value_count(), {'2': self.expected_totals[2]} ) # Use a legend with formula expression agg = Aggregator( layer_dict={'a': self.rasterlayer.id}, formula='a', grouping=self.legend_with_expression.id ) self.assertDictEqual( agg.value_count(), {'(x >= 2) & (x < 5)': self.expected_totals[2] + self.expected_totals[3] + self.expected_totals[4]} )
def test_layer_with_legend_grouping(self): # Use a legend with simple int expression agg = Aggregator( layer_dict={'a': self.rasterlayer.id}, formula='a', grouping=self.legend.id, ) self.assertDictEqual( agg.value_count(), { '2': self.expected_totals[2], '10': 0 }, ) # Use a legend with formula expression agg = Aggregator( layer_dict={'a': self.rasterlayer.id}, formula='a', grouping=self.legend_with_expression.id, ) self.assertDictEqual( agg.value_count(), { '(x >= 2) & (x < 5)': self.expected_totals[2] + self.expected_totals[3] + self.expected_totals[4] }, )
def test_valuecount_exception(self): # Invalid input type msg = 'Invalid grouping value found for valuecount.' with self.assertRaisesMessage(RasterAggregationException, msg): agg = Aggregator(layer_dict={'a': self.rasterlayer.id}, formula='a', grouping='unknown') agg.value_count() # Invalid legend ID msg = 'Invalid legend ID found in grouping value for valuecount.' with self.assertRaisesMessage(RasterAggregationException, msg): agg = Aggregator(layer_dict={'a': self.rasterlayer.id}, formula='a', grouping='99999')
def test_histogram_range(self): agg = Aggregator( layer_dict={'a': self.rasterlayer.id}, formula='a', grouping='continuous', hist_range=(0, 100) ) self.assertDictEqual( agg.value_count(), { '(0.0, 10.0)': 62440, '(20.0, 30.0)': 0, '(70.0, 80.0)': 0, '(80.0, 90.0)': 0, '(30.0, 40.0)': 0, '(10.0, 20.0)': 0, '(90.0, 100.0)': 0, '(60.0, 70.0)': 0, '(50.0, 60.0)': 0, '(40.0, 50.0)': 0, } ) # Limit histogram range. agg = Aggregator( layer_dict={'a': self.rasterlayer.id}, formula='a', grouping='continuous', hist_range=(0.5, 8) ) # Compute value count. vals = agg.value_count() self.assertDictEqual( vals, { '(0.5, 1.25)': 695, '(1.25, 2.0)': 0, '(2.0, 2.75)': 56, '(2.75, 3.5)': 4131, '(3.5, 4.25)': 31490, '(4.25, 5.0)': 0, '(5.0, 5.75)': 0, '(5.75, 6.5)': 0, '(6.5, 7.25)': 0, '(7.25, 8.0)': 1350 } ) # Statistics are clipped to range. self.assertEqual(agg._stats_min_value, 1) self.assertEqual(agg._stats_max_value, 8) self.assertEqual(agg._stats_t0, 37722) self.assertEqual(sum(vals.values()), agg._stats_t0) self.assertEqual(agg._stats_t1, 149960) self.assertEqual(agg._stats_t2, 628338)
def test_layer_with_no_tiles(self): agg = Aggregator( layer_dict={'a': self.rasterlayer.id, 'b': self.empty_rasterlayer.id}, formula='a*b' ) self.assertDictEqual(agg.value_count(), {})