def add_filter(request, view_id): """ Respond to the "/add_filter/NNN/" URL. We let the user add a new filter to the given tableau view. """ if not request.user.is_authenticated: return HttpResponseRedirect(reverse(settings.ADMIN_HOME_VIEW)) try: view = TableauView.objects.get(id=view_id) except TableauView.DoesNotExist: return HttpResponseRedirect(reverse("location_editor.views.main")) # See what the user wants to do. if request.method == "POST": # The user is submitting the form. See what the user wants to do. if request.POST.get("cancel") != None: # The user clicked on the "Cancel" button -> redirect the user back # to the "Edit View" page for this view. return HttpResponseRedirect( reverse("tableau_editor.views.edit_view", args=[view.id])) # If we get here, the user wants to add a new view filter. type = request.POST.get("type") filter = TableauViewFilter() filter.tableauView = view if type == "cur_loc": filter.type = TableauViewFilter.TYPE_CUR_LOCATION filter.value = "" elif type == "level": filter.type = TableauViewFilter.TYPE_LEVEL filter.value = "" elif type == "location": filter.type = TableauViewFilter.TYPE_LOCATION filter.value = "" elif type == "parents": filter.type = TableauViewFilter.TYPE_RELATION filter.value = "parent" elif type == "children": filter.type = TableauViewFilter.TYPE_RELATION filter.value = "child" elif type == "neighbors": filter.type = TableauViewFilter.TYPE_RELATION filter.value = "neighbor" elif type == "peers": filter.type = TableauViewFilter.TYPE_RELATION filter.value = "peer" else: filter.type = TableauViewFilter.TYPE_LEVEL filter.value = "" filter.save() return HttpResponseRedirect( reverse("tableau_editor.views.edit_view", args=[view.id])) # If we get here, we're displaying the form for the first time -> do so. cur_loc = view.tableau.location menu_html = menus.generate(request, "Tableau Editor", "tableau_editor", "add_filter") return render_to_response("tableau_editor/templates/add_view_filter.html", {'menu_html' : menu_html, 'heading' : "Add Filter for Tableau View '" + view.name + "'", 'cur_loc' : cur_loc, }, context_instance=RequestContext(request))
def create_tableau(factory, location): """ Create a single tableau for a given location using a given factory. This function does the actual work of generating an individual tableau based upon the factory definition. It can be called directly to generate a desired tableau, or it can be called indirectly by the daemon (using the private 'create_tableau' API call) to generate tableaux en masse. Upon completion, we return None if the tableau-generation attempt was successful. Otherwise, we return a suitable error message explaining why the tableau could not be generated. """ # Get the location's outline. try: outline = Outline.objects.get(location=location) except Outline.DoesNotExist: # We can't create a tableau for a location without an outline -> # tell the user the bad news. return "Location has no outline." # Delete the existing tableau with this name, if any. Tableau.objects.filter(location=location, name=factory.tableau_name).delete() # Create the new Tableau for this location. tableau = Tableau() tableau.location = location tableau.name = factory.tableau_name tableau.meta_data = factory.tableau_meta_data tableau.bounds_render = factory.tableau_bounds_render tableau.save() # Create a single view for the tableau, covering the location's entire # extent. min_long,min_lat,max_long,max_lat = outline.outline.extent # Add a margin around the edges so that the location is easier to see. width = abs(max_long - min_long) height = abs(max_lat - min_lat) buffer = 0.02 * (width + height) / 2 min_long = min_long - buffer max_long = max_long + buffer min_lat = min_lat - buffer max_lat = max_lat + buffer # Ensure the calculated view bounds are allowable. if min_lat < MIN_ALLOWED_LATITUDE: min_lat = MIN_ALLOWED_LATITUDE elif min_lat > MAX_ALLOWED_LATITUDE: min_lat = MAX_ALLOWED_LATITUDE if max_lat < MIN_ALLOWED_LATITUDE: max_lat = MIN_ALLOWED_LATITUDE elif max_lat > MAX_ALLOWED_LATITUDE: max_lat = MAX_ALLOWED_LATITUDE if min_long < MIN_ALLOWED_LONGITUDE: min_long = MIN_ALLOWED_LONGITUDE elif min_long > MAX_ALLOWED_LONGITUDE: min_long = MAX_ALLOWED_LONGITUDE if max_long < MIN_ALLOWED_LONGITUDE: max_long = MIN_ALLOWED_LONGITUDE elif max_long > MAX_ALLOWED_LONGITUDE: max_long = MAX_ALLOWED_LONGITUDE # Create the view. view = TableauView() view.tableau = tableau view.ordinal_rank = 1 view.name = location.display_name view.min_lat = "%0.4f" % min_lat view.max_lat = "%0.4f" % max_lat view.min_long = "%0.4f" % min_long view.max_long = "%0.4f" % max_long view.meta_data = factory.view_meta_data view.bounds_render = factory.view_bounds_render view.save() # Add the factory's filter(s) to the tableau's view. for factory_filter in factory.tableaufactoryviewfilter_set.all(): filter = TableauViewFilter() filter.tableauView = view filter.type = factory_filter.filter_type filter.value = factory_filter.filter_value filter.meta_data = factory_filter.filter_meta_data filter.draw_bubbles = factory_filter.filter_draw_bubbles filter.polygon_render = factory_filter.filter_polygon_render filter.bubble_render = factory_filter.filter_bubble_render filter.save() # Calculate the aspect ratio for the tableau's view. proj = GlobalMercator() min_x,min_y = proj.LatLonToMeters(min_lat, min_long) max_x,max_y = proj.LatLonToMeters(max_lat, max_long) viewWidth = max_x - min_x viewHeight = max_y - min_y if viewWidth == 0: viewWidth = 1.0 if viewHeight == 0: viewHeight = 1.0 aspectRatio = viewWidth / viewHeight # Create a single layout for the tableau. The size of the layout is # based on the view's aspect ratio. layout_width = LAYOUT_MAX_WIDTH layout_height = layout_width / aspectRatio if layout_height > LAYOUT_MAX_HEIGHT: layout_height = LAYOUT_MAX_HEIGHT layout_width = layout_height * aspectRatio layout = TableauLayout() layout.tableau = tableau layout.width = layout_width layout.height = layout_height layout.save() # Create a single TableauLayoutViewPosition record, positioning the view # within the layout. position = TableauLayoutViewPosition() position.tableauLayout = layout position.tableauView = view position.min_x = 0 position.min_y = 0 position.max_x = layout_width position.max_y = layout_height position.save() # Finally, tell the caller that the tableau was successfully generated. return None