urgent >> problem in using identify Task (identifying using multiple layers) in flex

768
12
04-28-2010 05:23 AM
mohamedbakri
New Contributor
Dear all,

I???m using flex builder version 3 (SDK 3.3) and ARCGIS Flex APIs version 1.2 
I tried to build identify module using identify task but I have big problem when I using it to identify on multiple layers as follows:

private function doIdentify(graphic:Graphic):void
{
if (identifyByAllLayers)
                {
                                                var LayerObject:Object=null;
                                                if (identifyBy == "Point")
                                                                LayerObject=servicesCombobox_Point.selectedItem;
                                                else if (identifyBy == "Polygon" && drawMode == "notBuffer")
                                                                LayerObject=servicesCombobox_Polygon.selectedItem;
                                                else if ((identifyBy == "Point" && drawMode == "buffer") || (identifyBy == "Polygon" && drawMode == "buffer"))
                                                                LayerObject=servicesCombobox_Buffer.selectedItem;


                                                for (var y:int=0; y < map.layers.length; y++)
                                                {
                                                                if (map.layers.url.indexOf(LayerObject.mapServiceName, 0) != -1)
                                                                {
                                                                                for (var x:int=0; x < map.layers.visibleLayers.length; x++)
                                                                                  {
                                                                                                arrLayerIds.push(Number(map.layers.visibleLayers));
                                                                                 }
break;
                                                                }
                                                }
                }
identifyParams.layerIds=arrLayerIds;
                identifyParams.width=map.width;
                identifyParams.height=map.height;
                identifyParams.geometry=graphic.geometry;
                identifyParams.mapExtent=map.extent;
                identifyParams.tolerance=2;
                identifyParams.spatialReference=map.spatialReference;
                identifyTask.execute(identifyParams, new AsyncResponder(myResultFunction, myFaultFunction, graphic));
}

The error occur in this case is faultCode:500 faultString:'Unable to perform identify. Please check your parameters' faultDetail:''

Please help me urgently in this issue
Tags (2)
0 Kudos
12 Replies
RhysDonoghue
New Contributor
Hi Robert

I can get multiple selection but cannot get the metadata for all of the layers.  I have stripped my code down and only three layers are in there now.  When clicking on a building, an info window should come up showing the building info, parcel info and zone info.  I am only getting the parcel info.  I'm sure I just need one line of code but don't know what that one line is 😞


<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
      xmlns:mx="library://ns.adobe.com/flex/mx"
      xmlns:esri="http://www.esri.com/2008/ags"
      xmlns:s="library://ns.adobe.com/flex/spark"
      pageTitle="Splice Group demo" xmlns:myClasses="myClasses.*">

