Flex select and zoom to a feature by values from datagrid

4441
18
Jump to solution
11-19-2014 12:20 AM
LiYao
by
New Contributor III

Dear all,

In my flex application, I have a function to retrieve feature attributes in a datagrid.


In the datagrid, I add a context menu "Select and Zoom", when click this context menu on a selected row, I need to select and zoom to the feature based on the "Item No" and "Item Sub No" value.

99999999999999999.jpg

The feature layer is a polyline layer.


I tried to find a solution from ESRI smaple, but no luck.  Could anybody please give me help on this? Thanks a lot.

I am using Adobe Flash Builder 4.6 and arcgis api for flex 3.6.

0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Emeritus

Li Yao,

  The portions of your code where you are using this.cursorManager.removeBusyCursor(); are not portions that you actually use. So the the busy cursor will stay unless you put that line in some code that is actually being called.

Maybe try this code update (line 8):

                                var unionExtent:Extent; 
                                var myFirstGraphic:Graphic = featureSet.features[0]; 
                                unionExtent = Polyline(myFirstGraphic.geometry).extent; 
                               
                                for each (var myGraphic1:Graphic in featureSet.features) 
                                { 
                                    graphicsLayer.add(myGraphic1);
                                    if(myGraphic1.geometry !== myFirstGraphic.geometry){
                                        unionExtent = unionExtent.union(Polyline(myGraphic1.geometry).extent);
                                    }
                                } 
                                map.extent = unionExtent;

View solution in original post

0 Kudos
18 Replies
RobertScheitlin__GISP
MVP Emeritus

Li Yao,

  Is your datagrid populated by a QueryTask results (i.e. Graphics.attributes)? What code do you currently have for the Select and Zoom function?

0 Kudos
LiYao
by
New Contributor III

Hi Robert,

It is select by attribute, I found Mark Hoyland's sample which based on your eSearch.

function onSelectItem(e:ContextMenuEvent):void{

     if(datagrid.selectedIndex >= 0){

     "selected Item No = " + datagrid.selectedItem.itemNo);

     "selected Item Sub No = " + datagrid.selectedItem.itemSubNo);

     this.cursorManager.setBusyCursor();


     var query:Query = new Query;

     query.where = "SELECT * from dev_db.DBO.ItemDetails WHERE Item_No = '" + datagrid.selectedItem.itemNo + "' and Sub_No = '" + datagrid.selectedItem.itemSubNo + "'";


     new AsyncResponder(onSelectResult, onSelectFault, targetLayer));
     else{

          "Select a record first","ATTENTION");

     }

  }


private function onSelectResult(info:Array, token:FeatureLayer = null😞void {

     this.cursorManager.removeBusyCursor();

     var fl:FeatureLayer = token;

     if (fl.selectedFeatures.length == 0)

          "Selection completed but found no features. Please check your parameters." ,

          "Nothing Found", Alert.OK);

}


private function onSelectFault(info:Object, token:Object = null😞void

{
     this.cursorManager.removeBusyCursor();

     "Could not complete Selection. Please try again.\n" + info.toString(),

     "Selection Error", Alert.OK);

}

All features are in the layer dev_db.DBO.ItemDetails, but never select the feature and the busy icon there.

Thanks a lot for the patient and attention.

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Li Yao,

  I we where you are defining your Query object in your code and setting the busy cursor but I don not see where you are actually executing the QueryTask . Like this:

queryTask.execute(query, new AsyncResponder(onResult, onFault));

LiYao
by
New Contributor III

Hi Robert,

I have updated my onSelectItem in the mxml file as follows:

private function onSelectItem(e:ContextMenuEvent):void{
if(datagrid.selectedIndex >= 0){
  Alert.show("selected Segment Id = " + datagrid.selectedItem.itemNo);
  Alert.show("selected BQ No = " + datagrid.selectedItem.itemSubNo); 
    
  this.cursorManager.setBusyCursor();
  var query:Query = new Query;
    
  query.where = "SELECT * from geri_db.DBO.BQ_Segment_1 WHERE Item_No = '" + datagrid.selectedItem.itemNo + "' and Sub_No = '" + datagrid.selectedItem.itemSubNo + "'";
  queryTask.execute(query, new AsyncResponder(onResult, onFault)); 
     
  function onResult(featureSet:FeatureSet, token:Object = null):void 
  {   
   myGraphicsLayer.clear(); 
      
   if (featureSet.features.length == 0) 
   { 
    Alert.show("No feature found. Please try again."); 
   } 
   else 
   { 
    var unionExtent:Extent; 
    var myFirstGraphic:Graphic = featureSet.features[0]; 
    unionExtent = Polyline(myFirstGraphic.geometry).extent; 
       
    for each (var myGraphic1:Graphic in featureSet.features) 
    { 
     myGraphicsLayer.add(myGraphic1); 
     unionExtent = unionExtent.union(Polyline(myGraphic1.geometry).extent); 
    } 
       
    MainMap.extent = unionExtent; 
   } 
  } 
  function onFault(info:Object, token:Object = null):void 
  { 
   Alert.show(info.toString()); 
  }

}else{
   Alert.show("Select a record first","ATTENTION");
      }
}

