xilducex

iOS AGSLocator object doesn't support OutSpatialReference?

Discussion created by xilducex on Nov 3, 2011
Latest reply on Nov 16, 2011 by njarecha-esristaff
Hello All,

I am VERY new to iOS development.  I've spent the last few years programming using the Silverlight API...

...Anyways I think I may have stumbled on a bug.  I was following the example in the ArcGIS iOS API for geocoding and for some reason I cannot get the AGSLocator object to return my address candidates in the correct spatial reference.  If I specify web mercator (WKID: 102100) I get my candidates back off the coast of Africa (clearly in WGS-84).

I am using Xcode v4.2 and I am using the iOS API with Automated Reference Counting enabled.

here is some code from my AddressFinder.m file
- (IBAction)btnLocate_Click:(id)sender 
{
    //show progress indicator graphic
    self.progressIndicator.hidden = NO;
    
    //collect values from text fields
    self.address1 = self.txtAddress1.text;
    self.address2 = self.txtAddress2.text;
    self.addressCity = self.txtAddressCity.text;
    self.addressState = self.txtAddressState.text;
    self.addressZip = self.txtAddressZip.text;
    
    ...
    
    //package address input for geocoder
    self.addressFields = [[NSDictionary alloc]initWithObjectsAndKeys:self.address1, @"Street", self.addressCity, @"City", self.addressState, @"State", self.addressZip, @"ZIP", nil];
    
    //specify return fields for the address candidates coming back
    self.outFields = [NSArray arrayWithObjects: @"Score", @"Match_addr", @"StreetName", @"X", @"Y", nil];
    
    //disable UI input while search is in progress
    [self ToggleEnableAll:NO];
    self.btnLocate.enabled = NO;
    self.btnClear.enabled = NO;
    
    //fire up geocoder if applicable
    if(self.locationService == nil)
    {
        if(self.locatorRESTEndpoint != NULL && self.locatorRESTEndpoint != @"")
        {
            NSURL *locatorURL = [[NSURL alloc] initWithString:self.locatorRESTEndpoint];
            self.locationService = [[AGSLocator alloc]initWithURL:locatorURL];
        }
        else
        {
            //alert user that no REST endpoint was specified. bad news bears
            ...
            
            return;
        }
    }
    
    self.locationService.delegate = self; //AGSLocator object
    
    //hit geocode service and handle output in delegate functions below
    [self.locationService locationsForAddress:self.addressFields returnFields:self.outFields outSpatialReference:self.mapSpatialReference];

}

I output the value of 'self.mapSpatialReference.wkid' and I get 102100 as expected.  Here's my callback code

- (void)locator:(AGSLocator *)locator operation:(NSOperation*)op didFindLocationsForAddress:(NSArray *)candidates
{
    if(candidates.count == 0)
    {
        //alert user that no candidates came back
        ...
    }
    else
    {
        //restore UI 
        [self ToggleEnableAll:YES];
        self.btnLocate.enabled = YES;
        self.btnClear.enabled = YES;
        
        //call delegate so that subscribers can handle candidate data
        [self.delegate OnFoundCandidates:candidates];
    }
    
    //hide progress indicator
    self.progressIndicator.hidden = YES;
}


if more than zero candidates come back I handle them on my main view controller. Here is code from the delegate function

- (void) OnFoundCandidates : (NSArray *)candidates
{  
    //this is the callback for the geocoder's "found address candidate" delegate
    //here we'll be either putting a point on the map for the best candidate or
    //allowing the user to choose his/her intended candidate
    if(candidates.count == 1)
    {
        //put it on the map
        AGSAddressCandidate *soleCandidate = [candidates objectAtIndex:0];
        if(soleCandidate)
        {
            //initialise symbol and geometry
            AGSPoint *mapPoint = soleCandidate.location;
            AGSSimpleMarkerSymbol *sms =  [[AGSSimpleMarkerSymbol alloc]initWithColor:[UIColor blueColor]];
            
            //initialise graphic
            AGSGraphic *candidateGraphic = [[AGSGraphic alloc]initWithGeometry:mapPoint symbol:sms attributes:nil infoTemplateDelegate:nil];
            
            //transfer attributes from candidate to graphic for callout data display later
            [candidateGraphic.attributes addEntriesFromDictionary:soleCandidate.attributes];
            
            //close popover
            [self.testController dismissPopoverAnimated:YES];
            
            //add graphic to map
            [self.geocodeGraphicsLayer addGraphic:candidateGraphic];
            [self.geocodeGraphicsLayer dataChanged];
        }
    }
    else
    {
        AGSAddressCandidate *oneHundredPercentMatch;
        
        for(AGSAddressCandidate * candidate in candidates)
        {
            if([[candidate.attributes objectForKey:@"Score"] doubleValue] == 100.0f)
            {
                oneHundredPercentMatch = candidate;
                break;
            }
        }
        
        if(oneHundredPercentMatch != nil && oneHundredPercentMatch != NULL)
        {
            NSLog(@"100 percent match: %f, %f ::: %f, %f",oneHundredPercentMatch.location.x, oneHundredPercentMatch.location.y, [[oneHundredPercentMatch.attributes objectForKey:@"X"]doubleValue], [[oneHundredPercentMatch.attributes objectForKey:@"Y"]doubleValue]);
            //initialise symbol and geometry
            AGSPoint *mapPoint = oneHundredPercentMatch.location;
            AGSSimpleMarkerSymbol *sms = [[AGSSimpleMarkerSymbol alloc]initWithColor:[UIColor blueColor]];
            
            //intiialise graphic
            AGSGraphic *candidateGraphic = [[AGSGraphic alloc]initWithGeometry:mapPoint symbol:sms attributes:nil infoTemplateDelegate:nil];
            
            //transfer attributes from candidate to graphic for callout data display later
            [candidateGraphic.attributes addEntriesFromDictionary:oneHundredPercentMatch.attributes];
            
            //close popover
            [self.testController dismissPopoverAnimated:YES];
            
            //add graphic to map
            [self.geocodeGraphicsLayer addGraphic:candidateGraphic];
            [self.geocodeGraphicsLayer dataChanged];
        }
        else
        {
            ...
        }
    }
}

The geocode service i was using is http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Locators/ESRI_Geocode_USA/GeocodeServer.  when I use the service in a browser I get the expected results which leads me to believe that the AGSLocator object doesn't support outspatialreference.

Sorry for being so verbose.  I've been chasing my tail for a while and hope that someone can help.

Thanks in advance,
Hasheen

Outcomes