<fx:Script>
  <![CDATA[
   import com.esri.ags.events.DrawEvent;
   import com.esri.ags.events.GeometryServiceEvent;
   import com.esri.ags.events.GraphicEvent;
   import com.esri.ags.events.MapMouseEvent;
   import com.esri.ags.FeatureSet;
   import com.esri.ags.geometry.Extent;
   import com.esri.ags.geometry.Geometry;
   import com.esri.ags.geometry.MapPoint;
   import com.esri.ags.geometry.Polygon;
   import com.esri.ags.geometry.Polyline;
   import com.esri.ags.Graphic;
   import com.esri.ags.layers.TiledMapServiceLayer;
   import com.esri.ags.SpatialReference;
   import com.esri.ags.symbols.InfoSymbol;
   import com.esri.ags.tasks.supportClasses.IdentifyParameters;
   import com.esri.ags.tasks.supportClasses.IdentifyResult;
   import com.esri.ags.tasks.supportClasses.LengthsParameters;
   import com.esri.ags.utils.GraphicUtil;
   import com.esri.ags.utils.WebMercatorUtil;
   import com.esri.ags.virtualearth.VEGeocodeResult;
   import flash.events.Event;
   import mx.controls.Alert;
   import mx.controls.DataGrid;
   import mx.events.FlexEvent;
   import mx.graphics.codec.JPEGEncoder;
   import mx.graphics.ImageSnapshot;   
   import mx.printing.FlexPrintJob;
   import mx.printing.FlexPrintJobScaleType;
   import mx.rpc.AsyncResponder;
   import mx.rpc.Fault;
   import mx.utils.ObjectUtil;
     
   [Bindable]private var lastIdentifyResultGraphic:Graphic;
   [Bindable]private var latestEndpoint:MapPoint;
     
   private function mapClickHandler(event:MapMouseEvent):void
   {
    clickGraphicsLayer.clear();
    lastIdentifyResultGraphic = null;
    var identifyParams:IdentifyParameters = new IdentifyParameters();
    identifyParams.returnGeometry = true;
    identifyParams.tolerance = 3;
    identifyParams.width = myMap.width;
    identifyParams.height = myMap.height;
    identifyParams.geometry = event.mapPoint;
    identifyParams.mapExtent = myMap.extent;
    identifyParams.spatialReference = myMap.spatialReference;
    identifyParams.layerOption = IdentifyParameters.LAYER_OPTION_ALL;
   
    var clickGraphic:Graphic = new Graphic(event.mapPoint, clickPtSym);
    clickGraphicsLayer.add(clickGraphic);
   
    identifyTask.execute(identifyParams, new AsyncResponder(myResultFunction, myFaultFunction, clickGraphic));
   }
  
   private function myResultFunction(results:Array, clickGraphic:Graphic = null):void
   {
    resultGraphicsLayer.clear();
    if (results && results.length > 0)
    {
     for each (var identifyResult:IdentifyResult in results)
     {
      var resultGraphic:Graphic = identifyResult.feature;
      switch (resultGraphic.geometry.type)
      {
       case Geometry.MAPPOINT:
       {
        resultGraphic.symbol = smsIdentify;
        break;
       }
       case Geometry.POLYLINE:
       {
        resultGraphic.symbol = slsIdentify;
        break;
       }
       case Geometry.POLYGON:
       {
        resultGraphic.symbol = sfsIdentify;
        break;
       }
      }
      resultGraphic.addEventListener(MouseEvent.MOUSE_OVER, onMouseOverHandler);
      resultGraphic.addEventListener(MouseEvent.MOUSE_OUT, onMouseOutHandler);
      resultGraphicsLayer.add(resultGraphic);
     
      //----------------------------------------------------
      // NOT SURE WHAT TO PUT HERE.  I WANT AN INFO WINDOW TO COME UP AND THE LINE BELOW TO ADD ALL OF THE ATTRIBUTES FOR ALL OF THE LAYERS.   
      //????resultGraphic.attributes = resultGraphic.attributes;
      //----------------------------------------------------
     }
    }
   }
  
   private function onMouseOutHandler(event:MouseEvent):void
   {
    myMap.infoWindow.hide();
   }
  
   private function onMouseOverHandler(event:MouseEvent):void
   {
    var gr:Graphic = Graphic(event.target);
    lastIdentifyResultGraphic = new Graphic(getGeomCenter(gr),new InfoSymbol,gr.attributes);
   }
  
   //get geom center
   private function getGeomCenter(graphic:Graphic):MapPoint
   {
    var pt:MapPoint;
    switch (graphic.geometry.type)
    {
     case Geometry.MAPPOINT:
     {
      pt = graphic.geometry as MapPoint;
      break;
     }
     case Geometry.POLYLINE:
     {
      const pl:Polyline = graphic.geometry as Polyline;
      const pathCount:Number = pl.paths.length;
      const pathIndex:int = int((pathCount / 2) - 1);
      const midPath:Array = pl.paths[pathIndex];
      const ptCount:Number = midPath.length;
      const ptIndex:int = int((ptCount / 2) - 1);
      pt = pl.getPoint(pathIndex, ptIndex);
      break;
     }
     case Geometry.POLYGON:
     {
      const poly:Polygon = graphic.geometry as Polygon;
      pt = poly.extent.center;
      break;
     }
    }
    return pt;
   }
  
  
   private function myFaultFunction(error:Object, clickGraphic:Graphic = null):void
   {
    Alert.show(String(error), "Identify Error");
   }
  
   private function layerShowHandler(event:FlexEvent):void
   {
    // update the LODs/zoomslider to use/show the levels for the selected base map
    var tiledLayer:TiledMapServiceLayer = event.target as TiledMapServiceLayer;
    myMap.lods = tiledLayer.tileInfo.lods;
   }
    
  ]]>
</fx:Script>


