GIS Module
Table of Contents
We use OpenLayers to display Maps with some GeoExt widgets.
Guidelines for Developers wishing to make use of Mapping within their Module
The easiest approach is to call the Mapping API.
Controller
map = gis.show_map() return dict(map=map)
View
{{=XML(map)}}
Examples
Check the following functions in controllers/gis.py
:
map_viewing_client()
display_feature()
display_features()
Full API description
Best to get live from the source:
Variable Markers
There are 3 basic approaches:
- Use a style JSON:
NB This only supports styling based on a single attribute & you need to add that to attr_fields
- Use a marker_fn:
- https://github.com/flavour/eden/blob/master/modules/templates/NYC/config.py#L302
- https://github.com/flavour/eden/blob/master/modules/templates/NYC/config.py#L430
This supports whatever lookups you want in Python...you don't pass the attr_field to client but this will pass the marker_url/marker_hight/marker_width in every record which will almost certainly be bulkier
- feature_queries
These are only supported in custom maps & always get loaded with the page...so cannot be refreshed via AJAX
Custom Popups
if r.representation == plain: xxxx
I usually do this in postp, which is a bit inefficient as it throws away the work done in prep/rest but it allows fuill customisation:
Guidelines for Developers wishing to extend the functionality of the core GIS
OpenLayers
The GIS module uses OpenLayers for Display purposes, so a thorough understanding of this is a great foundation for what we do:
- http://trac.openlayers.org/wiki/Documentation#BeforeGettingStarted--TheTechnologiesBehindOpenLayers
- http://trac.openlayers.org/wiki/NewToOpenLayers
Projections: http://trac.openlayers.org/wiki/Documentation/Dev/proj4js
Debugging advice: http://docs.openlayers.org/help/minimize.html
GUI
The map window is wrapped in an Ext GUI based on GeoExt (formerly MapFish client)
How to debug WMS
- WMS Inspector - Firefox add-on
How to add a new Layer type
Assuming that OpenLayers supports the layertype:
Model
modules/s3db/gis.py
_gis_layer_types = ["newlayertype", "..."] table = self.define_table("gis_layer_newlayertype", name_field(), Field("description", label=T("Description")), Field("enabled", "boolean", default=True, label=T("Available in Viewer?")), Field("visible", "boolean", default=True, label=T("On by default? (only applicable to Overlays)")), Field("url", label=T("Location"), requires = IS_NOT_EMPTY(), comment=DIV(_class="tooltip", _title="%s|%s" % (T("Location"), T("The URL to access the service.")))), Field("version", length=32, label=T("Version"), default="1.1.1", requires=IS_IN_SET(["1.1.1", "1.3.0"], zero=None)), Field("base", "boolean", default=False, label=T("Base Layer?")), Field("transparent", "boolean", default=True, label=T("Transparent?")), gis_opacity(), role_required(), # Single Role #roles_permitted(), # Multiple Roles (needs implementing in modules/s3gis.py) *s3_timestamp())
Controller
controllers/gis.py
def layer_newlayertype(): """ RESTful CRUD controller """ if settings.get_security_map() and not s3_has_role("MapAdmin"): unauthorised() resourcename = request.function tablename = "%s_%s" % (module, resourcename) table = s3db[tablename] # Model options table.url.comment = SPAN("*", _class="req") # CRUD Strings type = "New Layer Type" LAYERS = T(TYPE_LAYERS_FMT % type) ADD_NEW_LAYER = T(ADD_NEW_TYPE_LAYER_FMT % type) EDIT_LAYER = T(EDIT_TYPE_LAYER_FMT % type) LIST_LAYERS = T(LIST_TYPE_LAYERS_FMT % type) NO_LAYERS = T(NO_TYPE_LAYERS_FMT % type) s3.crud_strings[tablename] = Storage( title_create=ADD_LAYER, title_display=LAYER_DETAILS, title_list=LAYERS, title_update=EDIT_LAYER, title_search=SEARCH_LAYERS, subtitle_create=ADD_NEW_LAYER, subtitle_list=LIST_LAYERS, label_list_button=LIST_LAYERS, label_create_button=ADD_LAYER, label_delete_button = DELETE_LAYER, msg_record_created=LAYER_ADDED, msg_record_modified=LAYER_UPDATED, msg_record_deleted=LAYER_DELETED, msg_list_empty=NO_LAYERS) # Post-processor def postp(r, output): s3_action_buttons(r) return output response.s3.postp = postp output = s3_rest_controller() if not "gis" in response.view: response.view = "gis/" + response.view return output
View
views/gis/map_service_catalogue.html
<li><a href='{{=URL(f="layer_newlayertype")}}'>New Layer Type</a> - Description</li>
Module
Classes need adding:
modules/s3gis.py
class NewTypeLayer(Layer): ... def show_map(): for LayerType in [ ... NewTypeLayer,
Static
OpenLayers code needs adding:
static/scripts/S3/s3.gis.layers.js
function addNewTyppeLayer(layer) { ... } function addLayers() { .... if (S3.gis.layers_newlayertype) { for (i = 0; i < S3.gis.layers_newlayertype.length; i++) { addNewTypeLayer(S3.gis.layers_newlayertype[i]); } } .... }
cd static/scripts/tools build gis