[Commits] r2872 - sandbox/mapgears/geoext.ux/ux/ZoomTo/lib/GeoExt.ux/widgets

commits at geoext.org commits at geoext.org
Fri Feb 3 17:46:09 CET 2012


Author: adube
Date: 2012-02-03 17:46:09 +0100 (Fri, 03 Feb 2012)
New Revision: 2872

Modified:
   sandbox/mapgears/geoext.ux/ux/ZoomTo/lib/GeoExt.ux/widgets/ZoomTo.js
Log:
ZoomTo ux - dragging support, reproject on projection change, external recentering now possible, various cleanup

Modified: sandbox/mapgears/geoext.ux/ux/ZoomTo/lib/GeoExt.ux/widgets/ZoomTo.js
===================================================================
--- sandbox/mapgears/geoext.ux/ux/ZoomTo/lib/GeoExt.ux/widgets/ZoomTo.js	2012-01-25 10:38:41 UTC (rev 2871)
+++ sandbox/mapgears/geoext.ux/ux/ZoomTo/lib/GeoExt.ux/widgets/ZoomTo.js	2012-02-03 16:46:09 UTC (rev 2872)
@@ -63,11 +63,55 @@
     outOfRangCoordsText: "Coordinates are out of current extent range.",
     /* end i18n */
 
-    /** private: property[window]
-     *  ``Ext.Window``
+    // Public Properties
+
+    /** public: property[autoHideWindowOnZoom]
+     *  ``Boolean``
+     *  If set to true, hides the window after recentering.
      */
-    window: null,
+    autoHideWindowOnZoom: true,
 
+    /** public: property[defaultZoomLevel]
+     *  ``Integer``
+     */
+    defaultZoomLevel: null,
+
+    /** public: property[defaultZoomLevel]
+     *  ``Boolean``
+     *  Defaults to false.  If set to true, the center marker can be dragged.
+     */
+    enableDrag: false,
+
+    /** public: property[showCenter]
+     *  ``Boolean``
+     *  If set to true, shows a red cross marker on the center of the map
+     *  after recentering.
+     */
+    showCenter: true,
+
+    /** public: property[useIcons]
+     *  ``Boolean``
+     *  If set to true, enables the use of image icons.  Must be combined with
+     *  a .css (see in resources/css).
+     */
+    useIcons: true,
+
+    // Private Properties
+
+    /** private: property[currentProjection]
+     *  ``String``
+     *  Automatically set to a projection code from the comboBox on select.
+     */
+    currentProjection: null,
+
+    /** private: property[dragControl]
+     *  ``OpenLayers.Control.Drag``
+     *  Used to drag the center marker around after recentering.  The position
+     *  displayed in the fields is automatically changed according to its new
+     *  position.
+     */
+    dragControl: null,
+
     /** private: property[form]
      *  ``Ext.form.FormPanel``
      */
@@ -83,31 +127,11 @@
      */
     projectionStore: null,
 
-    /** private: property[defaultZoomLevel]
-     *  ``Integer``
+    /** private: property[window]
+     *  ``Ext.Window``
      */
-    defaultZoomLevel: null,
+    window: null,
 
-    /** private: property[autoHideWindowOnZoom]
-     *  ``Boolean``
-     *  If set to true, hides the window after recentering.
-     */
-    autoHideWindowOnZoom: true,
-
-    /** private: property[useIcons]
-     *  ``Boolean``
-     *  If set to true, enables the use of image icons.  Must be combined with
-     *  a .css (see in resources/css).
-     */
-    useIcons: true,
-
-    /** private: property[showCenter]
-     *  ``Boolean``
-     *  If set to true, shows a red cross marker on the center of the map
-     *  after recentering.
-     */
-    showCenter: true,
-
     /** private: method[constructor]
      */
     constructor: function(config) {
@@ -122,6 +146,8 @@
         } else {
             this.setText(this.zoomToText);
         }
