arcgis flex api---geocode identify

2710
10
Jump to solution
04-01-2014 01:05 PM
abukhan
New Contributor III
Hi :

I am trying to do geocoding using flex api...
Here is the issue.

After typing the address, press the find button.
   What I need:
        It should show point on the map..
        and also use this point, query a layer (say county/tract) to get the results(like county code, tract code)
              from this layer without any click on the map

I tried to use the identify feature shown in the example, but the results.length becomes zero.
and did not show any results.

here is the find address:
private function doFind():void
   {
    var parameters:AddressToLocationsParameters = new AddressToLocationsParameters();
    myGraphicsLayer.clear();
    parameters.address = { SingleLine: onelineaddress.text };
   
    // Use outFields to get back extra information
    // The exact fields available depends on the specific Locator used.
    parameters.outFields = [ "Loc_name" ];
   
    locator.addressToLocations(parameters, new AsyncResponder(onResult, onFault));
    function onResult(candidates:Array, token:Object = null):void
    {
     if (candidates.length > 0)
     {
      var addressCandidate:AddressCandidate = candidates[0];
      var myGraphic:Graphic = new Graphic();
      var myGraphicWGS:Graphic = new  Graphic();
     
      // for 9.3 servers, or anything else returning latlong:  myGraphic.geometry = WebMercatorUtil.geographicToWebMercator(addressCandidate.location);
     
      myGraphic.geometry = addressCandidate.location;
      myGraphic.symbol = mySymbol;
      myGraphic.toolTip = addressCandidate.address.toString();
      myGraphic.id = "graphic";
      myGraphicsLayer.add(myGraphic);
     
      MainMap.centerAt(myGraphic.geometry as MapPoint);
     
      // Zoom to an appropriate level
      // Note: your attribute and field value might differ depending on which Locator you are using...
      if (addressCandidate.attributes.Loc_name.search("RoofTop") > 0) // US_RoofTop
      {
       MainMap.scale = 10000;
      }
      else if (addressCandidate.attributes.Loc_name.search("Address") > 0)
      {
       MainMap.scale = 10000;
      }
      else if (addressCandidate.attributes.Loc_name.search("Street") > 0) // US_Streets, CAN_Streets, CAN_StreetName, EU_Street_Addr* or EU_Street_Name*
      {
       MainMap.scale = 15000;
      }
      else if (addressCandidate.attributes.Loc_name.search("ZIP4") > 0
       || addressCandidate.attributes.Loc_name.search("Postcode") > 0) // US_ZIP4, CAN_Postcode
      {
       MainMap.scale = 20000;
      }
      else if (addressCandidate.attributes.Loc_name.search("Zipcode") > 0) // US_Zipcode
      {
       MainMap.scale = 40000;
      }
      else if (addressCandidate.attributes.Loc_name.search("City") > 0) // US_CityState, CAN_CityProv
      {
       MainMap.scale = 150000;
      }
      else
      {
       MainMap.scale = 500000;
      }
      //vboxlatlong.visible=true;
      var wgsmappoint:MapPoint = WebMercatorUtil.webMercatorToGeographic(addressCandidate.location) as MapPoint;
      //labellongitude.text = (wgsmappoint.x.toFixed(5)).toString();
      //labellatitude.text = (wgsmappoint.y.toFixed(5)).toString();
     
      labeladdressresult.text = "<b>Address Found:</b><br/>" + addressCandidate.address.toString(); // formated address
    
      //identify
      doIdentify(wgsmappoint);
     }
     else
     {
      //vboxlatlong.visible=false;//
      //labellongitude.text="";
      //labellatitude.text="";
      labeladdressresult.text = "<b><font color='#FF0000'>Found nothing !!</b></font>";
     
      Alert.show("Sorry, couldn't find a location for this address"
       + "\nAddress: " + onelineaddress.text);
     
     };
    }


here is the doIdentify (without using any mouse click)


private function doIdentify(mpoint:MapPoint):void{
    
    //clickGraphicsLayer.clear();
   
    //Alert.show("Hey" + mpoint.x.toString());
   
    var identifyParams:IdentifyParameters = new IdentifyParameters();
    identifyParams.returnGeometry = true;
    identifyParams.tolerance = 1;
    identifyParams.width = MainMap.width;
    identifyParams.height = MainMap.height;
    identifyParams.geometry = mpoint;
    identifyParams.mapExtent = MainMap.extent;
    identifyParams.spatialReference = MainMap.spatialReference;
    //Alert.show(mpoint.x.toString());
    //var mappoint:MapPoint = new MapPoint();
    //mappoint = mpoint;
    var clickGraphic:Graphic = new Graphic(mpoint, clickPtSym);
    clickGraphicsLayer.add(clickGraphic);
   
    identifyTask.execute(identifyParams, new AsyncResponder(myResultFunction, myFaultFunction, clickGraphic));
   
   }


results.length shows zero

private function myResultFunction(results:Array, clickGraphic:Graphic = null):void
   {
    // Alert.show(" i m ahere result function ");
     Alert.show(" i m ahere result function " + results.length.toString());
    if (results && results.length > 0)
    {
     var result:IdentifyResult = results[0];
     var resultGraphic:Graphic = result.feature;
     //Alert.show(resultGraphic.attributes.toString());
     switch (resultGraphic.geometry.type)
     {
      case Geometry.MAPPOINT:
      {
       resultGraphic.symbol = smsIdentify;
       break;
      }
      
     }
     lastIdentifyResultGraphic = resultGraphic;
     //paneltractresult.visible = true;
   
    }
   }




Thanks

Abu
Tags (2)
0 Kudos
1 Solution

Accepted Solutions
AaronNash1
Occasional Contributor II
I used the Geocoder component to accomplish what you are tying to do

<esri:Geocoder width="230" map="{map}" id="geocodeWin" resultSelected="geocodeWin_resultSelectedHandler(event)" toolTip="Type in Address" autoComplete="true" url="put your map service here" prompt="Type in Address"/>

Here is the function for results selected

protected function geocodeWin_resultSelectedHandler(event:GeocoderEvent):void
{
     identifyMap()
}

Here is the identifyMap Funtion

private function identifyMap():void
{
              //Zoom to the location, clear the graphics layer and add a new graphic to the map
map.scale = 2000;
selectedGraphic.clear();
              var mapPointIcon:PictureMarkerSymbol = new PictureMarkerSymbol();
mapPointIcon.source = "assets/trash.png";
var selGraphic:Graphic= new Graphic(new MapPoint(map.center.x, map.center.y, map.spatialReference), mapPointIcon);       
selectedGraphic.add(selGraphic);
              //set up identify parameters
              identifyParams:IdentifyParameters = new IdentifyParameters();
identifyParams.layerOption = IdentifyParameters.LAYER_OPTION_VISIBLE;
identifyParams.layerIds = [0,1];
identifyParams.returnGeometry = true;   
identifyParams.tolerance = 3;
identifyParams.width = map.width;
identifyParams.height = map.height;
identifyParams.geometry = selGraphic.geometry;
identifyParams.mapExtent = map.extent;
identifyParams.spatialReference = map.spatialReference;   
identifyTask.execute(identifyParams, new AsyncResponder(myResultFunction, myFaultFunction));
}

So the user types in an address, selects the address, and then the map zooms to the location, drops a point and identifys the area.

View solution in original post

0 Kudos
10 Replies
AaronNash1
Occasional Contributor II
I used the Geocoder component to accomplish what you are tying to do

<esri:Geocoder width="230" map="{map}" id="geocodeWin" resultSelected="geocodeWin_resultSelectedHandler(event)" toolTip="Type in Address" autoComplete="true" url="put your map service here" prompt="Type in Address"/>

Here is the function for results selected

protected function geocodeWin_resultSelectedHandler(event:GeocoderEvent):void
{
     identifyMap()
}

Here is the identifyMap Funtion

private function identifyMap():void
{
              //Zoom to the location, clear the graphics layer and add a new graphic to the map
map.scale = 2000;
selectedGraphic.clear();
              var mapPointIcon:PictureMarkerSymbol = new PictureMarkerSymbol();
mapPointIcon.source = "assets/trash.png";
var selGraphic:Graphic= new Graphic(new MapPoint(map.center.x, map.center.y, map.spatialReference), mapPointIcon);       
selectedGraphic.add(selGraphic);
              //set up identify parameters
              identifyParams:IdentifyParameters = new IdentifyParameters();
identifyParams.layerOption = IdentifyParameters.LAYER_OPTION_VISIBLE;
identifyParams.layerIds = [0,1];
identifyParams.returnGeometry = true;   
identifyParams.tolerance = 3;
identifyParams.width = map.width;
identifyParams.height = map.height;
identifyParams.geometry = selGraphic.geometry;
identifyParams.mapExtent = map.extent;
identifyParams.spatialReference = map.spatialReference;   
identifyTask.execute(identifyParams, new AsyncResponder(myResultFunction, myFaultFunction));
}

So the user types in an address, selects the address, and then the map zooms to the location, drops a point and identifys the area.
0 Kudos
abukhan
New Contributor III
need to use our own locator (can not use world geo locator)? Can it be done?

Thanks
0 Kudos
AaronNash1
Occasional Contributor II
With the provided code I use my own locator, don't have any issues at all
0 Kudos
abukhan
New Contributor III
Also i need to show what match address was found.... and the score
0 Kudos
AaronNash1
Occasional Contributor II
in the geocoder result event add

protected function geocodeWin_resultSelectedHandler(event:GeocoderEvent):void
{
ScoreText.text = event.result.data.score;
AddressText.text = event.result.data.address;
              identifyMap()
}
0 Kudos
abukhan
New Contributor III
THanks for all these..

---Can the Geocoder tag have a search icon at the end of the inputbox where user can click (rather than just press enter)?

-- for own geocoder, i tried with the url property of the geocoder,, but it did not work .....

---  in your identify function code: the graphic is getting the map center, how it is getting the address point x,y?

private function identifyMap():void
{
//Zoom to the location, clear the graphics layer and add a new graphic to the map
map.scale = 2000;
selectedGraphic.clear();
var mapPointIcon:PictureMarkerSymbol = new PictureMarkerSymbol();
mapPointIcon.source = "assets/trash.png";
var selGraphic:Graphic= new Graphic(new MapPoint(map.center.x, map.center.y, map.spatialReference), mapPointIcon);
selectedGraphic.add(selGraphic);



THnaks.

abu
0 Kudos
AaronNash1
Occasional Contributor II
you can modify the GeocoderSkin.mxml file found in the API download folder.

Not sure why your URL is not working, you should use Fiddler to watch the URL requests to your rest end point, make sure the http requests are formatting correctly.

When you use the geocoder the default behavior is to pan the map to the geocoded location. So a user types in an address, the geocoder returns a Lat and Long, map pans to that location. The identifymap function zooms in closer "map.scale = 2000;" and then adds a graphic at the center of the map "var selGraphic:Graphic= new Graphic(new MapPoint(map.center.x, map.center.y, map.spatialReference), mapPointIcon);" I put the graphic at the center of the map because the map is already centered at the geocoded location. I then use the geometry of the graphic to identify a parcel and return information.
0 Kudos
raffia
by
New Contributor II
Hello Aaron;

Thanks for the replies above, I just have a question related to this so I hope it is ok to post it here.

I am basically trying to sniff all the initial matches returned and dd graphic points on the map, one for each match. My for loop is throwing an error:
index is out of bounds

What I am able to do however is get the selected result and then bring back all the details by getting the object id of the result and then firing a query, not necessarily faster than an identify, it is just what I came up with. So here is my code and any help is highly appreciated:

<esri:Geocoder autoComplete="true"   url="url here"  id="geoCoderID" map="{myMap}"/>

protected function application1_creationCompleteHandler(event:FlexEvent):void
{    
    
    geoLO.searchExtent = myMap.extent;
    geoCoderID.locatorOptions = geoLO;
    geoCoderID.locatorOptions.outFields = [ "Loc_name" , "Ref_ID" ];
    geoCoderID.addEventListener(GeocoderEvent.RESULT_SELECTED,geocoderResultSelected);
    geoCoderID.addEventListener(GeocoderEvent.SEARCH_AUTO_COMPLETE,geocoderSearchAutoCompleteEventHandler);
    geoCoderID.addEventListener(GeocoderEvent.SEARCH_COMPLETE, geocoderResultsEvent);
    
}    


private function geocoderSearchAutoCompleteEventHandler(event:GeocoderEvent):void
{


    var geocoderResultsGraphic:Graphic = new Graphic();
    geocoderResultsGraphic.id = "graphicResults";
    geocoderResultsGraphic.symbol = geocoderResultSymbol;
    
    for(var i:int = 1; i<event.results.length; i++)
    {
        geocoderResultsGraphic.geometry = event.results[0].geometry;    
            geocoderResultsGraphic.toolTip = event.results[0].label.toString();
                myMap.defaultGraphicsLayer.add(geocoderResultsGraphic);    
    
    }


}
    

//The below function works as intended


private function geocoderResultSelected(event:GeocoderEvent):void
{
    
    landmarkPointX = event.result.data.location.x;
    landmarkPointY = event.result.data.location.y;
    landmarkMapPoint = new MapPoint(landmarkPointX,landmarkPointY,null);
    identifyMapPoint = new MapPoint(landmarkPointX,landmarkPointY,null);
    myMap.defaultGraphicsLayer.clear();
    if(event.result.data.attributes.Loc_name == "LandmarkCom.ELandmarkAll" ||
        event.result.data.attributes.Loc_name == "LandmarkCom.ELandmarkName")
    {




        queryLandmarks.where = "OBJECTID="+ event.result.data.attributes.Ref_ID;    
        queryTaskLandmarks.execute(queryLandmarks, new AsyncResponder(catchLandmarkGeocoderDetails, onURLLoadFault ));    
        
    }
        
    else if(event.result.data.attributes.Loc_name == "BuildingCom.EBuildingAll" 
        || event.result.data.attributes.Loc_name == "BuildingCom.EBuildingArea" 
        || event.result.data.attributes.Loc_name == "BuildingCom.EBuildingNumber")
    {


        queryBuildingURL.where = "OBJECTID="+ event.result.data.attributes.Ref_ID;    
        queryTaskBuildingURL.execute(queryBuildingURL, new AsyncResponder( onBuildingURLResults, onURLLoadFault ));                
        
    }
        
    else if(event.result.data.attributes.Loc_name == "StreetCom.EStreetAll" || event.result.data.attributes.Loc_name == "StreetCom.EStreetName")
    {


        queryStreetURL.where = "OBJECTID="+ event.result.data.attributes.Ref_ID;    
        queryTaskStreetURL.execute(queryStreetURL, new AsyncResponder( onStreetURLResults, onURLLoadFault ));
        
    }
    geoCoderID.clearButton.addEventListener(MouseEvent.CLICK,clearGeocoderGraphic);        
    
    myMap.scale = 5000;
    
    var geocoderGraphic:Graphic = new Graphic();
    geocoderGraphic.geometry = event.result.geometry;
    geocoderGraphic.symbol = geocoderResultSymbol;
    geocoderGraphic.toolTip = event.result.label.toString();
    geocoderGraphic.id = "graphic";
    myMap.defaultGraphicsLayer.add(geocoderGraphic);
    
}

0 Kudos
AaronNash1
Occasional Contributor II
try this

private function geocoderSearchAutoCompleteEventHandler(event:GeocoderEvent):void
   {
    //check to make sure there are results
    if (event.results.length > 0)
    {
     //clear the graphics layer before add more
     graphicsLayer.clear();             
     for(var i:int = 0; i < event.results.length; i++)
     {
      var geocoderResultsGraphic:Graphic = new Graphic();
      geocoderResultsGraphic.id = "graphicResults";
      geocoderResultsGraphic.geometry = event.results.geometry;    
      geocoderResultsGraphic.toolTip = event.results.label.toString();
      geocoderResultsGraphic.symbol = mySymbol;
      //don't use default
      graphicsLayer.add(geocoderResultsGraphic);     
     }
    } 
   }


if you debugged it, it was creating one graphic and then stalling on the second. Doing it this way allows it to create multiple and loop through. Seems to work pretty well.
0 Kudos