Identify Example

2886
10
07-06-2010 01:28 PM
JeffPapirtis
New Contributor III
Does anyone have an example of implementing an Identify function within the SDK?  I have read through the "Tasks" documentation on the Identify Task, but I am a bit confused.  It seems that something is missing from the examples given.  Any help would be appreciated!
0 Kudos
10 Replies
NimeshJarecha
Esri Regular Contributor
Why are you confused? What do you feel is missing? Can you please upload your attempted project so I can have a look and help you with?

Regards,
Nimesh
0 Kudos
JeffPapirtis
New Contributor III
Why are you confused? What do you feel is missing? Can you please upload your attempted project so I can have a look and help you with?

Regards,
Nimesh


Hi Nimesh,
I am rebuilding my code using the new SDK.  Once I have finished I will post my code for you to look through.

I think that my biggest issue is that the documentation is written assuming that the user has some understanding of dependencies.  Ex: MapPoint geometry within the parameters.  Is this an instance of AGSPoint?

I was able to build and run the application within the simulator, but I am not sure exactly if anything was happening as I was not able to execute the identify function.  Is an action required to to execute the code?  I am a bit lost, once I have finished rewriting my code I will also include some thoughts on what I was not understanding based on the example given in the documentation.

Thanks for your help!
0 Kudos
JeffPapirtis
New Contributor III
Hi Nimesh,
Below is my sample project (it was too large to attach as a Zip, 3.4 MB).  I have **** out some of the URL addresses within the code.
--------------------------------
header
#import <UIKit/UIKit.h>
#import "ArcGIS.h"

@interface iOS4_AGSViewController : UIViewController{
IBOutlet AGSMapView *mapView;
UIView *baseView;
UIView *facilities;

//Identify Components
AGSPoint *mapPoint;
AGSGraphicsLayer *glayer;
AGSIdentifyTask *identifyTask;

}

@property (nonatomic, retain) IBOutlet AGSMapView *mapView;
@property(nonatomic, retain) UIView *baseView;
@property(nonatomic, retain) UIView *facilities;

//Identify Components
@property(nonatomic, retain) AGSPoint *mapPoint;
@property(nonatomic, retain) AGSGraphicsLayer *gLayer;
@property(nonatomic, retain) AGSIdentifyTask *identifyTask;

@end
------------------------
Implementation


#import "iOS4_AGSViewController.h"

@implementation iOS4_AGSViewController
@synthesize mapView;
@synthesize baseView;
@synthesize facilities;

//Identify Components
@synthesize mapPoint;
@synthesize gLayer;
@synthesize identifyTask;

//setting up the results for the Identify Task

-(void) identifyTask:(AGSIdentifyTask *) identifyTask didExecuteWithIdentifyResults:(NSArray *) results{
[AGSMapView showNetworkActivityIndicator:NO];
[self.gLayer removeAllGraphics];

AGSSymbol* symbol = [AGSSimpleFillSymbol simpleFillSymbol];
symbol.color = [UIColor colorWithRed:0 green:0 blue:1 alpha:.5];
for (AGSIdentifyResult* result in results){
  result.feature.symbol = symbol;
  [self.gLayer addGraphic:result.feature];
}
[self.gLayer dataChanged];
}


/*
// The designated initializer. Override to perform setup that is required before the view is loaded.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
        // Custom initialization
    }
    return self;
}
*/

/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
}
*/



// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    [super viewDidLoad];

//Basemap information
AGSTiledMapServiceLayer *baseMap = [[AGSTiledMapServiceLayer alloc]
          initWithURL:[NSURL URLWithString:@"http://****/ArcGIS/rest/services/*****_Basemap/MapServer"]];
self.baseView = [self.mapView addMapLayer: baseMap withName:@"BaseMap"];

//Dynamic Map information
AGSDynamicMapServiceLayer *facilityMap = [[AGSDynamicMapServiceLayer alloc]
             initWithURL:[NSURL URLWithString:@"http://****/ArcGIS/rest/services/****_Facilities/MapServer"]];
