AGSGeometryEngine *ge = [AGSGeometryEngine defaultGeometryEngine]; AGSEnvelope *actualEnv = (AGSEnvelope *)[ge projectGeometry:self.mapView.visibleArea.envelope toSpatialReference:self.spaRef] ; double xLength = actualEnv.xmax - actualEnv.xmin;
//Previously in my method AGSEnvelope *visibleEnv = [[self.mapView.visibleArea.envelope copy] autorelease]; AGSSpatialReference *spaRef = [[self.spaRef copy] autorelease]; ... AGSGeometryEngine *ge = [AGSGeometryEngine defaultGeometryEngine]; AGSEnvelope *actualEnv = (AGSEnvelope *)[ge projectGeometry:visibleEnv toSpatialReference:self.spaRef] ; double xLength = actualEnv.xmax - actualEnv.xmin;
Solved! Go to Solution.
#import "MapViewController.h"
@implementation MapViewController
...
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"MapView";
self.mapView.layerDelegate = self;
self.mapView.touchDelegate = self;
self.mapView.calloutDelegate = self;
self.visibleLayers = [NSMutableArray arrayWithObjects:[NSNumber numberWithInt:3],
nil];
isOSMDisplayed = YES;
[self setupMapView:YES];
isAreaSearch = NO;
// zoom to UniNe (WKID 102100) -> OpenStreetMap
AGSEnvelope *env = [AGSEnvelope envelopeWithXmin:773466.697310 ymin:5941903.815693 xmax:773768.071705 ymax:5942295.602407 spatialReference:self.mapView.spatialReference];
[self.mapView zoomToEnvelope:env animated:YES];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(respondToZoomlevelChange:) name:@"MapDidEndZooming" object:nil];
// setup the variables for the ResultsViewController
entryOrder = [NSArray arrayWithObjects: @"BAT_ADRESSE", @"ETG_DESIGNATION", @"LOC_CODE", @"LOC_SURFACE", @"LOC_TYPE_DESIGNATION", @"LOC_OCCUPANTS", nil];
self.queryTaskContainer = [self initializeQueryTaskContainer];
self.query = [AGSQuery query];
self.query.returnGeometry = NO;
self.query.spatialRelationship = AGSSpatialRelationshipIntersects;
self.query.outFields = entryOrder;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)viewDidUnload {
}
- (void)dealloc {
self.mapView = nil;
self.dynamicLayer = nil;
self.dynamicLayerView = nil;
self.graphicsLayer = nil;
self.queryTaskContainer = nil;
self.query = nil;
self.srUniNe = nil;
self.infoView = nil;
self.infoLabel = nil;
self.scaleBarView = nil;
entryOrder = nil;
titleText = nil;
[super dealloc];
}
#pragma mark -
- (void) setupMapView:(BOOL)withOSMLayer {
if(withOSMLayer) {
// if the dynamic layer base is open during the changing of layers, delete during zoom back
if ([self.visibleLayers containsObject:[NSNumber numberWithInt:5]]){
[self.visibleLayers removeObject:[NSNumber numberWithInt:5]];
}
AGSOpenStreetMapLayer *osmLayer = [[[AGSOpenStreetMapLayer alloc]init]autorelease];
// add the openStreetMap as basemap
UIView<AGSLayerView>* lyr = [self.mapView addMapLayer:osmLayer withName:@"tiledLayer"];
lyr.drawDuringPanning = YES;
lyr.drawDuringZooming = YES;
}
// save a reference of the spatial reference from UniNe provided maps
self.srUniNe = [AGSSpatialReference spatialReferenceWithWKID:kSpatialRefWkidUniNe];
if (self.dynamicLayerInfo != nil) {
self.dynamicLayer = [[[AGSDynamicMapServiceLayer alloc] initWithMapServiceInfo: self.dynamicLayerInfo] autorelease];
} else {
AGSDynamicMapServiceLayer *dmLayer = [[[AGSDynamicMapServiceLayer alloc] initWithURL:[NSURL URLWithString:kDynamicMapServiceURL]] autorelease];
self.dynamicLayer = dmLayer;
// copy the mapServiceInfo, otherwise the pointer gets lost during the reset of the map
self.dynamicLayerInfo = [[dmLayer.mapServiceInfo copy] autorelease];
}
if (withOSMLayer) {
if ([self.visibleLayers containsObject:[NSNumber numberWithInt:6]]) {
[self.visibleLayers removeObject:[NSNumber numberWithInt:6]];
}
self.dynamicLayer.visibleLayers = [NSArray arrayWithArray:self.visibleLayers];
} else {
if (! [self.visibleLayers containsObject:[NSNumber numberWithInt:6]]) {
[self.visibleLayers addObject:[NSNumber numberWithInt:6]];
}
self.dynamicLayer.visibleLayers = [NSArray arrayWithArray:self.visibleLayers];
}
UIView<AGSLayerView> *dynamicLayerView = [self.mapView addMapLayer:self.dynamicLayer withName:@"dynamicLayer"];
dynamicLayerView.drawDuringPanning = YES;
dynamicLayerView.drawDuringZooming = YES;
self.dynamicLayerView.alpha = 0.7;
// create and add the graphics layer to the map
self.graphicsLayer = [AGSGraphicsLayer graphicsLayer];
[self.mapView addMapLayer:self.graphicsLayer withName:@"graphicsLayer"];
}
- (NSDictionary *) initializeQueryTaskContainer {
NSMutableDictionary *tmpDic = [[NSMutableDictionary new] autorelease];
//the basemap where we zoom, just use for setting the layers in the menu
AGSQueryTask *qtl = [[[AGSQueryTask alloc] initWithURL:[NSURL URLWithString:kDynamicMapServiceURL]] autorelease];
qtl.delegate = self;
[tmpDic setObject:qtl forKey:[NSNumber numberWithInt:5]];
//the difference floors
AGSQueryTask *qtl0 = [[[AGSQueryTask alloc] initWithURL:[NSURL URLWithString:kDynamicMapLayer0ServiceURL]] autorelease];
qtl0.delegate = self;
[tmpDic setObject:qtl0 forKey:[NSNumber numberWithInt:0]];
...
return [NSDictionary dictionaryWithDictionary:tmpDic];
}
- (void)respondToZoomlevelChange: (NSNotification*) notification {
[self.scaleBarView updateBar:(1 / AGSUnitsToUnits(self.mapView.resolution, self.mapView.units, AGSUnitsMeters))];
AGSEnvelope *actEnv = [[[self.mapView.visibleArea envelope] copy] autorelease];
if (self.mapView.resolution <= 0.6 && isOSMDisplayed) {
[self.mapView reset];
[self setupMapView:NO];
isOSMDisplayed = NO;
if (isAreaSearch){
self.query.returnGeometry = NO;
} else {
self.query.returnGeometry = YES;
}
AGSGeometryEngine *ge = [AGSGeometryEngine defaultGeometryEngine];
[self.mapView zoomToEnvelope:(AGSEnvelope *)[ge projectGeometry:actEnv toSpatialReference:self.mapView.spatialReference] animated:YES];
} else if (self.mapView.resolution > 0.6 && ! isOSMDisplayed) {
[self.mapView reset];
[self setupMapView:YES];
isOSMDisplayed = YES;
self.query.returnGeometry = NO;
AGSGeometryEngine *ge = [AGSGeometryEngine defaultGeometryEngine];
[self.mapView zoomToEnvelope:(AGSEnvelope *)[ge projectGeometry:actEnv toSpatialReference:self.mapView.spatialReference] animated:YES];
}
}
#pragma mark -
#pragma mark IBAction methods
-(IBAction) gpsButtonClicked {
if (self.mapView.gps.enabled) {
// according to apple, this should work on iOS 5..but somehow it doesn't...
self.gpsButton.tintColor = [UIColor blackColor];
[self.mapView.gps stop];
} else {
// according to apple, this should work on iOS 5..but somehow it doesn't...
self.gpsButton.tintColor = [UIColor whiteColor];
[self.mapView.gps start];
}
}
-(IBAction) infoButtonClicked {
SettingsMenuViewController *settingsMenuController = [[SettingsMenuViewController alloc] initWithNibName:kXibNameSettingsMenuView bundle:nil];
settingsMenuController.visibleLayers = self.dynamicLayer.visibleLayers;
settingsMenuController.isOSMDisplayed = isOSMDisplayed;
settingsMenuController.parentDelegate = self;
[self presentModalViewController:settingsMenuController animated:YES];
[settingsMenuController release];
}
-(IBAction) queryModeValueChanged {
foundLocation = NO;
[self.graphicsLayer removeAllGraphics];
[self.graphicsLayer dataChanged];
self.mapView.callout.hidden = YES;
if (self.queryModeSwitch.selectedSegmentIndex == 1) {
self.infoLabel.text = @"area search";
} else {
self.infoLabel.text = @"single location search";
}
}
#pragma mark -
#pragma mark AGSMapViewLayerDelegate
-(void) mapViewDidLoad:(AGSMapView*)mapView {
// startup GPS but not autoPan
[self.mapView.gps start];
[self.scaleBarView updateBar:(1 / AGSUnitsToUnits(self.mapView.resolution, self.mapView.units, AGSUnitsMeters))];
}
#pragma mark AGSMapViewTouchDelegate
- (void) mapView:(AGSMapView *)mapView didClickAtPoint:(CGPoint)screen mapPoint:(AGSPoint *)mappoint graphics:(NSDictionary *)graphics {
AGSEnvelope *visibleEnv = [[[self.mapView.visibleArea envelope] copy] autorelease];
AGSSpatialReference *spaRef = [[self.srUniNe copy] autorelease];
foundLocation = NO;
[self.graphicsLayer removeAllGraphics];
self.infoLabel.text = @"";
self.clickedPoint = mappoint;
AGSGeometryEngine *ge = [AGSGeometryEngine defaultGeometryEngine];
AGSPoint *point_srUniNe = (AGSPoint *)[ge projectGeometry:mappoint toSpatialReference:self.srUniNe];
if (self.queryModeSwitch.selectedSegmentIndex == 1) {
// arcGIS iOS v2.1 Pay attention!
// visibleArea can be null, when the baseMap isn't fully loaded yet. (http://forums.arcgis.com/threads/44385-iOS-API-2.1-envelope-to-visibleArea-deprication)
AGSEnvelope *actualEnv = (AGSEnvelope *)[ge projectGeometry:visibleEnv toSpatialReference:spaRef];
isAreaSearch = YES;
self.query.returnGeometry = NO;
double xLength = actualEnv.xmax - actualEnv.xmin;
// size the square according to the height of the device
if (self.interfaceOrientation == UIDeviceOrientationLandscapeLeft || self.interfaceOrientation == UIDeviceOrientationLandscapeRight) {
xLength = actualEnv.ymax - actualEnv.ymin;
}
double xmin = point_srUniNe.x - (xLength / 13);
double xmax = point_srUniNe.x + (xLength / 13);
double ymin = point_srUniNe.y - (xLength / 13);
double ymax = point_srUniNe.y + (xLength / 13);
AGSEnvelope *queryEnv = [AGSEnvelope envelopeWithXmin:xmin ymin:ymin xmax:xmax ymax:ymax spatialReference:self.srUniNe];
self.query.geometry = queryEnv;
AGSSymbol* symbol = [AGSSimpleFillSymbol simpleFillSymbol];
symbol.color = [UIColor colorWithRed:0 green:0 blue:1 alpha:0.5];
AGSEnvelope *queryEnv_srOSM = (AGSEnvelope *)[ge projectGeometry:queryEnv toSpatialReference:self.mapView.spatialReference];
AGSGraphic *envGraphic = [AGSGraphic graphicWithGeometry:queryEnv_srOSM symbol:symbol attributes:[NSMutableDictionary dictionary] infoTemplateDelegate:nil];
[self.graphicsLayer addGraphic:envGraphic];
[self.graphicsLayer dataChanged];
} else {
isAreaSearch = NO;
if (isOSMDisplayed){
self.query.returnGeometry = NO;
} else {
self.query.returnGeometry = YES;
}
self.query.geometry = point_srUniNe;
}
for (NSNumber *nr in self.dynamicLayer.visibleLayers) {
if (foundLocation) {
break;
}
[[self.queryTaskContainer objectForKey:nr] executeWithQuery:self.query];
}
}
#pragma mark - AGSMapViewCalloutDelegate
- (void)mapView:(AGSMapView *)mapView didClickCalloutAccessoryButtonForGraphic: (AGSGraphic *) graphic {
//The user clicked the callout button, so display the complete set of results
ResultsViewController *resultsVC = [[ResultsViewController alloc] initWithNibName:kXibNameResultsView bundle:nil];
resultsVC.entryOrder = entryOrder;
NSMutableDictionary *tmp = [NSMutableDictionary new];
[tmp setObject:@"Adress" forKey:@"BAT_ADRESSE"];
...
[tmp release];
//set our attributes/results into the results VC
if ([self.resultsArray count] > 20) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Too many results" message:[NSString stringWithFormat:@"%d results found.\nDisplay maximum is 20.\nZoom in for less results", [self.resultsArray count]] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alert show];
[alert release];
NSRange range;
range.location = 0;
range.length = 20;
resultsVC.resultsArray = [[NSArray arrayWithArray:self.resultsArray] subarrayWithRange:range];
} else {
resultsVC.resultsArray = [NSArray arrayWithArray:self.resultsArray];
}
[self presentModalViewController:resultsVC animated:YES];
[resultsVC release];
}
#pragma mark - AGSQueryTaskDelegate
- (void)queryTask:(AGSQueryTask *)queryTask operation:(NSOperation*)op didExecuteWithFeatureSetResult:(AGSFeatureSet *)featureSet {
if ([featureSet.features count] > 0) {
if (foundLocation) {
for (AGSGraphic *graphic in featureSet.features) {
[self.resultsArray addObject:graphic.attributes];
}
} else {
foundLocation = YES;
AGSSymbol* symbol = [AGSSimpleFillSymbol simpleFillSymbol];
symbol.color = [UIColor colorWithRed:0 green:0 blue:1 alpha:0.5];
// set the symbol and add it to the graphics layer
AGSGraphic *resultGraphic = [featureSet.features objectAtIndex:0];
if (self.resultsArray == nil) {
self.resultsArray = [[NSMutableArray new] autorelease];
} else {
[self.resultsArray removeAllObjects];
}
for (AGSGraphic *graphic in featureSet.features) {
[self.resultsArray addObject:graphic.attributes];
}
resultGraphic.symbol = symbol;
[self.graphicsLayer addGraphic:resultGraphic];
if (self.queryModeSwitch.selectedSegmentIndex == 1) {
self.infoLabel.text = @"area search";
self.mapView.callout.title = @"Details";
self.mapView.callout.detail = @"Click for more details..";
} else {
NSString *numero = [[NSDictionary dictionaryWithDictionary:resultGraphic.attributes] valueForKey:@"LOC_CODE"];
self.infoLabel.text = numero;
self.mapView.callout.title = numero;
self.mapView.callout.detail = @"Click for more detail..";
}
[self.mapView showCalloutAtPoint:self.clickedPoint forGraphic:resultGraphic animated:YES];
[self.graphicsLayer dataChanged];
}
}
}
- (void)queryTask:(AGSQueryTask *)queryTask operation:(NSOperation*)op didFailWithError:(NSError *)error {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Query Task Failed"
message:[NSString stringWithFormat:@"Error: %@", [error localizedDescription]] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alert show];
[alert release];
}
#pragma mark - ContextMenuReturnDelegate
- (void) returnVisibleLayers:(NSArray*)visibleLayers {
self.dynamicLayer.visibleLayers = visibleLayers;
self.visibleLayers = [NSMutableArray arrayWithArray:visibleLayers];
foundLocation = NO;
[self.dynamicLayer dataChanged];
[self.graphicsLayer removeAllGraphics];
[self.graphicsLayer dataChanged];
self.infoLabel.text = @"";
self.clickedPoint = nil;
}
@end