Skip to content
This repository has been archived by the owner on May 6, 2021. It is now read-only.

Proposal #3: Pluggable SpatialSelector and SpatialSelectorQueryPanel

Alejandro Díaz Torres edited this page Mar 5, 2014 · 5 revisions

Overview

Redesign Spatial Selector Field to make it pluggable.

Proposed By

Alejandro Díaz (alediator)

Assigned to Release

MapStore 1.6

State

Choose one of: Under Discussion, In Progress, Completed, Rejected, Deferred

Motivation

Develop new widgets SpatialSelectorQueryForm and SpatialSelector to let you personalize the QueryPanel with default and customized spatial selector methods.

Proposal

The first aproach is available here.

You can configure the new query panel with differents pluggins for the spatial selector:

	    {
		  "ptype": "gxp_spatialqueryform",
...
		  "spatialSelectorsConfig":{
		        "bbox":{
		            "ptype": "gxp_spatial_bbox_selector"
		        },
		        "buffer":{
		            "ptype": "gxp_spatial_buffer_selector"
		        },
		        "circle":{
		            "ptype": "gxp_spatial_circle_selector",
		            "zoomToCurrentExtent": true
		        },
		        "polygon":{
		            "ptype": "gxp_spatial_polygon_selector"
		        },
		        "geocoder":{
		            "ptype": "gxp_spatial_geocoding_selector",
		            "wpsManagerID": "wpsManager",
		            "wfsBaseURL": "http://localhost:8080/geoserver/wfs?",
		            "geocoderTypeName": "topp:states",
		            "geocoderTypeRecordModel":[
		                {
		                    "name":"id",
		                    "mapping":"id"
		                },
		                {
		                    "name":"name",
		                    "mapping":"properties.STATE_NAME"
		                },
		                {
		                    "name":"custom",
		                    "mapping":"properties.SUB_REGION"
		                },
		                {
		                    "name":"geometry",
		                    "mapping":"geometry"
		                }
		            ],
		            "geocoderTypeSortBy":null,
		            "geocoderTypeQueriableAttributes":[
		                "STATE_NAME", "SUB_REGION"
		            ],
		            "spatialOutputCRS": "EPSG:4326",
		            "wpsBufferProcessID": "JTS:buffer",
		            "geocoderTypePageSize": 10,
		            "wpsUnionProcessID": "JTS:union",
		            "showSelectionSummary": true,
		            "zoomToCurrentExtent": true
		        }
	      }
    	}

The available plugins are:

  • BBOXSpatialSelectorMethod: gxp_spatial_bbox_selector
  • BufferSpatialSelectorMethod: gxp_spatial_buffer_selector
  • CircleSpatialSelectorMethod: gxp_spatial_circle_selector
  • GeocoderSpatialSelectorMethod: gxp_spatial_geocoding_selector
  • PolygonSpatialSelectorMethod: gxp_spatial_polygon_selector

and you can see a complete example here

Class/Interface Name

The design of the new Spatial Selector split each selection method as another plugin with common code in SpatialSelectorMethod.

/** api: constructor
 *  .. class:: SpatialSelectorMethod(config)
 *
 *    Common code for plugins for spatial selection.
 *    Known plugins: <ul>
 *       <li>BBOXSpatialSelectorMethod: `gxp_spatial_bbox_selector` ptype</li>
 *       <li>BufferSpatialSelectorMethod: `gxp_spatial_buffer_selector` ptype</li>
 *       <li>CircleSpatialSelectorMethod: `gxp_spatial_circle_selector` ptype</li>
 *       <li>GeocoderSpatialSelectorMethod: `gxp_spatial_geocoding_selector` ptype</li>
 *       <li>PolygonSpatialSelectorMethod: `gxp_spatial_polygon_selector` ptype</li>
 * 	  </ul>
 */
