Module 7 - Customizing the web service
======================================

This module will show you two examples of web service customization. The first
example is based on MapFish-provides APIs. The second example involves
knowlegde in the powerful SQLAlchemy database toolkit.

Simple customization
--------------------

You're going to customize the ``countries`` web service so it includes only
countries of the Oceana continent in its GeoJSON responses.

**Programming task**

This is done by adding code to the ``index`` action (function) of the
``CountriesController``. The code to be added involves creating a
``Comparison`` filter and combining it with the default MapFish filter::

    def index(self, format='json'):
        """GET /: return all features."""
        default_filter = create_default_filter(request, Countrie)
        compare_filter = comparison.Comparison(
            comparison.Comparison.EQUAL_TO,
            Countrie.continent,
            value="Oceana"
        )
        filter = logical.Logical(logical.Logical.AND, [default_filter, compare_filter])
        return self.protocol.index(request, response, format=format, filter=filter)

MapFish provides several filter classes that the application developer can use
to customize his web services. See the `filters reference API
<http://www.mapfish.org/doc/1.2/reference/filters.html>`_ [#]_.

[`Add Filter Correction <_static/controller_countries_module7.py>`_]

Advanced customization
----------------------

You're now going to customize the ``countries`` web sercice so it sends
simplified geometries in its GeoJSON responses.

**Programming task**

This is done by modifying the ``countries`` model so that SQL queries of type
``SELECT simplify(the_geom, 2) ...`` are executed by the database. This
modification requires knowledge in the SQLAlchemy ORM. Here it is::

    countries_table = Table(
        'countries', metadata,
        Column('the_geom', Geometry(4326)),
        autoload=True, autoload_with=engine)

    class Country(GeometryTableMixIn):
        # for GeometryTableMixIn to do its job the __table__ property
        # must be set here
        __table__ = countries_table
            
        def toFeature(self):
            # overload toFeature to replace the geometry value with the
            # simplified geometry value
            self.the_geom = wkb.loads(self.the_geom_simple.decode("hex"))
            return GeometryTableMixIn.toFeature(self)

    mapper(Country, countries_table, properties={
        "the_geom_simple": column_property(
            func.simplify(countries_table.c.the_geom, 2).label("the_geom")
        )
    })

[`Simplify Geometries Correction <_static/model_countries_module7.py>`_]

.. [#] http://www.mapfish.org/doc/1.2/reference/filters.html

**Bonus task**

Modify the configuration of the ``mapfish.Searcher.Map`` object so that, in
addition to displaying the popup, it also draws the geometry in a vector vector
of the map. This is done by listening to ``searchcomplete`` events and adding
the received feature to a vector layer.