<!-- Start Declarations -->
<fx:Declarations>
 
  <!-- Symbol for where the user clicked -->
  <esri:SimpleMarkerSymbol id="clickPtSym"
         color="0xFF0000"
         size="12"
         style="x"/>
 
  <!-- Symbol for Identify Result as Polyline -->
  <esri:SimpleLineSymbol id="slsIdentify"
          width="2"
          alpha="1"
          color="0x00FF00"
          style="solid"/>
 
  <!-- Symbol for Identify Result as Point -->
  <esri:SimpleMarkerSymbol id="smsIdentify"
         color="0x00FF00"
         size="15"
         style="diamond"/>
 
  <!-- Symbol for Identify Result as Polygon -->
  <esri:SimpleFillSymbol id="sfsIdentify"/>
 
  <!-- Identify Task -->
  <esri:IdentifyTask id="identifyTask"
         concurrency="last"
         url="http://remote.splicegroup.co.nz/ArcGIS/rest/services/BRANZ_ALL/MapServer"
         />

</fx:Declarations>

<!-- End Declarations -->


<esri:Map id="myMap"
     level="18"
     load="myMap.centerAt(new MapPoint(19470000, -5045000))"
     mapClick="mapClickHandler(event)"
     openHandCursorVisible="false"     
     >
 
  <!-- OpenStreetMap server down so commented out -->
  <esri:OpenStreetMapLayer show="layerShowHandler(event)"
         tileServers="http://b.tile.openstreetmap.org/"
         />
  
  <esri:ArcGISTiledMapServiceLayer  url="http://remote.splicegroup.co.nz/ArcGIS/rest/services/BRANZ_buildings/MapServer"
            />
 
  <esri:ArcGISTiledMapServiceLayer  url="http://remote.splicegroup.co.nz/ArcGIS/rest/services/BRANZ_parcels/MapServer"
            />
 
  <esri:ArcGISTiledMapServiceLayer  url="http://remote.splicegroup.co.nz/ArcGIS/rest/services/BRANZ_corrosion_zones/MapServer"
            alpha="0.1"
            />

  <esri:GraphicsLayer id="myResultsLayer" graphicProvider="{lastIdentifyResultGraphic}"/>
  <esri:GraphicsLayer id="clickGraphicsLayer"/>
  <esri:GraphicsLayer id="resultGraphicsLayer"/>
  <esri:GraphicsLayer graphicProvider="{lastIdentifyResultGraphic}"/>
 
</esri:Map>
 
</s:Application>
0 Kudos
RobertScheitlin__GISP
MVP Emeritus
Rhys,

   The problem with the approach you want to take is how do you distinguish which attributes are for which layer?

Here is some code that will merge the attributes to show in one infowindow but if common fields will be overwritten (i.e. OBJECTID, Shape_Length). This does not seem like a very viable solution.

   private function myResultFunction(results:Array, clickGraphic:Graphic = null):void
   {
    resultGraphicsLayer.clear();
    if (results && results.length > 0)
    {
     var obj:Object = new Object();
     for each (var identifyResult:IdentifyResult in results)
     {
      var resultGraphic:Graphic = identifyResult.feature;
      switch (resultGraphic.geometry.type)
      {
       case Geometry.MAPPOINT:
       {
        resultGraphic.symbol = smsIdentify;
        break;
       }
       case Geometry.POLYLINE:
       {
        resultGraphic.symbol = slsIdentify;
        break;
       }
       case Geometry.POLYGON:
       {
        resultGraphic.symbol = sfsIdentify;
        break;
       }
      }
      lastIdentifyResultGraphic = resultGraphic;
      merge(obj ,resultGraphic.attributes);
     }
     // update clickGraphic (from mouse click to returned feature)
     clickGraphic.symbol = new InfoSymbol(); // use default renderer
     clickGraphic.attributes = obj;
    }
   }
   
   private function merge(target:Object, source:Object):void{
    for(var p:String in source){
     target
 = source
;
    }
   }
0 Kudos
RhysDonoghue
New Contributor
Hi Robert.  Thanks heaps for that.  It looks like it is working how I want.  For one of the layers (e.g. the parcel layer), I want to see up to ten fields.  For the other two layers, e.g. hazard zone or whatever, I only want to see one field and the fields have unique names.  I can work with this.  Thanks again.
0 Kudos