Rotation Of Maps

2472
4
10-20-2010 04:06 PM
ChrisBurns
New Contributor
I am currently working on a project to combine the ArcGIS on the iPad with ArcGIS running on a multitouch tabletop. One of our goals is to have the iPad "line up" with the underlying map when it's placed onto the table.

To accomplish this I would need to rotate the map with the same orientation as the iPad had relative to the tabletop. Is this possible to do using the API?  The use of envelopes seems to imply that "up" on the iPad is always north.

Any advice?


Chris
0 Kudos
4 Replies
NoureddineEl-zaatari
New Contributor
im trying to rotate the map based on data returned from GPS,, is there any way rotate maps on IOS devices ??
0 Kudos
DiveshGoyal
Esri Regular Contributor
Thank you for your feedback.

Map rotation is currently not supported (v2.0).

We hope to support it in an upcoming version.
0 Kudos
BedaKuster
New Contributor
Rotation of MapView can be implemented by setting mapView.transform = CGAffineTransformMakeRotation(alpha). This rotates the full mapView (including Callout, graphics...) on UIView-Base and can be hanged on your Compass with use of CLLocationManager.

You can try my code in "ZüriPlan" - App available on App Store.
PS: I block Interface rotation when Compass is active. Its a mess! Also deactivate Compass when Pushing your map away with NavigationController or if you leave MapView through TabViewController. Deactivate it when leaving the App or push the Standby button (AppDelegate Functions...) it's very Energy-hungry 😉

My Code:

Interface:

@Interface MapViewController:UIViewController<CLLocationManagerDelegate>
//CLLocationManagerDelegate provides functions to listen to Heading/GPS Change
{
....

      CGRect originalMapViewFrame; // Save the current mapView Size here
      IBOutlet AGSMapView *mapView; //your AGSMapView Reference...

      CLLocationManager *locationManager; //locationManager Instance


...

}


//Serve your LocationManager as retained Property to manage your Memory correctly, don't forgett to release it in your dealloc-Funciton
@property(retain) CLLocationManager *locationManager;


@end



Implementation:



@implementation MapViewController
@synthesize locationManager; //generate property code
...

-(void) startHeading
{
        //locationManager is an Object of Type CLLocationManager -> import CoreLocation
        if (!self.locationManager) {
  self.locationManager = [[[CLLocationManager alloc] init]autorelease];
  self.locationManager.delegate = self;
 }

        
        // First: Backup current mapview Size. It will be restored on stopHeading
 CGPoint origin = self.mapView.frame.origin;
 CGSize size = self.mapView.frame.size;
  
 originalMapViewFrame = CGRectMake(origin.x, origin.y, size.width, size.height);


        //Blow up your map to a Square, this will hide white Areas when rotating your map
        //The new size will be the diagonal length using Phytagoras...
        CGFloat newWidth = floor(sqrt(pow(size.width, 2) + pow(size.height, 2)));
 
        //Calculate new x and y origins  
 CGFloat x = origin.x - ((newWidth - size.width) /2);
 CGFloat y = origin.y - ((newWidth - size.height) /2);
  
        //Set the new Layoutinformation to your mapView
 self.mapView.frame = CGRectMake(x, y, newWidth, newWidth);
  
        //tell your LocationManager to start the updating
 [self.locationManager startUpdatingHeading];

}

//Will be called from locationManager and updates every Heading Changed
-(void) locationManager: (CLLocationManager *)manager didUpdateHeading: (CLHeading *)newHeading
{
 
        // Get your magneticHeading. If you need the "true" heading, use newHeading.trueHeading instead. But trueHeading only works, if GPS is enabled for your App and your Device is GPS ready...
 float heading = newHeading.magneticHeading;
 

        // You can use this block for smoother Rotation using a UIView Animation
 [UIView beginAnimations:nil context:UIGraphicsGetCurrentContext()];
 [UIView setAnimationCurve:UIViewAnimationCurveLinear];
 [UIView setAnimationDuration:0.05];
 
 //make some math (radial to degree or something...)
 float rotation = -1.0f * M_PI * (heading) / 180.0f;
 
        //Apply a rotation Transform to your map
 self.mapView.transform = CGAffineTransformMakeRotation( rotation);
 

        //Commit the animation
 [UIView commitAnimations];
 

        // if you need actual heading somewhere else, save it. otherwise you don't need this
 self.heading = rotation; 
}

//Stops heading
-(void) stopHeading
{
               [self.locationManager stopUpdatingHeading];
  
                //Remove Rotate Animation
  self.mapView.transform = CGAffineTransformMakeRotation(0);
  
              // Restore original Framedata for your mapView
  self.mapView.frame = originalMapViewFrame;

}
@end
0 Kudos
SandeepKuniel
New Contributor II
Thank you Beda,
I have been looking for this function for a long time and your approach works gr8.
0 Kudos