[fusion-commits] r2721 - trunk/lib

svn_fusion at osgeo.org svn_fusion at osgeo.org
Tue May 28 23:54:18 PDT 2013


Author: jng
Date: 2013-05-28 23:54:18 -0700 (Tue, 28 May 2013)
New Revision: 2721

Modified:
   trunk/lib/Map.js
Log:
#570: Add digitization APIs to the Map widget. The new APIs are:
 * digitizePoint/digitizeLine/digitizeLineString/digitizeRectangle/digitizePolygon - Performs the digitization and passes the digitized OpenLayers.Geometry to the supplied callback function. These APIs include a options parameter where a prompt can be specified. If specified, the MapMessage component is used to display the prompt for the duration of digitization.
 * cancelDigitization - To cancel the digitization process. A keypress handler has been added so that ESC keypress hooks into this function.
 * isDigitizing - Indicates if digitization is in process

Modified: trunk/lib/Map.js
===================================================================
--- trunk/lib/Map.js	2013-05-29 03:53:11 UTC (rev 2720)
+++ trunk/lib/Map.js	2013-05-29 06:54:18 UTC (rev 2721)
@@ -127,6 +127,13 @@
  * **********************************************************************/
 Fusion.Widget.Map = OpenLayers.Class(Fusion.Lib.EventMgr, {
     
+    ID_DIGITIZING_LAYER: "FusionMapDigitizingLayer",
+    DRAW_CONTROL_POINT: "FusionMapDrawPoint",
+    DRAW_CONTROL_LINE: "FusionMapDrawLine",
+    DRAW_CONTROL_LINESTR: "FusionMapDrawLineString",
+    DRAW_CONTROL_RECT: "FusionMapDrawRect",
+    DRAW_CONTROL_POLY: "FusionMapDrawPoly",
+    
     /** The DOM object that holds the map */
     _oDomObj: null,
     
@@ -181,12 +188,22 @@
     maxScale: null, //set this to a large number in AppDef to zoom out beyond maxExtent, e.g. 1 billion
 
     /**
+     * Property: isDigitizing
+     *
+     * Gets whether a digitizer is currently active
+     */
+    isDigitizing: false,
+
+    /**
      * Property: message
      * 
      * The {<Fusion.MapMessage>} notification bar
      */
     message: null,
 
+    /** The OL style map for digitizing **/
+    digitizingStyleMap: null,
+
     /**
      * construct a new view Fusion.Widget.Map class.
      */
@@ -306,6 +323,19 @@
         this.aSelectionCallbacks = [];
         this.bFetchingSelection = false;
 
+        //Create style map
+        this.digitizingStyleMap = new OpenLayers.StyleMap(new OpenLayers.Style({
+            pointRadius: 4,
+            graphicName: "square",
+            fillColor: "white",
+            fillOpacity: 0.4,
+            strokeWidth: 2,
+            strokeOpacity: 1,
+            strokeColor: "#666666",
+            strokeColor: "#666666"
+        }));
+        this.keyHandler = OpenLayers.Function.bind(this.onKeyPress, this);
+
         //create the 'Map' layer widgets defined in the MapGroup
         this.loadMapGroup(mapGroup);
     },
@@ -320,8 +350,8 @@
      * Return: none
      */
     mapLoaded: function() {
-      this.setViewOptions(this.getUnits());
-      this.loadScaleRanges(OpenLayers.Function.bind(this.scaleRangesLoaded, this));
+        this.setViewOptions(this.getUnits());
+        this.loadScaleRanges(OpenLayers.Function.bind(this.scaleRangesLoaded, this));
     },
 
     /**
@@ -578,6 +608,9 @@
 
         var initialExtent = this.setInitialExtents();
         this.setExtents(initialExtent);
+        
+        //Start observing keypresses
+        OpenLayers.Event.observe(document,"keypress",this.keyHandler);
 
         this.triggerEvent(Fusion.Event.MAP_LOADED, mapTag);
     },
@@ -1646,28 +1679,287 @@
         return OpenLayers.Util.getParameterString(queryParams);
      },
      
-     supressContextMenu: function( bSupress ) {
-         this.bSupressContextMenu = bSupress;
-     },
+    supressContextMenu: function( bSupress ) {
+        this.bSupressContextMenu = bSupress;
+    },
 
-     setContextMenu: function(menu) {                         
-         //console.log('setcontextmenu');
-         this.oContextMenu = menu;
-     },
+    setContextMenu: function(menu) {                         
+        //console.log('setcontextmenu');
+        this.oContextMenu = menu;
+    },
 
-     onContextMenu: function(e) {
-         //console.log('oncontextmenu');
-         if (this.oContextMenu && !this.bSupressContextMenu && this.isLoaded()) {
-             this.oContextMenu.show(new Event(e));
-             this.contextMenuPosition = this.getEventPosition(e);
-             OpenLayers.Event.stop(e);
-         }
-     },
+    onContextMenu: function(e) {
+        //console.log('oncontextmenu');
+        if (this.oContextMenu && !this.bSupressContextMenu && this.isLoaded()) {
+            this.oContextMenu.show(new Event(e));
+            this.contextMenuPosition = this.getEventPosition(e);
+            OpenLayers.Event.stop(e);
+        }
+    },
 
-     executeFromContextMenu: function(widget) {
-         //console.log('executefromcontextmenu');
-         widget.activate(this.contextMenuPosition.x, this.contextMenuPosition.y);
-     }
+    executeFromContextMenu: function(widget) {
+     //console.log('executefromcontextmenu');
+     widget.activate(this.contextMenuPosition.x, this.contextMenuPosition.y);
+    },
+    _getDigitizingLayer: function() {
+        var layer = this.oMapOL.getLayer(this.ID_DIGITIZING_LAYER);
+        if (layer == null) {
+            layer = new OpenLayers.Layer.Vector("Digitizing Layer", { styleMap: this.digitizingStyleMap });
+            this.oMapOL.addLayers([layer]);
+        }
+        return layer;
+    },
+    /**
+     * Method: cancelDigitization
+     *
+     * De-activates any active digitizers
+     */
+    cancelDigitization: function() {
+        //Don't trigger until the end
+        this._deactivateDigitizer(this.DRAW_CONTROL_POINT, false, true);
+        this._deactivateDigitizer(this.DRAW_CONTROL_LINE, false, true);
+        this._deactivateDigitizer(this.DRAW_CONTROL_LINESTR, false, true);
+        this._deactivateDigitizer(this.DRAW_CONTROL_RECT, false, true);
+        this._deactivateDigitizer(this.DRAW_CONTROL_POLY, false, true);
+        this._triggerDigitizerDeactivated();
+    },
+    _onGeometryDigitized: function(evt, controlId, origCallback) {
+        this._deactivateDigitizer(controlId, true, true);
+        origCallback(evt.feature.geometry);
+    },
+    _setDigitizationPrompt: function(prompt) {
+        this.message.info(prompt + ' <a id="abortDigitizationLink" href="javascript:void(0)">' + OpenLayers.i18n("stop") + '</a>');
+        var link = this.message.container.ownerDocument.getElementById("abortDigitizationLink");
+        //Wire the anchor click
+        link.onclick = OpenLayers.Function.bind(function() {
+            this.cancelDigitization();
+        }, this);
+    },
+    _deactivateDigitizer: function(controlId, bTrigger, bUnsub) {
+        var ctrl = this.oMapOL.getControl(controlId);
+        if (ctrl) {
+            ctrl.deactivate();
+            ctrl.layer.removeAllFeatures();
+            if (bUnsub)
+                ctrl.events.remove("featureadded");
+        }
+        if (bTrigger)
+            this._triggerDigitizerDeactivated();
+    },
+    _activateDigitizer: function(ctrl, controlId, origCallback) {
+        //Register for one-shot callback notification
+        if (ctrl.events) {
+            var oneShotHandler = OpenLayers.Function.bind(function(cid, evt) {
+                ctrl.events.unregister("featureadded", null, oneShotHandler);
+                console.log("De-registered one-shot callback for: " + cid)
+                this._onGeometryDigitized(evt, cid, origCallback);
+            }, this, controlId);
+            ctrl.events.register("featureadded", null, oneShotHandler);
+            console.log("Register one-shot callback for: " + controlId);
+        }
+        ctrl.activate();
+        this._triggerDigitizerActivated();
+    },
+    _triggerDigitizerActivated: function() {
+        this.isDigitizing = true;
+        this.triggerEvent(Fusion.Event.MAP_DIGITIZER_ACTIVATED);
+        console.log("digitizer activated")
+    },
+    _triggerDigitizerDeactivated: function() {
+        this.isDigitizing = false;
+        try {
+            this.message.clear();
+        } catch (e) {}
+        this.triggerEvent(Fusion.Event.MAP_DIGITIZER_DEACTIVATED);
+        console.log("digitizer de-activated")
+    },
+    onKeyPress: function(e) {
+        if (this.isDigitizing) {
+            var charCode = (e.charCode) ? e.charCode : ((e.keyCode) ? e.keyCode : e.which);
+            if (charCode == OpenLayers.Event.KEY_ESC) {
+                this.cancelDigitization();
+            }
+        }
+    },
+    /**
+     * Method: digitizePoint
+     *
+     * Digitizes a point and passes the value to a function for processing. Digitization can be cancelled via the cancelDigitization()
+     * method or via pressing the ESC key
+     *
+     * Parameters:
+     * callback - {Function} The callback function that will receive the digitized geometry
+     *
+     * Return:
+     * {OpenLayers.Geometry.Point}
+     */
+    digitizePoint: function(options, callback) {
+        var ctrl = this.oMapOL.getControl(this.DRAW_CONTROL_POINT);
+        if (ctrl == null) {
+            ctrl = new OpenLayers.Control.DrawFeature(
+                this._getDigitizingLayer(),
+                OpenLayers.Handler.Point, {
+                    id: this.DRAW_CONTROL_POINT,
+                    handlerOptions: {
+                        layerOptions: {
+                            styleMap: this.digitizingStyleMap
+                        }
+                    }
+                });
+            this.oMapOL.addControl(ctrl);
+        }
+        if (options.prompt) {
+            this._setDigitizationPrompt(options.prompt);
+        }
+        this._activateDigitizer(ctrl, this.DRAW_CONTROL_POINT, callback);
+    },
+    /**
+     * Method: digitizeLine
+     *
+     * Digitizes a line and passes the value to a function for processing. Digitization can be cancelled via the cancelDigitization()
+     * method or via pressing the ESC key
+     *
+     * Parameters:
+     * options - {Object} digitization options
+     * callback - {Function} The callback function that will receive the digitized geometry
+     *
+     * Return:
+     * {OpenLayers.Geometry.LineString}
+     */
+    digitizeLine: function(options, callback) {
+        var ctrl = this.oMapOL.getControl(this.DRAW_CONTROL_LINE);
+        if (ctrl == null) {
+            ctrl = new OpenLayers.Control.DrawFeature(
+                this._getDigitizingLayer(),
+                OpenLayers.Handler.Path, {
+                    id: this.DRAW_CONTROL_LINE,
+                    handlerOptions: {
+                        maxVertices: 2,
+                        freehandToggle: null, 
+                        freehand: false, 
+                        persist: true,
+                        style: "default", // this forces default render intent
+                        layerOptions: {
+                            styleMap: this.digitizingStyleMap
+                        }
+                    }
+                });
+            this.oMapOL.addControl(ctrl);
+        }
+        if (options.prompt) {
+            this._setDigitizationPrompt(options.prompt);
+        }
+        this._activateDigitizer(ctrl, this.DRAW_CONTROL_LINE, callback);
+    },
+    /**
+     * Method: digitizeLineString
+     *
+     * Digitizes a line string and passes the value to a function for processing. Digitization can be cancelled via the cancelDigitization()
+     * method or via pressing the ESC key
+     *
+     * Parameters:
+     * options - {Object} digitization options
+     * callback - {Function} The callback function that will receive the digitized geometry
+     *
+     * Return:
+     * {OpenLayers.Geometry.LineString}
+     */
+    digitizeLineString: function(options, callback) {
+        var ctrl = this.oMapOL.getControl(this.DRAW_CONTROL_LINESTR);
+        if (ctrl == null) {
+            ctrl = new OpenLayers.Control.DrawFeature(
+                this._getDigitizingLayer(),
+                OpenLayers.Handler.Path, {
+                    id: this.DRAW_CONTROL_LINESTR,
+                    handlerOptions: {
+                        freehand: false, 
+                        persist: true, 
+                        style: "default", // this forces default render intent
+                        layerOptions: {
+                            styleMap: this.digitizingStyleMap
+                        }
+                    }
+                });
+            this.oMapOL.addControl(ctrl);
+        }
+        if (options.prompt) {
+            this._setDigitizationPrompt(options.prompt);
+        }
+        this._activateDigitizer(ctrl, this.DRAW_CONTROL_LINESTR, callback);
+    },
+    /**
+     * Method: digitizeRectangle
+     *
+     * Digitizes a rectangle and passes the value to a function for processing. Digitization can be cancelled via the cancelDigitization()
+     * method or via pressing the ESC key
+     *
+     * Parameters:
+     * options - {Object} digitization options
+     * callback - {Function} The callback function that will receive the digitized geometry
+     *
+     * Return:
+     * {OpenLayers.Geometry.Polygon}
+     */
+    digitizeRectangle: function(options, callback) {
+        var ctrl = this.oMapOL.getControl(this.DRAW_CONTROL_RECT);
+        if (ctrl == null) {
+            ctrl = new OpenLayers.Control.DrawFeature(
+                this._getDigitizingLayer(),
+                OpenLayers.Handler.RegularPolygon, {
+                    id: this.DRAW_CONTROL_RECT,
+                    handlerOptions: {
+                        persist: true, 
+                        sides: 4, 
+                        irregular: true,
+                        style: "default", // this forces default render intent
+                        layerOptions: {
+                            styleMap: this.digitizingStyleMap
+                        }
+                    }
+                });
+            this.oMapOL.addControl(ctrl);
+        }
+        if (options.prompt) {
+            this._setDigitizationPrompt(options.prompt);
+        }
+        this._activateDigitizer(ctrl, this.DRAW_CONTROL_RECT, callback);
+    },
+    /**
+     * Method: digitizePolygon
+     *
+     * Digitizes a polygon and passes the value to a function for processing. Digitization can be cancelled via the cancelDigitization()
+     * method or via pressing the ESC key
+     *
+     * Parameters:
+     * options - {Object} digitization options
+     * callback - {Function} The callback function that will receive the digitized geometry
+     *
+     * Return:
+     * {OpenLayers.Geometry.Polygon}
+     */
+    digitizePolygon: function(options, callback) {
+        var ctrl = this.oMapOL.getControl(this.DRAW_CONTROL_POLY);
+        if (ctrl == null) {
+            ctrl = new OpenLayers.Control.DrawFeature(
+                this._getDigitizingLayer(),
+                OpenLayers.Handler.Polygon, {
+                    id: this.DRAW_CONTROL_POLY,
+                    handlerOptions: {
+                        freehand: false, 
+                        persist: true, 
+                        style: "default", // this forces default render intent
+                        layerOptions: {
+                            styleMap: this.digitizingStyleMap
+                        }
+                    }
+                });
+            this.oMapOL.addControl(ctrl);
+        }
+        if (options.prompt) {
+            this._setDigitizationPrompt(options.prompt);
+        }
+        this._activateDigitizer(ctrl, this.DRAW_CONTROL_POLY, callback);
+    }
 });
 
 /**



More information about the fusion-commits mailing list