Geocoding and getting better address location score

806
3
Jump to solution
04-03-2012 12:27 PM
ThomasMcCracken
New Contributor III
Afternoon everyone in ESRI Flex API land,

I'm having a little trouble getting a better match to come up in my geocoding.  I'm trying to add a for loop to the code like below:

for(i=0; addressCandidate.score>80, i=10; i++)
{
if (candidates.length > 0)
                    {
                        var addressCandidate:AddressCandidate = candidates[0];
                        var myGraphic:Graphic = new Graphic();

....

}

I've tried several variations of this loop with the candidates array and putting it within the if statement but no luck.
Basically I just want to add a loop to go through all the potential address matches until a score of 80 is reached on the match and then continue with the rest of the Geocoding function found in the API Samples for geocoding.

Anyone attempted to do this and have any luck?  Care to share some code with me??????? =D

Thanks,

Thomas McCracken
GIS Analyst
Georgia Power Company
Tags (2)
0 Kudos
1 Solution

Accepted Solutions
IvanBespalov
Occasional Contributor III
Thomas,
private const ADDRESS_FROM_LOCATION:uint = 0x1; private const ADDRESS_TO_LOCATION: uint = 0x2;  private function findNearestAddress(location:MapPoint, distance:Number):void {  var token:Object = { type: ADDRESS_FROM_LOCATION };  locateTask.locationToAddress(location,    distance,    new AsyncResponder(onLocateTaskResult, onLocateTaskFault, token));     }  private function executeLocatorTask(address:String):void {  // search attributes { Attribute1: "attribute value", Attribute2: "attribute value"}  // defined in/by geocode service as request parameters  var token:Object = { type: ADDRESS_TO_LOCATION };  var addressObj:Object = { StreetName: address };  var outFields:Array = [ "*" ];  locateTask.outSpatialReference = map.spatialReference;  locateTask.addressToLocations(addressObj,    outFields,    new AsyncResponder(onLocateTaskResult, onLocateTaskFault, token)); }  protected function onLocateTaskResult(result:*, token:Object = null):void {  var candidates:Array = null;  var addressCandidate:AddressCandidate = null;       if (result is Array)  {   candidates = result as Array;  }  else if (result is AddressCandidate)  {   addressCandidate = result as AddressCandidate;  }       if (token != null && token.type != null)  {   switch (token.type)   {    case ADDRESS_TO_LOCATION:    {     var bestCandidates:Array = findBestScoredCandidates(candidates);     var suitableCandidates:Array = findSuitableCandidates(candidates, 80);     break;    }    case ADDRESS_FROM_LOCATION:    {     showCandidateOnMap(addressCandidate);     break;    }   }  } }     protected function onLocateTaskFault(info:Object, token:Object = null):void {  trace(StringUtil.substitute("Error\n>>>\n{0}", info.toString())); }  private function showCandidateOnMap(candidate:AddressCandidate):void {  myGraphicsLayer.clear(); //   var address:Object = candidate.address;  var candidateMapPoint:MapPoint = candidate.location;  if (candidateMapPoint.spatialReference.wkid != myMap.spatialReference.wkid)  {   candidateMapPoint = WebMercatorUtil.geographicToWebMercator(candidate.location) as MapPoint;  }  var myGraphic:Graphic = new Graphic(candidateMapPoint, mySymbol, address);  myGraphic.toolTip = address.Address.toString();    myGraphicsLayer.add(myGraphic); }  private function findBestScoredCandidates(candidates:Array):Array {  if (candidates != null)  {   if (candidates.length > 0)   {    var bestScore:Number = 0;    var bestScoredCandidates:Array = new Array();     for (var index:int; index < candidates.length; index++)    {     var nextCandidate:AddressCandidate = candidates[index];          if (nextCandidate.score > bestScore) // candidate with better score found     {      bestScoredCandidates = new Array();      bestScoredCandidates.push(nextCandidate);      bestScore = nextCandidate.score;     }     else if (nextCandidate.score > bestScore) // candidate with same score found     {      bestScoredCandidates.push(nextCandidate);     }         }     return bestScoredCandidates;   }  }    return null; }  private function findSuitableCandidates(candidates:Array, suitableScore:Number):Array {  if (candidates != null)  {   if (candidates.length > 0)   {    var suiatableCandidates:Array = new Array();     for (var index:int; index < candidates.length; index++)    {     var nextCandidate:AddressCandidate = candidates[index];          if (nextCandidate.score >= suitableScore)     {      suiatableCandidates.push(nextCandidate);     }         }     return suiatableCandidates;   }  }    return null; }


Also, as I remember Location Service has alot of configurations on server side, so you can try sort, filter ... results on server.

View solution in original post

0 Kudos
3 Replies
TracySchloss
Frequent Contributor
Are you using your own locator or one from ESRI?  I have found that some of the ESRI locators are better about having the best match returned first.  Others are pretty sloppy.
0 Kudos
IvanBespalov
Occasional Contributor III
Thomas,
private const ADDRESS_FROM_LOCATION:uint = 0x1; private const ADDRESS_TO_LOCATION: uint = 0x2;  private function findNearestAddress(location:MapPoint, distance:Number):void {  var token:Object = { type: ADDRESS_FROM_LOCATION };  locateTask.locationToAddress(location,    distance,    new AsyncResponder(onLocateTaskResult, onLocateTaskFault, token));     }  private function executeLocatorTask(address:String):void {  // search attributes { Attribute1: "attribute value", Attribute2: "attribute value"}  // defined in/by geocode service as request parameters  var token:Object = { type: ADDRESS_TO_LOCATION };  var addressObj:Object = { StreetName: address };  var outFields:Array = [ "*" ];  locateTask.outSpatialReference = map.spatialReference;  locateTask.addressToLocations(addressObj,    outFields,    new AsyncResponder(onLocateTaskResult, onLocateTaskFault, token)); }  protected function onLocateTaskResult(result:*, token:Object = null):void {  var candidates:Array = null;  var addressCandidate:AddressCandidate = null;       if (result is Array)  {   candidates = result as Array;  }  else if (result is AddressCandidate)  {   addressCandidate = result as AddressCandidate;  }       if (token != null && token.type != null)  {   switch (token.type)   {    case ADDRESS_TO_LOCATION:    {     var bestCandidates:Array = findBestScoredCandidates(candidates);     var suitableCandidates:Array = findSuitableCandidates(candidates, 80);     break;    }    case ADDRESS_FROM_LOCATION:    {     showCandidateOnMap(addressCandidate);     break;    }   }  } }     protected function onLocateTaskFault(info:Object, token:Object = null):void {  trace(StringUtil.substitute("Error\n>>>\n{0}", info.toString())); }  private function showCandidateOnMap(candidate:AddressCandidate):void {  myGraphicsLayer.clear(); //   var address:Object = candidate.address;  var candidateMapPoint:MapPoint = candidate.location;  if (candidateMapPoint.spatialReference.wkid != myMap.spatialReference.wkid)  {   candidateMapPoint = WebMercatorUtil.geographicToWebMercator(candidate.location) as MapPoint;  }  var myGraphic:Graphic = new Graphic(candidateMapPoint, mySymbol, address);  myGraphic.toolTip = address.Address.toString();    myGraphicsLayer.add(myGraphic); }  private function findBestScoredCandidates(candidates:Array):Array {  if (candidates != null)  {   if (candidates.length > 0)   {    var bestScore:Number = 0;    var bestScoredCandidates:Array = new Array();     for (var index:int; index < candidates.length; index++)    {     var nextCandidate:AddressCandidate = candidates[index];          if (nextCandidate.score > bestScore) // candidate with better score found     {      bestScoredCandidates = new Array();      bestScoredCandidates.push(nextCandidate);      bestScore = nextCandidate.score;     }     else if (nextCandidate.score > bestScore) // candidate with same score found     {      bestScoredCandidates.push(nextCandidate);     }         }     return bestScoredCandidates;   }  }    return null; }  private function findSuitableCandidates(candidates:Array, suitableScore:Number):Array {  if (candidates != null)  {   if (candidates.length > 0)   {    var suiatableCandidates:Array = new Array();     for (var index:int; index < candidates.length; index++)    {     var nextCandidate:AddressCandidate = candidates[index];          if (nextCandidate.score >= suitableScore)     {      suiatableCandidates.push(nextCandidate);     }         }     return suiatableCandidates;   }  }    return null; }


Also, as I remember Location Service has alot of configurations on server side, so you can try sort, filter ... results on server.
0 Kudos
ThomasMcCracken
New Contributor III
Tracy, I'm using ESRI's North America 10 address locator just like in their sample geocode here on the resource center.  I tried using some of the others with no luck.  If it is in fact giving me the best possible match then their matching algorithm is horrible as I get a Jefferson Ave. everytime I enter Jefferson Street.

Thanks ibespalov for the code!
0 Kudos