self.facilities = [self.mapView addMapLayer:facilityMap withName:@"Facilities"];

//Creating the layer for identify Task
[AGSIdentifyTask
  identifyTaskWithURL:[NSURL URLWithString:@"http://*****/ArcGIS/rest/services/*****_Facilities/MapServer"]];
//identifyTask.delegate = self;

//Setting the Parameters
AGSIdentifyParameters *identifyParamas = [[AGSIdentifyParameters alloc] init];
identifyParamas.layerIds = [NSArray arrayWithObjects:[NSNumber numberWithInt:0],nil];
identifyParamas.tolerance = 3;
identifyParamas.geometry = mapPoint;
identifyParamas.size = self.mapView.bounds.size;
identifyParamas.mapEnvelope = self.mapView.envelope;
identifyParamas.returnGeometry = YES;
identifyParamas.layerOption = AGSIdentifyParametersLayerOptionAll;
identifyParamas.spatialReference = self.mapView.spatialReference;

//execute Task

[AGSMapView showNetworkActivityIndicator:YES];

[self.identifyTask executeWithParameters:identifyParamas];


}




/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/

- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

// Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}


- (void)dealloc {
[mapView release];
[baseView release];
[facilities release];
[mapPoint release];
[gLayer release];
[identifyTask release];

    [super dealloc];
}

@end
--------------------------------


Like I posted earlier, I am not sure exactly what comes next reading through the example in the concepts for Identify.  I believe that I have all of the right code, but maybe it is not in the right place, or it is not correctly implemented in xib file.

On what was missing from the documention that would have been helpful for me.
- dependancies, reading through the documentation gLayer, and mapPoint do not have any explanation.  Do these need to be instantiated in the header and implementation files?  From trying to build and run, it seems like they are. 
what types are gLayer and mapPoint? AGSGraphicsLayer & AGSPoint?

in order to execute the code, what has to happen in IB?  is there an action that should be defined in Xcode?

Thanks for your help!
0 Kudos
NimeshJarecha
Esri Regular Contributor
Thanks for posting your code. I've created a demo application (see attached) and here is the code.

*****code from .h file*****
#import <UIKit/UIKit.h>
#import "ArcGIS.h"

@interface IdentifyTaskDemoViewController : UIViewController <AGSMapViewDelegate, AGSIdentifyTaskDelegate> {

AGSMapView *_mapView;
AGSGraphicsLayer *_graphicsLayer;
AGSIdentifyTask *_identifyTask;
AGSIdentifyParameters *_identifyParams;
}

@property (nonatomic, retain) IBOutlet AGSMapView *mapView;
@property (nonatomic, retain) IBOutlet AGSGraphicsLayer *graphicsLayer;
@property (nonatomic, retain) IBOutlet AGSIdentifyTask *identifyTask;
@property (nonatomic, retain) IBOutlet AGSIdentifyParameters *identifyParams;

@end
*************************

*****code from .m file*****
#import "IdentifyTaskDemoViewController.h"
#define kDynamicMapServiceURL @"http://*****/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer"

@implementation IdentifyTaskDemoViewController
@synthesize mapView=_mapView;
@synthesize graphicsLayer=_graphicsLayer;
@synthesize identifyTask=_identifyTask,identifyParams=_identifyParams;


// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {

self.mapView.mapViewDelegate = self;

AGSDynamicMapServiceLayer *dynamicLayer = [[AGSDynamicMapServiceLayer alloc] initWithURL:[NSURL URLWithString:kDynamicMapServiceURL]];
dynamicLayer.visibleLayers = [NSArray arrayWithObjects:[NSNumber numberWithInt:5], nil];
[self.mapView addMapLayer:dynamicLayer withName:@"Dynamic Layer"];
[dynamicLayer release];

self.graphicsLayer = [AGSGraphicsLayer graphicsLayer];
[self.mapView addMapLayer:self.graphicsLayer withName:@"Graphics Layer"];

//Create Identify Task
self.identifyTask = [AGSIdentifyTask identifyTaskWithURL:[NSURL URLWithString:kDynamicMapServiceURL]];
self.identifyTask.delegate = self;