gxp.plugins.spatialselector.SpatialSelectorMethod = Ext.extend(gxp.plugins.Tool, {

	// common parameters
	currentGeometry: null,
	currentFilter: null,
	filterGeometryName: null,
	output: null,
	hideWhenDeactivate: true,
	label: "Spatial selector",
	name: "Spatial selector",
	zoomToCurrentExtent: false,

	/** api: config[defaultStyle]
	 *  ``Object``
	 */
	defaultStyle : {
		"strokeColor" : "#ee9900",
		"fillColor" : "#ee9900",
		"fillOpacity" : 0.4,
		"strokeWidth" : 1
	},

	/** api: config[selectStyle]
	 *  ``Object``
	 */
	selectStyle : {
		"strokeColor" : "#ee9900",
		"fillColor" : "#ee9900",
		"fillOpacity" : 0.4,
		"strokeWidth" : 1
	},

	/** api: config[temporaryStyle]
	 *  ``Object``
	 */
	temporaryStyle : {
		"pointRadius" : 6,
		"fillColor" : "#FF00FF",
		"strokeColor" : "#FF00FF",
		"label" : "Select",
		"graphicZIndex" : 2
	},

	// init spatialSelectors 
	constructor : function(config) {
		Ext.apply(this, config);
		
		return gxp.plugins.spatialselector.SpatialSelectorMethod.superclass.constructor.call(this, arguments);
	},

	// Generate a item for the combobox
	getSelectionMethodItem: function(){
        return {
        	label: this.label, 
        	name: this.name
        };
	},

	// Generate filter
	getQueryFilter: function(){
		this.currentFilter = new OpenLayers.Filter.Spatial({
			type: OpenLayers.Filter.Spatial.INTERSECTS,
			property:  this.filterGeometryName,
			value: this.currentGeometry,
			bounds: this.currentGeometry.getBounds()
		});

		return this.currentFilter;
	},

	// trigger action when activate the plugin
	activate: function(){
		this.reset();
		if(this.output){
			if(this.output.setDisabled){
				this.output.setDisabled(false);	
			}
			if(this.hideWhenDeactivate && this.output.show){
				this.output.show();
			}
		}else{
			this.output = this.addOutput();
		}
	},

	// trigger action when deactivate the plugin
	deactivate: function(){
		this.reset();
		if(this.output){
			if(this.output.setDisabled){
				this.output.setDisabled(true);	
			}
			if(this.hideWhenDeactivate && this.output.hide){
				this.output.hide();
			}
		}
	},

    /** api: method[addOutput]
     */
    addOutput: function() {
    	// TODO: Override it on plugins
    },

    reset: function(){
    	// TODO: Override it on plugins	
    	this.currentGeometry = null;
    	this.currentFilter = null;
    },

    // set current geometry
    setCurrentGeometry: function(geometry){
		this.currentGeometry = geometry;
    	if (geometry) {

			if (this.zoomToCurrentExtent && geometry && geometry.getBounds) {
				var dataExtent = geometry.getBounds();
				this.target.mapPanel.map.zoomToExtent(dataExtent, closest=false);
			}
		} 
    }
});

As you can see, you have some methods to interact with the new plugin that delegates on each spatial selector method:

/** api: constructor
 *  .. class:: SpatialSelector(config)
 *
 *    Spatial selector with pluggable colectors**: 
 */
gxp.plugins.spatialselector.SpatialSelector = Ext.extend(gxp.plugins.Tool, {

...

    // reset 
    reset: function(){
    	if(this.spatialSelectors){
	    	for (var key in this.spatialSelectors){
	    		this.spatialSelectors[key].deactivate();
	    		this.activeMethod = null;
	    	}
	    	if(!this._updating 
	    		&& this.defaultSelectionMethod
	    		&& this.spatialSelectors[this.defaultSelectionMethod]){
	    		this.spatialSelectors[this.defaultSelectionMethod].activate();
				this.activeMethod = this.spatialSelectors[this.defaultSelectionMethod];
	    	}
    	}
    },

	// Generate filter
	getQueryFilter: function(){
		if(this.activeMethod){
			this.activeMethod.filterGeometryName = this.filterGeometryName;
			return this.activeMethod.getQueryFilter();
		}else{
			return null;
		}
	},

	// Get geometry
	getGeometry: function(){
		if(this.activeMethod){
			return this.activeMethod.currentGeometry;
		}else{
			return null;
		}
	}

});
  • getGeometry: Get the geometry selected on the selected method
  • getQueryFilter: Get a filter based on the selecter geometry

