← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 5901: (GIS) New layer called 'Boundary layer' implemented. Lets you draw borders (no data) from stored ...

 

Merge authors:
  Jan Henrik Øverland (janhenrik-overland)
------------------------------------------------------------
revno: 5901 [merge]
committer: Jan Henrik Overland <janhenrik.overland@xxxxxxxxx>
branch nick: dhis2
timestamp: Thu 2012-02-09 16:18:09 +0100
message:
  (GIS) New layer called 'Boundary layer' implemented. Lets you draw borders (no data) from stored coordinates on top of Google Maps / below the thematic layers.
added:
  dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/images/boundary.png
  dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/images/boundary_small.png
  dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/resources/mapfish/core/GeoStat/Boundary.js
  dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/resources/mapfish/widgets/geostat/Boundary.js
renamed:
  dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/geojson.vm => dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/geojsonmin.vm
  dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/geojsonmin.vm => dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/geojsonminValues.vm
modified:
  dhis-2/dhis-web/dhis-web-mapping/src/main/java/org/hisp/dhis/mapping/action/GetGeoJsonAction.java
  dhis-2/dhis-web/dhis-web-mapping/src/main/resources/org/hisp/dhis/mapping/i18n_module.properties
  dhis-2/dhis-web/dhis-web-mapping/src/main/resources/org/hisp/dhis/mapping/i18n_module_fr_FR.properties
  dhis-2/dhis-web/dhis-web-mapping/src/main/resources/struts.xml
  dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/i18n.vm
  dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/mapping/css/style.css
  dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/mapping/javascript/global.js
  dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/mapping/javascript/index.js
  dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/resources/mapfish/MapFish.js
  dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/resources/mapfish/widgets/geostat/Choropleth.js
  dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/geojsonmin.vm


--
lp:dhis2
https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk

Your team DHIS 2 developers is subscribed to branch lp:dhis2.
To unsubscribe from this branch go to https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription
=== added file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/images/boundary.png'
Binary files dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/images/boundary.png	1970-01-01 00:00:00 +0000 and dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/images/boundary.png	2012-02-08 15:15:18 +0000 differ
=== added file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/images/boundary_small.png'
Binary files dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/images/boundary_small.png	1970-01-01 00:00:00 +0000 and dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/images/boundary_small.png	2012-02-08 15:15:18 +0000 differ
=== modified file 'dhis-2/dhis-web/dhis-web-mapping/src/main/java/org/hisp/dhis/mapping/action/GetGeoJsonAction.java'
--- dhis-2/dhis-web/dhis-web-mapping/src/main/java/org/hisp/dhis/mapping/action/GetGeoJsonAction.java	2011-12-26 10:07:59 +0000
+++ dhis-2/dhis-web/dhis-web-mapping/src/main/java/org/hisp/dhis/mapping/action/GetGeoJsonAction.java	2012-02-08 15:15:18 +0000
@@ -123,4 +123,4 @@
 
         return SUCCESS;
     }
-}
+}
\ No newline at end of file

=== modified file 'dhis-2/dhis-web/dhis-web-mapping/src/main/resources/org/hisp/dhis/mapping/i18n_module.properties'
--- dhis-2/dhis-web/dhis-web-mapping/src/main/resources/org/hisp/dhis/mapping/i18n_module.properties	2012-02-07 16:24:39 +0000
+++ dhis-2/dhis-web/dhis-web-mapping/src/main/resources/org/hisp/dhis/mapping/i18n_module.properties	2012-02-08 15:15:18 +0000
@@ -297,3 +297,4 @@
 centroid_layer=Symbol layer
 no_values_found=No values found
 close=Close
+boundary_layer=Boundary layer

=== modified file 'dhis-2/dhis-web/dhis-web-mapping/src/main/resources/org/hisp/dhis/mapping/i18n_module_fr_FR.properties'
--- dhis-2/dhis-web/dhis-web-mapping/src/main/resources/org/hisp/dhis/mapping/i18n_module_fr_FR.properties	2012-02-07 16:24:39 +0000
+++ dhis-2/dhis-web/dhis-web-mapping/src/main/resources/org/hisp/dhis/mapping/i18n_module_fr_FR.properties	2012-02-08 15:15:18 +0000
@@ -297,3 +297,4 @@
 centroid_layer=Couche de symboles
 no_values_found=Aucune valeurs trouv\u00e9e
 close=Fermer
+boundary_layer=Couche de limite

=== modified file 'dhis-2/dhis-web/dhis-web-mapping/src/main/resources/struts.xml'
--- dhis-2/dhis-web/dhis-web-mapping/src/main/resources/struts.xml	2011-12-05 13:32:32 +0000
+++ dhis-2/dhis-web/dhis-web-mapping/src/main/resources/struts.xml	2012-02-08 15:15:18 +0000
@@ -334,12 +334,12 @@
 
         <action name="getGeoJson"
             class="org.hisp.dhis.mapping.action.GetGeoJsonAction">
-            <result name="success" type="velocity-json">/dhis-web-mapping/geojson.vm</result>
+            <result name="success" type="velocity-json">/dhis-web-mapping/geojsonmin.vm</result>
         </action>
 
         <action name="getGeoJsonWithValues"
             class="org.hisp.dhis.mapping.action.GetGeoJsonWithValuesAction">
-            <result name="success" type="velocity-json">/dhis-web-mapping/geojsonmin.vm</result>
+            <result name="success" type="velocity-json">/dhis-web-mapping/geojsonminValues.vm</result>
         </action>
 
         <action name="getGeoJsonFacilities"

