= GIS Module = [[TOC]] We use [http://openlayers.org OpenLayers] to display Maps with some [http://geoext.org 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: * https://github.com/flavour/eden/blob/master/modules/s3/s3gis.py#L6089 === Variable Markers === There are 3 basic approaches: 1. Use a style JSON: * https://github.com/flavour/eden/blob/master/modules/templates/IFRC/gis_layer_feature.csv#L6 NB This only supports styling based on a single attribute & you need to add that to attr_fields 2. 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 3. 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: * https://github.com/flavour/eden/blob/master/modules/templates/ARC/config.py#L913 == 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 [http://geoext.org GeoExt] (formerly [https://trac.mapfish.org/trac/mapfish/wiki/HowToUseWidgets MapFish client]) === How to debug WMS === * [https://addons.mozilla.org/en-US/firefox/addon/91406 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}}} {{{
  • New Layer Type - Description
  • }}} ==== 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 === * [wiki:BluePrint/GIS] * [wiki:UserGuidelines/GIS] * [wiki:DeveloperGuidelines/GIS/InAction] DeveloperGuidelines