The related components in the mxml is like follows:

<esri:QueryTask id="queryTask" 
      url="http://localhost:6080/arcgis/rest/services/MyService/MapServer/1"/
  <esri:QueryTask id="queryTaskZoom" 
      url="http://localhost:6080/arcgis/rest/services/MyService/MapServer/1"/
 
 
  <esri:Query id="query" returnGeometry="true" outSpatialReference="{MainMap.spatialReference}">
  </esri:Query>

<esri:Map id="MainMap"> 
  <esri:extent> 
   <esri:Extent xmin="-126" ymin="24" xmax="-67" ymax="50"> 
    <esri:SpatialReference wkid="4326"/> 
   </esri:Extent> 
  </esri:extent> 
  <esri:ArcGISDynamicMapServiceLayer 
   url="http://10.180.8.144:6080/arcgis/rest/services/MyService/MapServer"/
  <esri:GraphicsLayer id="myGraphicsLayer" symbol="{sfs}" graphicProvider="{lastIdentifyResultGraphic}"/> 
</esri:Map>

But got "RPC Fault 400" warning as displayed here:

55555555555555555555555555.jpg

Thanks a lot for the help.

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Li Yao,

   Well I was expecting to see the QueryTask created in the onSelectItem function using action script. an I have no idea why you are showing me a mxml map object as the viewer uses a action script map object from the MapManager.as and each widget has access to that map...

I think it would be best for you to add an attachment with your whole widget code so I can clear see what you are doing.

LiYao
by
New Contributor III

Hi Robert,

I have attached my widget package. I am using asp.net to retrieve the data from sql server database. The part of retrieving the data is handled by others, currently I am using a example sql query statement in asp.net (that means every time I will get the same result in the datagrid), what I am focusing is the map part.

In "Attribute Search" widget, what I am testing is onclick the "Ok" button and open the datagridview (attribute search results widget).

Seems I am very far away from the correct way, so sorry to trouble you so many times.

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Li Yao,

  So here is your main issue in the AttributeSearch.mxml:

            public function handleEvent():void
            {
//You don't close the widget that the code is running in using this code
                /*var widgetId:Number = ViewerContainer.getInstance().widgetManager.getWidgetId("Attribute Search");
                AppEvent.dispatch(AppEvent.WIDGET_CLOSE, widgetId);*/

                var widgetId2:Number = ViewerContainer.getInstance().widgetManager.getWidgetId("Attribute Search Results");
//ViewerContainer.dispatchEvent has been depreciated, you should have seen the warning in Flash builder about this
                //ViewerContainer.dispatchEvent(new AppEvent(AppEvent.WIDGET_RUN, widgetId2));
                AppEvent.dispatch(AppEvent.WIDGET_RUN, widgetId2);
//This is how you close the same widget that the code is running in
                this.setState("closed");
            }

In your AttributeSearchResult.mxml

Why you are adding a map component to your widget I am not sure... Do you really want a map inside this widget?...

If you are wanting to add layers to the main Viewers map then just use the map keyword in your widgets code.

</viewer:WidgetTemplate>    
    <esri:Map id="MainMap" width="245" height="42">  
        <esri:extent> 
            <esri:Extent xmin="-126" ymin="24" xmax="-67" ymax="50">  
                <esri:SpatialReference wkid="4326"/>  
            </esri:Extent>  
        </esri:extent>  
        <esri:ArcGISDynamicMapServiceLayer  
            url="http://localhost:6080/arcgis/rest/services/MyService/MapServer"/>  
        <esri:GraphicsLayer id="myGraphicsLayer" symbol="{sfs}" graphicProvider="{lastIdentifyResultGraphic}"/>  
    </esri:Map>  
</viewer:BaseWidget>

This copy you provided of this widget still has issue that I helped you resolve in another thread. Like you GridColumns need to children of a spark ArrayList. and your results from your web service need to be wrapped in an array collection:

            public function GetLoc(event:ResultEvent):void {
                // Databind data from webservice to datagrid
                datagrid.dataProvider = new ArrayCollection(event.result as Array);
            }
LiYao
by
New Contributor III

Hi Robert,

Thanks so much for the help!

Unfortunately, the error still exists.

have updated my code accordingly.

In fact, I don't need the map component in the widget.

For the selection query I have checked in Arcmap. In arcmap the feature really exist and the query works.

There are 3 warning messages in the flash builder:

(1) 1084:function 'onFault' will be scoped to the default namespace:AttributeSearchResult:intenal. It will not be visible outside of this package.

(2) 1084:function 'onResult' will be scoped to the default namespace:AttributeSearchResult:intenal. It will not be visible outside of this package.

(3) widgets.MyService.AttributeSearch:WebserviceTest is a module or application that is directly referenced. This will cause widgets.MyService.AttributeSearch:WebserviceTest and all of its dependencies to be linked in with widgets.MyService.AttributeSearch:AttributeSearch. Using an interface is the recommended practice to avoid this.

Thanks a lot.

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Li Yao,

  OK, I have commented out many line (unused or unneeded) and made several coding comments, and added some code. Take a look at these changes.