=== renamed file 'dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/geojson.vm' => 'dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/geojsonmin.vm'
--- dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/geojson.vm	2011-12-02 13:24:16 +0000
+++ dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/geojsonmin.vm	2012-02-08 15:15:18 +0000
@@ -1,1 +1,5 @@
-#set($size=$object.size()){"type":"FeatureCollection","features":[#foreach($unit in $object){"geometry":{"type":#if($!{unit.featureType}=="Point")"Point"#else"MultiPolygon"#end,"coordinates":$!encoder.jsonEncode($!{unit.validCoordinates})},"properties":{"id":"$!{unit.id}","name":"$!encoder.jsonEncode(${unit.name})"#if($!{unit.featureType}!="Point"),"hcwc":$!{unit.hasChildrenWithCoordinates()}#end}}#if($velocityCount<$size),#end#end],"crs":{"type":"EPSG","properties":{"code":"4326"}}}
\ No newline at end of file
+#set($size=$object.size())[
+
+#foreach($unit in $object)
+{
+"t":#if(${unit.featureType}=="Point")"2"#else"1"#end,"c":$!encoder.jsonEncode($!{unit.validCoordinates}),"i":"$!{unit.id}","n":"$!encoder.jsonEncode(${unit.name})"}#if($velocityCount<$size),#end#end]
\ No newline at end of file

=== renamed file 'dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/geojsonmin.vm' => 'dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/geojsonminValues.vm'
=== modified file 'dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/i18n.vm'
--- dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/i18n.vm	2012-02-07 16:24:39 +0000
+++ dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/i18n.vm	2012-02-08 15:15:18 +0000
@@ -325,5 +325,6 @@
     symbol_layer:    '$encoder.jsEscape($i18n.getString( 'symbol_layer' ) , "'")',
     centroid_layer:    '$encoder.jsEscape($i18n.getString( 'centroid_layer' ) , "'")',
     no_values_found:    '$encoder.jsEscape($i18n.getString( 'no_values_found' ) , "'")',
-    close: '$encoder.jsEscape($i18n.getString( 'close' ) , "'")'
+    close: '$encoder.jsEscape($i18n.getString( 'close' ) , "'")',
+    boundary_layer: '$encoder.jsEscape($i18n.getString( 'boundary_layer' ) , "'")'
 };
\ No newline at end of file

=== modified file 'dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/mapping/css/style.css'
--- dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/mapping/css/style.css	2011-11-21 12:44:20 +0000
+++ dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/mapping/css/style.css	2012-02-08 15:15:18 +0000
@@ -39,6 +39,9 @@
     background:url('../../resources/ext-ux/theme/gray-extend-ux/leaf.gif') center center;
     padding-right:1px;
 }
+.treepanel-node-icon-boundary {
+    background:url('../../../images/boundary_small.png') center center no-repeat !important;
+}
 .treepanel-node-icon-thematic1 {
     background:url('../../../images/thematic1_small.png') center center no-repeat !important;
 }
@@ -239,6 +242,9 @@
 .x-btn button {
 	font:normal 10px lucida sans unicode,arial,ubuntu;
 }
+.x-btn .icon-boundary  {
+	background-image:url('../../../images/boundary.png');
+}
 .x-btn .icon-thematic1  {
 	background-image:url('../../../images/thematic1.png');
 }
@@ -311,12 +317,6 @@
 .x-btn .icon-measure {
 	background-image:url('../../../images/measure.png');
 }
-.x-btn .icon-thematic1 {
-	background-image:url('../../../images/thematic1.png');
-}
-.x-btn .icon-thematic2 {
-	background-image:url('../../../images/thematic2.png');
-}
 .x-btn-noicon .x-btn-small .x-btn-text {
     height:16px;
     padding:0 5px;
@@ -362,6 +362,12 @@
 	font:normal 11px lucida sans unicode,arial,ubuntu;
 	color:#555555;	
 }
+#window-boundary-title {
+	padding:0 0 3px 21px;
+	background:url('../../../images/boundary.png') no-repeat 0 0 transparent;
+	font:bold 11px arial;
+	color:#111;
+}
 #window-thematic1-title {
 	padding:0 0 3px 21px;
 	background:url('../../../images/thematic1.png') no-repeat 0 0 transparent;

=== modified file 'dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/mapping/javascript/global.js'
--- dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/mapping/javascript/global.js	2012-01-15 13:33:35 +0000
+++ dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/mapping/javascript/global.js	2012-02-09 15:02:07 +0000
@@ -8,6 +8,7 @@
     
 //  Layer names
 
+	boundary_layer: G.i18n.boundary_layer,
     thematic_layer_1: G.i18n.thematic_layer  + ' 1',
     thematic_layer_2: G.i18n.thematic_layer  + ' 2',
     symbol_layer: G.i18n.symbol_layer,
