def search_tree_benefits(request, instance): filter_str = request.REQUEST.get('q', '') hide_summary_text = request.REQUEST.get('hide_summary', 'false') hide_summary = hide_summary_text.lower() == 'true' filter = Filter(filter_str, instance) total_plots = filter.get_object_count(Plot) benefits, basis = get_benefits_for_filter(filter) # Inject the plot count as a basis for tree benefit calcs basis.get('plot', {})['n_plots'] = total_plots formatted = _format_benefits(instance, benefits, basis) formatted['hide_summary'] = hide_summary return formatted
def search_tree_benefits(request, instance): filter_str = request.REQUEST.get('q', '') display_str = request.REQUEST.get('show', '') hide_summary_text = request.REQUEST.get('hide_summary', 'false') hide_summary = hide_summary_text.lower() == 'true' filter = Filter(filter_str, display_str, instance) total_plots = get_cached_plot_count( filter, lambda: filter.get_object_count(Plot)) benefits, basis = get_benefits_for_filter(filter) # Inject the plot count as a basis for tree benefit calcs basis.get('plot', {})['n_plots'] = total_plots # We also want to inject the total currency amount saved # for plot-based items except CO2 stored total_currency_saved = 0 for benefit_name, benefit in benefits.get('plot', {}).iteritems(): if benefit_name != BenefitCategory.CO2STORAGE: currency = benefit.get('currency', 0.0) if currency: total_currency_saved += currency # save it as if it were a normal benefit so we get formatting # and currency conversion benefits.get('plot', {})['totals'] = { 'value': None, 'currency': total_currency_saved, 'label': _('Total annual benefits') } formatted = format_benefits(instance, benefits, basis, digits=0) formatted['hide_summary'] = hide_summary formatted['tree_count_label'] = ( 'tree,' if basis['plot']['n_total'] == 1 else 'trees,') formatted['plot_count_label'] = ( 'planting site' if basis['plot']['n_plots'] == 1 else 'planting sites') if instance.has_resources and 'resource' in basis: formatted['plot_count_label'] += ',' return formatted
def search_tree_benefits(request, instance): filter_str = request.REQUEST.get('q', '') display_str = request.REQUEST.get('show', '') hide_summary_text = request.REQUEST.get('hide_summary', 'false') hide_summary = hide_summary_text.lower() == 'true' filter = Filter(filter_str, display_str, instance) total_plots = filter.get_object_count(Plot) benefits, basis = get_benefits_for_filter(filter) # Inject the plot count as a basis for tree benefit calcs basis.get('plot', {})['n_plots'] = total_plots # We also want to inject the total currency amount saved # for plot-based items except CO2 stored total_currency_saved = 0 for benefit_name, benefit in benefits.get('plot', {}).iteritems(): if benefit_name != BenefitCategory.CO2STORAGE: currency = benefit.get('currency', 0.0) if currency: total_currency_saved += currency # save it as if it were a normal benefit so we get formatting # and currency conversion benefits.get('plot', {})['totals'] = { 'value': None, 'currency': total_currency_saved, 'label': trans('Total annual benefits') } formatted = format_benefits(instance, benefits, basis) formatted['hide_summary'] = hide_summary formatted['tree_count_label'] = ( 'tree,' if basis['plot']['n_total'] == 1 else 'trees,') formatted['plot_count_label'] = ( 'planting site' if basis['plot']['n_plots'] == 1 else 'planting sites') if instance.supports_resources and 'resource' in benefits: formatted['plot_count_label'] += ',' return formatted
def search_tree_benefits(request, instance): filter_str = request.REQUEST.get("q", "") display_str = request.REQUEST.get("show", "") hide_summary_text = request.REQUEST.get("hide_summary", "false") hide_summary = hide_summary_text.lower() == "true" filter = Filter(filter_str, display_str, instance) total_plots = filter.get_object_count(Plot) benefits, basis = get_benefits_for_filter(filter) # Inject the plot count as a basis for tree benefit calcs basis.get("plot", {})["n_plots"] = total_plots # We also want to inject the total currency amount saved # for plot-based items except CO2 stored total_currency_saved = 0 for benefit_name, benefit in benefits.get("plot", {}).iteritems(): if benefit_name != "co2storage": currency = benefit.get("currency", 0.0) if currency: total_currency_saved += currency # save it as if it were a normal benefit so we get formatting # and currency conversion benefits.get("plot", {})["totals"] = { "value": None, "currency": total_currency_saved, "label": trans("Total annual benefits"), } formatted = format_benefits(instance, benefits, basis) formatted["hide_summary"] = hide_summary formatted["tree_count_label"] = "tree," if basis["plot"]["n_total"] == 1 else "trees," formatted["plot_count_label"] = "planting site" if basis["plot"]["n_plots"] == 1 else "planting sites" if instance.supports_resources and "resource" in benefits: formatted["plot_count_label"] += "," return formatted
def test_all_ecobenefits(self): p = self._center_as_3857() plot = Plot(geom=p, instance=self.instance) plot.save_with_user(self.user) tree = Tree(plot=plot, instance=self.instance, readonly=False, species=self.species, diameter=1630) tree.save_with_user(self.user) p.x += 1.1 p.y += 1.1 box = self._box_around_point(p) bioswale = Bioswale(instance=self.instance, geom=p, polygon=box, feature_type='Bioswale', drainage_area=100.0) bioswale.save_with_user(self.user) filter = Filter('', '', self.instance) benefits, basis = get_benefits_for_filter(filter) self.assertIn('plot', benefits) plot_benefits = benefits['plot'] plot_categories = set(plot_benefits.keys()) self.assertSetEqual(plot_categories, set(BenefitCategory.GROUPS)) plot_currencies = { cat: benefit.get('currency', None) for cat, benefit in plot_benefits.items() } self.assertIsNotNone(min(plot_currencies.values())) expected_total_currency = sum( [benefit['currency'] for benefit in plot_benefits.values()]) - \ plot_benefits[BenefitCategory.CO2STORAGE]['currency'] + \ benefits['resource'][BenefitCategory.STORMWATER]['currency'] formatted = format_benefits(self.instance, benefits, basis, digits=0) self.assertAlmostEqual(formatted['benefits_total_currency'], expected_total_currency, 3)
def search_tree_benefits(request, instance): filter_str = request.GET.get('q', '') display_str = request.GET.get('show', '') hide_summary_text = request.GET.get('hide_summary', 'false') hide_summary = hide_summary_text.lower() == 'true' filter = Filter(filter_str, display_str, instance) total_plots = get_cached_plot_count(filter) benefits, basis = get_benefits_for_filter(filter) # Inject the plot count as a basis for tree benefit calcs basis.get('plot', {})['n_plots'] = total_plots formatted = format_benefits(instance, benefits, basis, digits=0) n_trees = basis['plot']['n_total'] n_plots = basis['plot']['n_plots'] n_empty_plots = n_plots - n_trees n_resources = 0 tree_count_label = ungettext('tree', 'trees', n_trees) + ',' empty_plot_count_label = ungettext( 'empty planting site', 'empty planting sites', n_empty_plots) has_resources = instance.has_resources and 'resource' in basis if has_resources: n_resources = basis['resource']['n_total'] empty_plot_count_label += ',' context = { 'n_trees': n_trees, 'n_empty_plots': n_empty_plots, 'n_resources': n_resources, 'tree_count_label': tree_count_label, 'empty_plot_count_label': empty_plot_count_label, 'has_resources': has_resources, 'hide_summary': hide_summary, 'single_result': _single_result_context(instance, n_plots, n_resources, filter) } context.update(formatted) return context
def test_bulk_partial_drainage_known(self): drainage_area_sq_meters = 100000000.0 # NOTE # Today, no check is made for overlapping stormwater resources. # In the future, either overlap should be invalid, # or the intersection should only be counted once in the total area. self._make_map_feature(Bioswale, drainage_area=drainage_area_sq_meters) self._make_map_feature(Bioswale, geom=self._make_point(-75.5, 39), polygon=self._make_square_polygon(-75.5, 39)) benefits, basis = Bioswale.benefits.benefits_for_filter( self.instance, Filter('', '', self.instance)) runoff_reduced = benefits['resource']['stormwater']['value'] self.assert_basis(basis, 1, 1) self._assert_runoff_reduced(self.polygon_area_sq_meters, drainage_area_sq_meters, .5, runoff_reduced)
def test_resource_ecobenefits(self): p = self._center_as_3857() box = self._box_around_point(p) bioswale = Bioswale(instance=self.instance, geom=p, polygon=box, feature_type='Bioswale', drainage_area=100.0) bioswale.save_with_user(self.user) filter = Filter('', '', self.instance) benefits, __ = get_benefits_for_filter(filter) self.assertIn('resource', benefits) resource_benefits = benefits['resource'] self.assertIn(BenefitCategory.STORMWATER, resource_benefits) stormwater = resource_benefits[BenefitCategory.STORMWATER] self.assertTrue(isinstance(stormwater['value'], float)) self.assertGreater(stormwater['value'], 0.0) self.assertTrue(isinstance(stormwater['currency'], float)) self.assertEqual(stormwater['value'], stormwater['currency'])
def setUp(self): self.instance = make_instance() self.user = make_commander_user(self.instance) self.benefits = 'some benefits' self.filter = Filter('', '', self.instance)
def plot_count(self): from treemap.ecocache import get_cached_plot_count from treemap.search import Filter all_plots_filter = Filter('', '', self) return get_cached_plot_count(all_plots_filter)
def async_csv_export(job, model, query, display_filters): instance = job.instance if model == 'species': initial_qs = (Species.objects.filter(instance=instance)) extra_select, values = extra_select_and_values_for_model( instance, job, 'treemap_species', 'Species') ordered_fields = values + extra_select.keys() limited_qs = initial_qs.extra(select=extra_select)\ .values(*ordered_fields) else: # model == 'tree' # TODO: if an anonymous job with the given query has been # done since the last update to the audit records table, # just return that job # get the plots for the provided # query and turn them into a tree queryset initial_qs = Filter(query, display_filters, instance)\ .get_objects(Tree) extra_select_tree, values_tree = extra_select_and_values_for_model( instance, job, 'treemap_tree', 'Tree') extra_select_plot, values_plot = extra_select_and_values_for_model( instance, job, 'treemap_mapfeature', 'Plot', prefix='plot') extra_select_sp, values_sp = extra_select_and_values_for_model( instance, job, 'treemap_species', 'Species', prefix='species') if 'plot__geom' in values_plot: values_plot = [f for f in values_plot if f != 'plot__geom'] values_plot += ['plot__geom__x', 'plot__geom__y'] get_ll = 'ST_Transform(treemap_mapfeature.the_geom_webmercator, 4326)' extra_select = { 'plot__geom__x': 'ST_X(%s)' % get_ll, 'plot__geom__y': 'ST_Y(%s)' % get_ll } extra_select.update(extra_select_tree) extra_select.update(extra_select_plot) extra_select.update(extra_select_sp) ordered_fields = (sorted(values_tree) + sorted(values_plot) + sorted(values_sp)) if ordered_fields: limited_qs = initial_qs.extra(select=extra_select)\ .values(*ordered_fields) else: limited_qs = initial_qs.none() if not initial_qs.exists(): job.status = ExportJob.EMPTY_QUERYSET_ERROR # if the initial queryset was not empty but the limited queryset # is empty, it means that there were no fields which the user # was allowed to export. elif not limited_qs.exists(): job.status = ExportJob.MODEL_PERMISSION_ERROR else: csv_file = TemporaryFile() write_csv(limited_qs, csv_file, field_order=ordered_fields) job.complete_with(generate_filename(limited_qs), File(csv_file)) job.save()
def async_csv_export(job, model, query, display_filters): instance = job.instance select = OrderedDict() select_params = [] field_header_map = {} field_serializer_map = {} if model == 'species': initial_qs = (Species.objects. filter(instance=instance)) values = _values_for_model(instance, job, 'treemap_species', 'Species', select, select_params) field_names = values + select.keys() limited_qs = (initial_qs .extra(select=select, select_params=select_params) .values(*field_names)) else: # model == 'tree' # TODO: if an anonymous job with the given query has been # done since the last update to the audit records table, # just return that job # get the plots for the provided # query and turn them into a tree queryset initial_qs = Filter(query, display_filters, instance)\ .get_objects(Plot) tree_fields = _values_for_model( instance, job, 'treemap_tree', 'Tree', select, select_params, prefix='tree') plot_fields = _values_for_model( instance, job, 'treemap_mapfeature', 'Plot', select, select_params) species_fields = _values_for_model( instance, job, 'treemap_species', 'Species', select, select_params, prefix='tree__species') if 'geom' in plot_fields: plot_fields = [f for f in plot_fields if f != 'geom'] plot_fields += ['geom__x', 'geom__y'] if tree_fields: select['tree_present'] = "treemap_tree.id is not null" plot_fields += ['tree_present'] get_ll = 'ST_Transform(treemap_mapfeature.the_geom_webmercator, 4326)' select['geom__x'] = 'ST_X(%s)' % get_ll select['geom__y'] = 'ST_Y(%s)' % get_ll plot_fields += ['updated_by__username'] field_names = set(tree_fields + plot_fields + species_fields) if field_names: field_header_map = _csv_field_header_map(field_names) field_serializer_map = _csv_field_serializer_map(instance, field_names) limited_qs = (initial_qs .extra(select=select, select_params=select_params) .values(*field_header_map.keys())) else: limited_qs = initial_qs.none() if not initial_qs.exists(): job.status = ExportJob.EMPTY_QUERYSET_ERROR # if the initial queryset was not empty but the limited queryset # is empty, it means that there were no fields which the user # was allowed to export. elif not limited_qs.exists(): job.status = ExportJob.MODEL_PERMISSION_ERROR else: csv_file = TemporaryFile() write_csv(limited_qs, csv_file, field_order=field_header_map.keys(), field_header_map=field_header_map, field_serializer_map=field_serializer_map) filename = generate_filename(limited_qs).replace('plot', 'tree') job.complete_with(filename, File(csv_file)) job.save()
def search_tree_benefits(request, instance): filter_str = request.REQUEST.get('q', '') display_str = request.REQUEST.get('show', '') hide_summary_text = request.REQUEST.get('hide_summary', 'false') hide_summary = hide_summary_text.lower() == 'true' filter = Filter(filter_str, display_str, instance) total_plots = get_cached_plot_count(filter) benefits, basis = get_benefits_for_filter(filter) # Inject the plot count as a basis for tree benefit calcs basis.get('plot', {})['n_plots'] = total_plots # We also want to inject the total currency amount saved # for plot-based items except CO2 stored total_currency_saved = 0 for benefit_name, benefit in benefits.get('plot', {}).iteritems(): if benefit_name != BenefitCategory.CO2STORAGE: currency = benefit.get('currency', 0.0) if currency: total_currency_saved += currency # save it as if it were a normal benefit so we get formatting # and currency conversion benefits.get('plot', {})['totals'] = { 'value': None, 'currency': total_currency_saved, 'label': _('Total annual benefits') } formatted = format_benefits(instance, benefits, basis, digits=0) n_trees = basis['plot']['n_total'] n_plots = basis['plot']['n_plots'] n_empty_plots = n_plots - n_trees n_resources = 0 tree_count_label = ungettext('tree', 'trees', n_trees) + ',' empty_plot_count_label = ungettext('empty planting site', 'empty planting sites', n_empty_plots) has_resources = instance.has_resources and 'resource' in basis if has_resources: n_resources = basis['resource']['n_total'] empty_plot_count_label += ',' context = { 'n_trees': n_trees, 'n_empty_plots': n_empty_plots, 'n_resources': n_resources, 'tree_count_label': tree_count_label, 'empty_plot_count_label': empty_plot_count_label, 'has_resources': has_resources, 'hide_summary': hide_summary, 'single_result': _single_result_context(instance, n_plots, n_resources, filter) } context.update(formatted) return context
def csv_export(job_pk, model, query, display_filters): job = ExportJob.objects.get(pk=job_pk) instance = job.instance if model == 'species': initial_qs = (Species.objects. filter(instance=instance)) extra_select, values = extra_select_and_values_for_model( instance, job, 'treemap_species', 'species') ordered_fields = values + extra_select.keys() limited_qs = initial_qs.extra(select=extra_select)\ .values(*ordered_fields) else: # model == 'tree' # TODO: if an anonymous job with the given query has been # done since the last update to the audit records table, # just return that job # get the plots for the provided # query and turn them into a tree queryset initial_qs = Filter(query, display_filters, instance)\ .get_objects(Tree) extra_select_tree, values_tree = extra_select_and_values_for_model( instance, job, 'treemap_tree', 'Tree') extra_select_plot, values_plot = extra_select_and_values_for_model( instance, job, 'treemap_mapfeature', 'Plot', prefix='plot') extra_select_sp, values_sp = extra_select_and_values_for_model( instance, job, 'treemap_species', 'Species', prefix='species') if 'plot__geom' in values_plot: values_plot = [f for f in values_plot if f != 'plot__geom'] values_plot += ['plot__geom__x', 'plot__geom__y'] extra_select = {'plot__geom__x': 'ST_X(treemap_mapfeature.the_geom_webmercator)', 'plot__geom__y': 'ST_Y(treemap_mapfeature.the_geom_webmercator)'} extra_select.update(extra_select_tree) extra_select.update(extra_select_plot) extra_select.update(extra_select_sp) ordered_fields = (sorted(values_tree) + sorted(values_plot) + sorted(values_sp)) if ordered_fields: limited_qs = initial_qs.extra(select=extra_select)\ .values(*ordered_fields) else: limited_qs = initial_qs.none() if not initial_qs.exists(): job.status = ExportJob.EMPTY_QUERYSET_ERROR # if the initial queryset was not empty but the limited queryset # is empty, it means that there were no fields which the user # was allowed to export. elif not limited_qs.exists(): job.status = ExportJob.MODEL_PERMISSION_ERROR else: csv_file = TemporaryFile() write_csv(limited_qs, csv_file, field_order=ordered_fields) csv_name = generate_filename(limited_qs) job.outfile.save(csv_name, File(csv_file)) job.status = ExportJob.COMPLETE job.save()
def async_csv_export(job, model, query, display_filters): instance = job.instance select = OrderedDict() select_params = [] field_header_map = {} if model == 'species': initial_qs = (Species.objects.filter(instance=instance)) values = _values_for_model(instance, job, 'treemap_species', 'Species', select, select_params) field_names = values + select.keys() limited_qs = (initial_qs.extra( select=select, select_params=select_params).values(*field_names)) else: # model == 'tree' # TODO: if an anonymous job with the given query has been # done since the last update to the audit records table, # just return that job # get the plots for the provided # query and turn them into a tree queryset initial_qs = Filter(query, display_filters, instance)\ .get_objects(Plot) tree_fields = _values_for_model(instance, job, 'treemap_tree', 'Tree', select, select_params, prefix='tree') plot_fields = _values_for_model(instance, job, 'treemap_mapfeature', 'Plot', select, select_params) species_fields = _values_for_model(instance, job, 'treemap_species', 'Species', select, select_params, prefix='tree__species') if 'geom' in plot_fields: plot_fields = [f for f in plot_fields if f != 'geom'] plot_fields += ['geom__x', 'geom__y'] if tree_fields: select['tree_present'] = "treemap_tree.id is not null" plot_fields += ['tree_present'] get_ll = 'ST_Transform(treemap_mapfeature.the_geom_webmercator, 4326)' select['geom__x'] = 'ST_X(%s)' % get_ll select['geom__y'] = 'ST_Y(%s)' % get_ll field_names = set(tree_fields + plot_fields + species_fields) if field_names: field_header_map = _csv_field_header_map(field_names) limited_qs = (initial_qs.extra( select=select, select_params=select_params).values(*field_header_map.keys())) else: limited_qs = initial_qs.none() if not initial_qs.exists(): job.status = ExportJob.EMPTY_QUERYSET_ERROR # if the initial queryset was not empty but the limited queryset # is empty, it means that there were no fields which the user # was allowed to export. elif not limited_qs.exists(): job.status = ExportJob.MODEL_PERMISSION_ERROR else: csv_file = TemporaryFile() write_csv(limited_qs, csv_file, field_order=field_header_map.keys(), field_header_map=field_header_map) filename = generate_filename(limited_qs).replace('plot', 'tree') job.complete_with(filename, File(csv_file)) job.save()
def async_csv_export(job, model, query, display_filters): instance = job.instance select = OrderedDict() select_params = [] if model == "species": initial_qs = Species.objects.filter(instance=instance) values = values_for_model(instance, job, "treemap_species", "Species", select, select_params) ordered_fields = values + select.keys() limited_qs = initial_qs.extra(select=select, select_params=select_params).values(*ordered_fields) else: # model == 'tree' # TODO: if an anonymous job with the given query has been # done since the last update to the audit records table, # just return that job # get the plots for the provided # query and turn them into a tree queryset initial_qs = Filter(query, display_filters, instance).get_objects(Tree) values_tree = values_for_model(instance, job, "treemap_tree", "Tree", select, select_params) values_plot = values_for_model( instance, job, "treemap_mapfeature", "Plot", select, select_params, prefix="plot" ) values_sp = values_for_model( instance, job, "treemap_species", "Species", select, select_params, prefix="species" ) if "plot__geom" in values_plot: values_plot = [f for f in values_plot if f != "plot__geom"] values_plot += ["plot__geom__x", "plot__geom__y"] get_ll = "ST_Transform(treemap_mapfeature.the_geom_webmercator, 4326)" select["plot__geom__x"] = "ST_X(%s)" % get_ll select["plot__geom__y"] = "ST_Y(%s)" % get_ll ordered_fields = sorted(values_tree) + sorted(values_plot) + sorted(values_sp) if ordered_fields: limited_qs = initial_qs.extra(select=select, select_params=select_params).values(*ordered_fields) else: limited_qs = initial_qs.none() if not initial_qs.exists(): job.status = ExportJob.EMPTY_QUERYSET_ERROR # if the initial queryset was not empty but the limited queryset # is empty, it means that there were no fields which the user # was allowed to export. elif not limited_qs.exists(): job.status = ExportJob.MODEL_PERMISSION_ERROR else: csv_file = TemporaryFile() write_csv(limited_qs, csv_file, field_order=ordered_fields) job.complete_with(generate_filename(limited_qs), File(csv_file)) job.save()