You can extend it as you want, but you have available this methods based on the old implementation:

BBOXSpatialSelectorMethod

  • ptype: gxp_spatial_bbox_selector

Configuration

  • zoomToCurrentExtent: enable the zoom to the selected extent when you select the geometry on each selection method
  • defaultStyle: Style for features drawn
  • selectStyle: Style for selected features drawn
  • temporaryStyle: Style for features drawn in this state

BufferSpatialSelectorMethod

  • ptype: gxp_spatial_buffer_selector

Configuration

  • zoomToCurrentExtent: enable the zoom to the selected extent when you select the geometry on each selection method
  • defaultStyle: Style for features drawn
  • selectStyle: Style for selected features drawn
  • temporaryStyle: Style for features drawn in this state
  • bufferOptions: Map with Buffer spatial selector options: minValue, maxValue, decimalPrecision, distanceUnits`.
  • geodesic: Use geodesic on the buffer fieldset

CircleSpatialSelectorMethod

  • ptype: gxp_spatial_circle_selector

Configuration

  • zoomToCurrentExtent: enable the zoom to the selected extent when you select the geometry on each selection method
  • defaultStyle: Style for features drawn
  • selectStyle: Style for selected features drawn
  • temporaryStyle: Style for features drawn in this state

PolygonSpatialSelectorMethod

  • ptype: gxp_spatial_polygon_selector

Configuration

  • zoomToCurrentExtent: enable the zoom to the selected extent when you select the geometry on each selection method
  • defaultStyle: Style for features drawn
  • selectStyle: Style for selected features drawn
  • temporaryStyle: Style for features drawn in this state

GeocoderSpatialSelectorMethod

  • ptype: gxp_spatial_geocoding_selector

Configuration

  • zoomToCurrentExtent: enable the zoom to the selected extent when you select the geometry on each selection method
  • defaultStyle: Style for features drawn
  • selectStyle: Style for selected features drawn
  • temporaryStyle: Style for features drawn in this state
  • labelStyle: Style for the label on selected features
  • wfsBaseURL: WFS Base URL
  • geocoderTypeName: Type name to perform the query
  • geocoderTypeTpl: Tpl for the Geocoder combo items
  • geocoderTypeRecordModel: Record model for the geocoder combo
  • geocoderTypeSortBy: If you want to order the WFS query, put here the order. If you won't, put a null inside
  • geocoderTypeQueriableAttributes: Fetaure properties array to perform the query
  • geocoderTypeDisplayField: Feature type property to select as name on the grid.
  • geocoderTypePageSize: Page size for the WFS search combo
  • wpsUnionProcessID: ID of the WPS Union Process. Default is JTS:union
  • wpsManagerID: Id of the WPS Manager to be used for the union. If it's null, or the tool is not found, it will disable the multiple selection
  • multipleSelection: Append a grid and allow multiple WFS record selections. It needs a WPS manager configured.

Feedback

This section should contain feedback provided by members who may have a problem with the proposal.

Pending issues

  • Sometimes geocoder combobox is not loaded.
  • Improve geocoder to allow work without WPS selecting only one record to perform the query
  • Improve code documentation.

Backwards Compatibility

The old spatial selector field and query panel are already available, but they are deprecated.

Voting

Alejandro Díaz: +1

Clone this wiki locally