@@ -224,15 +225,15 @@
 
     labels: {
         vector: {
-            getActivatedOpenLayersStyleMap: function(fsize, fweight, fstyle, fcolor) {
+            getActivatedOpenLayersStyleMap: function(widget, fsize, fweight, fstyle, fcolor) {
                 return new OpenLayers.StyleMap({
                     'default' : new OpenLayers.Style(
                         OpenLayers.Util.applyDefaults({
-                            'fillOpacity': 1,
+                            'fillOpacity': widget == boundary ? 0 : 1,
+                            'strokeColor': widget == boundary ? '#000' : '#fff',
                             'strokeWidth': 1,
-                            'strokeColor': '#fff',
                             'label': '${labelString}',
-                            'fontFamily': 'arial,lucida sans unicode',
+                            'fontFamily': 'arial,sans-serif,ubuntu,consolas',
                             'fontSize': fsize ? fsize : 13,
                             'fontWeight': fweight ? 'bold' : 'normal',
                             'fontStyle': fstyle ? 'italic' : 'normal',
@@ -247,12 +248,12 @@
                     })
                 });
             },
-            getDeactivatedOpenLayersStyleMap: function() {
+            getDeactivatedOpenLayersStyleMap: function(widget) {
                 return new OpenLayers.StyleMap({
                     'default': new OpenLayers.Style(
                         OpenLayers.Util.applyDefaults({
-                            'fillOpacity': 1,
-                            'strokeColor': '#fff',
+                            'fillOpacity': widget == boundary ? 0 : 1,
+                            'strokeColor': widget == boundary ? '#000' : '#fff',
                             'strokeWidth': 1
                         },
                         OpenLayers.Feature.Vector.style['default'])
@@ -266,11 +267,11 @@
             },
             toggleFeatureLabels: function(widget, fsize, fweight, fstyle, fcolor) {
                 function activateLabels() {
-                    widget.layer.styleMap = this.getActivatedOpenLayersStyleMap(fsize, fweight, fstyle, fcolor);
+                    widget.layer.styleMap = this.getActivatedOpenLayersStyleMap(widget, fsize, fweight, fstyle, fcolor);
                     widget.labels = true;
                 }
                 function deactivateLabels(scope) {
-                    widget.layer.styleMap = this.getDeactivatedOpenLayersStyleMap();
+                    widget.layer.styleMap = this.getDeactivatedOpenLayersStyleMap(widget);
                     widget.labels = false;
                 }
                 
@@ -790,16 +791,16 @@
         return new Ext.Button({
             iconCls: iconCls,
             tooltip: tooltip,
+            widget: widget,
             style: 'margin-top:1px',
-            widget: widget,
             enableItems: function(bool) {
-                var menuItems = [2,3,5,6,7,9];
-                for (var i = 0; i < menuItems.length; i++) {
+                var menuItems = widget == boundary ? [2,3,5,6,8] : [2,3,5,6,7,9];
+                for (var i = 0, items = this.menu.items.items; i < menuItems.length; i++) {
                     if (bool) {
-                        this.menu.items.items[menuItems[i]].enable();
+                        items[menuItems[i]].enable();
                     }
                     else {
-                        this.menu.items.items[menuItems[i]].disable();
+                        items[menuItems[i]].disable();
                     }
                 }
             },

=== modified file 'dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/mapping/javascript/index.js'
--- dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/mapping/javascript/index.js	2012-02-07 16:25:58 +0000
+++ dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/mapping/javascript/index.js	2012-02-09 15:12:23 +0000
@@ -305,6 +305,23 @@
     };
     
 	/* Thematic layers */
+	boundaryLayer = new OpenLayers.Layer.Vector(G.i18n.boundary_layer, {
+        strategies: [ new OpenLayers.Strategy.Refresh({force:true}) ],
+        'visibility': false,
+        'displayInLayerSwitcher': false,
+        'styleMap': new OpenLayers.StyleMap({
+            'default': new OpenLayers.Style(
+                OpenLayers.Util.applyDefaults(
+                    {'fillOpacity': 0, 'strokeColor': '#000', 'strokeWidth': 1, 'pointRadius': 5},
+                    OpenLayers.Feature.Vector.style['default']
+                )
+            )
+        })
+    });
+    
+    boundaryLayer.layerType = G.conf.map_layer_type_thematic;
+    G.vars.map.addLayer(boundaryLayer);
+    
     polygonLayer = new OpenLayers.Layer.Vector(G.conf.thematic_layer_1, {
         strategies: [ new OpenLayers.Strategy.Refresh({force:true}) ],
         'visibility': false,
@@ -787,6 +804,7 @@
                     else {
                         var exportForm = document.getElementById('exportForm');
                         exportForm.action = '../exportImage.action';
+                        exportForm.method = 'post';
                         
                         document.getElementById('titleField').value = title;
                         document.getElementById('svgField').value = svg;
@@ -1976,10 +1994,16 @@
                 {
                     nodeType: 'gx_baselayercontainer',
                     expanded: true,
-                    text: G.i18n.base_layers
-                },
-                {
-                    nodeType: 'gx_overlaylayercontainer'
+                    text: G.i18n.baselayers
+                },
+                {
+                    nodeType: 'gx_overlaylayercontainer',
+                    text: G.i18n.overlays_
+                },
+                {
+                    nodeType: 'gx_layer',
+                    layer: G.conf.boundary_layer,
+                    iconCls: 'treepanel-node-icon-boundary'
                 },
                 {
                     nodeType: 'gx_layer',
@@ -2117,16 +2141,16 @@
             ]
         }),
         clickEventFn: function(node, e) {
-            if (node.attributes.text !== G.i18n.base_layers && node.attributes.text !== G.i18n.overlays ) {
+            if (node.attributes.text !== G.i18n.baselayers && node.attributes.text !== G.i18n.overlays_ ) {
                 node.select();
                 
-                if (node.parentNode.attributes.text === G.i18n.base_layers ) {
+                if (node.parentNode.attributes.text === G.i18n.baselayers ) {
                     var cmb = node.getOwnerTree().contextMenuBaselayer;
                     cmb.contextNode = node;
                     cmb.showAt(e.getXY());
                 }
                 
-                else if (node.parentNode.attributes.text === G.i18n.overlays ) {
+                else if (node.parentNode.attributes.text === G.i18n.overlays_ ) {
                     var cmo = node.layer.overlayType === 'wms' ?
                         node.getOwnerTree().contextMenuOverlayWMS : node.getOwnerTree().contextMenuOverlayFile;
                     cmo.contextNode = node;
@@ -2167,6 +2191,78 @@
 	});
 	
     /* Section: widgets */
+    boundary = new mapfish.widgets.geostat.Boundary({
+        map: G.vars.map,
+        layer: boundaryLayer,
+        featureSelection: false,
+        defaults: {width: 130},
+        listeners: {
+            'expand': function() {
+                //G.vars.activePanel.setPolygon();
+            },
+            'afterrender': function() {
+                this.layer.widget = this;
+            }
+        }
+    });
+    
+    boundary.window = new Ext.Window({
+        title: '<span id="window-boundary-title">' + G.i18n.boundary_layer + '</span>',
+        layout: 'fit',
+        bodyStyle: 'padding:8px; background-color:#fff',
+        closeAction: 'hide',
+        width: 287,
+        collapsed: false,
+        isUpdate: false,
+        cmp: {},
+        items: boundary,
+        bbar: [
+            '->',
+            {
+                xtype: 'button',
+                text: G.i18n.update,
+                iconCls: 'icon-assign',
+                disabled: true,
+                scope: boundary,
+                handler: function() {
+                    var node = this.cmp.parent.selectedNode;
+                    this.organisationUnitSelection.setValues(node.attributes.id, node.attributes.text, node.attributes.level,
+                        this.cmp.level.getValue(), this.cmp.level.getRawValue());
+                    this.window.isUpdate = true;                    
+                    this.loadGeoJson();
+                },
+                listeners: {
+                    'render': {
+                        fn: function(b) {
+                            b.scope.window.cmp.apply = b;
+                        }
+                    }
+                }
+            },
+            ' ',
+            {
+                xtype: 'button',
+                text: G.i18n.close,
+                iconCls: 'icon-cancel',
+                scope: boundary,
+                handler: function() {
+                    this.window.hide();
+                }
+            }
+        ],
+        listeners: {
+            'show': {
+                scope: boundary,
+                fn: function() {
+                    this.cmp.parent.isLoaded = true;
+                    this.window.isShown = true;
+                }
+            }
+        }
+    });    
+    boundary.window.setPagePosition(G.conf.window_x_left,G.conf.window_y_left);
+	
+    /* Section: widgets */
     choropleth = new mapfish.widgets.geostat.Choropleth({
         map: G.vars.map,
         layer: polygonLayer,
@@ -2544,6 +2640,8 @@
             G.util.zoomToVisibleExtent();
         }
 	});
+	
+	var boundaryButton = new G.cls.vectorLayerButton('icon-boundary', G.i18n.boundary_layer, boundary);
     
     var choroplethButton = new G.cls.vectorLayerButton('icon-thematic1', G.i18n.thematic_layer + ' 1', choropleth);
     
@@ -2733,7 +2831,8 @@
 			'-',
 			' ',' ',' ',
 			layersLabel,
-			' ',' ', 
+			' ',' ',
+			boundaryButton,
             choroplethButton,
             pointButton,
             symbolButton,
@@ -2834,13 +2933,14 @@
                 var svg = document.getElementsByTagName('svg');
                 
                 if (!Ext.isIE) {
-                    polygonLayer.svgId = svg[0].id;
-                    pointLayer.svgId = svg[1].id;
-                    symbolLayer.svgId = svg[2].id;
-                    centroidLayer.svgId = svg[3].id;
+					boundaryLayer.svgId = svg[0].id;
+                    polygonLayer.svgId = svg[1].id;
+                    pointLayer.svgId = svg[2].id;
+                    symbolLayer.svgId = svg[3].id;
+                    centroidLayer.svgId = svg[4].id;
                 }
                 
-                for (var i = 0, j = 3; i < G.vars.map.layers.length; i++) {
+                for (var i = 0, j = 4; i < G.vars.map.layers.length; i++) {
                     if (G.vars.map.layers[i].layerType == G.conf.map_layer_type_overlay) {
                         G.vars.map.layers[i].svgId = svg[j++].id;
                     }
@@ -2894,6 +2994,9 @@
                 
                 document.getElementById('featuredatatext').innerHTML = '<div style="color:#666">' + G.i18n.no_feature_selected + '</div>';
                 
+				boundaryButton.menu.remove(boundaryButton.menu.items.items[5]);
+                boundaryButton.menu.remove(boundaryButton.menu.items.last());
+                boundaryButton.menu.remove(boundaryButton.menu.items.last());
                 symbolButton.menu.remove(symbolButton.menu.items.last());
                 symbolButton.menu.remove(symbolButton.menu.items.last());
                 centroidButton.menu.remove(centroidButton.menu.items.last());

=== modified file 'dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/resources/mapfish/MapFish.js'
--- dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/resources/mapfish/MapFish.js	2011-07-05 19:34:01 +0000
+++ dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/resources/mapfish/MapFish.js	2012-02-08 15:15:18 +0000
@@ -95,6 +95,7 @@
 			//"lang/en.js",
             "core/Color.js",
             "core/GeoStat.js",
+            "core/GeoStat/Boundary.js",
             "core/GeoStat/Choropleth.js",
             "core/GeoStat/Point.js",
             "core/GeoStat/Symbol.js",
@@ -119,6 +120,7 @@
             //"widgets/data/SearchStoreMediator.js",
             //"widgets/data/LayerStoreMediator.js",
             //"widgets/data/GridRowFeatureMediator.js",
+            "widgets/geostat/Boundary.js",
             "widgets/geostat/Choropleth.js",
             "widgets/geostat/Point.js",
             "widgets/geostat/Symbol.js",

=== added file 'dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/resources/mapfish/core/GeoStat/Boundary.js'
--- dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/resources/mapfish/core/GeoStat/Boundary.js	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/resources/mapfish/core/GeoStat/Boundary.js	2012-02-08 15:15:18 +0000
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2007  Camptocamp
+ *
+ * This file is part of MapFish Client
+ *
+ * MapFish Client is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * MapFish Client is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MapFish Client.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * @requires core/GeoStat.js
+ */
+
+mapfish.GeoStat.Boundary = OpenLayers.Class(mapfish.GeoStat, {
+
+    colors: [
+        new mapfish.ColorRgb(120, 120, 0),
+        new mapfish.ColorRgb(255, 0, 0)
+    ],
+
+    method: mapfish.GeoStat.Distribution.CLASSIFY_BY_QUANTILS,
+
+    numClasses: 5,
+	
+	minSize: 3,
+	
+	maxSize: 20,
+	
+	minVal: null,
+	
+	maxVal: null,
+
+    defaultSymbolizer: {'fillOpacity': 1},
+
+    classification: null,
+
+    colorInterpolation: null,
+    
+    widget: null,
+
+    initialize: function(map, options) {
+        mapfish.GeoStat.prototype.initialize.apply(this, arguments);
+    },
+
+    updateOptions: function(newOptions) {
+        var oldOptions = OpenLayers.Util.extend({}, this.options);
+        this.addOptions(newOptions);
+        if (newOptions) {
+            this.setClassification();
+        }
+    },
+    
+    createColorInterpolation: function() {
+        var numColors = this.classification.bins.length;
+		var mapLegendType = this.widget.cmp.mapLegendType.getValue();
+        this.widget.imageLegend = [];
+        
+        this.colorInterpolation = mapLegendType == G.conf.map_legendset_type_automatic ?
+            mapfish.ColorRgb.getColorsArrayByRgbInterpolation(this.colors[0], this.colors[1], numColors) : this.widget.colorInterpolation;
+            
+        for (var i = 0; i < this.classification.bins.length; i++) {
+            this.widget.imageLegend.push({
+                label: this.classification.bins[i].label.replace('&nbsp;&nbsp;', ' '),
+                color: this.colorInterpolation[i].toHexString()
+            });
+        }
+    },
+
+    setClassification: function() {
+        var values = [];
+        for (var i = 0; i < this.layer.features.length; i++) {
+            values.push(this.layer.features[i].attributes[this.indicator]);
+        }
+        
+        var distOptions = {
+            'labelGenerator': this.options.labelGenerator
+        };
+        var dist = new mapfish.GeoStat.Distribution(values, distOptions);
+
+		this.minVal = dist.minVal;
+        this.maxVal = dist.maxVal;
+
+        this.classification = dist.classify(
+            this.method,
+            this.numClasses,
+            null
+        );
+
+        this.createColorInterpolation();
+    },
+
+    applyClassification: function(options, widget) {
+        this.widget = widget;
+        this.updateOptions(options);
+        
+		var calculateRadius = OpenLayers.Function.bind(
+			function(feature) {
+				var value = feature.attributes[this.indicator];
+                var size = (value - this.minVal) / (this.maxVal - this.minVal) *
+					(this.maxSize - this.minSize) + this.minSize;
+                return size || this.minSize;
+            },	this
+		);
+		this.extendStyle(null, {'pointRadius': '${calculateRadius}'}, {'calculateRadius': calculateRadius});
+    
+        var boundsArray = this.classification.getBoundsArray();
+        var rules = new Array(boundsArray.length-1);        
+        for (var i = 0; i < boundsArray.length-1; i++) {
+            var rule = new OpenLayers.Rule({
+                symbolizer: {fillColor: this.colorInterpolation[i].toHexString()},
+                filter: new OpenLayers.Filter.Comparison({
+                    type: OpenLayers.Filter.Comparison.BETWEEN,
+                    property: this.indicator,
+                    lowerBoundary: boundsArray[i],
+                    upperBoundary: boundsArray[i + 1]
+                })
+            });
+            rules[i] = rule;
+        }
+
+        this.extendStyle(rules);
+        mapfish.GeoStat.prototype.applyClassification.apply(this, arguments);
+    },
+
+    updateLegend: function() {
+        if (!this.legendDiv) {
+            return;
+        }
+        
+        var info = this.widget.formValues.getLegendInfo.call(this.widget);
+        var element;
+        this.legendDiv.update("");
+        
+        for (var p in info) {
+            element = document.createElement("div");
+            element.style.height = "14px";
+            element.innerHTML = info[p];
+            this.legendDiv.appendChild(element);
+            
+            element = document.createElement("div");
+            element.style.clear = "left";
+            this.legendDiv.appendChild(element);
+        }
+        
+        element = document.createElement("div");
+        element.style.width = "1px";
+        element.style.height = "5px";
+        this.legendDiv.appendChild(element);
+        
+        if (G.vars.activeWidget.legend.value == G.conf.map_legendset_type_automatic) {        
+            for (var i = 0; i < this.classification.bins.length; i++) {
+                var element = document.createElement("div");
+                element.style.backgroundColor = this.colorInterpolation[i].toHexString();
+                element.style.width = "30px";
+                element.style.height = "15px";
+                element.style.cssFloat = "left";
+                element.style.marginRight = "8px";
+                this.legendDiv.appendChild(element);
+
+                element = document.createElement("div");
+                element.innerHTML = this.classification.bins[i].label;
+                this.legendDiv.appendChild(element);
+
+                element = document.createElement("div");
+                element.style.clear = "left";
+                this.legendDiv.appendChild(element);
+            }
+        }
+        else if (G.vars.activeWidget.legend.value == G.conf.map_legendset_type_predefined) {
+            for (var i = 0; i < this.classification.bins.length; i++) {
+                var element = document.createElement("div");
+                element.style.backgroundColor = this.colorInterpolation[i].toHexString();
+                element.style.width = "30px";
+                element.style.height = this.widget.legendNames[i] ? "25px" : "20px";
+                element.style.cssFloat = "left";
+                element.style.marginRight = "8px";
+                this.legendDiv.appendChild(element);
+
+                element = document.createElement("div");
+                element.style.lineHeight = this.widget.legendNames[i] ? "12px" : "7px";
+                element.innerHTML = '<b style="color:#222">' + (this.widget.legendNames[i] || '') + '</b><br/>' + this.classification.bins[i].label;
+                this.legendDiv.appendChild(element);
+
+                element = document.createElement("div");
+                element.style.clear = "left";
+                this.legendDiv.appendChild(element);
+            }
+        }
+    },
+
+    CLASS_NAME: "mapfish.GeoStat.Boundary"
+});

=== added file 'dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/resources/mapfish/widgets/geostat/Boundary.js'
--- dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/resources/mapfish/widgets/geostat/Boundary.js	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/resources/mapfish/widgets/geostat/Boundary.js	2012-02-09 15:02:07 +0000
@@ -0,0 +1,459 @@
+/*
+ * Copyright (C) 2007-2008  Camptocamp|
+ *
+ * This file is part of MapFish Client
+ *
+ * MapFish Client is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * MapFish Client is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MapFish Client.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * @requires core/GeoStat/Boundary.js
+ * @requires core/Color.js
+ */
+
+Ext.namespace('mapfish.widgets', 'mapfish.widgets.geostat');
+
+mapfish.widgets.geostat.Boundary = Ext.extend(Ext.Panel, {
+
+    layer: null,
+
+    format: null,
+
+    url: null,
+
+    featureSelection: true,
+
+    nameAttribute: null,
+
+    indicator: null,
+
+    indicatorText: null,
+
+    coreComp: null,
+
+    classificationApplied: false,
+
+    ready: false,
+
+    border: false,
+
+    loadMask: false,
+
+    labelGenerator: null,
+
+    colorInterpolation: false,
+
+    legend: false,
+
+	bounds: false,
+
+    mapView: false,
+    
+    labels: false,
+    
+    valueType: false,
+    
+    selectFeatures: false,
+    
+    organisationUnitSelection: false,
+    
+    updateValues: false,
+    
+    isDrillDown: false,
+
+	imageLegend: false,
+    
+    stores: false,
+    
+    infrastructuralPeriod: false,
+    
+    featureOptions: {},
+    
+    cmp: {},
+    
+    requireUpdate: false,
+    
+    featureStorage: [],
+    
+    initComponent: function() {
+    
+        this.initProperties();
+        
+        this.createItems();
+        
+        this.addItems();
+        
+		mapfish.widgets.geostat.Boundary.superclass.initComponent.apply(this);
+    },
+    
+    setUrl: function(url) {
+        this.url = url;
+        this.coreComp.setUrl(this.url);
+    },
+
+    requestSuccess: function(request) {
+        this.ready = true;
+
+        if (this.loadMask && this.rendered) {
+            this.loadMask.hide();
+        }
+    },
+
+    requestFailure: function(request) {
+        OpenLayers.Console.error(G.i18n.ajax_request_failed);
+    },
+    
+    getColors: function() {
+        var startColor = new mapfish.ColorRgb();
+        startColor.setFromHex(this.cmp.startColor.getValue());
+        var endColor = new mapfish.ColorRgb();
+        endColor.setFromHex(this.cmp.endColor.getValue());
+        return [startColor, endColor];
+    },
+    
+    initProperties: function() {
+        this.legend = {
+            value: G.conf.map_legendset_type_automatic,
+            method: G.conf.classify_by_equal_intervals,
+            classes: 5,
+            reset: function() {
+                this.value = G.conf.map_legendset_type_automatic;
+                this.method = G.conf.classify_by_equal_intervals;
+                this.classes = 5;
+            }
+        };
+        
+        this.organisationUnitSelection = {
+            parent: {
+                id: null,
+                name: null,
+                level: null
+            },
+            level: {
+                level: null,
+                name: null
+            },
+            setValues: function(pid, pn, pl, ll, ln) {
+                this.parent.id = pid || this.parent.id;
+                this.parent.name = pn || this.parent.name;
+                this.parent.level = pl || this.parent.level;
+                this.level.level = ll || this.level.level;
+                this.level.name = ln || this.level.name;
+            },
+            getValues: function() {
+                return {
+                    parent: {
+                        id: this.parent.id,
+                        name: this.parent.name,
+                        level: this.parent.level
+                    },
+                    level: {
+                        level: this.level.level,
+                        name: this.level.name
+                    }                    
+                };
+            },
+            setValuesOnDrillDown: function(pid, pn) {
+                this.parent.id = pid;
+                this.parent.name = pn;
+                this.parent.level = this.level.level;
+                this.level.level++;
+                this.level.name = G.stores.organisationUnitLevel.getAt(
+                    G.stores.organisationUnitLevel.find('level', this.level.level)).data.name;
+            }                
+        };
+        
+        this.valueType = {
+            value: G.conf.map_value_type_indicator,
+            setIndicator: function() {
+                this.value = G.conf.map_value_type_indicator;
+            },
+            setDatElement: function() {
+                this.value = G.conf.map_value_type_dataelement;
+            },
+            isIndicator: function() {
+                return this.value == G.conf.map_value_type_indicator;
+            },
+            isDataElement: function() {
+                return this.value == G.conf.map_value_type_dataelement;
+            }
+        };
+        
+        this.stores = {
+            infrastructuralDataElementMapValue: new Ext.data.JsonStore({
+                url: G.conf.path_mapping + 'getInfrastructuralDataElementMapValues' + G.conf.type,
+                root: 'mapValues',
+                fields: ['dataElementName', 'value'],
+                sortInfo: {field: 'dataElementName', direction: 'ASC'},
+                autoLoad: false,
+                isLoaded: false,
+                listeners: {
+                    'load': G.func.storeLoadListener
+                }
+            }),
+            indicatorsByGroup: new Ext.data.JsonStore({
+                url: G.conf.path_mapping + 'getIndicatorsByIndicatorGroup' + G.conf.type,
+                root: 'indicators',
+                fields: ['id', 'name', 'shortName'],
+                idProperty: 'id',
+                sortInfo: {field: 'name', direction: 'ASC'},
+                autoLoad: false,
+                isLoaded: false,
+                listeners: {
+                    'load': function(store) {
+                        store.isLoaded = true;
+                        store.each(
+                            function fn(record) {
+                                var name = record.get('name');
+                                name = name.replace('&lt;', '<').replace('&gt;', '>');
+                                record.set('name', name);
+                            }
+                        );
+                    }
+                }
+            }),
+            dataElementsByGroup: new Ext.data.JsonStore({
+                url: G.conf.path_mapping + 'getDataElementsByDataElementGroup' + G.conf.type,
+                root: 'dataElements',
+                fields: ['id', 'name', 'shortName'],
+                sortInfo: {field: 'name', direction: 'ASC'},
+                autoLoad: false,
+                isLoaded: false,
+                listeners: {
+                    'load': function(store) {
+                        store.isLoaded = true;
+                        store.each(
+                            function fn(record) {
+                                var name = record.get('name');
+                                name = name.replace('&lt;', '<').replace('&gt;', '>');
+                                record.set('name', name);
+                            }
+                        );
+                    }
+                }
+            }),
+            periodsByType: new Ext.data.JsonStore({
+                url: G.conf.path_mapping + 'getPeriodsByPeriodType' + G.conf.type,
+                root: 'periods',
+                fields: ['id', 'name'],
+                autoLoad: false,
+                isLoaded: false,
+                listeners: {
+                    'load': G.func.storeLoadListener
+                }
+            })
+        };
+    },
+    
+    createItems: function() {
+        
+        this.cmp.level = new Ext.form.ComboBox({
+            fieldLabel: G.i18n.level,
+            editable: false,
+            valueField: 'level',
+            displayField: 'name',
+            mode: 'remote',
+            forceSelection: true,
+            triggerAction: 'all',
+            selectOnFocus: true,
+            fieldLabel: G.i18n.level,
+            width: G.conf.combo_width,
+            store: G.stores.organisationUnitLevel,
+            listeners: {
+                'select': {
+                    scope: this,
+                    fn: function(c) {
+                        this.requireUpdate = true;
+                        this.formValidation.validateForm.call(this);
+                        this.organisationUnitSelection.setValues(null, null, null, c.getValue(), c.getRawValue());
+                    }
+                }
+            }
+        });
+        
+        this.cmp.parent = new Ext.tree.TreePanel({
+            cls: 'treepanel-layer-border',
+            autoScroll: true,
+            lines: false,
+            loader: new Ext.tree.TreeLoader({
+                dataUrl: G.conf.path_mapping + 'getOrganisationUnitChildren' + G.conf.type
+            }),
+            root: {
+                id: G.system.rootNode.id,
+                text: G.system.rootNode.name,
+                level: G.system.rootNode.level,
+                hasChildrenWithCoordinates: G.system.rootNode.hasChildrenWithCoordinates,
+                nodeType: 'async',
+                draggable: false,
+                expanded: true
+            },
+            widget: this,
+            isLoaded: false,
+            reset: function() {
+                if (this.getSelectionModel().getSelectedNode()) {
+                    this.getSelectionModel().getSelectedNode().unselect();
+                }                
+                this.collapseAll();
+                this.getRootNode().expand();
+                this.widget.window.cmp.apply.disable();
+            },
+            listeners: {
+                'click': {
+                    scope: this,
+                    fn: function(n) {
+                        var tree = n.getOwnerTree();
+                        tree.selectedNode = n;
+                        this.requireUpdate = true;
+                        this.formValidation.validateForm.call(this);
+                        this.organisationUnitSelection.setValues(n.attributes.id, n.attributes.text, n.attributes.level);
+                    }
+                }
+            }
+        });
+    },
+    
+    addItems: function() {
+        
+        this.items = [
+			{
+				xtype: 'panel',
+				width: 270,
+				items: [
+					{ html: '<div class="window-info">' + G.i18n.organisation_unit_level + '</div>' },                            
+					{
+						xtype: 'panel',
+						layout: 'form',
+						items: [
+							this.cmp.level
+						]
+					},                            
+					{ html: '<div class="thematic-br"></div><div class="thematic-br"></div>' },                            
+					{ html: '<div class="window-info">' + G.i18n.parent_organisation_unit + '</div>' },
+					this.cmp.parent
+				]
+			}
+        ];
+    },
+    
+    formValidation: {
+        validateForm: function() {
+            if (!this.cmp.parent.selectedNode || !this.cmp.level.getValue()) {
+                this.window.cmp.apply.disable();
+                return false;
+            }
+            
+            if (this.cmp.parent.selectedNode.attributes.level > this.cmp.level.getValue()) {
+                this.window.cmp.apply.disable();
+                return false;
+            }
+            
+            if (this.requireUpdate) {
+                if (this.window.isUpdate) {
+                    this.window.cmp.apply.disable();
+                    this.requireUpdate = false;
+                    this.window.isUpdate = false;
+                }
+                else {
+                    this.window.cmp.apply.enable();
+                }
+            }
+            
+            return true;
+        }
+    },
+    
+    formValues: {
+		getAllValues: function() {
+			return {
+                parentOrganisationUnitId: this.organisationUnitSelection.parent.id,
+                parentOrganisationUnitLevel: this.organisationUnitSelection.parent.level,
+                parentOrganisationUnitName: this.organisationUnitSelection.parent.name,
+                organisationUnitLevel: this.organisationUnitSelection.level.level,
+                organisationUnitLevelName: this.organisationUnitSelection.level.name,
+                longitude: G.vars.map.getCenter().lon,
+                latitude: G.vars.map.getCenter().lat,
+                zoom: parseFloat(G.vars.map.getZoom())
+			};
+		},
+        
+        clearForm: function(clearLayer) {            
+            this.cmp.level.clearValue();
+            this.cmp.parent.reset();
+            
+            this.window.cmp.apply.disable();
+            
+            if (clearLayer) {
+                this.layer.destroyFeatures();
+                this.layer.setVisibility(false);
+            }
+        }
+	},
+    
+    loadGeoJson: function() {
+        G.vars.mask.msg = G.i18n.loading;
+        G.vars.mask.show();
+        G.vars.activeWidget = this;
+        this.updateValues = false;
+        
+        var url = G.conf.path_mapping + 'getGeoJson.action?' + 
+            '&parentId=' + this.organisationUnitSelection.parent.id +
+            '&level=' + this.organisationUnitSelection.level.level;
+        this.setUrl(url);
+    },
+
+    classify: function(exception, lockPosition, loaded) {
+        if (this.formValidation.validateForm.apply(this, [exception])) {
+            if (!this.layer.features.length && !loaded) {
+                this.loadGeoJson();
+            }
+            
+            this.applyValues();			
+        }
+    },
+    
+    applyValues: function() {            
+		for (var i = 0; i < this.layer.features.length; i++) {
+			var f = this.layer.features[i];
+			f.attributes.labelString = f.attributes.name;
+			f.attributes.fixedName = G.util.cutString(f.attributes.name, 30);
+		}
+		
+		this.layer.renderer.clear();
+		this.layer.redraw();
+		this.layer.setVisibility(true);
+		
+		G.util.zoomToVisibleExtent();
+		G.vars.mask.hide();
+	},
+    
+    onRender: function(ct, position) {
+        mapfish.widgets.geostat.Boundary.superclass.onRender.apply(this, arguments);
+
+		var coreOptions = {
+            'layer': this.layer,
+            'format': this.format,
+            'url': this.url,
+            'requestSuccess': this.requestSuccess.createDelegate(this),
+            'requestFailure': this.requestFailure.createDelegate(this),
+            'featureSelection': this.featureSelection,
+            'nameAttribute': this.nameAttribute,
+            'legendDiv': this.legendDiv,
+            'labelGenerator': this.labelGenerator
+        };
+
+        this.coreComp = new mapfish.GeoStat.Boundary(this.map, coreOptions);
+    }
+});
+
+Ext.reg('boundary', mapfish.widgets.geostat.Boundary);

=== modified file 'dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/resources/mapfish/widgets/geostat/Choropleth.js'
--- dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/resources/mapfish/widgets/geostat/Choropleth.js	2012-01-20 15:06:41 +0000
+++ dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/resources/mapfish/widgets/geostat/Choropleth.js	2012-02-08 15:15:18 +0000
@@ -1732,7 +1732,7 @@
     
     applyValues: function() {
         for (var i = 0; i < this.layer.features.length; i++) {
-            var f = this.layer.features[i];            
+            var f = this.layer.features[i];
             if (!f.attributes.value) {
                 this.layer.features.splice(i,1);
                 i--;