CS185c
Chris Pollett
May 2, 2012
<!DOCTYPE html> <html> <head> <title>Location Test</title> </head> <body> <h1>Hi There</h1> <script type="text/javascript"> function mycallback(position) { alert("Your latitude is: " + position.coords.latitude); alert("Your longitude is: " + position.coords.longitude); alert("The accuracy is:" + position.coords.accuracy); } function error(msg) { if(msg) { alert(msg); } else { alert("that did not work"); } } if (navigator.geolocation) { navigator.geolocation.getCurrentPosition(mycallback, error); } else { error('not supported'); } </script> </body> </html>
<!DOCTYPE html> <html> <head> <title>A Google Test</title> </head> <body onload="drawMap()"> <h1>A Google Map</h1> <div id="mymap"></div> <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script> <!-- ?sensor=false means not determining location of map using a sensor--> <script type="text/javascript"> function drawMap() { var latlng = new google.maps.LatLng(37.375, -121.833); mapcanvas= document.getElementById("mymap"); mapcanvas.style.height = '400px'; mapcanvas.style.width = '600px'; var myOptions = { zoom: 15, center: latlng, mapTypeControl: false, navigationControlOptions: {style: google.maps.NavigationControlStyle.SMALL}, mapTypeId: google.maps.MapTypeId.ROADMAP }; var map = new google.maps.Map( mapcanvas, myOptions); var marker = new google.maps.Marker({ position: latlng, map: map, title:"This is a great pin!" }); } </script> </body> </html>
<html> <body> <div id="mapdiv" style="width:400px; height:400px"></div> <script src="http://www.openlayers.org/api/OpenLayers.js"></script> <script> map = new OpenLayers.Map("mapdiv"); map.addLayer(new OpenLayers.Layer.OSM()); var lonLat = new OpenLayers.LonLat( -0.1279688 ,51.5077286 ) .transform( new OpenLayers.Projection("EPSG:4326"), // transform from WGS 1984 map.getProjectionObject() // to Spherical Mercator Projection ); var zoom=16; var markers = new OpenLayers.Layer.Markers( "Markers" ); map.addLayer(markers); markers.addMarker(new OpenLayers.Marker(lonLat)); map.setCenter (lonLat, zoom); </script> </body> </html>
#import <UIKit/UIKit.h> #import <MapKit/MapKit.h> @class DetailViewController; @interface MapViewController : UIViewController <MKMapViewDelegate> { MKMapView *mapView; DetailViewController *detailViewController; NSMutableArray *mapAnnotations; } @property (nonatomic, retain) IBOutlet MKMapView *mapView; @property (nonatomic, retain) IBOutlet DetailViewController *detailViewController; @property (nonatomic, retain) NSMutableArray *mapAnnotations; + (CGFloat)annotationPadding; + (CGFloat)calloutHeight; - (IBAction)cityAction:(id)sender; - (IBAction)bridgeAction:(id)sender; - (IBAction)allAction:(id)sender; @end
#import "MapViewController.h" #import "DetailViewController.h" #import "SFAnnotation.h" #import "BridgeAnnotation.h" enum { kCityAnnotationIndex = 0, kBridgeAnnotationIndex }; @implementation MapViewController @synthesize mapView, detailViewController, mapAnnotations; #pragma mark - + (CGFloat)annotationPadding; { return 10.0f; } + (CGFloat)calloutHeight; { return 40.0f; } - (void)gotoLocation { // start off by default in San Francisco MKCoordinateRegion newRegion; newRegion.center.latitude = 37.786996; newRegion.center.longitude = -122.440100; newRegion.span.latitudeDelta = 0.112872; newRegion.span.longitudeDelta = 0.109863; [self.mapView setRegion:newRegion animated:YES]; } - (void)viewDidAppear:(BOOL)animated { // bring back the toolbar [self.navigationController setToolbarHidden:NO animated:NO]; } - (void)viewDidLoad { self.mapView.mapType = MKMapTypeStandard; // also MKMapTypeSatellite or MKMapTypeHybrid // create a custom navigation bar button and set it to always says "Back" UIBarButtonItem *temporaryBarButtonItem = [[UIBarButtonItem alloc] init]; temporaryBarButtonItem.title = @"Back"; self.navigationItem.backBarButtonItem = temporaryBarButtonItem; [temporaryBarButtonItem release]; // create out annotations array (in this example only 2) self.mapAnnotations = [[NSMutableArray alloc] initWithCapacity:2]; // annotation for the City of San Francisco SFAnnotation *sfAnnotation = [[SFAnnotation alloc] init]; [self.mapAnnotations insertObject:sfAnnotation atIndex:kCityAnnotationIndex]; [sfAnnotation release]; // annotation for Golden Gate Bridge BridgeAnnotation *bridgeAnnotation = [[BridgeAnnotation alloc] init]; [self.mapAnnotations insertObject:bridgeAnnotation atIndex:kBridgeAnnotationIndex]; [bridgeAnnotation release]; [self gotoLocation]; // finally goto San Francisco } - (void)viewDidUnload { self.mapAnnotations = nil; self.detailViewController = nil; self.mapView = nil; } - (void)dealloc { [mapView release]; [detailViewController release]; [mapAnnotations release]; [super dealloc]; } #pragma mark - #pragma mark ButtonActions - (IBAction)cityAction:(id)sender { [self gotoLocation];//"" avoid this by checking its region from ours?? [self.mapView removeAnnotations:self.mapView.annotations]; // remove any annotations that exist [self.mapView addAnnotation:[self.mapAnnotations objectAtIndex:kCityAnnotationIndex]]; } - (IBAction)bridgeAction:(id)sender { [self gotoLocation]; [self.mapView removeAnnotations:self.mapView.annotations]; // remove any annotations that exist [self.mapView addAnnotation:[self.mapAnnotations objectAtIndex:kBridgeAnnotationIndex]]; } - (IBAction)allAction:(id)sender { [self gotoLocation]; [self.mapView removeAnnotations:self.mapView.annotations]; // remove any annotations that exist [self.mapView addAnnotations:self.mapAnnotations]; } #pragma mark - #pragma mark MKMapViewDelegate - (void)showDetails:(id)sender { // the detail view does not want a toolbar so hide it [self.navigationController setToolbarHidden:YES animated:NO]; [self.navigationController pushViewController:self.detailViewController animated:YES]; } - (MKAnnotationView *)mapView:(MKMapView *)theMapView viewForAnnotation:(id)annotation { // if it's the user location, just return nil. if ([annotation isKindOfClass:[MKUserLocation class]]) return nil; // handle our two custom annotations // if ([annotation isKindOfClass:[BridgeAnnotation class]]) // for Golden Gate Bridge { // try to dequeue an existing pin view first static NSString* BridgeAnnotationIdentifier = @"bridgeAnnotationIdentifier"; MKPinAnnotationView* pinView = (MKPinAnnotationView *) [mapView dequeueReusableAnnotationViewWithIdentifier:BridgeAnnotationIdentifier]; if (!pinView) { // if an existing pin view was not available, create one MKPinAnnotationView* customPinView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:BridgeAnnotationIdentifier] autorelease]; customPinView.pinColor = MKPinAnnotationColorPurple; customPinView.animatesDrop = YES; customPinView.canShowCallout = YES; // add a detail disclosure button to the callout which will open a new view controller page // // note: you can assign a specific call out accessory view, or as MKMapViewDelegate you can implement: // - (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control; // UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; [rightButton addTarget:self action:@selector(showDetails:) forControlEvents:UIControlEventTouchUpInside]; customPinView.rightCalloutAccessoryView = rightButton; return customPinView; } else { pinView.annotation = annotation; } return pinView; } else if ([annotation isKindOfClass:[SFAnnotation class]]) // for City of San Francisco { static NSString* SFAnnotationIdentifier = @"SFAnnotationIdentifier"; MKPinAnnotationView* pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:SFAnnotationIdentifier]; if (!pinView) { MKAnnotationView *annotationView = [[[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:SFAnnotationIdentifier] autorelease]; annotationView.canShowCallout = YES; UIImage *flagImage = [UIImage imageNamed:@"flag.png"]; CGRect resizeRect; resizeRect.size = flagImage.size; CGSize maxSize = CGRectInset(self.view.bounds, [MapViewController annotationPadding], [MapViewController annotationPadding]).size; maxSize.height -= self.navigationController.navigationBar.frame.size.height + [MapViewController calloutHeight]; if (resizeRect.size.width > maxSize.width) resizeRect.size = CGSizeMake(maxSize.width, resizeRect.size.height / resizeRect.size.width * maxSize.width); if (resizeRect.size.height > maxSize.height) resizeRect.size = CGSizeMake(resizeRect.size.width / resizeRect.size.height * maxSize.height, maxSize.height); resizeRect.origin = (CGPoint){0.0f, 0.0f}; UIGraphicsBeginImageContext(resizeRect.size); [flagImage drawInRect:resizeRect]; UIImage *resizedImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); annotationView.image = resizedImage; annotationView.opaque = NO; UIImageView *sfIconView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"SFIcon.png"]]; annotationView.leftCalloutAccessoryView = sfIconView; [sfIconView release]; return annotationView; } else { pinView.annotation = annotation; } return pinView; } return nil; } @end
The app also has a DetailViewController .h and .m files but nothing particularly interesting is contain in them.
To control the text next to our pins we use Annotations. For San Francisco the header looks like:
#import <MapKit/MapKit.h> @interface SFAnnotation : NSObject <MKAnnotation> { UIImage *image; NSNumber *latitude; NSNumber *longitude; } @property (nonatomic, retain) UIImage *image; @property (nonatomic, retain) NSNumber *latitude; @property (nonatomic, retain) NSNumber *longitude; @end
The implementation looks like:
#import "SFAnnotation.h" @implementation SFAnnotation @synthesize image; @synthesize latitude; @synthesize longitude; - (CLLocationCoordinate2D)coordinate; { CLLocationCoordinate2D theCoordinate; theCoordinate.latitude = 37.786996; theCoordinate.longitude = -122.419281; return theCoordinate; } - (void)dealloc { [image release]; [super dealloc]; } - (NSString *)title { return @"San Francisco"; } // optional - (NSString *)subtitle { return @"Founded: June 29, 1776"; } @end
The header looks like:
#import <MapKit/MapKit.h> @interface BridgeAnnotation : NSObject{ } @end
The implementation looks like:
#import "BridgeAnnotation.h" @implementation BridgeAnnotation - (CLLocationCoordinate2D)coordinate; { CLLocationCoordinate2D theCoordinate; theCoordinate.latitude = 37.810000; theCoordinate.longitude = -122.477989; return theCoordinate; } // required if you set the MKPinAnnotationView's "canShowCallout" property to YES - (NSString *)title { return @"Golden Gate Bridge"; } // optional - (NSString *)subtitle { return @"Opened: May 27, 1937"; } - (void)dealloc { [super dealloc]; } @end