[fusion-commits] r1727 - in branches/fusion2-mg21/layers/MapGuide: . php

svn_fusion at osgeo.org svn_fusion at osgeo.org
Thu Dec 18 18:46:16 EST 2008


Author: chrisclaydon
Date: 2008-12-18 18:46:16 -0500 (Thu, 18 Dec 2008)
New Revision: 1727

Added:
   branches/fusion2-mg21/layers/MapGuide/php/HighlightSelection.php
Modified:
   branches/fusion2-mg21/layers/MapGuide/MapGuide.js
   branches/fusion2-mg21/layers/MapGuide/php/SetSelection.php
Log:
Ref #199 - Apply selection speed improvements to fusion2-mg21 branch

Author:           Ronnie Louie
Date:             Thursday, December 18, 2008
Title:            1161170 Improve selection performance in Fusion
Reviewed by:      Chris Claydon

========
Abstract
========
Selection performance in Fusion is significantly slower than the performance on 
the Ajax viewer with basic weblayouts.  It generally can take two or three times 
as long (if not more) to select features in Flexible WebLayouts than in Basic 
layouts.  The slowdown is attributed to the additional server requests that are 
made when the Query.php script is executed for Fusion.  To improve the response 
time, feedback is provided to the user by highlighting the selection on the 
screen first, via the quicker QueryMapFeatures request, and then feature 
attributes for the selection are retrieved and displayed.  The end result is an 
improved user experience when selecting features in flexible weblayout.  Running 
in a debug environment (server and webtier) selection of roughly 1500 features 
would take around 8 seconds before the selection is displayed.  It now takes 
about 3 seconds to display.

TESTING PERFORMED:
- Tested point-selection and drag-selection for a single selectable layer.
- Tested point-selection and drag-selection for multiple selectable layers.
- Tested extended-selection via point and drag select.
- Tested toggle on/off of features when the features are selected again.
- Tested radius/polygon select for single and multiple selectable layers.
- Tested radius/polygon select for extended selection.
- Tested radius/polygon select for toggling selected features.
- Tested selection for all layers.
- Tested selection for only the active layer.
- Tested zoom selection.
- All tests executed in FireFox and Internet Explorer.

================
Module by Module
================
//MgDev/OS/Oem/fusion/layers/MapGuide/MapGuide.js
  - modified selection to draw the overlay first before retrieving the 
attributes to display

//MgDev/OS/Oem/fusion/layers/MapGuide/php/HighlightSelection.php
  - new file added to save the selection to the repository and return a json 
data structure 

//MgDev/OS/Oem/fusion/layers/MapGuide/php/SetSelection.php
  - removed saving of the selection set to the repository since this is already 
done in HightlightSelection.php
  - optimize the code so that the retrieval of spatial contexts and creation of 
a coordinate system is moved into in if block to be executed only when computed 
properties are needed.  The existing code was not doing anything for computed 
properties so this block of coded did not need to be executed.
  - replace the code for determining the feature count for each layer with a 
call to MgSelection::GetSelectedFeaturesCount()


Modified: branches/fusion2-mg21/layers/MapGuide/MapGuide.js
===================================================================
--- branches/fusion2-mg21/layers/MapGuide/MapGuide.js	2008-12-18 23:29:31 UTC (rev 1726)
+++ branches/fusion2-mg21/layers/MapGuide/MapGuide.js	2008-12-18 23:46:16 UTC (rev 1727)
@@ -626,14 +626,13 @@
     },
 
     /**
-     * advertise a new selection is available and redraw the map
+     * advertise a new selection is available
      */
     newSelection: function() {
         if (this.oSelection) {
             this.oSelection = null;
         }
         this.bSelectionOn = true;
-        this.drawSelection();
         this.triggerEvent(Fusion.Event.MAP_SELECTION_ON);
     },
 
@@ -689,7 +688,23 @@
       Fusion.ajaxRequest(setSelectionScript, options);
     },
 
