<commit_before>The Features App
################

The ``lingcod.features`` app works along with other MarineMap apps to create a 
system that is best described as a content management system for user-designed
spatial features. This system can be configured quickly to support a range of 
management options such as marine protected areas, hydrokinetic generators, 
wind turbines, or undersea cables. With one model definition it's possible to
define the data schema for storing these features, as well as what behaviors 
and actions they support within the MarineMap interface. I high degree of 
customization can be achieved with a MarineMap project with this declarative 
format, without having to customize the view or client-side javascript 
components.

Feature Classes can be configured to:

  * Represent various management scenarios as Point, LineString or Polygon 
    data
  * Collect attributes from users using forms generated from the model 
    definition (or customized forms)
  * Pre-process and validate user-defined geometries with Manipulators
  * Enable sharing of features among users
  * Add custom downloads, like Shapefile or Excel files
  * Support custom editing actions
  
In addition, FeatureCollection Classes can be created that are collections of
Feature Class instances with their own attributes. These can be used to 
represent simple Folders to help users organize their designs, or represent 
management concepts such as Marine Protected Area Networks.

Creating a Spatial Feature Class
********************************

Lets walk through the basics of creating a simple Feature Class. The basic 
process involves:

  * Defining a subclass of ``PointFeature``, ``LineStringFeature``, 
    ``PolygonFeature``, or ``3dModelFeature``, including the attributes to be
    stored with it.
  * Creating an Options inner-class, and using it to specify a form to use 
    when creating or editing this Feature Class.
  * Specifying links to downloads or services related to the Feature Class.
  * Specifying any optional parameters on the Options inner-class
  * Creating a template to use when displaying this Feature Class' attributes
  * Creating a kml template that can be used to represent it
  
Look at this crap example::

    @features.register
    class Mpa(PolygonFeature):
        ext = models.CharField(max_length="12")

        class Options:
            verbose_name = 'Marine Protected Area'
            form = 'myproject.forms.MpaForm'
            links = (
                alternate('Shapefile',
                    'mlpa.views.shapefile', 
                    select='single', 
                    type='application/shapefile'),

                alternate('KMZ (Google Earth)', 
                    'mlpa.views.kml_export', 
                    select='single multiple', 
                    type='application/vnd.google-earth.kmz',
                    generic=True),

                related('MPA Spreadsheet',
                    'mlpa.views.spreadsheet', 
                    select='single',
                    type='application/excel'),

                edit('Delete w/Grids', 
                    'mlpa.views.delete_w_grids', 
                    confirm="Are you sure you want to delete with grids?", 
                    select="single multiple",
                    args=[MpaArray],
                    kwargs={'keyword_argument': True}),

                edit_form('Tags',
                    'mlpa.views.tag', 
                    select='single multiple',
                    generic=True,
                    models=(MpaArray, MlpaMpa)),
            )

Defining the Model
==================

Must be a subclass of one of the ``Feature`` subclasses (``PointFeature``, 
``PolygonFeature``, ``LineStringFeature``, ``3dModelFeature``)

Specifying a Form
=================

All Feature Classes must have an ``Options`` inner-class that contains a 
property specifying the ``FeatureForm`` subclass that can be used to edit it.
All :ref:`other properties <optional-properties>` on the Options inner-class 
are optional.

Creating a "Show" Template
==========================

The show template is used to render sidebar content for a feature within the
MarineMap interface, and can also be used to render a printable and 
bookmarkable page for it. This template can be placed in any template 
directory by default under ``{{slug}}/show.html``. Subdirectories are used to
allow for overriding templates as mentioned in the 
`django documentation <http://docs.djangoproject.com/en/1.2/ref/templates/api/#using-subdirectories>`_.
The default path to the show template can be changed using an optional 
`show_template`_ parameter to the Options inner-class.

Templates will be rendered with the following context:
    
    * ``instance`` - the feature class instance being being displayed
    * ...
    * ...

You can add to this list using the `show_context`_ Option property.

Creating a KML Template
=======================

Create a template under ``{{slug}}/feature.kml`` that represents your feature,
otherwise a default rendering will be used. The tag used must be a 
`KML Feature <http://code.google.com/apis/kml/documentation/kmlreference.html#feature>`_,
and have an ``id`` attribute populated with the value of ``instance.uid``.

KML templates are rendered with the same context as show templates.

Specifying Links
================

