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