+    highlightSelection: function (selText, zoomTo) {
+      this.mapWidget._addWorker();
+      var sl = Fusion.getScriptLanguage();
+      var highlightSelectionScript = 'layers/' + this.arch + '/' + sl  + '/HighlightSelection.' + sl;
+      var params = {
+          'mapname': this.getMapName(),
+          'session': this.getSessionID(),
+          'selection': selText,
+          'seq': Math.random()
+      };
+      var options = {onSuccess: OpenLayers.Function.bind(this.processResultsForRendering, this, zoomTo),
+                     parameters:params, asynchronous:false};
+      Fusion.ajaxRequest(highlightSelectionScript, options);
+    },
 
+
+
      /**
      * asynchronously load the current selection.  When the current
      * selection changes, the selection is not loaded because it
@@ -764,7 +779,11 @@
               onSuccess: OpenLayers.Function.bind(this.selectionCleared, this)
           };
           Fusion.ajaxRequest(s, options);
+          if (this.previousSelection != null)
+          {
+              this.previousSelection.clear();
       }
+      }
     },
 
     /**
@@ -779,7 +798,8 @@
 
 
     /**
-       Call back function when slect functions are called (eg queryRect)
+       Call back function when select functions are called (eg queryRect)
+       to handle feature attributes
     */
     processQueryResults: function(zoomTo, r) {
         this.mapWidget._removeWorker();
@@ -788,6 +808,25 @@
             eval('oNode='+r.responseText);
 
             if (oNode.hasSelection) {
+              this.newSelection();
+            } else {
+              this.clearSelection();
+              return;
+            }
+        }
+    },
+
+    /**
+       Call back function when select functions are called (eg queryRect)
+       to render the selection
+    */
+    processResultsForRendering: function(zoomTo, r) {
+        this.mapWidget._removeWorker();
+        if (r.responseText) {   //TODO: make the equivalent change to MapServer.js
+            var oNode;
+            eval('oNode='+r.responseText);
+
+            if (oNode.hasSelection) {
               if (this.selectionAsOverlay) {
                 if (!this.queryLayer) {
                   this.queryLayer = this.createOLLayer("query layer", false, true, 5);
@@ -814,7 +853,7 @@
                 var extents = new OpenLayers.Bounds(ext.minx, ext.miny, ext.maxx, ext.maxy);
                 this.mapWidget.setExtents(extents);
               }
-              this.newSelection();
+              this.drawSelection();
             } else {
               this.clearSelection();
               return;
@@ -833,34 +872,39 @@
           this.aLayers[j].selectedFeatureCount = 0;
         }
 
-        var bPersistant = options.persistent || true;
-        var zoomTo = options.zoomTo ?  true : false;
-        var sl = Fusion.getScriptLanguage();
-        var loadmapScript = 'layers/' + this.arch + '/' + sl  + '/Query.' + sl;
-
-        var params = {
-            'mapname': this._sMapname,
-            'session': this.getSessionID(),
-            'spatialfilter': options.geometry || '',
-            'computed': options.computed || '',
-            'queryHiddenLayers': options.queryHiddenLayers || 'false',
-            'maxfeatures': options.maxFeatures || 0, //zero means select all features
-            'layers': options.layers || '',
-            'variant': options.selectionType || this.selectionType
-        };
-        if (options.filter) {
-            params.filter= options.filter;
+        var persist = 1;
+        var layerAttributeFilter = 3;
+        var maxFeatures = options.maxFeatures;
+        if(maxFeatures == null || maxFeatures == 0)
+        {
+            maxFeatures = -1;
         }
-        if (options.extendSelection) {
-            params.extendselection = true;
+        if (options.extendSelection == true)
+        {
+            var r = new Fusion.Lib.MGRequest.MGQueryMapFeatures(this.getSessionID(),
+                                                                this._sMapname,
+                                                                options.geometry,
+                                                                maxFeatures,
+                                                                persist,
+                                                                options.selectionType || this.selectionType,
+                                                                options.layers,
+                                                                layerAttributeFilter);
+            var callback = OpenLayers.Function.bind(this.processAndMergeFeatureInfo, this);
+            Fusion.oBroker.dispatchRequest(r, OpenLayers.Function.bind(Fusion.xml2json, this, callback));
         }
-        if (options.computedProperties) {
-            params.computed = true;
+        else
+        {
+            var r = new Fusion.Lib.MGRequest.MGQueryMapFeatures(this.getSessionID(),
+                                                                this._sMapname,
+                                                                options.geometry,
+                                                                maxFeatures,
+                                                                persist,
+                                                                options.selectionType || this.selectionType,
+                                                                options.layers,
+                                                                layerAttributeFilter);
+            var callback = OpenLayers.Function.bind(this.processFeatureInfo, this);
+            Fusion.oBroker.dispatchRequest(r, OpenLayers.Function.bind(Fusion.xml2json, this, callback));
         }
-        var ajaxOptions = {
-            onSuccess: OpenLayers.Function.bind(this.processQueryResults, this, zoomTo),
-            parameters: params};
-        Fusion.ajaxRequest(loadmapScript, ajaxOptions);
     },
 
     showLayer: function( layer, noDraw ) {
@@ -990,7 +1034,271 @@
         url += "&TS=" + (new Date()).getTime();
       }
       return url;
+    },
+
+
+    processFeatureInfo: function (r)
+    {
+        eval('o='+r.responseText);
+        var newSelection = new Fusion.SimpleSelectionObject(o);
+        var selText = newSelection.getSelectionXml();
+        if(selText != "" && selText != null)
+        {
+            this.highlightSelection(selText, false);
+            this.setSelection(selText, false);
+
+            this.previousSelection = newSelection;
     }
+        else
+        {
+            this.clearSelection();
+        }
+        this.mapWidget._removeWorker();
+    },
 
+    processAndMergeFeatureInfo: function (r)
+    {
+        // get the current selection
+        eval('o='+r.responseText);
+        var newSelection = new Fusion.SimpleSelectionObject(o);
+        
+        // merge the previousSelection with the currentSelection
+        newSelection.merge(this.previousSelection);
+        
+        
+        var selText = newSelection.getSelectionXml();
+        if(selText != "" && selText != null)
+        {
+            this.highlightSelection(selText, false);
+            this.setSelection(selText, false);
+            
+            this.previousSelection = newSelection;
+        }
+        else
+        {
+            this.clearSelection();
+        }
+        this.mapWidget._removeWorker();
+    }
 });
 
+Fusion.SimpleSelectionObject = OpenLayers.Class({
+    aLayers : null,
+    nLayers : 0,
+
+    initialize: function(featureInfoResponse)
+    {
+        this.aLayers = [];
+        this.nLayers = 0;
+        try
+        {
+            var layers = featureInfoResponse.FeatureInformation.FeatureSet[0].Layer;
+            if (layers != null)
+            {
+                for(var i = 0; i < layers.length; i++)
+                {
+                    var layerId = o['FeatureInformation']['FeatureSet'][0]['Layer'][i]['@id'][0];
+
+                    var classElt = o['FeatureInformation']['FeatureSet'][0]['Layer'][i]['Class'][0];
+                    var className = o['FeatureInformation']['FeatureSet'][0]['Layer'][i]['Class'][0]['@id'][0];
+
+                    var layer = new Fusion.SimpleSelectionObject.Layer(layerId, className);
+
+                    this.addLayer(layer);
+
+                    var features = classElt.ID;
+                    for(var j=0; j < features.length; j++)
+                    {
+                        layer.addFeature(features[j]);
+                    }
+                }    
+            }
+        }
+        catch(e) {}
+
+    },
+
+    addLayer: function(layer)
+    {
+        this.aLayers[this.nLayers] = layer;
+        this.nLayers++;
+    },
+
+    getNumLayers : function()
+    {
+        return this.nLayers;
+    },
+
+    getLayerByName : function(name)
+    {
+        var oLayer = null;
+        for (var i=0; i<this.nLayers; i++)
+        {
+            if (this.aLayers[i].getName() == name)
+            {
+                oLayer = this.aLayers[i];
+                break;
+            }
+        }
+        return oLayer;
+    },
+
+    getLayer : function(iIndice)
+    {
+        if (iIndice >=0 && iIndice < this.nLayers)
+        {
+            return this.aLayers[iIndice];
+        }
+        else
+        {
+            return null;
+        }
+    },
+
+    getSelectionXml : function()
+    {
+        var xmlSelection = "";
+        if(this.nLayers > 0)
+        {
+            xmlSelection = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<FeatureSet>\n";
+            for(var i = 0; i < this.nLayers; i++)
+            {
+                var layer = this.aLayers[i];
+                xmlSelection += "<Layer id=\"" + layer.getName() + "\">\n";
+                xmlSelection += "<Class id=\"" + layer.getClassName() + "\">\n";
+                for(var j = 0; j < layer.getNumFeatures(); j++)
+                {
+                    var featId = layer.featIds[j];
+                    xmlSelection += "<ID>" +  featId + "</ID>\n";
+                }
+                xmlSelection += "</Class>\n</Layer>\n";
+            }
+            xmlSelection += "</FeatureSet>\n";
+        }
+        return xmlSelection;
+    },
+    
+    merge : function(previousSelection)
+    {
+        if (previousSelection != null && previousSelection.nLayers > 0)
+        {
+            for (var prevSelIndex = 0; prevSelIndex < previousSelection.nLayers; prevSelIndex++)
+            {
+                var prevSelLayer = previousSelection.aLayers[prevSelIndex];
+
+                // find the previously selected layer name in the current selection
+                var currentLayer = this.getLayerByName(prevSelLayer.getName());
+                if (currentLayer != null)
+                {
+                    // add the previously selected features for this layer
+                    for (var j = 0; j < prevSelLayer.getNumFeatures(); j++)
+                    {
+                        var prevSelFeatureIndexes = currentLayer.featIds.find(prevSelLayer.featIds[j]);
+                        if (prevSelFeatureIndexes == null)
+                        {
+                            currentLayer.addFeature(prevSelLayer.featIds[j]);
+                        }
+                        else
+                        {
+                            // the feature was previously selected, so toggle it off when selected again
+                            currentLayer.removeFeatures(prevSelFeatureIndexes);
+                        }
+                    }
+                    if (currentLayer.featIds.length == 0)
+                    {
+                        this.clear();
+                    }
+                }
+                else
+                {
+                    // the current selection does not include this previously selected layer
+
+                    // need to add this previously selected layer and its features
+                    var missingLayer = new Fusion.SimpleSelectionObject.Layer(prevSelLayer.getName(), prevSelLayer.getClassName());
+                    for (var k = 0; k < prevSelLayer.getNumFeatures(); k++)
+                    {
+                        missingLayer.addFeature(prevSelLayer.featIds[k]);
+                    }
+                    this.addLayer(missingLayer);
+                }
+            }
+        }
+    },
+    
+    clear: function()
+    {
+        this.aLayers = [];
+        this.nLayers = 0;
+    }
+});
+
+Fusion.SimpleSelectionObject.Layer = OpenLayers.Class({
+    name: "",
+    className: "",
+    featIds: null,
+    nFeatures: 0,
+
+    initialize: function(layerName, className)
+    {
+        this.name =  layerName;
+        this.className = className;
+        this.nFeatures = 0;
+        this.featIds =  [];
+    },
+
+    addFeature : function (featId)
+    {
+        this.featIds[this.nFeatures] = featId;
+        this.nFeatures++;
+    },
+
+    getName : function()
+    {
+        return this.name;
+    },
+
+    getClassName : function()
+    {
+        return this.className;
+    },
+
+    getNumFeatures : function()
+    {
+        return this.nFeatures;
+    },
+    
+    removeFeatures : function (featureIndexes)
+    {
+        var numIndexes = featureIndexes.length;
+        for (var featIndex = 0; featIndex < numIndexes; featIndex++)
+        {
+            this.featIds.remove(featureIndexes[featIndex]);
+            this.nFeatures--;
+        }
+    }
+});
+
+Array.prototype.find = function(searchStr) {
+  var returnArray = null;
+  for (i=0; i<this.length; i++) {
+    if (typeof(searchStr) == 'function') {
+      if (searchStr.test(this[i])) {
+        if (!returnArray) { returnArray = [] }
+        returnArray.push(i);
+      }
+    } else {
+      if (this[i]===searchStr) {
+        if (!returnArray) { returnArray = [] }
+        returnArray.push(i);
+      }
+    }
+  }
+  return returnArray;
+};
+
+Array.prototype.remove = function(indexToRemove) {
+    this.splice(indexToRemove, 1);
+};
+
+
+

Added: branches/fusion2-mg21/layers/MapGuide/php/HighlightSelection.php
===================================================================
--- branches/fusion2-mg21/layers/MapGuide/php/HighlightSelection.php	                        (rev 0)
+++ branches/fusion2-mg21/layers/MapGuide/php/HighlightSelection.php	2008-12-18 23:46:16 UTC (rev 1727)
@@ -0,0 +1,110 @@
+<?php
+/**
+ * SetSelection
+ *
+ * $Id: SetSelection.php 1664 2008-11-12 21:41:00Z madair $
+ *
+ * Copyright (c) 2007, DM Solutions Group Inc.
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+include('Common.php');
+include('../../../common/php/Utilities.php');
+include('Utilities.php');
+
+    $selText = "";
+    GetRequestParameters();
+
+    try
+    {
+        //load the map runtime state
+        //
+        $map = new MgMap();
+        $map->Open($resourceService, $mapName);
+        // Create the selection set and save it
+        $selection = new MgSelection($map);
+        if($selText != "") {
+            $selection->FromXml($selText);
+        }
+        $selection->Save($resourceService, $mapName);
+        
+        //now return a data struture which is the same as Query.php
+        
+        //process 
+        header('Content-type: text/x-json');
+        header('X-JSON: true');
+        $layers = $selection->GetLayers();
+        
+        $result = NULL;
+        $result->hasSelection = false;
+        if ($layers && $layers->GetCount() >= 0)
+        {
+            $result->hasSelection = true;
+            $result->extents = NULL;
+            
+            $result->layers = array();
+            for ($i=0; $i<$layers->GetCount(); $i++) {
+              $layer = $layers->GetItem($i);
+              $layerName = $layer->GetName();
+              array_push($result->layers, $layerName);
+              $layerClassName = $layer->GetFeatureClassName();
+              $filter = $selection->GenerateFilter($layer, $layerClassName);
+              $a = explode('OR', $filter);
+              $result->$layerName->featureCount = count($a);
+            }
+
+        }
+        echo var2json($result);
+
+
+    } catch(MgException $e) {
+        echo "/* SetSelection Exception: " . $e->GetDetails()."*/";
+    }
+
+function GetParameters($params)
+{
+    global $selText;
+
+    $selText = UnescapeMagicQuotes($params['selection']);
+}
+
+
+function UnescapeMagicQuotes($str)
+{
+    if(ini_get("magic_quotes_sybase") == "1")
+        return str_replace("''", "'", $str);
+    else if(get_magic_quotes_gpc() == "1")
+    {
+        //Unescape double quotes
+        $str = str_replace('\\"', '"', $str);
+
+        //remove additional backslash
+        return str_replace("\\", "", $str);
+    }
+    return $str;
+}
+
+function GetRequestParameters()
+{
+    if($_SERVER['REQUEST_METHOD'] == "POST")
+        GetParameters($_POST);
+    else
+        GetParameters($_GET);
+}
+?>


Property changes on: branches/fusion2-mg21/layers/MapGuide/php/HighlightSelection.php
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: branches/fusion2-mg21/layers/MapGuide/php/SetSelection.php
===================================================================
--- branches/fusion2-mg21/layers/MapGuide/php/SetSelection.php	2008-12-18 23:29:31 UTC (rev 1726)
+++ branches/fusion2-mg21/layers/MapGuide/php/SetSelection.php	2008-12-18 23:46:16 UTC (rev 1727)
@@ -37,12 +37,11 @@
         //
         $map = new MgMap();
         $map->Open($resourceService, $mapName);
-        // Create the selection set and save it
+        // Create the selection set
         $selection = new MgSelection($map);
         if($selText != "") {
             $selection->FromXml($selText);
         }
-        $selection->Save($resourceService, $mapName);
         
         //now return a data struture which is the same as Query.php
         $featureService = $siteConnection->CreateService(MgServiceType::FeatureService);
@@ -93,34 +92,39 @@
             $layerName = $oLayer->GetName();
             array_push($properties->layers, $layerName);
 
-            $spatialContext = $featureService->GetSpatialContexts($featureResId, true);
-            $srsLayerWkt = false;
-            if($spatialContext != null && $spatialContext->ReadNext() != null) {
-                $srsLayerWkt = $spatialContext->GetCoordinateSystemWkt();
-                /* skip this layer if the srs is empty */
-            }
-            if ($srsLayerWkt == null) {
-                $srsLayerWkt = $srsDefMap;
-            }
-            /* create a coordinate system from the layer's SRS wkt */
-            $srsLayer = $srsFactory->Create($srsLayerWkt);
-
-            // exclude layer if:
-            //  the map is non-arbitrary and the layer is arbitrary or vice-versa
-            //     or
-            //  layer and map are both arbitrary but have different units
-            //
-            $bLayerSrsIsArbitrary = ($srsLayer->GetType() == MgCoordinateSystemType::Arbitrary);
-            $bMapSrsIsArbitrary = ($srsMap->GetType() == MgCoordinateSystemType::Arbitrary);
+	    // TODO: Check if computed properties are needed?
             $bComputedProperties = false;
             $bNeedsTransform = false;
-            if (($bLayerSrsIsArbitrary != $bMapSrsIsArbitrary) ||
-                ($bLayerSrsIsArbitrary && ($srsLayer->GetUnits() != $srsMap->GetUnits()))) {
-                $bComputedProperties = false;
-            } else {
-                $srsTarget = null;
-                $srsXform = null;
-                $bNeedsTransform = ($srsLayer->GetUnitScale() != 1.0);
+            $srsLayer = NULL;
+            if ($bComputedProperties)
+            {
+		$spatialContext = $featureService->GetSpatialContexts($featureResId, true);
+		$srsLayerWkt = false;
+		if($spatialContext != null && $spatialContext->ReadNext() != null) {
+		    $srsLayerWkt = $spatialContext->GetCoordinateSystemWkt();
+		    /* skip this layer if the srs is empty */
+		}
+		if ($srsLayerWkt == null) {
+		    $srsLayerWkt = $srsDefMap;
+		}
+		/* create a coordinate system from the layer's SRS wkt */
+		$srsLayer = $srsFactory->Create($srsLayerWkt);
+
+		// exclude layer if:
+		//  the map is non-arbitrary and the layer is arbitrary or vice-versa
+		//     or
+		//  layer and map are both arbitrary but have different units
+		//
+		$bLayerSrsIsArbitrary = ($srsLayer->GetType() == MgCoordinateSystemType::Arbitrary);
+		$bMapSrsIsArbitrary = ($srsMap->GetType() == MgCoordinateSystemType::Arbitrary);
+		if (($bLayerSrsIsArbitrary != $bMapSrsIsArbitrary) ||
+		    ($bLayerSrsIsArbitrary && ($srsLayer->GetUnits() != $srsMap->GetUnits()))) {
+		    $bComputedProperties = false;
+		} else {
+		    $srsTarget = null;
+		    $srsXform = null;
+		    $bNeedsTransform = ($srsLayer->GetUnitScale() != 1.0);
+		}
             }
 
             $properties = BuildSelectionArray($featureReader, $layerName, $properties,
@@ -158,9 +162,7 @@
               $layerName = $layer->GetName();
               array_push($result->layers, $layerName);
               $layerClassName = $layer->GetFeatureClassName();
-              $filter = $selection->GenerateFilter($layer, $layerClassName);
-              $a = explode('OR', $filter);
-              $result->$layerName->featureCount = count($a);
+              $result->$layerName->featureCount = $selection->GetSelectedFeaturesCount($layer, $layerClassName);
             }
 
             /*save selection in the session*/



More information about the fusion-commits mailing list