Links allow developers to extend the functionality of features by specifying
downloads, actions, or related pages that should be made available through the
interface. There are 4 types of Links:

  * ``alternate`` links specify alternative representations of features that 
    should be made available through the Export menu.
  * ``related`` links specify related downloads or pages that are also made 
    available in the Export menu but in a downloads section.
  * ``edit`` links specify items that should appear in the Edit menu. These 
    actions can be performed without any user interaction, such as a special 
    delete view.
  * ``edit_form`` links appear in the Edit menu. These types of edit actions
    first display a form to the user requiring input. This can be used to 
    implement actions such as tagging.

Here's an example of links in use::
    
    @features.register
    class Mpa(PolygonFeature):
        ext = models.CharField(max_length="12")

        class Options:
            verbose_name = 'Folder'
            form = 'myproject.forms.MpaForm'
            links = (
                alternate('Shapefile',
                    'mlpa.views.shapefile', 
                    select='single', 
                    type='application/shapefile'),

                alternate('KMZ (Google Earth)', 
                    'mlpa.views.kml_export', 
                    select='single multiple', 
                    type='application/vnd.google-earth.kmz',
                    generic=True),

                related('MPA Spreadsheet',
                    'mlpa.views.spreadsheet', 
                    select='single',
                    type='application/excel'),

                edit('Delete w/Grids', 
                    'mlpa.views.delete_w_grids', 
                    confirm="Are you sure you want to delete with grids?", 
                    select="single multiple",
                    args=[MpaArray],
                    kwargs={'keyword_argument': True}),

                edit_form('Tags',
                    'mlpa.views.tag', 
                    select='single multiple',
                    generic=True,
                    models=(MpaArray, MlpaMpa)),
            )

Beyond the Basics
=================

Enabling Sharing
----------------

Implementing a Custom Copy Method
---------------------------------

Specifying Manipulators
-----------------------

Etc
---

Base Classes
************

Spatial Types
=============

PointFeature
------------

LineStringFeature
-----------------

PolygonFeature
--------------
<commit_msg>Made note about generic views that are Link'ed requiring a certain method signature<commit_after>The Features App
################

The ``lingcod.features`` app works along with other MarineMap apps to create a 
system that is best described as a content management system for user-designed
spatial features. This system can be configured quickly to support a range of 
management options such as marine protected areas, hydrokinetic generators, 
wind turbines, or undersea cables. With one model definition it's possible to
define the data schema for storing these features, as well as what behaviors 
and actions they support within the MarineMap interface. I high degree of 
customization can be achieved with a MarineMap project with this declarative 
format, without having to customize the view or client-side javascript 
components.

Feature Classes can be configured to:

  * Represent various management scenarios as Point, LineString or Polygon 
    data
  * Collect attributes from users using forms generated from the model 
    definition (or customized forms)
  * Pre-process and validate user-defined geometries with Manipulators
  * Enable sharing of features among users
  * Add custom downloads, like Shapefile or Excel files
  * Support custom editing actions
  
In addition, FeatureCollection Classes can be created that are collections of
Feature Class instances with their own attributes. These can be used to 
represent simple Folders to help users organize their designs, or represent 
management concepts such as Marine Protected Area Networks.

Creating a Spatial Feature Class
********************************

Lets walk through the basics of creating a simple Feature Class. The basic 
process involves:

  * Defining a subclass of ``PointFeature``, ``LineStringFeature``, 
    ``PolygonFeature``, or ``3dModelFeature``, including the attributes to be
    stored with it.
  * Creating an Options inner-class, and using it to specify a form to use 
    when creating or editing this Feature Class.
  * Specifying links to downloads or services related to the Feature Class.
  * Specifying any optional parameters on the Options inner-class
  * Creating a template to use when displaying this Feature Class' attributes
  * Creating a kml template that can be used to represent it
  
Look at this crap example::

    @features.register
    class Mpa(PolygonFeature):
        ext = models.CharField(max_length="12")

        class Options:
            verbose_name = 'Marine Protected Area'
            form = 'myproject.forms.MpaForm'
            links = (
                alternate('Shapefile',
                    'mlpa.views.shapefile', 
                    select='single', 
                    type='application/shapefile'),

                alternate('KMZ (Google Earth)', 
                    'mlpa.views.kml_export', 
                    select='single multiple', 
                    type='application/vnd.google-earth.kmz',
                    generic=True),

                related('MPA Spreadsheet',
                    'mlpa.views.spreadsheet', 
                    select='single',
                    type='application/excel'),

                edit('Delete w/Grids', 
                    'mlpa.views.delete_w_grids', 
                    confirm="Are you sure you want to delete with grids?", 
                    select="single multiple",
                    args=[MpaArray],
                    kwargs={'keyword_argument': True}),

                edit_form('Tags',
                    'mlpa.views.tag', 
                    select='single multiple',
                    generic=True,
                    models=(MpaArray, MlpaMpa)),
            )