self.identifyParams = [[AGSIdentifyParameters alloc] init];

    [super viewDidLoad];
}

- (void)mapView:(AGSMapView *)mapView didClickAtPoint:(CGPoint)screen mapPoint:(AGSPoint *)mappoint graphics:(NSDictionary *)graphics {

//the layer we want is layer �??5�?? (from the map service doc)
self.identifyParams.layerIds = [NSArray arrayWithObjects:[NSNumber numberWithInt:5], nil];
self.identifyParams.tolerance = 10;
self.identifyParams.geometry = mappoint;
self.identifyParams.size = self.mapView.bounds.size;
self.identifyParams.mapEnvelope = self.mapView.envelope;
self.identifyParams.returnGeometry = YES;
self.identifyParams.layerOption = AGSIdentifyParametersLayerOptionAll;
self.identifyParams.spatialReference = self.mapView.spatialReference;

//Turn on network activity indicator using the AGSMapView class method
[AGSMapView showNetworkActivityIndicator:TRUE];

//execute the task
[self.identifyTask executeWithParameters:self.identifyParams];

}

- (void)identifyTask:(AGSIdentifyTask *)identifyTask operation:(NSOperation *)op didExecuteWithIdentifyResults:(NSArray *)results {

//Turn off network activity indicator
    [AGSMapView showNetworkActivityIndicator:FALSE];

    //clear previous results
    [self.graphicsLayer removeAllGraphics];

    //add new results
    AGSSymbol* symbol = [AGSSimpleFillSymbol simpleFillSymbol];
    symbol.color = [UIColor colorWithRed:0 green:0 blue:1 alpha:0.5];
    for (AGSIdentifyResult* result in results) {
        result.feature.symbol = symbol;
        [self.graphicsLayer addGraphic:result.feature];
    }
    //call dataChanged on the graphics layer to redraw the graphics
    [self.graphicsLayer dataChanged];

}
*************************

Hope this helps! Please feel free to contact if you need any further help.

Regards,
Nimesh
0 Kudos
JeffPapirtis
New Contributor III
Hi Nimesh,
Your sample code helped me quite a bit, thank you.  I do have another question.
I am having difficulty with identifying more than one set of features.

Example:
I have two identify Tasks set up for two dynamic layers.  I beleive that I have all of the tasks set up properly. 

// identify Tasks

- (void)mapView:(AGSMapView *)mapView didClickAtPoint:(CGPoint)screen mapPoint:(AGSPoint *)mappoint graphics:(NSDictionary *)graphics {

//first Identify Task
self.wellidentifyParams.layerIds = [NSArray arrayWithObjects:[NSNumber numberWithInt:0], nil];
self.wellidentifyParams.tolerance = 10;
self.wellidentifyParams.geometry = mappoint;
self.wellidentifyParams.size = self.mapView.bounds.size;
self.wellidentifyParams.mapEnvelope = self.mapView.envelope;
self.wellidentifyParams.returnGeometry = YES;
self.wellidentifyParams.layerOption = AGSIdentifyParametersLayerOptionAll;
self.wellidentifyParams.spatialReference = self.mapView.spatialReference;

//Turn on network activity indicator using the AGSMapView class method
[AGSMapView showNetworkActivityIndicator:TRUE];

//execute the task
[self.wellidentifyTask executeWithParameters:self.wellidentifyParams];


//the layer we want is layer �??5�?? (from the map service doc)
   self.leaseIdentifyParams.layerIds = [NSArray arrayWithObjects:[NSNumber numberWithInt:6], nil];
    self.leaseIdentifyParams.tolerance = 1;
    self.leaseIdentifyParams.geometry = mappoint;
    self.leaseIdentifyParams.size = self.mapView.bounds.size;
    self.leaseIdentifyParams.mapEnvelope = self.mapView.envelope;
    self.leaseIdentifyParams.returnGeometry = YES;
    self.leaseIdentifyParams.layerOption = AGSIdentifyParametersLayerOptionAll;
    self.leaseIdentifyParams.spatialReference = self.mapView.spatialReference;
 
    //Turn on network activity indicator using the AGSMapView class method
    [AGSMapView showNetworkActivityIndicator:TRUE];
 
    //execute the task
    [self.leaseIdentifyTask executeWithParameters:self.leaseIdentifyParams];
}

