def add_view(request, tableau_id): """ Respond to the "/add_view/NNN/" URL. We let the user add a new view to the given tableau. """ if not request.user.is_authenticated: return HttpResponseRedirect(reverse(settings.ADMIN_HOME_VIEW)) try: tableau = Tableau.objects.get(id=tableau_id) except Tableau.DoesNotExist: return HttpResponseRedirect(reverse("location_editor.views.main")) # See what the user wants to do. if request.method == "GET": # We're displaying this form for the first time -> set up our default # values. name = "" err_msg = None elif request.method == "POST": # The user is submitting this 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 Tableau" page for this tableau. return HttpResponseRedirect( reverse("tableau_editor.views.edit_tableau", args=[tableau.id])) # If we get here, the user is attempting to add a new view. Check that # the entered name is valid. name = request.POST.get("name") err_msg = None # initially. if name == "": err_msg = "Please enter a name for this view." if TableauView.objects.filter(tableau=tableau, name=name).exists(): err_msg = "Sorry, there is already a view with that name " \ + "for this tableau." if err_msg == None: # The entered name is valid -> add the view. query = TableauView.objects.filter(tableau=tableau) rank = query.aggregate(Max("ordinal_rank"))['ordinal_rank__max'] if rank == None: rank = 1 else: rank = rank + 1 view = TableauView() view.tableau = tableau view.name = name view.ordinal_rank = rank view.min_lat = 0 view.max_lat = 0 view.min_long = 0 view.max_long = 0 view.save() # Return the user back to the main "Edit Tableau" page for this # tableau. return HttpResponseRedirect( reverse("tableau_editor.views.edit_tableau", args=[tableau.id])) # Finally, display our page. menu_html = menus.generate(request, "Tableau Editor", "tableau_editor", "add_view") return render_to_response("tableau_editor/templates/add_view.html", {'menu_html' : menu_html, 'heading' : "Add View for Tableau '" + tableau.name + "'", 'name' : name, 'err_msg' : err_msg, }, 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