Version 52 (modified by 10 years ago) ( diff ) | ,
---|
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
def show_map( self, id = "default_map", height = None, width = None, bbox = {}, lat = None, lon = None, zoom = None, projection = None, add_feature = False, add_feature_active = False, add_line = False, add_line_active = False, add_polygon = False, add_polygon_active = False, features = None, feature_queries = None, feature_resources = None, wms_browser = {}, catalogue_layers = False, legend = False, toolbar = False, area = False, nav = None, save = False, search = False, mouse_position = None, overview = None, permalink = None, scaleline = None, zoomcontrol = None, zoomWheelEnabled = True, mgrs = {}, window = False, window_hide = False, closable = True, maximizable = True, collapsed = False, callback = "DEFAULT", plugins = None, ): """ Returns the HTML to display a map Normally called in the controller as: map = gis.show_map() In the view, put: {{=XML(map)}} @param id: ID to uniquely identify this map if there are several on a page @param height: Height of viewport (if not provided then the default deployment setting is used) @param width: Width of viewport (if not provided then the default deployment setting is used) @param bbox: default Bounding Box of viewport (if not provided then the Lat/Lon/Zoom are used) (Dict): {"lon_min" : float, "lat_min" : float, "lon_max" : float, "lat_max" : float, } @param lat: default Latitude of viewport (if not provided then the default setting from the Map Service Catalogue is used) @param lon: default Longitude of viewport (if not provided then the default setting from the Map Service Catalogue is used) @param zoom: default Zoom level of viewport (if not provided then the default setting from the Map Service Catalogue is used) @param projection: EPSG code for the Projection to use (if not provided then the default setting from the Map Service Catalogue is used) @param add_feature: Whether to include a DrawFeature control to allow adding a marker to the map @param add_feature_active: Whether the DrawFeature control should be active by default @param add_polygon: Whether to include a DrawFeature control to allow drawing a polygon over the map @param add_polygon_active: Whether the DrawFeature control should be active by default @param features: Simple Features to overlay on Map (no control over appearance & not interactive) [wkt] @param feature_queries: Feature Queries to overlay onto the map & their options (List of Dicts): [{"name" : T("MyLabel"), # A string: the label for the layer "query" : query, # A gluon.sql.Rows of gis_locations, which can be from a simple query or a Join. # Extra fields can be added for 'popup_url', 'popup_label' & either # 'marker' (url/height/width) or 'shape' (with optional 'colour' & 'size') "active" : True, # Is the feed displayed upon load or needs ticking to load afterwards? "marker" : None, # Optional: A per-Layer marker query or marker_id for the icon used to display the feature "opacity" : 1, # Optional "cluster_attribute", # Optional "cluster_distance", # Optional "cluster_threshold" # Optional }] @param feature_resources: REST URLs for (filtered) resources to overlay onto the map & their options (List of Dicts): [{"name" : T("MyLabel"), # A string: the label for the layer "id" : "search", # A string: the id for the layer (for manipulation by JavaScript) "active" : True, # Is the feed displayed upon load or needs ticking to load afterwards? EITHER: "layer_id" : 1, # An integer: the layer_id to load (optional alternative to specifying URL/tablename/marker) "filter" : "filter", # A string: an optional URL filter which *replaces* any in the layer OR: "tablename" : "module_resource", # A string: the tablename (used to determine whether to locate via location_id or site_id) "url" : "/eden/module/resource.geojson?filter", # A URL to load the resource "marker" : None, # Optional: A per-Layer marker dict for the icon used to display the feature (overrides layer_id if-set) "opacity" : 1, # Optional (overrides layer_id if-set) "cluster_attribute", # Optional (overrides layer_id if-set) "cluster_distance", # Optional (overrides layer_id if-set) "cluster_threshold", # Optional (overrides layer_id if-set) "dir", # Optional (overrides layer_id if-set) "style", # Optional (overrides layer_id if-set) }] @param wms_browser: WMS Server's GetCapabilities & options (dict) {"name": T("MyLabel"), # Name for the Folder in LayerTree "url": string # URL of GetCapabilities } @param catalogue_layers: Show all the enabled Layers from the GIS Catalogue Defaults to False: Just show the default Base layer @param legend: True: Show the GeoExt Legend panel, False: No Panel, "float": New floating Legend Panel @param toolbar: Show the Icon Toolbar of Controls @param area: Show the Area tool on the Toolbar @param nav: Show the Navigation controls on the Toolbar @param save: Show the Save tool on the Toolbar @param search: Show the Geonames search box (requires a username to be configured) @param mouse_position: Show the current coordinates in the bottom-right of the map. 3 Options: 'normal', 'mgrs', False (defaults to checking deployment_settings, which defaults to 'normal') @param overview: Show the Overview Map (defaults to checking deployment_settings, which defaults to True) @param permalink: Show the Permalink control (defaults to checking deployment_settings, which defaults to True) @param scaleline: Show the ScaleLine control (defaults to checking deployment_settings, which defaults to True) @param zoomcontrol: Show the Zoom control (defaults to checking deployment_settings, which defaults to True) @param mgrs: Use the MGRS Control to select PDFs {"name": string, # Name for the Control "url": string # URL of PDF server } @ToDo: Also add MGRS Search support: http://gxp.opengeo.org/master/examples/mgrs.html @param window: Have viewport pop out of page into a resizable window @param window_hide: Have the window hidden by default, ready to appear (e.g. on clicking a button) @param closable: In Window mode, whether the window is closable or not @param collapsed: Start the Tools panel (West region) collapsed @param callback: Code to run once the Map JavaScript has loaded @param plugins: an iterable of objects which support the following methods: .extend_gis_map(map) Client-side portion suppoprts the following methods: .addToMapWindow(items) .setup(map) """
Variable Markers
Example:
query = (db.gis_location.deleted == False) query = query & (db.gis_location.id == db["%s_%s" % (module, resource)].location_id) locations = db(query).select(db.gis_location.id, db.gis_location.uuid, db.gis_location.name, db.gis_location.wkt, db.gis_location.lat, db.gis_location.lon) for i in range(0, len(locations)): locations[i].gis_location.shape = "circle" locations[i].gis_location.size = locations[i][db["%s_%s" % (module, resource)].MyIntegerField]
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