wiki:DeveloperGuidelines/GIS

Version 54 (modified by Fran Boon, 6 years ago) ( diff )

--

GIS Module

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:

  1. Use a style JSON:

NB This only supports styling based on a single attribute & you need to add that to attr_fields

  1. Use a marker_fn:

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

  1. feature_queries

These are only supported in custom maps & always get loaded with the page...so cannot be refreshed via AJAX

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:

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

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

See Also

DeveloperGuidelines

Note: See TracWiki for help on using the wiki.