Defining the Model
==================

Must be a subclass of one of the ``Feature`` subclasses (``PointFeature``, 
``PolygonFeature``, ``LineStringFeature``, ``3dModelFeature``)

Specifying a Form
=================

All Feature Classes must have an ``Options`` inner-class that contains a 
property specifying the ``FeatureForm`` subclass that can be used to edit it.
All :ref:`other properties <optional-properties>` on the Options inner-class 
are optional.

Creating a "Show" Template
==========================

The show template is used to render sidebar content for a feature within the
MarineMap interface, and can also be used to render a printable and 
bookmarkable page for it. This template can be placed in any template 
directory by default under ``{{slug}}/show.html``. Subdirectories are used to
allow for overriding templates as mentioned in the 
`django documentation <http://docs.djangoproject.com/en/1.2/ref/templates/api/#using-subdirectories>`_.
The default path to the show template can be changed using an optional 
`show_template`_ parameter to the Options inner-class.

Templates will be rendered with the following context:
    
    * ``instance`` - the feature class instance being being displayed
    * ...
    * ...

You can add to this list using the `show_context`_ Option property.

Creating a KML Template
=======================

Create a template under ``{{slug}}/feature.kml`` that represents your feature,
otherwise a default rendering will be used. The tag used must be a 
`KML Feature <http://code.google.com/apis/kml/documentation/kmlreference.html#feature>`_,
and have an ``id`` attribute populated with the value of ``instance.uid``.

KML templates are rendered with the same context as show templates.

Specifying Links
================

Links allow developers to extend the functionality of features by specifying
downloads, actions, or related pages that should be made available through the
interface. There are 4 types of Links:

  * ``alternate`` links specify alternative representations of features that 
    should be made available through the Export menu.
  * ``related`` links specify related downloads or pages that are also made 
    available in the Export menu but in a downloads section.
  * ``edit`` links specify items that should appear in the Edit menu. These 
    actions can be performed without any user interaction, such as a special 
    delete view.
  * ``edit_form`` links appear in the Edit menu. These types of edit actions
    first display a form to the user requiring input. This can be used to 
    implement actions such as tagging.

Here's an example of links in use::
    
    @features.register
    class Mpa(PolygonFeature):
        ext = models.CharField(max_length="12")

        class Options:
            verbose_name = 'Folder'
            form = 'myproject.forms.MpaForm'
            links = (
                alternate('Shapefile',
                    'mlpa.views.shapefile', 
                    select='single', 
                    type='application/shapefile'),

                alternate('KMZ (Google Earth)', 
                    'mlpa.views.kml_export', 
                    select='single multiple', 
                    type='application/vnd.google-earth.kmz',
                    generic=True),

                related('MPA Spreadsheet',
                    'mlpa.views.spreadsheet', 
                    select='single',
                    type='application/excel'),

                edit('Delete w/Grids', 
                    'mlpa.views.delete_w_grids', 
                    confirm="Are you sure you want to delete with grids?", 
                    select="single multiple",
                    args=[MpaArray],
                    kwargs={'keyword_argument': True}),

                edit_form('Tags',
                    'mlpa.views.tag', 
                    select='single multiple',
                    generic=True,
                    models=(MpaArray, MlpaMpa)),
            )

Views that are wired up to features using links must accept a second argument
named ``instance`` or ``instances`` depending on whether they can work on a 
single or multiple selected features. Generic views will handle cases where a
user is not authorized to view or edit a feature, requests related to features
that cannot be found, and improperly configured views. 

Beyond the Basics
=================

Enabling Sharing
----------------

Implementing a Custom Copy Method
---------------------------------

Specifying Manipulators
-----------------------

Etc
---

Base Classes
************

Spatial Types
=============

PointFeature
------------

LineStringFeature
-----------------

PolygonFeature
--------------

{'fraction_non_alphanumeric': 0.10295106005987659, 'fraction_numerical': 0.001099773935357732, 'mean_word_length': 2.4677966101694917, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 2, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '481317', 'n_tokens_mistral': 4070, 'n_tokens_neox': 3698, 'n_words': 1635}