Tags: , , | Categories: Blog Posted by al on 10/7/2010 7:53 PM | Comments (0)


Working a little with the iPhone lately using the Esri iOS SDK. I’m using the GPS device on board of the iphone to find my location and show it in the map. Now the GPS is always a geographic measure and now that all web maps use the Web Mercator, I have to reproject the output of the device to show it in the map. I thought I’ll post the code here for anybody that wants it.

Gathering the GPS location with lat and long with Geographic projection WGS1984

- (id) init {
    self = [super init];
    if (self != nil) {
        self.locationManager = [[[CLLocationManager alloc] init] autorelease];
		self.locationManager.distanceFilter = 25;
		
        self.locationManager.delegate = self; // send loc updates to myself
		
		_bTracking = NO;
		_bOneTime = NO;
    }
    return self;
}

- (void)locationManager:(CLLocationManager *)manager
    didUpdateToLocation:(CLLocation *)newLocation
           fromLocation:(CLLocation *)oldLocation
{
    NSLog(@"Location: %@", [newLocation description]);
			
	WebMercator *webMercator = [[WebMercator alloc]init];
	
	double webMercatorLongitude = [webMercator toWebMercatorX:newLocation.coordinate.longitude];
	double webMercatorLatitude = [webMercator toWebMercatorY:newLocation.coordinate.latitude];
	
		//create extent to be used as default
		AGSEnvelope *envelope = [AGSEnvelope envelopeWithXmin:webMercatorLongitude+0.0001
                                                     ymin:webMercatorLatitude-0.0001
                                                     xmax:webMercatorLongitude
                                                     ymax:webMercatorLatitude
													spatialReference:self.mapView.spatialReference];
    
		
		
		[self.mapView zoomToEnvelope:envelope animated:YES];	
	
		if ( _bTracking == NO)
			[self.locationManager stopUpdatingLocation];
		
		// Create the graphic layer for position if does not exist
		if ( self.trackGraphicsLayer == nil)
		{		
			// Add a point into the graphic layer with the correct attributes
			self.trackGraphicsLayer = [AGSGraphicsLayer graphicsLayer];
			
			//add graphics layer (data is loaded in mapViewDidLoad method)
			[self.mapView addMapLayer:self.trackGraphicsLayer withName:@"Track"];		
		}
		
		// Add a point where the gps finds you.		
		AGSPictureMarkerSymbol *myPicture = [AGSPictureMarkerSymbol pictureMarkerSymbolWithImageNamed:@"GpsDisplay.png"];
		
		AGSPoint* myMarkerPoint =
		[AGSPoint pointWithX:webMercatorLongitude
						  y:webMercatorLatitude
			spatialReference:self.mapView.spatialReference];
		
		//Create the Graphic, using the symbol and
		//geometry created earlier
		AGSGraphic* myGraphic =
		[AGSGraphic graphicWithGeometry:myMarkerPoint
								symbol:myPicture
							attributes:nil
						  infoTemplate:nil];
		
		//Add the graphic to the Graphics layer
		[self.trackGraphicsLayer addGraphic:myGraphic];
		
		//Tell the layer to redraw itself
		[self.trackGraphicsLayer dataChanged];	
		
				
		[webMercator release];
		
		return;
	}
 
Converting from WGS1984 to WebMercator:
#import "WebMercator.h"
#import <math.h>


@implementation WebMercator


- (double)toWebMercatorY:(double)latitude
{
	double rad = latitude * RADIANS_PER_DEGREES;
	double fsin = sin(rad);
	
	double y = 6378137 / 2.0 * log((1.0 + fsin) / (1.0 - fsin));
	
	return y;
}


- (double)toWebMercatorX:(double)longitude
{
	double x = longitude * 0.017453292519943 * 6378137;
	
	return x;
}

@end


Or you can use the methods from the iPhone ESRI SDK

() and AGSGeometryGeographicToWebMercator() functions to convert your geometries respectively.

Global Functions:

http://help.arcgis.com/en/arcgismobile/10.0/apis/iphone/reference/globals_func.html

 

 
blog comments powered by Disqus