- (void)identifyTask:(AGSIdentifyTask *)identifyTask operation:(NSOperation *)op didExecuteWithIdentifyResults:(NSArray *)results {


//Turn off network activity indicator
    [AGSMapView showNetworkActivityIndicator:FALSE];

    //clear previous results
    //[self.wellgraphicsLayer removeAllGraphics];

    AGSSymbol* symbol = [AGSSimpleMarkerSymbol simpleMarkerSymbol];
    symbol.color = [UIColor colorWithRed:0 green:0 blue:1 alpha:0.5];
    for (AGSIdentifyResult* result in results) {
        result.feature.symbol = symbol;
        [self.wellgraphicsLayer addGraphic:result.feature];
}
    //call dataChanged on the graphics layer to redraw the graphics
    [self.wellgraphicsLayer dataChanged];
   
  //Turn off network activity indicator
  [AGSMapView showNetworkActivityIndicator:FALSE];
 
  //clear previous results
  [self.leaseGraphicsLayer removeAllGraphics];
 
  //add new results
  AGSSymbol* fillSymbol = [AGSSimpleFillSymbol simpleFillSymbol];
  fillSymbol.color = [UIColor colorWithRed:0 green:0 blue:1 alpha:0.5];
  for (AGSIdentifyResult* result in results) {
   result.feature.symbol = fillSymbol;
   [self.leaseGraphicsLayer addGraphic:result.feature];
  }
  //call dataChanged on the graphics layer to redraw the graphics
  [self.leaseGraphicsLayer dataChanged];
}

After looking at the code for a awhile it seems that the AGSSymbol is being redefined and as a result is not rendering.

I have also tried to control which graphic is drawn by using a segmented controller with an if statement.

if(((UISegmentedControl *)segmentIndex).selectedIndex ==0) {
.....AGSSymbol is AGSSimpleMarkerSymbol...
}else {
....AGSSymbol is AGSSimpleFillSybol....

any help would be greatly appreciated.

Thanks!
0 Kudos
JeffPapirtis
New Contributor III
I solved the above problem. 
Does anyone know how to properly initiate a simpleLineSymbol?

here is what I have, Not sure on how to specify width or style after ready the documentation.

AGSSymbol* symbol = [AGSSimpleLineSymbol simpleLineSymbol];
  symbol.color = [UIColor colorWithRed:9 green:0 blue: 0 alpha:0.5];
  for (AGSIdentifyResult* result in results) {
   result.feature.symbol = symbol;
   [self.graphicsLayer addGraphic:result.feature];
0 Kudos
NimeshJarecha
Esri Regular Contributor
Glad to know that you got it fixed. You can create a simple line symbol like this,

AGSSimpleLineSymbol *symbol = [AGSSimpleLineSymbol simpleLineSymbol];
symbol.color = [UIColor colorWithRed:9 green:0 blue: 0 alpha:0.5];
symbol.width = 5.0;
symbol.style = AGSSimpleLineSymbolStyleSolid;

Hope this helps!

Regards,
Nimesh
0 Kudos
SpencerLace
New Contributor III
Should this example do anything more than return the graphic?  Identify usually means the results are returned as attributes in a table, or info window of some sort.  Does the graphic signal a successful identify task and the rest is left to our imagination, or did I miss something?
Thanks,
Spencer
0 Kudos
JeffPapirtis
New Contributor III
Should this example do anything more than return the graphic?  Identify usually means the results are returned as attributes in a table, or info window of some sort.  Does the graphic signal a successful identify task and the rest is left to our imagination, or did I miss something?
Thanks,
Spencer


Touch the item once to create the graphic.  Touch the same graphic again to have the call out box appear.
0 Kudos