def handle(self, shapefile, manipulator, *args, **options): try: manip_model = get_class(manipulator) except: raise Exception("The %s model could not be found. \nBe sure and provide the complete description: <module name>.models.<manipulator model name>" % manipulator) ds = DataSource(shapefile) if len(ds) != 1: raise Exception("Data source should only contain a single layer. Aborting.") layer = ds[0] if len(layer) != 1: raise Exception("Layer should containing ONLY a single feature") if not 'polygon' in layer.geom_type.name.lower(): print layer.geom_type.name raise Exception("This geometry must be a polygon") mapping = {'geometry': 'MULTIPOLYGON'} lm = LayerMapping(manip_model, shapefile, mapping) lm.save() manip_geom = manip_model.objects.order_by('-creation_date')[0] if options.get('region_name'): manip_geom.name = options.get('region_name') manip_geom.save() else: manip_geom.name = layer.name manip_geom.save() print "" print "The manipulaotr geometry, %s, has been added to the %s model with primary key = %s" % (manip_geom.name, manipulator, manip_geom.pk) print "To switch to this geometry, you will need to run 'manage.py change_manipulator_geom %s %s'" % (manip_geom.pk, manipulator) print ""
def get_form_class(self): """ Returns the form class for this Feature Class. """ try: klass = get_class(self.form) except Exception, e: raise FeatureConfigurationError( "Feature class %s is not configured with a valid form class. \ Could not import %s.\n%s" % (self._model.__name__, self.form, e))
def handle(self, pk, manipulator, **options): try: manip_model = get_class(manipulator) except: raise Exception("The %s model could not be found. \nBe sure and provide the complete description: <module name>.models.<manipulator model name>" % manipulator) # Turn them all off regions = manip_model.objects.all() for region in regions: region.active = False region.save() # Now active the single study region new_geom = manip_model.objects.get(pk=pk) new_geom.active = True new_geom.save() print "%s is now the active %s manipulator" % (new_geom, manipulator)
def get_valid_children(self): if not self.valid_children: raise FeatureConfigurationError( "%r is not a properly configured FeatureCollection" % (self._model)) valid_child_classes = [] for vc in self.valid_children: try: vc_class = get_class(vc) except: raise FeatureConfigurationError( "Error trying to import module %s" % vc) from madrona.features.models import Feature if not issubclass(vc_class, Feature): raise FeatureConfigurationError( "%r is not a Feature; can't be a child" % vc) valid_child_classes.append(vc_class) return valid_child_classes
def handle(self, shapefile, manipulator, *args, **options): try: manip_model = get_class(manipulator) except: raise Exception( "The %s model could not be found. \nBe sure and provide the complete description: <module name>.models.<manipulator model name>" % manipulator) ds = DataSource(shapefile) if len(ds) != 1: raise Exception( "Data source should only contain a single layer. Aborting.") layer = ds[0] if len(layer) != 1: raise Exception("Layer should containing ONLY a single feature") if not 'polygon' in layer.geom_type.name.lower(): print layer.geom_type.name raise Exception("This geometry must be a polygon") mapping = {'geometry': 'MULTIPOLYGON'} lm = LayerMapping(manip_model, shapefile, mapping) lm.save() manip_geom = manip_model.objects.order_by('-creation_date')[0] if options.get('region_name'): manip_geom.name = options.get('region_name') manip_geom.save() else: manip_geom.name = layer.name manip_geom.save() print "" print "The manipulaotr geometry, %s, has been added to the %s model with primary key = %s" % ( manip_geom.name, manipulator, manip_geom.pk) print "To switch to this geometry, you will need to run 'manage.py change_manipulator_geom %s %s'" % ( manip_geom.pk, manipulator) print ""
def __init__(self, rel, title, view, method='GET', select='single', type=None, slug=None, generic=False, models=None, extra_kwargs={}, confirm=False, edits_original=None, must_own=False, limit_to_groups=None): self.rel = rel """Type of link - alternate, related, edit, or edit_form. """ try: self.view = get_class(view) """ View function handling requests to this link. """ except Exception as err: msg = 'Link "%s" configured with invalid path to view %s' % (title, view) msg += '\n%s\n' % str(err) if "cannot import" in str(err): msg += "(Possible cause: importing Features at the top level in views.py can cause" msg += " circular dependencies; Try to import Features within the view function)" raise FeatureConfigurationError(msg) self.title = title """ Human-readable title for the link to be shown in the user interface. """ self.method = method """ For rel=edit links, identifies whether a form should be requested or that url should just be POST'ed to. """ self.type = type """ MIME type of this link, useful for alternate links. May in the future be used to automatically assign an icon in the dropdown Export menu. """ self.slug = slug """ Part of this link's path. """ self.select = select """ Determines whether this link accepts requests with single or multiple instances of a feature class. Valid values are "single", "multiple", "single multiple", and "multiple single". """ self.extra_kwargs = extra_kwargs """ Extra keyword arguments to pass to the view. """ self.generic = generic """ Whether this view can be applied to multiple feature classes. """ self.models = models """ List of feature classes that a this view can be applied to, if it is generic. """ self.confirm = confirm """ Confirmation message to show the user before POSTing to rel=edit link """ self.edits_original = edits_original """ Set to false for editing links that create a copy of the original. This will allow users who do not own the instance(s) but can view them perform the action. """ self.must_own = must_own if self.edits_original: self.must_own = True """ Whether this link should be accessible to non-owners. Default link behavior is False; i.e. Link can be used for shared features as well as for user-owned features. If edits_original is true, this implies must_own = True as well. """ self.limit_to_groups = limit_to_groups """ Allows you to specify groups (a list of group names) that should have access to the link. Default is None; i.e. All users have link access regardless of group membership """ if self.models is None: self.models = [] # Make sure title isn't empty if self.title is '': raise FeatureConfigurationError('Link title is empty') valid_options = ('single', 'multiple', 'single multiple', 'multiple single') # Check for valid 'select' kwarg if self.select not in valid_options: raise FeatureConfigurationError( 'Link specified with invalid select option "%s"' % ( self.select, )) # Create slug from the title unless a custom slug is specified if self.slug is None: self.slug = slugify(title) # Make sure the view has the right signature self._validate_view(self.view)
def __init__(self, model): # Import down here to avoid circular reference from madrona.features.models import Feature, FeatureCollection # call this here to ensure that permsissions get created #enable_sharing() if not issubclass(model, Feature): raise FeatureConfigurationError('Is not a subclass of \ madrona.features.models.Feature') self._model = model name = model.__name__ if not getattr(model, 'Options', False): raise FeatureConfigurationError( 'Have not defined Options inner-class on registered feature \ class %s' % (name, )) self._options = model.Options if not hasattr(self._options, 'form'): raise FeatureConfigurationError( "Feature class %s is not configured with a form class. \ To specify, add a `form` property to its Options inner-class." % (name,)) if not isinstance(self._options.form, str): raise FeatureConfigurationError( "Feature class %s is configured with a form property that is \ not a string path." % (name,)) self.form = self._options.form """ Path to FeatureForm used to edit this class. """ self.slug = slugify(name) """ Name used in the url path to this feature as well as part of the Feature's uid """ self.verbose_name = getattr(self._options, 'verbose_name', name) """ Name specified or derived from the feature class name used in the user interface for representing this feature class. """ self.form_template = getattr(self._options, 'form_template', 'features/form.html') """ Location of the template that should be used to render forms when editing or creating new instances of this feature class. """ self.form_context = getattr(self._options, 'form_context', {}) """ Context to merge with default context items when rendering templates to create or modify features of this class. """ self.show_context = getattr(self._options, 'show_context', {}) """ Context to merge with default context items when rendering templates to view information about instances of this feature class. """ self.icon_url = getattr(self._options, 'icon_url', None) """ Optional; URL to 16x16 icon to use in kmltree Use full URL or relative to MEDIA_URL """ self.links = [] """ Links associated with this class. """ opts_links = getattr(self._options, 'links', False) if opts_links: self.links.extend(opts_links) self.enable_copy = getattr(self._options, 'disable_copy', True) """ Enable copying features. Uses the feature class' copy() method. Defaults to True. """ # Add a copy method unless disabled if self.enable_copy: self.links.insert(0, edit('Copy', 'madrona.features.views.copy', select='multiple single', edits_original=False)) confirm = "Are you sure you want to delete this feature and it's contents?" # Add a multi-share generic link # TODO when the share_form view takes multiple instances # we can make sharing a generic link #self.links.insert(0, edit('Share', # 'madrona.features.views.share_form', # select='multiple single', # method='POST', # edits_original=True, #)) # Add a multi-delete generic link self.links.insert(0, edit('Delete', 'madrona.features.views.multi_delete', select='multiple single', method='DELETE', edits_original=True, confirm=confirm, )) # Add a staticmap generic link export_png = getattr(self._options, 'export_png', True) if export_png: self.links.insert(0, alternate('PNG Image', 'madrona.staticmap.views.staticmap_link', select='multiple single', method='GET', )) self.valid_children = getattr(self._options, 'valid_children', None) """ valid child classes for the feature container """ if self.valid_children and not issubclass(self._model, FeatureCollection): raise FeatureConfigurationError("valid_children Option only \ for FeatureCollection classes" % m) self.manipulators = [] """ Required manipulators applied to user input geometries """ manipulators = getattr(self._options, 'manipulators', []) for m in manipulators: try: manip = get_class(m) except: raise FeatureConfigurationError("Error trying to import module %s" % m) # Test that manipulator is compatible with this Feature Class geom_field = self._model.geometry_final._field.__class__.__name__ if geom_field not in manip.Options.supported_geom_fields: raise FeatureConfigurationError("%s does not support %s geometry types (only %r)" % (m, geom_field, manip.Options.supported_geom_fields)) #logger.debug("Added required manipulator %s" % m) self.manipulators.append(manip) self.optional_manipulators = [] """ Optional manipulators that may be applied to user input geometries """ optional_manipulators = getattr(self._options, 'optional_manipulators', []) for m in optional_manipulators: try: manip = get_class(m) except: raise FeatureConfigurationError("Error trying to import module %s" % m) # Test that manipulator is compatible with this Feature Class geom_field = self._model.geometry_final._field.__class__.__name__ try: if geom_field not in manip.Options.supported_geom_fields: raise FeatureConfigurationError("%s does not support %s geometry types (only %r)" % (m, geom_field, manip.Options.supported_geom_fields)) except AttributeError: raise FeatureConfigurationError("%s is not set up properly; must have " "Options.supported_geom_fields list." % m) #logger.debug("Added optional manipulator %s" % m) self.optional_manipulators.append(manip) self.enable_kml = True """ Enable kml visualization of features. Defaults to True. """ # Add a kml link by default if self.enable_kml: self.links.insert(0,alternate('KML', 'madrona.features.views.kml', select='multiple single')) self.links.insert(0,alternate('KMZ', 'madrona.features.views.kmz', select='multiple single')) for link in self.links: if self._model not in link.models: link.models.append(self._model)
def __init__(self, rel, title, view, method='GET', select='single', type=None, slug=None, generic=False, models=None, extra_kwargs={}, confirm=False, edits_original=None, must_own=False, limit_to_groups=None): self.rel = rel """Type of link - alternate, related, edit, or edit_form. """ try: self.view = get_class(view) """ View function handling requests to this link. """ except Exception as err: msg = 'Link "%s" configured with invalid path to view %s' % (title, view) msg += '\n%s\n' % str(err) if "cannot import" in str(err): msg += "(Possible cause: importing Features at the top level in views.py can cause" msg += " circular dependencies; Try to import Features within the view function)" raise FeatureConfigurationError(msg) self.title = title """ Human-readable title for the link to be shown in the user interface. """ self.method = method """ For rel=edit links, identifies whether a form should be requested or that url should just be POST'ed to. """ self.type = type """ MIME type of this link, useful for alternate links. May in the future be used to automatically assign an icon in the dropdown Export menu. """ self.slug = slug """ Part of this link's path. """ self.select = select """ Determines whether this link accepts requests with single or multiple instances of a feature class. Valid values are "single", "multiple", "single multiple", and "multiple single". """ self.extra_kwargs = extra_kwargs """ Extra keyword arguments to pass to the view. """ self.generic = generic """ Whether this view can be applied to multiple feature classes. """ self.models = models """ List of feature classes that a this view can be applied to, if it is generic. """ self.confirm = confirm """ Confirmation message to show the user before POSTing to rel=edit link """ self.edits_original = edits_original """ Set to false for editing links that create a copy of the original. This will allow users who do not own the instance(s) but can view them perform the action. """ self.must_own = must_own if self.edits_original: self.must_own = True """ Whether this link should be accessible to non-owners. Default link behavior is False; i.e. Link can be used for shared features as well as for user-owned features. If edits_original is true, this implies must_own = True as well. """ self.limit_to_groups = limit_to_groups """ Allows you to specify groups (a list of group names) that should have access to the link. Default is None; i.e. All users have link access regardless of group membership """ if self.models is None: self.models = [] # Make sure title isn't empty if self.title is '': raise FeatureConfigurationError('Link title is empty') valid_options = ('single', 'multiple', 'single multiple', 'multiple single') # Check for valid 'select' kwarg if self.select not in valid_options: raise FeatureConfigurationError( 'Link specified with invalid select option "%s"' % (self.select, )) # Create slug from the title unless a custom slug is specified if self.slug is None: self.slug = slugify(title) # Make sure the view has the right signature self._validate_view(self.view)
def __init__(self, model): # Import down here to avoid circular reference from madrona.features.models import Feature, FeatureCollection # call this here to ensure that permsissions get created #enable_sharing() if not issubclass(model, Feature): raise FeatureConfigurationError('Is not a subclass of \ madrona.features.models.Feature') self._model = model name = model.__name__ if not getattr(model, 'Options', False): raise FeatureConfigurationError( 'Have not defined Options inner-class on registered feature \ class %s' % (name, )) self._options = model.Options if not hasattr(self._options, 'form'): raise FeatureConfigurationError( "Feature class %s is not configured with a form class. \ To specify, add a `form` property to its Options inner-class." % (name, )) if not isinstance(self._options.form, str): raise FeatureConfigurationError( "Feature class %s is configured with a form property that is \ not a string path." % (name, )) self.form = self._options.form """ Path to FeatureForm used to edit this class. """ self.slug = slugify(name) """ Name used in the url path to this feature as well as part of the Feature's uid """ self.verbose_name = getattr(self._options, 'verbose_name', name) """ Name specified or derived from the feature class name used in the user interface for representing this feature class. """ self.form_template = getattr(self._options, 'form_template', 'features/form.html') """ Location of the template that should be used to render forms when editing or creating new instances of this feature class. """ self.form_context = getattr(self._options, 'form_context', {}) """ Context to merge with default context items when rendering templates to create or modify features of this class. """ self.show_context = getattr(self._options, 'show_context', {}) """ Context to merge with default context items when rendering templates to view information about instances of this feature class. """ self.icon_url = getattr(self._options, 'icon_url', None) """ Optional; URL to 16x16 icon to use in kmltree Use full URL or relative to MEDIA_URL """ self.links = [] """ Links associated with this class. """ opts_links = getattr(self._options, 'links', False) if opts_links: self.links.extend(opts_links) self.enable_copy = getattr(self._options, 'disable_copy', True) """ Enable copying features. Uses the feature class' copy() method. Defaults to True. """ # Add a copy method unless disabled if self.enable_copy: self.links.insert( 0, edit('Copy', 'madrona.features.views.copy', select='multiple single', edits_original=False)) confirm = "Are you sure you want to delete this feature and it's contents?" # Add a multi-share generic link # TODO when the share_form view takes multiple instances # we can make sharing a generic link #self.links.insert(0, edit('Share', # 'madrona.features.views.share_form', # select='multiple single', # method='POST', # edits_original=True, #)) # Add a multi-delete generic link self.links.insert( 0, edit( 'Delete', 'madrona.features.views.multi_delete', select='multiple single', method='DELETE', edits_original=True, confirm=confirm, )) # Add a staticmap generic link export_png = getattr(self._options, 'export_png', True) if export_png: self.links.insert( 0, alternate( 'PNG Image', 'madrona.staticmap.views.staticmap_link', select='multiple single', method='GET', )) # Add a geojson generic link export_geojson = getattr(self._options, 'export_geojson', True) if export_geojson: self.links.insert( 0, alternate( 'GeoJSON', 'madrona.features.views.geojson_link', select='multiple single', method='GET', )) self.valid_children = getattr(self._options, 'valid_children', None) """ valid child classes for the feature container """ if self.valid_children and not issubclass(self._model, FeatureCollection): raise FeatureConfigurationError("valid_children Option only \ for FeatureCollection classes" % m) self.manipulators = [] """ Required manipulators applied to user input geometries """ manipulators = getattr(self._options, 'manipulators', []) for m in manipulators: try: manip = get_class(m) except: raise FeatureConfigurationError( "Error trying to import module %s" % m) # Test that manipulator is compatible with this Feature Class geom_field = self._model.geometry_final._field.__class__.__name__ if geom_field not in manip.Options.supported_geom_fields: raise FeatureConfigurationError( "%s does not support %s geometry types (only %r)" % (m, geom_field, manip.Options.supported_geom_fields)) #logger.debug("Added required manipulator %s" % m) self.manipulators.append(manip) self.optional_manipulators = [] """ Optional manipulators that may be applied to user input geometries """ optional_manipulators = getattr(self._options, 'optional_manipulators', []) for m in optional_manipulators: try: manip = get_class(m) except: raise FeatureConfigurationError( "Error trying to import module %s" % m) # Test that manipulator is compatible with this Feature Class geom_field = self._model.geometry_final._field.__class__.__name__ try: if geom_field not in manip.Options.supported_geom_fields: raise FeatureConfigurationError( "%s does not support %s geometry types (only %r)" % (m, geom_field, manip.Options.supported_geom_fields)) except AttributeError: raise FeatureConfigurationError( "%s is not set up properly; must have " "Options.supported_geom_fields list." % m) #logger.debug("Added optional manipulator %s" % m) self.optional_manipulators.append(manip) self.enable_kml = True """ Enable kml visualization of features. Defaults to True. """ # Add a kml link by default if self.enable_kml: self.links.insert( 0, alternate('KML', 'madrona.features.views.kml', select='multiple single')) self.links.insert( 0, alternate('KMZ', 'madrona.features.views.kmz', select='multiple single')) for link in self.links: if self._model not in link.models: link.models.append(self._model)