+
+        this.createWindow();
     },
 
     /** private: method[initMap]
@@ -146,115 +172,142 @@
      *  Called when action is clicked.
      */
     onActionClick: function() {
-        if (!this.window) {
+        this.window.show();
+    },
 
-            if (!this.projectionStore) {
-                this.projectionStore = new Ext.data.SimpleStore({
-                    fields: ['projection'],
-                    data : [
-                        ['EPSG:4326'],
-                        ['EPSG:900913']
-                    ]
-                });
-            }
-                        
-            // get first value of store as default value
-            var defaultProj = this.projectionStore.data.items[0].data[
-                this.projectionStore.getAt(0).fields.get(0)['name']
-            ];
-
-            // FormPanel
-            this.form = new Ext.form.FormPanel({
-                border: false,
-                plain: true,
-                defaults: {width: 170},
-                defaultType: 'textfield',
-                labelAlign: 'top',
-                bodyStyle:'padding:5px 5px 0',
-                items: [{
-                        fieldLabel: this.xCoordinateText,
-                        name: 'coordx'
-                    },{
-                        fieldLabel: this.yCoordinateText,
-                        name: 'coordy' 
-                    },{
-                        fieldLabel: this.projectionText,
-                        name: 'projection',
-                        value: defaultProj,
-                        xtype: 'combo',
-                        store: this.projectionStore,
-                        displayField: 'projection',
-                        typeAhead: true,
-                        mode: 'local',
-                        forceSelection: true,
-                        triggerAction: 'all',
-                        allowBlank: false,
-                        invalidText: this.invalidEntryText,
-                        emptyText: "",
-                        selectOnFocus:true
-                    }
+    /** private: method[createWindow]
+     *  Creates a new Ext.Window object containing all fields used to zoom
+     */
+    createWindow: function() {
+        if (!this.projectionStore) {
+            this.projectionStore = new Ext.data.SimpleStore({
+                fields: ['projection'],
+                data : [
+                    ['EPSG:4326'],
+                    ['EPSG:900913']
                 ]
             });
+        }
 
-            var windowButtons = [];
+        // get first value of store as default value
+        var defaultProj = this.projectionStore.data.items[0].data[
+            this.projectionStore.getAt(0).fields.get(0)['name']
+        ];
+        this.currentProjection = defaultProj;
 
-            // remove marker button (optional)
-            if (this.showCenter === true) {
-                windowButtons.push({
-                    text: this.destroyMarkerActionText,
-                    scope: this,
-                    handler: function(){
-                        this.destroyMarker();
+        // FormPanel
+        this.form = new Ext.form.FormPanel({
+            border: false,
+            plain: true,
+            defaults: {width: 170},
+            defaultType: 'textfield',
+            labelAlign: 'top',
+            bodyStyle:'padding:5px 5px 0',
+            items: [{
+                    fieldLabel: this.xCoordinateText,
+                    name: 'coordx'
+                },{
+                    fieldLabel: this.yCoordinateText,
+                    name: 'coordy' 
+                },{
+                    fieldLabel: this.projectionText,
+                    name: 'projection',
+                    value: defaultProj,
+                    xtype: 'combo',
+                    store: this.projectionStore,
+                    displayField: 'projection',
+                    typeAhead: true,
+                    mode: 'local',
+                    forceSelection: true,
+                    triggerAction: 'all',
+                    allowBlank: false,
+                    invalidText: this.invalidEntryText,
+                    emptyText: "",
+                    selectOnFocus:true,
+                    listeners: {
+                        "select": this.onProjectionSelect,
+                        scope: this
                     }
-                });
-            }
-
-            // close button
-            /*
-            windowButtons.push({
-                text: this.closeActionText,
-                scope: this,
-                handler: function(){
-                    this.window.hide();
                 }
-            });
-            */
+            ]
+        });
 
-            // zoom button
+        var windowButtons = [];
+
+        // remove marker button (optional)
+        if (this.showCenter === true) {
             windowButtons.push({
-                text: this.zoomActionText,
+                text: this.destroyMarkerActionText,
                 scope: this,
                 handler: function(){
-                    this.recenter();
+                    this.destroyMarker();
+                    this.dragControl && this.dragControl.deactivate();
                 }
             });
-
-            // Window with buttons
-            this.window = new Ext.Window({
-                title: this.widgetTitleText,
-                layout: 'form',
-                width: 200,
-                autoHeight: true,
-                height: 'auto',
-                closeAction: 'hide',
-                modal: false,
-                plain: false,
-                resizable: false,
-                buttonAlign: 'center',
-                items: [this.form],
-                buttons: windowButtons
-            });
         }
 
-        this.window.show();
+        // zoom button
+        windowButtons.push({
+            text: this.zoomActionText,
+            scope: this,
+            handler: function(){
+                this.recenter(this.form.getForm().getValues());
+            }
+        });
+
+        // Window with buttons
+        this.window = new Ext.Window({
+            title: this.widgetTitleText,
+            layout: 'form',
+            width: 200,
+            autoHeight: true,
+            height: 'auto',
+            closeAction: 'hide',
+            modal: false,
+            plain: false,
+            resizable: false,
+            buttonAlign: 'center',
+            items: [this.form],
+            buttons: windowButtons
+        });
     },
 
-    /** private: method[recenter]
-     * Recenters map using user-provided coordinates and scale.
+    /** private: method[onProjctionSelect]
+     *  :param comboBox: ``Ext.form.ComboBox``
+     *  :param record: ``Ext.data.Record``
+     *  :param index: ``Integer``
+     *  
+     *  Callback method of the projection comboBox "select" event.  Manage
+     *  projection change and reproject the coordinates if any.
      */
-    recenter: function() {
+    onProjectionSelect: function(comboBox, record, index) {
+        var newProj = record.get("projection");
+        if (this.currentProjection == newProj) {
+            return;
+        }
+        // manage projection change
+        var oldProj = this.currentProjection;
         var values = this.form.getForm().getValues();
+        if (values.coordx != "" && values.coordy != "") {
+            var point = this.getTransformedCoords(
+                values.coordx, values.coordy, oldProj, newProj);
+            this.setValues({coordx: point.x, coordy: point.y});
+        }
+        this.currentProjection = newProj;
+    },
 
+    /** public: method[recenter]
+     *  :param values: ``Object`` Hash of values to uze to recenter.  Possible
+     *                            values are :
+     *    - coordx     : (Float) Mandatory. The X coordinate
+     *    - coordy     : (Float) Mandatory. The Y coordinate
+     *    - projection : (String) Mandatory.  The projection code of the
+     *                   coordinates
+     *    - zoom       : (Integer) Optional.  The zoom level to use
+     *  
+     *  Recenters map using user-provided coordinates and scale.
+     */
+    recenter: function(values) {
         if (values.projection == "") {
             this.showError(this.missingProjectionText);
             return false;
@@ -271,8 +324,11 @@
             
             var zoom;
 
-            if (this.scales && values.scaleValue) {
-                // use user-provided scale
+            if (Ext.isNumber(values.zoom)) {
+                // use user-provided zoom
+                zoom = values.zoom;
+            } else if (this.scales && values.scaleValue) {
+                // use user-provided scale to calculate zoom
                 resolution = OpenLayers.Util.getResolutionFromScale(values.scaleValue,
                 this.map.units);
                 zoom = this.map.getZoomForResolution(resolution);
@@ -284,37 +340,42 @@
         }
     },
 
-    /** private: method[checkCoords]
-     *  Checks that submitted coordinates are well-formatted and within the map
-     *      bounds.
+    /** public: method[setValues]
+     *  :param values: ``Object`` Hash of values to uze to recenter.  See
+     *                            above 'recenter' method to know possible keys
+     *  
+     *  Sets values for fields in basic form in bulk.  Also set current
+     *  projection if set in values.
+     */
+    setValues: function(values) {
+        if (values.projection) {
+            this.currentProjection = values.projection;
+        }
+        this.form.getForm().setValues(values);
+    },
+
+    /** private: method[getTransformedCoords]
+     *  :param x: ``Float`` easting coordinate
+     *  :param y: ``Float`` northing coordinate
+     *  :param source: ``String`` projection code to use as source
+     *  :param dest: ``String`` projection code to use as destination.
+     *                          Defaults to map projection.
+     *  :return: ``Object`` containing x and y properties
      *
-     *  Parameters:
-     *  x    {Float}  - easting coordinate
-     *  y    {Float}  - northing coordinate
-     *  proj {String} - projection of inputed coordinates
-     *
-     *  Returns: 
-     *  {Object}
+     *  Returns an object containing x and y properties. Transform using
+     *  given projections if needed.
      */
-    getTransformedCoords: function(x, y, proj) {
-        var transformedCoords = {};
-
-        if (this.map.getProjection() === proj) {
-            transformedCoords['x'] = x;
-            transformedCoords['y'] = y;
+    getTransformedCoords: function(x, y, source, dest) {
+        dest = dest || this.map.getProjection();
+        if (dest === source) {
+            return {x: x, y: y};
         } else {
-            var objProj = new OpenLayers.Projection(proj);
-            var point = new OpenLayers.LonLat(x, y);
-            point.transform(
-                objProj,
-                new OpenLayers.Projection(this.map.getProjection())
+            var transformed = new OpenLayers.LonLat(x, y).transform(
+                new OpenLayers.Projection(source),
+                new OpenLayers.Projection(dest)
             );
-
-            transformedCoords['x'] = point.lon;
-            transformedCoords['y'] = point.lat;
+            return {x: transformed.lon, y: transformed.lat};
         }
-
-        return transformedCoords;
     },
 
     /** private: method[checkCoords]
@@ -385,6 +446,7 @@
      */
     showCenterMark: function(x, y) {
         this.prepareVectorLayer();
+        this.enableDrag && this.prepareDragControl();
 
         var features = [
             new OpenLayers.Feature.Vector(
@@ -425,6 +487,41 @@
         }
     },
 
+    /** private: method[prepareVectorLayer]
+     *  Adds a layer for displaying the center symbol. If it is already set,
+     *  removes existing features.
+     */
+    prepareDragControl: function() {
+        if (!this.dragControl) {
+            this.dragControl = new OpenLayers.Control.DragFeature(
+                this.vectorLayer, {
+                    onDrag: this.onMarkerDrag,
+                    zoomToWidget: this
+                }
+            );
+            this.map.addControl(this.dragControl);
+        }
+        this.dragControl.activate();
+    },
+
+    /** private: method[onMarkerDrag]
+     *  Callback method of the drag control. Triggered when the marker is
+     *  dragged.
+     */
+    onMarkerDrag: function(feature, pixel) {
+        var me = this.zoomToWidget;
+        var point = me.getTransformedCoords(
+            feature.geometry.x,
+            feature.geometry.y,
+            me.map.getProjection(),
+            me.form.getForm().getValues().projection
+        );
+        me.setValues({
+            coordx: point.x,
+            coordy: point.y
+        });
+    },
+
     /** private: method[destroyMarker]
      *  Removes existing features from vector layer
      */



More information about the Commits mailing list